scan.c 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187
  1. /*++
  2. Copyright (c) 2013 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. scan.c
  9. Abstract:
  10. This module implements string scanning functions.
  11. Author:
  12. Evan Green 25-May-2013
  13. Environment:
  14. User Mode C Library
  15. --*/
  16. //
  17. // ------------------------------------------------------------------- Includes
  18. //
  19. #include "libcp.h"
  20. #include <assert.h>
  21. #include <limits.h>
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <errno.h>
  25. //
  26. // ---------------------------------------------------------------- Definitions
  27. //
  28. //
  29. // ------------------------------------------------------ Data Type Definitions
  30. //
  31. //
  32. // ----------------------------------------------- Internal Function Prototypes
  33. //
  34. BOOL
  35. ClpStreamScannerGetInput (
  36. PSCAN_INPUT Input,
  37. PCHAR Character
  38. );
  39. //
  40. // -------------------------------------------------------------------- Globals
  41. //
  42. //
  43. // ------------------------------------------------------------------ Functions
  44. //
  45. LIBC_API
  46. int
  47. sscanf (
  48. const char *Input,
  49. const char *Format,
  50. ...
  51. )
  52. /*++
  53. Routine Description:
  54. This routine scans in a string and converts it to a number of arguments
  55. based on a format string.
  56. Arguments:
  57. Input - Supplies a pointer to the input string to scan.
  58. Format - Supplies the format string that specifies how to convert the input
  59. to the arguments.
  60. ... - Supplies the remaining pointer arguments where the scanned data will
  61. be returned.
  62. Return Value:
  63. Returns the number of successfully matched items on success. If the input
  64. ends before the first matching failure or conversion, EOF is returned. If
  65. a read error occurs, EOF shall be returned and errno shall be set to
  66. indicate the error.
  67. --*/
  68. {
  69. va_list ArgumentList;
  70. ULONG FormatLength;
  71. ULONG InputLength;
  72. ULONG ItemsScanned;
  73. int ReturnValue;
  74. KSTATUS Status;
  75. va_start(ArgumentList, Format);
  76. InputLength = MAX_ULONG;
  77. FormatLength = MAX_ULONG;
  78. Status = RtlStringScanVaList((PSTR)Input,
  79. InputLength,
  80. (PSTR)Format,
  81. FormatLength,
  82. CharacterEncodingDefault,
  83. &ItemsScanned,
  84. ArgumentList);
  85. if (!KSUCCESS(Status)) {
  86. ReturnValue = EOF;
  87. errno = ClConvertKstatusToErrorNumber(Status);
  88. if (Status != STATUS_END_OF_FILE) {
  89. if (ItemsScanned != 0) {
  90. ReturnValue = ItemsScanned;
  91. }
  92. }
  93. } else {
  94. ReturnValue = ItemsScanned;
  95. }
  96. va_end(ArgumentList);
  97. return ReturnValue;
  98. }
  99. LIBC_API
  100. int
  101. vsscanf (
  102. const char *String,
  103. const char *Format,
  104. va_list ArgumentList
  105. )
  106. /*++
  107. Routine Description:
  108. This routine scans in a string and converts it to a number of arguments
  109. based on a format string.
  110. Arguments:
  111. String - Supplies a pointer to the input string to scan.
  112. Format - Supplies the format string that specifies how to convert the input
  113. to the arguments.
  114. ArgumentList - Supplies the remaining arguments, which are all pointers to
  115. various types to be scanned.
  116. Return Value:
  117. Returns the number of successfully matched items on success. If the input
  118. ends before the first matching failure or conversion, EOF is returned. If
  119. a read error occurs, EOF shall be returned and errno shall be set to
  120. indicate the error.
  121. --*/
  122. {
  123. ULONG FormatLength;
  124. ULONG InputLength;
  125. ULONG ItemsScanned;
  126. int ReturnValue;
  127. KSTATUS Status;
  128. InputLength = MAX_ULONG;
  129. FormatLength = MAX_ULONG;
  130. Status = RtlStringScanVaList((PSTR)String,
  131. InputLength,
  132. (PSTR)Format,
  133. FormatLength,
  134. CharacterEncodingDefault,
  135. &ItemsScanned,
  136. ArgumentList);
  137. if (Status == STATUS_END_OF_FILE) {
  138. assert(ItemsScanned == 0);
  139. ReturnValue = EOF;
  140. } else {
  141. ReturnValue = ItemsScanned;
  142. }
  143. return ReturnValue;
  144. }
  145. LIBC_API
  146. int
  147. fscanf (
  148. FILE *Stream,
  149. const char *Format,
  150. ...
  151. )
  152. /*++
  153. Routine Description:
  154. This routine scans in a string from a stream and converts it to a number of
  155. arguments based on a format string.
  156. Arguments:
  157. Stream - Supplies a pointer to the input stream.
  158. Format - Supplies the format string that specifies how to convert the input
  159. to the arguments.
  160. ... - Supplies the remaining arguments, which are all pointers to
  161. various types to be scanned.
  162. Return Value:
  163. Returns the number of successfully matched items on success. If the input
  164. ends before the first matching failure or conversion, EOF is returned. If
  165. a read error occurs, EOF shall be returned and errno shall be set to
  166. indicate the error.
  167. --*/
  168. {
  169. va_list ArgumentList;
  170. int Result;
  171. va_start(ArgumentList, Format);
  172. Result = vfscanf(Stream, Format, ArgumentList);
  173. va_end(ArgumentList);
  174. return Result;
  175. }
  176. LIBC_API
  177. int
  178. vfscanf (
  179. FILE *Stream,
  180. const char *Format,
  181. va_list ArgumentList
  182. )
  183. /*++
  184. Routine Description:
  185. This routine scans in a string from a stream and converts it to a number
  186. of arguments based on a format string.
  187. Arguments:
  188. Stream - Supplies a pointer to the input stream.
  189. Format - Supplies the format string that specifies how to convert the input
  190. to the arguments.
  191. ArgumentList - Supplies the remaining arguments, which are all pointers to
  192. various types to be scanned.
  193. Return Value:
  194. Returns the number of successfully matched items on success. If the input
  195. ends before the first matching failure or conversion, EOF is returned. If
  196. a read error occurs, EOF shall be returned and errno shall be set to
  197. indicate the error.
  198. --*/
  199. {
  200. int Result;
  201. ClpLockStream(Stream);
  202. Result = vfscanf_unlocked(Stream, Format, ArgumentList);
  203. ClpUnlockStream(Stream);
  204. return Result;
  205. }
  206. LIBC_API
  207. int
  208. vfscanf_unlocked (
  209. FILE *Stream,
  210. const char *Format,
  211. va_list ArgumentList
  212. )
  213. /*++
  214. Routine Description:
  215. This routine scans in a string from a stream and converts it to a number
  216. of arguments based on a format string. This routine does not acquire the
  217. stream's lock.
  218. Arguments:
  219. Stream - Supplies a pointer to the input stream.
  220. Format - Supplies the format string that specifies how to convert the input
  221. to the arguments.
  222. ArgumentList - Supplies the remaining arguments, which are all pointers to
  223. various types to be scanned.
  224. Return Value:
  225. Returns the number of successfully matched items on success. If the input
  226. ends before the first matching failure or conversion, EOF is returned. If
  227. a read error occurs, EOF shall be returned and errno shall be set to
  228. indicate the error.
  229. --*/
  230. {
  231. SCAN_INPUT Input;
  232. ULONG ItemsScanned;
  233. int ReturnValue;
  234. KSTATUS Status;
  235. RtlZeroMemory(&Input, sizeof(SCAN_INPUT));
  236. Input.DataU.Context = Stream;
  237. Input.ReadU.GetInput = ClpStreamScannerGetInput;
  238. RtlInitializeMultibyteState(&(Input.State), CharacterEncodingDefault);
  239. Status = RtlScan(&Input,
  240. (PSTR)Format,
  241. MAX_ULONG,
  242. &ItemsScanned,
  243. ArgumentList);
  244. if (Status == STATUS_END_OF_FILE) {
  245. assert(ItemsScanned == 0);
  246. ReturnValue = EOF;
  247. } else {
  248. ReturnValue = ItemsScanned;
  249. }
  250. //
  251. // Unget any characters that might be there.
  252. //
  253. while (Input.ValidUnputCharacters != 0) {
  254. ungetc_unlocked(Input.UnputCharacters[Input.ValidUnputCharacters - 1],
  255. Stream);
  256. Input.ValidUnputCharacters -= 1;
  257. }
  258. return ReturnValue;
  259. }
  260. LIBC_API
  261. int
  262. scanf (
  263. const char *Format,
  264. ...
  265. )
  266. /*++
  267. Routine Description:
  268. This routine scans in a string from standard in and converts it to a number
  269. of arguments based on a format string.
  270. Arguments:
  271. Format - Supplies the format string that specifies how to convert the input
  272. to the arguments.
  273. ... - Supplies the remaining arguments, which are all pointers to
  274. various types to be scanned.
  275. Return Value:
  276. Returns the number of successfully matched items on success. If the input
  277. ends before the first matching failure or conversion, EOF is returned. If
  278. a read error occurs, EOF shall be returned and errno shall be set to
  279. indicate the error.
  280. --*/
  281. {
  282. va_list ArgumentList;
  283. int Result;
  284. va_start(ArgumentList, Format);
  285. Result = vscanf(Format, ArgumentList);
  286. va_end(ArgumentList);
  287. return Result;
  288. }
  289. LIBC_API
  290. int
  291. vscanf (
  292. const char *Format,
  293. va_list ArgumentList
  294. )
  295. /*++
  296. Routine Description:
  297. This routine scans in a string from standard in and converts it to a number
  298. of arguments based on a format string.
  299. Arguments:
  300. Format - Supplies the format string that specifies how to convert the input
  301. to the arguments.
  302. ArgumentList - Supplies the remaining arguments, which are all pointers to
  303. various types to be scanned.
  304. Return Value:
  305. Returns the number of successfully matched items on success. If the input
  306. ends before the first matching failure or conversion, EOF is returned. If
  307. a read error occurs, EOF shall be returned and errno shall be set to
  308. indicate the error.
  309. --*/
  310. {
  311. int Result;
  312. Result = vfscanf(stdin, Format, ArgumentList);
  313. return Result;
  314. }
  315. LIBC_API
  316. int
  317. atoi (
  318. const char *String
  319. )
  320. /*++
  321. Routine Description:
  322. This routine converts a string to an integer. This routine is provided for
  323. compatibility with existing applications. New applications should use
  324. strtol instead.
  325. Arguments:
  326. String - Supplies a pointer to the null terminated string to convert to an
  327. integer.
  328. Return Value:
  329. Returns the integer representation of the string. If the value could not be
  330. converted, 0 is returned.
  331. --*/
  332. {
  333. return (int)strtol(String, NULL, 10);
  334. }
  335. LIBC_API
  336. double
  337. atof (
  338. const char *String
  339. )
  340. /*++
  341. Routine Description:
  342. This routine converts a string to a double floating point value. This
  343. routine is provided for compatibility with existing applications. New
  344. applications should use strtod instead.
  345. Arguments:
  346. String - Supplies a pointer to the null terminated string to convert to a
  347. double.
  348. Return Value:
  349. Returns the floating point representation of the string. If the value could
  350. not be converted, 0 is returned.
  351. --*/
  352. {
  353. return strtod(String, NULL);
  354. }
  355. LIBC_API
  356. long
  357. atol (
  358. const char *String
  359. )
  360. /*++
  361. Routine Description:
  362. This routine converts a string to an integer. This routine is provided for
  363. compatibility with existing applications. New applications should use
  364. strtol instead.
  365. Arguments:
  366. String - Supplies a pointer to the null terminated string to convert to an
  367. integer.
  368. Return Value:
  369. Returns the integer representation of the string. If the value could not be
  370. converted, 0 is returned.
  371. --*/
  372. {
  373. return strtol(String, NULL, 10);
  374. }
  375. LIBC_API
  376. long long
  377. atoll (
  378. const char *String
  379. )
  380. /*++
  381. Routine Description:
  382. This routine converts a string to an integer. This routine is provided for
  383. compatibility with existing applications. New applications should use
  384. strtoll instead.
  385. Arguments:
  386. String - Supplies a pointer to the null terminated string to convert to an
  387. integer.
  388. Return Value:
  389. Returns the integer representation of the string. If the value could not be
  390. converted, 0 is returned.
  391. --*/
  392. {
  393. return strtoll(String, NULL, 10);
  394. }
  395. LIBC_API
  396. float
  397. strtof (
  398. const char *String,
  399. char **StringAfterScan
  400. )
  401. /*++
  402. Routine Description:
  403. This routine converts the initial portion of the given string into a
  404. float. This routine will scan past any whitespace at the beginning of
  405. the string.
  406. Arguments:
  407. String - Supplies a pointer to the null terminated string to convert to a
  408. float.
  409. StringAfterScan - Supplies a pointer where a pointer will be returned
  410. representing the remaining portion of the string after the float was
  411. scanned. If the entire string is made up of whitespace or invalid
  412. characters, then this will point to the beginning of the given string
  413. (the scanner will not be advanced).
  414. Return Value:
  415. Returns the float representation of the string. If the value could not be
  416. converted, 0 is returned, and errno will be set to either EINVAL if the
  417. number could not be converted or ERANGE if the number is outside of the
  418. return type's expressible range.
  419. --*/
  420. {
  421. double Double;
  422. Double = strtod(String, StringAfterScan);
  423. return (float)Double;
  424. }
  425. LIBC_API
  426. double
  427. strtod (
  428. const char *String,
  429. char **StringAfterScan
  430. )
  431. /*++
  432. Routine Description:
  433. This routine converts the initial portion of the given string into a
  434. double. This routine will scan past any whitespace at the beginning of
  435. the string.
  436. Arguments:
  437. String - Supplies a pointer to the null terminated string to convert to a
  438. double.
  439. StringAfterScan - Supplies a pointer where a pointer will be returned
  440. representing the remaining portion of the string after the double was
  441. scanned. If the entire string is made up of whitespace or invalid
  442. characters, then this will point to the beginning of the given string
  443. (the scanner will not be advanced).
  444. Return Value:
  445. Returns the double representation of the string. If the value could not be
  446. converted, 0 is returned, and errno will be set to either EINVAL if the
  447. number could not be converted or ERANGE if the number is outside of the
  448. return type's expressible range.
  449. --*/
  450. {
  451. double Double;
  452. PCSTR RemainingString;
  453. KSTATUS Status;
  454. ULONG StringLength;
  455. StringLength = MAX_ULONG;
  456. RemainingString = (PSTR)String;
  457. Status = RtlStringScanDouble(&RemainingString, &StringLength, &Double);
  458. if (StringAfterScan != NULL) {
  459. *StringAfterScan = (PSTR)RemainingString;
  460. }
  461. if (!KSUCCESS(Status)) {
  462. if (Status == STATUS_INVALID_SEQUENCE) {
  463. Status = STATUS_INVALID_PARAMETER;
  464. }
  465. errno = ClConvertKstatusToErrorNumber(Status);
  466. return Double;
  467. }
  468. return Double;
  469. }
  470. LIBC_API
  471. long double
  472. strtold (
  473. const char *String,
  474. char **StringAfterScan
  475. )
  476. /*++
  477. Routine Description:
  478. This routine converts the initial portion of the given string into a
  479. long double. This routine will scan past any whitespace at the beginning of
  480. the string.
  481. Arguments:
  482. String - Supplies a pointer to the null terminated string to convert to a
  483. long double.
  484. StringAfterScan - Supplies a pointer where a pointer will be returned
  485. representing the remaining portion of the string after the long double
  486. was scanned. If the entire string is made up of whitespace or invalid
  487. characters, then this will point to the beginning of the given string
  488. (the scanner will not be advanced).
  489. Return Value:
  490. Returns the long double representation of the string. If the value could not
  491. be converted, 0 is returned, and errno will be set to either EINVAL if the
  492. number could not be converted or ERANGE if the number is outside of the
  493. return type's expressible range.
  494. --*/
  495. {
  496. double Double;
  497. Double = strtod(String, StringAfterScan);
  498. return (long double)Double;
  499. }
  500. LIBC_API
  501. long
  502. strtol (
  503. const char *String,
  504. char **StringAfterScan,
  505. int Base
  506. )
  507. /*++
  508. Routine Description:
  509. This routine converts the initial portion of the given string into an
  510. integer. This routine will scan past any whitespace at the beginning of
  511. the string. The string may have an optional plus or minus in front of the
  512. number to indicate sign.
  513. Arguments:
  514. String - Supplies a pointer to the null terminated string to convert to an
  515. integer.
  516. StringAfterScan - Supplies a pointer where a pointer will be returned
  517. representing the remaining portion of the string after the integer was
  518. scanned. If the entire string is made up of whitespace or invalid
  519. characters, then this will point to the beginning of the given string
  520. (the scanner will not be advanced).
  521. Base - Supplies the base system to interpret the number as. If zero is
  522. supplied, the base will be figured out based on the contents of the
  523. string. If the string begins with 0, it's treated as an octal (base 8)
  524. number. If the string begins with 1-9, it's treated as a decimal
  525. (base 10) number. And if the string begins with 0x or 0X, it's treated
  526. as a hexadecimal (base 16) number. Other base values must be specified
  527. explicitly here.
  528. Return Value:
  529. Returns the integer representation of the string. If the value could not be
  530. converted, 0 is returned, and errno will be set to either EINVAL if the
  531. number could not be converted or ERANGE if the number is outside of the
  532. return type's expressible range.
  533. --*/
  534. {
  535. LONGLONG Integer;
  536. PCSTR RemainingString;
  537. KSTATUS Status;
  538. ULONG StringLength;
  539. StringLength = MAX_ULONG;
  540. RemainingString = (PSTR)String;
  541. Status = RtlStringScanInteger(&RemainingString,
  542. &StringLength,
  543. Base,
  544. TRUE,
  545. &Integer);
  546. if (StringAfterScan != NULL) {
  547. *StringAfterScan = (PSTR)RemainingString;
  548. }
  549. if (!KSUCCESS(Status)) {
  550. errno = ClConvertKstatusToErrorNumber(Status);
  551. //
  552. // On integer overflow, set errno to ERANGE, but still return the
  553. // value, which will be a very extreme value.
  554. //
  555. if (Status == STATUS_INTEGER_OVERFLOW) {
  556. if (Integer == LLONG_MAX) {
  557. return LONG_MAX;
  558. }
  559. return LONG_MIN;
  560. } else {
  561. return 0;
  562. }
  563. }
  564. if (Integer > LONG_MAX) {
  565. errno = ERANGE;
  566. return LONG_MAX;
  567. } else if (Integer < LONG_MIN) {
  568. errno = ERANGE;
  569. return LONG_MIN;
  570. }
  571. return (LONG)Integer;
  572. }
  573. LIBC_API
  574. long long
  575. strtoll (
  576. const char *String,
  577. char **StringAfterScan,
  578. int Base
  579. )
  580. /*++
  581. Routine Description:
  582. This routine converts the initial portion of the given string into an
  583. integer. This routine will scan past any whitespace at the beginning of
  584. the string. The string may have an optional plus or minus in front of the
  585. number to indicate sign.
  586. Arguments:
  587. String - Supplies a pointer to the null terminated string to convert to an
  588. integer.
  589. StringAfterScan - Supplies a pointer where a pointer will be returned
  590. representing the remaining portion of the string after the integer was
  591. scanned. If the entire string is made up of whitespace or invalid
  592. characters, then this will point to the beginning of the given string
  593. (the scanner will not be advanced).
  594. Base - Supplies the base system to interpret the number as. If zero is
  595. supplied, the base will be figured out based on the contents of the
  596. string. If the string begins with 0, it's treated as an octal (base 8)
  597. number. If the string begins with 1-9, it's treated as a decimal
  598. (base 10) number. And if the string begins with 0x or 0X, it's treated
  599. as a hexadecimal (base 16) number. Other base values must be specified
  600. explicitly here.
  601. Return Value:
  602. Returns the integer representation of the string. If the value could not be
  603. converted, 0 is returned, and errno will be set to EINVAL to indicate the
  604. number could not be converted.
  605. --*/
  606. {
  607. LONGLONG Integer;
  608. PCSTR RemainingString;
  609. KSTATUS Status;
  610. ULONG StringLength;
  611. StringLength = MAX_ULONG;
  612. RemainingString = (PSTR)String;
  613. Status = RtlStringScanInteger(&RemainingString,
  614. &StringLength,
  615. Base,
  616. TRUE,
  617. &Integer);
  618. if (StringAfterScan != NULL) {
  619. *StringAfterScan = (PSTR)RemainingString;
  620. }
  621. if (!KSUCCESS(Status)) {
  622. if (Status != STATUS_INTEGER_OVERFLOW) {
  623. Integer = 0;
  624. }
  625. errno = ClConvertKstatusToErrorNumber(Status);
  626. }
  627. return Integer;
  628. }
  629. LIBC_API
  630. unsigned long
  631. strtoul (
  632. const char *String,
  633. char **StringAfterScan,
  634. int Base
  635. )
  636. /*++
  637. Routine Description:
  638. This routine converts the initial portion of the given string into an
  639. integer. This routine will scan past any whitespace at the beginning of
  640. the string. The string may have an optional plus or minus in front of the
  641. number to indicate sign.
  642. Arguments:
  643. String - Supplies a pointer to the null terminated string to convert to an
  644. integer.
  645. StringAfterScan - Supplies a pointer where a pointer will be returned
  646. representing the remaining portion of the string after the integer was
  647. scanned. If the entire string is made up of whitespace or invalid
  648. characters, then this will point to the beginning of the given string
  649. (the scanner will not be advanced).
  650. Base - Supplies the base system to interpret the number as. If zero is
  651. supplied, the base will be figured out based on the contents of the
  652. string. If the string begins with 0, it's treated as an octal (base 8)
  653. number. If the string begins with 1-9, it's treated as a decimal
  654. (base 10) number. And if the string begins with 0x or 0X, it's treated
  655. as a hexadecimal (base 16) number. Other base values must be specified
  656. explicitly here.
  657. Return Value:
  658. Returns the integer representation of the string. If the value could not be
  659. converted, 0 is returned, and errno will be set to either EINVAL if the
  660. number could not be converted or ERANGE if the number is outside of the
  661. return type's expressible range.
  662. --*/
  663. {
  664. LONGLONG Integer;
  665. PCSTR RemainingString;
  666. KSTATUS Status;
  667. ULONG StringLength;
  668. StringLength = MAX_ULONG;
  669. RemainingString = (PSTR)String;
  670. Status = RtlStringScanInteger(&RemainingString,
  671. &StringLength,
  672. Base,
  673. FALSE,
  674. &Integer);
  675. if (StringAfterScan != NULL) {
  676. *StringAfterScan = (PSTR)RemainingString;
  677. }
  678. if (!KSUCCESS(Status)) {
  679. errno = ClConvertKstatusToErrorNumber(Status);
  680. if (Status == STATUS_INTEGER_OVERFLOW) {
  681. return ULONG_MAX;
  682. } else {
  683. return 0;
  684. }
  685. }
  686. if ((ULONGLONG)Integer > ULONG_MAX) {
  687. errno = ERANGE;
  688. return ULONG_MAX;
  689. }
  690. return (ULONG)(ULONGLONG)Integer;
  691. }
  692. LIBC_API
  693. unsigned long long
  694. strtoull (
  695. const char *String,
  696. char **StringAfterScan,
  697. int Base
  698. )
  699. /*++
  700. Routine Description:
  701. This routine converts the initial portion of the given string into an
  702. integer. This routine will scan past any whitespace at the beginning of
  703. the string. The string may have an optional plus or minus in front of the
  704. number to indicate sign.
  705. Arguments:
  706. String - Supplies a pointer to the null terminated string to convert to an
  707. integer.
  708. StringAfterScan - Supplies a pointer where a pointer will be returned
  709. representing the remaining portion of the string after the integer was
  710. scanned. If the entire string is made up of whitespace or invalid
  711. characters, then this will point to the beginning of the given string
  712. (the scanner will not be advanced).
  713. Base - Supplies the base system to interpret the number as. If zero is
  714. supplied, the base will be figured out based on the contents of the
  715. string. If the string begins with 0, it's treated as an octal (base 8)
  716. number. If the string begins with 1-9, it's treated as a decimal
  717. (base 10) number. And if the string begins with 0x or 0X, it's treated
  718. as a hexadecimal (base 16) number. Other base values must be specified
  719. explicitly here.
  720. Return Value:
  721. Returns the integer representation of the string. If the value could not be
  722. converted, 0 is returned, and errno will be set to EINVAL to indicate the
  723. number could not be converted.
  724. --*/
  725. {
  726. LONGLONG Integer;
  727. PCSTR RemainingString;
  728. KSTATUS Status;
  729. ULONG StringLength;
  730. StringLength = MAX_ULONG;
  731. RemainingString = (PSTR)String;
  732. Status = RtlStringScanInteger(&RemainingString,
  733. &StringLength,
  734. Base,
  735. FALSE,
  736. &Integer);
  737. if (StringAfterScan != NULL) {
  738. *StringAfterScan = (PSTR)RemainingString;
  739. }
  740. if (!KSUCCESS(Status)) {
  741. if (Status != STATUS_INTEGER_OVERFLOW) {
  742. Integer = 0;
  743. }
  744. errno = ClConvertKstatusToErrorNumber(Status);
  745. }
  746. return (ULONGLONG)Integer;
  747. }
  748. LIBC_API
  749. intmax_t
  750. strtoimax (
  751. const char *String,
  752. char **StringAfterScan,
  753. int Base
  754. )
  755. /*++
  756. Routine Description:
  757. This routine converts the initial portion of the given string into an
  758. integer. This routine will scan past any whitespace at the beginning of
  759. the string. The string may have an optional plus or minus in front of the
  760. number to indicate sign.
  761. Arguments:
  762. String - Supplies a pointer to the null terminated string to convert to an
  763. integer.
  764. StringAfterScan - Supplies a pointer where a pointer will be returned
  765. representing the remaining portion of the string after the integer was
  766. scanned. If the entire string is made up of whitespace or invalid
  767. characters, then this will point to the beginning of the given string
  768. (the scanner will not be advanced).
  769. Base - Supplies the base system to interpret the number as. If zero is
  770. supplied, the base will be figured out based on the contents of the
  771. string. If the string begins with 0, it's treated as an octal (base 8)
  772. number. If the string begins with 1-9, it's treated as a decimal
  773. (base 10) number. And if the string begins with 0x or 0X, it's treated
  774. as a hexadecimal (base 16) number. Other base values must be specified
  775. explicitly here.
  776. Return Value:
  777. Returns the integer representation of the string. If the value could not be
  778. converted, 0 is returned, and errno will be set to EINVAL to indicate the
  779. number could not be converted.
  780. --*/
  781. {
  782. return strtoll(String, StringAfterScan, Base);
  783. }
  784. LIBC_API
  785. uintmax_t
  786. strtoumax (
  787. const char *String,
  788. char **StringAfterScan,
  789. int Base
  790. )
  791. /*++
  792. Routine Description:
  793. This routine converts the initial portion of the given string into an
  794. integer. This routine will scan past any whitespace at the beginning of
  795. the string. The string may have an optional plus or minus in front of the
  796. number to indicate sign.
  797. Arguments:
  798. String - Supplies a pointer to the null terminated string to convert to an
  799. integer.
  800. StringAfterScan - Supplies a pointer where a pointer will be returned
  801. representing the remaining portion of the string after the integer was
  802. scanned. If the entire string is made up of whitespace or invalid
  803. characters, then this will point to the beginning of the given string
  804. (the scanner will not be advanced).
  805. Base - Supplies the base system to interpret the number as. If zero is
  806. supplied, the base will be figured out based on the contents of the
  807. string. If the string begins with 0, it's treated as an octal (base 8)
  808. number. If the string begins with 1-9, it's treated as a decimal
  809. (base 10) number. And if the string begins with 0x or 0X, it's treated
  810. as a hexadecimal (base 16) number. Other base values must be specified
  811. explicitly here.
  812. Return Value:
  813. Returns the integer representation of the string. If the value could not be
  814. converted, 0 is returned, and errno will be set to EINVAL to indicate the
  815. number could not be converted.
  816. --*/
  817. {
  818. return strtoull(String, StringAfterScan, Base);
  819. }
  820. //
  821. // --------------------------------------------------------- Internal Functions
  822. //
  823. BOOL
  824. ClpStreamScannerGetInput (
  825. PSCAN_INPUT Input,
  826. PCHAR Character
  827. )
  828. /*++
  829. Routine Description:
  830. This routine retrieves another byte of input from the input scanner for a
  831. stream based scanner.
  832. Arguments:
  833. Input - Supplies a pointer to the input scanner structure.
  834. Character - Supplies a pointer where the character will be returned on
  835. success.
  836. Return Value:
  837. TRUE if a character was read.
  838. FALSE if the end of the file or string was encountered.
  839. --*/
  840. {
  841. int NewCharacter;
  842. NewCharacter = fgetc_unlocked(Input->DataU.Context);
  843. if (NewCharacter == EOF) {
  844. return FALSE;
  845. }
  846. *Character = (CHAR)NewCharacter;
  847. Input->CharactersRead += 1;
  848. return TRUE;
  849. }