fmt.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440
  1. /*
  2. * Copyright (c) 2010-2018 Richard Braun.
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. *
  17. * Upstream site with license notes :
  18. * http://git.sceen.net/rbraun/librbraun.git/
  19. */
  20. #include <assert.h>
  21. #include <errno.h>
  22. #include <limits.h>
  23. #include <stdbool.h>
  24. #include <stdarg.h>
  25. #include <stddef.h>
  26. #include <stdint.h>
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include <kern/fmt.h>
  30. #include <kern/macros.h>
  31. #include <kern/types.h>
  32. /*
  33. * Size for the temporary number buffer. The minimum base is 8 so 3 bits
  34. * are consumed per digit. Add one to round up. The conversion algorithm
  35. * doesn't use the null byte.
  36. */
  37. #define FMT_MAX_NUM_SIZE \
  38. (((sizeof (uint64_t) * CHAR_BIT) / 3) + 1)
  39. // Special character used to denote that the putback buffer is empty.
  40. #define FMT_NOPUTBACK (EOF - 1)
  41. /*
  42. * Formatting flags.
  43. *
  44. * FMT_FORMAT_LOWER must be 0x20 as it is OR'd with fmt_digits, eg.
  45. * '0': 0x30 | 0x20 => 0x30 ('0')
  46. * 'A': 0x41 | 0x20 => 0x61 ('a')
  47. */
  48. #define FMT_FORMAT_ALT_FORM 0x0001 // "Alternate form"
  49. #define FMT_FORMAT_ZERO_PAD 0x0002 // Zero padding on the left
  50. #define FMT_FORMAT_LEFT_JUSTIFY 0x0004 // Align text on the left
  51. #define FMT_FORMAT_BLANK 0x0008 // Blank space before positive number
  52. #define FMT_FORMAT_SIGN 0x0010 // Always place a sign (either + or -)
  53. #define FMT_FORMAT_LOWER 0x0020 // To lowercase (for %x)
  54. #define FMT_FORMAT_CONV_SIGNED 0x0040 // Format specifies signed conversion
  55. #define FMT_FORMAT_DISCARD 0x0080 // Discard output (scanf)
  56. #define FMT_FORMAT_CHECK_WIDTH 0x0100 // Check field width (scanf)
  57. enum
  58. {
  59. FMT_MODIFIER_NONE,
  60. FMT_MODIFIER_CHAR,
  61. FMT_MODIFIER_SHORT,
  62. FMT_MODIFIER_LONG,
  63. FMT_MODIFIER_LONGLONG,
  64. FMT_MODIFIER_PTR, // Used only for %p
  65. FMT_MODIFIER_SIZE,
  66. FMT_MODIFIER_PTRDIFF,
  67. };
  68. enum
  69. {
  70. FMT_SPECIFIER_INVALID,
  71. FMT_SPECIFIER_INT,
  72. FMT_SPECIFIER_CHAR,
  73. FMT_SPECIFIER_STR,
  74. FMT_SPECIFIER_NRCHARS,
  75. FMT_SPECIFIER_PERCENT,
  76. };
  77. /*
  78. * Note that copies of the original va_list object are made, because va_arg()
  79. * may not reliably be used by different callee functions, and despite the
  80. * standard explicitely allowing pointers to va_list objects, it's apparently
  81. * very difficult for implementations to provide and is best avoided.
  82. */
  83. struct fmt_ostate
  84. {
  85. const char *format;
  86. va_list ap;
  87. unsigned int flags;
  88. int width;
  89. int precision;
  90. unsigned int modifier;
  91. unsigned int specifier;
  92. unsigned int base;
  93. struct stream *stream;
  94. int nr_chars;
  95. };
  96. struct fmt_istate
  97. {
  98. const char *format;
  99. va_list ap;
  100. unsigned int flags;
  101. int width;
  102. unsigned int modifier;
  103. unsigned int specifier;
  104. unsigned int base;
  105. int nr_convs;
  106. struct stream *stream;
  107. int nr_chars;
  108. int cur_ch;
  109. };
  110. static const char fmt_digits[] = "0123456789ABCDEF";
  111. static char
  112. fmt_consume (const char **strp)
  113. {
  114. char c = **strp;
  115. (*strp)++;
  116. return (c);
  117. }
  118. static bool
  119. fmt_isdigit (char c)
  120. {
  121. return (c >= '0' && c <= '9');
  122. }
  123. static bool
  124. fmt_isxdigit (char c)
  125. {
  126. return (fmt_isdigit (c) ||
  127. (c >= 'a' && c <= 'f') ||
  128. (c >= 'A' && c <= 'F'));
  129. }
  130. static void
  131. fmt_ostate_init (struct fmt_ostate *state, struct stream *stream,
  132. const char *format, va_list ap)
  133. {
  134. state->format = format;
  135. va_copy (state->ap, ap);
  136. state->stream = stream;
  137. state->nr_chars = 0;
  138. stream_lock (state->stream);
  139. }
  140. static void
  141. fmt_ostate_produce_raw_char (struct fmt_ostate *state, char c)
  142. {
  143. stream_write_unlocked (state->stream, &c, 1);
  144. ++state->nr_chars;
  145. }
  146. static void
  147. fmt_ostate_produce_raw_str (struct fmt_ostate *state,
  148. const char *s, int n)
  149. {
  150. stream_write_unlocked (state->stream, s, n);
  151. state->nr_chars += n;
  152. }
  153. static int
  154. fmt_ostate_finalize (struct fmt_ostate *state)
  155. {
  156. va_end (state->ap);
  157. stream_unlock (state->stream);
  158. return (state->nr_chars);
  159. }
  160. static char
  161. fmt_ostate_consume_format (struct fmt_ostate *state)
  162. {
  163. return (*state->format++);
  164. }
  165. static void
  166. fmt_ostate_restore_format (struct fmt_ostate *state)
  167. {
  168. --state->format;
  169. }
  170. static void
  171. fmt_ostate_consume_flags (struct fmt_ostate *state)
  172. {
  173. bool found = true;
  174. state->flags = 0;
  175. do
  176. {
  177. int c = fmt_ostate_consume_format (state);
  178. switch (c)
  179. {
  180. case '#':
  181. state->flags |= FMT_FORMAT_ALT_FORM;
  182. break;
  183. case '0':
  184. state->flags |= FMT_FORMAT_ZERO_PAD;
  185. break;
  186. case '-':
  187. state->flags |= FMT_FORMAT_LEFT_JUSTIFY;
  188. break;
  189. case ' ':
  190. state->flags |= FMT_FORMAT_BLANK;
  191. break;
  192. case '+':
  193. state->flags |= FMT_FORMAT_SIGN;
  194. break;
  195. default:
  196. found = false;
  197. break;
  198. }
  199. }
  200. while (found);
  201. fmt_ostate_restore_format (state);
  202. }
  203. static void
  204. fmt_ostate_consume_width (struct fmt_ostate *state)
  205. {
  206. int c = fmt_ostate_consume_format (state);
  207. if (fmt_isdigit (c))
  208. {
  209. state->width = 0;
  210. do
  211. {
  212. state->width = state->width * 10 + (c - '0');
  213. c = fmt_ostate_consume_format (state);
  214. }
  215. while (fmt_isdigit (c));
  216. fmt_ostate_restore_format (state);
  217. }
  218. else if (c == '*')
  219. {
  220. state->width = va_arg (state->ap, int);
  221. if (state->width < 0)
  222. {
  223. state->flags |= FMT_FORMAT_LEFT_JUSTIFY;
  224. state->width = -state->width;
  225. }
  226. }
  227. else
  228. {
  229. state->width = 0;
  230. fmt_ostate_restore_format (state);
  231. }
  232. }
  233. static void
  234. fmt_ostate_consume_precision (struct fmt_ostate *state)
  235. {
  236. int c = fmt_ostate_consume_format (state);
  237. if (c == '.')
  238. {
  239. c = fmt_ostate_consume_format (state);
  240. if (fmt_isdigit (c))
  241. {
  242. state->precision = 0;
  243. do
  244. {
  245. state->precision = state->precision * 10 + (c - '0');
  246. c = fmt_ostate_consume_format (state);
  247. }
  248. while (fmt_isdigit (c));
  249. fmt_ostate_restore_format (state);
  250. }
  251. else if (c == '*')
  252. {
  253. state->precision = va_arg (state->ap, int);
  254. if (state->precision < 0)
  255. state->precision = 0;
  256. }
  257. else
  258. {
  259. state->precision = 0;
  260. fmt_ostate_restore_format (state);
  261. }
  262. }
  263. else
  264. { // precision is >= 0 only if explicit.
  265. state->precision = -1;
  266. fmt_ostate_restore_format (state);
  267. }
  268. }
  269. static void
  270. fmt_ostate_consume_modifier (struct fmt_ostate *state)
  271. {
  272. int c2, c = fmt_ostate_consume_format (state);
  273. switch (c)
  274. {
  275. case 'h':
  276. case 'l':
  277. c2 = fmt_ostate_consume_format (state);
  278. if (c == c2)
  279. state->modifier = c == 'h' ?
  280. FMT_MODIFIER_CHAR : FMT_MODIFIER_LONGLONG;
  281. else
  282. {
  283. state->modifier = c == 'h' ?
  284. FMT_MODIFIER_SHORT : FMT_MODIFIER_LONG;
  285. fmt_ostate_restore_format (state);
  286. }
  287. break;
  288. case 'z':
  289. state->modifier = FMT_MODIFIER_SIZE;
  290. __fallthrough;
  291. case 't':
  292. state->modifier = FMT_MODIFIER_PTRDIFF;
  293. break;
  294. default:
  295. state->modifier = FMT_MODIFIER_NONE;
  296. fmt_ostate_restore_format (state);
  297. break;
  298. }
  299. }
  300. static void
  301. fmt_ostate_consume_specifier (struct fmt_ostate *state)
  302. {
  303. int c = fmt_ostate_consume_format (state);
  304. switch (c)
  305. {
  306. case 'd':
  307. case 'i':
  308. state->flags |= FMT_FORMAT_CONV_SIGNED;
  309. __fallthrough;
  310. case 'u':
  311. state->base = 10;
  312. state->specifier = FMT_SPECIFIER_INT;
  313. break;
  314. case 'o':
  315. state->base = 8;
  316. state->specifier = FMT_SPECIFIER_INT;
  317. break;
  318. case 'p':
  319. state->flags |= FMT_FORMAT_ALT_FORM;
  320. state->modifier = FMT_MODIFIER_PTR;
  321. __fallthrough;
  322. case 'x':
  323. state->flags |= FMT_FORMAT_LOWER;
  324. __fallthrough;
  325. case 'X':
  326. state->base = 16;
  327. state->specifier = FMT_SPECIFIER_INT;
  328. break;
  329. case 'c':
  330. state->specifier = FMT_SPECIFIER_CHAR;
  331. break;
  332. case 's':
  333. state->specifier = FMT_SPECIFIER_STR;
  334. break;
  335. case 'n':
  336. state->specifier = FMT_SPECIFIER_NRCHARS;
  337. break;
  338. case '%':
  339. state->specifier = FMT_SPECIFIER_PERCENT;
  340. break;
  341. default:
  342. state->specifier = FMT_SPECIFIER_INVALID;
  343. fmt_ostate_restore_format (state);
  344. break;
  345. }
  346. }
  347. static int
  348. fmt_ostate_consume (struct fmt_ostate *state)
  349. {
  350. int c = fmt_consume (&state->format);
  351. if (! c)
  352. return (ENOENT);
  353. else if (c != '%')
  354. {
  355. fmt_ostate_produce_raw_char (state, c);
  356. return (EAGAIN);
  357. }
  358. fmt_ostate_consume_flags (state);
  359. fmt_ostate_consume_width (state);
  360. fmt_ostate_consume_precision (state);
  361. fmt_ostate_consume_modifier (state);
  362. fmt_ostate_consume_specifier (state);
  363. return (0);
  364. }
  365. static void
  366. fmt_ostate_produce_int (struct fmt_ostate *state)
  367. {
  368. uint64_t n;
  369. switch (state->modifier)
  370. {
  371. case FMT_MODIFIER_CHAR:
  372. if (state->flags & FMT_FORMAT_CONV_SIGNED)
  373. n = (signed char) va_arg (state->ap, int);
  374. else
  375. n = (unsigned char) va_arg (state->ap, int);
  376. break;
  377. case FMT_MODIFIER_SHORT:
  378. if (state->flags & FMT_FORMAT_CONV_SIGNED)
  379. n = (short) va_arg (state->ap, int);
  380. else
  381. n = (unsigned short) va_arg (state->ap, int);
  382. break;
  383. case FMT_MODIFIER_LONG:
  384. if (state->flags & FMT_FORMAT_CONV_SIGNED)
  385. n = va_arg (state->ap, long);
  386. else
  387. n = va_arg (state->ap, unsigned long);
  388. break;
  389. case FMT_MODIFIER_LONGLONG:
  390. if (state->flags & FMT_FORMAT_CONV_SIGNED)
  391. n = va_arg (state->ap, long long);
  392. else
  393. n = va_arg (state->ap, unsigned long long);
  394. break;
  395. case FMT_MODIFIER_PTR:
  396. n = (uintptr_t) va_arg (state->ap, void *);
  397. break;
  398. case FMT_MODIFIER_SIZE:
  399. if (state->flags & FMT_FORMAT_CONV_SIGNED)
  400. n = va_arg (state->ap, ssize_t);
  401. else
  402. n = va_arg (state->ap, size_t);
  403. break;
  404. case FMT_MODIFIER_PTRDIFF:
  405. n = va_arg (state->ap, ptrdiff_t);
  406. break;
  407. default:
  408. if (state->flags & FMT_FORMAT_CONV_SIGNED)
  409. n = va_arg (state->ap, int);
  410. else
  411. n = va_arg (state->ap, unsigned int);
  412. break;
  413. }
  414. if ((state->flags & FMT_FORMAT_LEFT_JUSTIFY) || state->precision >= 0)
  415. state->flags &= ~FMT_FORMAT_ZERO_PAD;
  416. int sign = '\0';
  417. if (state->flags & FMT_FORMAT_ALT_FORM)
  418. {
  419. // '0' for octal.
  420. --state->width;
  421. // '0x' or '0X' for hexadecimal.
  422. if (state->base == 16)
  423. --state->width;
  424. }
  425. else if (state->flags & FMT_FORMAT_CONV_SIGNED)
  426. {
  427. if ((int64_t)n < 0)
  428. {
  429. sign = '-';
  430. --state->width;
  431. n = -(int64_t)n;
  432. }
  433. else if (state->flags & FMT_FORMAT_SIGN)
  434. { // FMT_FORMAT_SIGN must precede FMT_FORMAT_BLANK.
  435. sign = '+';
  436. --state->width;
  437. }
  438. else if (state->flags & FMT_FORMAT_BLANK)
  439. {
  440. sign = ' ';
  441. --state->width;
  442. }
  443. }
  444. // Convert the integer.
  445. int i, c;
  446. char tmp[FMT_MAX_NUM_SIZE], *outp = tmp + sizeof (tmp);
  447. if (! n)
  448. {
  449. if (state->precision)
  450. *--outp = '0';
  451. }
  452. else if (state->base == 10)
  453. {
  454. /*
  455. * Try to avoid 64 bits operations if the processor doesn't
  456. * support them. Note that even when using modulus and
  457. * division operators close to each other, the compiler may
  458. * forge two functions calls to compute the quotient and the
  459. * remainder, whereas processor instructions are generally
  460. * correctly used once, giving both results at once, through
  461. * plain or reciprocal division.
  462. */
  463. #ifndef __LP64__
  464. if (state->modifier == FMT_MODIFIER_LONGLONG)
  465. {
  466. #endif
  467. do
  468. {
  469. uint32_t r = n % 10;
  470. n /= 10;
  471. *--outp = fmt_digits[r];
  472. }
  473. while (n);
  474. #ifndef __LP64__
  475. }
  476. else
  477. {
  478. uint32_t m = (uint32_t)n;
  479. do
  480. {
  481. uint32_t r = m % 10;
  482. m /= 10;
  483. *--outp = fmt_digits[r];
  484. }
  485. while (m);
  486. }
  487. #endif
  488. }
  489. else
  490. {
  491. uint32_t mask = state->base - 1,
  492. shift = state->base == 8 ? 3 : 4;
  493. do
  494. {
  495. uint32_t r = n & mask;
  496. n >>= shift;
  497. *--outp = fmt_digits[r] | (state->flags & FMT_FORMAT_LOWER);
  498. }
  499. while (n);
  500. }
  501. i = (int)(&tmp[sizeof (tmp)] - outp);
  502. if (i > state->precision)
  503. state->precision = i;
  504. state->width -= state->precision;
  505. if (!(state->flags & (FMT_FORMAT_LEFT_JUSTIFY | FMT_FORMAT_ZERO_PAD)))
  506. {
  507. for (; state->width > 0; --state->width)
  508. fmt_ostate_produce_raw_char (state, ' ');
  509. --state->width;
  510. }
  511. if (state->flags & FMT_FORMAT_ALT_FORM)
  512. {
  513. fmt_ostate_produce_raw_char (state, '0');
  514. if (state->base == 16)
  515. {
  516. c = 'X' | (state->flags & FMT_FORMAT_LOWER);
  517. fmt_ostate_produce_raw_char (state, c);
  518. }
  519. }
  520. else if (sign)
  521. fmt_ostate_produce_raw_char (state, sign);
  522. if (!(state->flags & FMT_FORMAT_LEFT_JUSTIFY))
  523. {
  524. c = (state->flags & FMT_FORMAT_ZERO_PAD) ? '0' : ' ';
  525. for (; state->width > 0; --state->width)
  526. fmt_ostate_produce_raw_char (state, c);
  527. --state->width;
  528. }
  529. for (; i < state->precision; --state->precision)
  530. fmt_ostate_produce_raw_char (state, '0');
  531. --state->precision;
  532. fmt_ostate_produce_raw_str (state, outp, i);
  533. for (; state->width > 0; --state->width)
  534. fmt_ostate_produce_raw_char (state, ' ');
  535. --state->width;
  536. }
  537. static void
  538. fmt_ostate_produce_char (struct fmt_ostate *state)
  539. {
  540. int c = va_arg (state->ap, int);
  541. if (!(state->flags & FMT_FORMAT_LEFT_JUSTIFY))
  542. while (1)
  543. {
  544. if (--state->width <= 0)
  545. break;
  546. fmt_ostate_produce_raw_char (state, ' ');
  547. }
  548. fmt_ostate_produce_raw_char (state, c);
  549. while (1)
  550. {
  551. if (--state->width <= 0)
  552. break;
  553. fmt_ostate_produce_raw_char (state, ' ');
  554. }
  555. }
  556. static void
  557. fmt_ostate_produce_str (struct fmt_ostate *state)
  558. {
  559. char *s = va_arg (state->ap, char *);
  560. if (! s)
  561. s = "(null)";
  562. int len;
  563. for (len = 0; s[len] != '\0'; len++)
  564. if (len == state->precision)
  565. break;
  566. if (!(state->flags & FMT_FORMAT_LEFT_JUSTIFY))
  567. for (; len < state->width; --state->width)
  568. fmt_ostate_produce_raw_char (state, ' ');
  569. fmt_ostate_produce_raw_str (state, s, len);
  570. for (; len < state->width; --state->width)
  571. fmt_ostate_produce_raw_char (state, ' ');
  572. }
  573. static void
  574. fmt_ostate_produce_nrchars (struct fmt_ostate *state)
  575. {
  576. if (state->modifier == FMT_MODIFIER_CHAR)
  577. *va_arg(state->ap, signed char *) = state->nr_chars;
  578. else if (state->modifier == FMT_MODIFIER_SHORT)
  579. *va_arg(state->ap, short *) = state->nr_chars;
  580. else if (state->modifier == FMT_MODIFIER_LONG)
  581. *va_arg(state->ap, long *) = state->nr_chars;
  582. else if (state->modifier == FMT_MODIFIER_LONGLONG)
  583. *va_arg(state->ap, long long *) = state->nr_chars;
  584. else if (state->modifier == FMT_MODIFIER_SIZE)
  585. *va_arg(state->ap, ssize_t *) = state->nr_chars;
  586. else if (state->modifier == FMT_MODIFIER_PTRDIFF)
  587. *va_arg(state->ap, ptrdiff_t *) = state->nr_chars;
  588. else
  589. *va_arg(state->ap, int *) = state->nr_chars;
  590. }
  591. static void
  592. fmt_ostate_produce (struct fmt_ostate *state)
  593. {
  594. switch (state->specifier)
  595. {
  596. case FMT_SPECIFIER_INT:
  597. fmt_ostate_produce_int (state);
  598. break;
  599. case FMT_SPECIFIER_CHAR:
  600. fmt_ostate_produce_char (state);
  601. break;
  602. case FMT_SPECIFIER_STR:
  603. fmt_ostate_produce_str (state);
  604. break;
  605. case FMT_SPECIFIER_NRCHARS:
  606. fmt_ostate_produce_nrchars (state);
  607. break;
  608. case FMT_SPECIFIER_PERCENT:
  609. case FMT_SPECIFIER_INVALID:
  610. fmt_ostate_produce_raw_char (state, '%');
  611. break;
  612. }
  613. }
  614. int
  615. fmt_vxprintf (struct stream *stream, const char *format, va_list ap)
  616. {
  617. struct fmt_ostate state;
  618. fmt_ostate_init (&state, stream, format, ap);
  619. while (1)
  620. {
  621. int error = fmt_ostate_consume (&state);
  622. if (error == EAGAIN)
  623. continue;
  624. else if (error)
  625. break;
  626. fmt_ostate_produce (&state);
  627. }
  628. return (fmt_ostate_finalize (&state));
  629. }
  630. int
  631. fmt_xprintf (struct stream *stream, const char *format, ...)
  632. {
  633. va_list ap;
  634. va_start (ap, format);
  635. int ret = fmt_vxprintf (stream, format, ap);
  636. va_end (ap);
  637. return (ret);
  638. }
  639. int
  640. fmt_sprintf (char *str, const char *format, ...)
  641. {
  642. va_list ap;
  643. va_start (ap, format);
  644. int length = fmt_vsprintf (str, format, ap);
  645. va_end (ap);
  646. return (length);
  647. }
  648. int
  649. fmt_vsprintf (char *str, const char *format, va_list ap)
  650. {
  651. return (fmt_vsnprintf (str, SIZE_MAX, format, ap));
  652. }
  653. int
  654. fmt_snprintf (char *str, size_t size, const char *format, ...)
  655. {
  656. va_list ap;
  657. va_start (ap, format);
  658. int length = fmt_vsnprintf (str, size, format, ap);
  659. va_end (ap);
  660. return (length);
  661. }
  662. int
  663. fmt_vsnprintf (char *str, size_t size, const char *format, va_list ap)
  664. {
  665. struct string_stream stream;
  666. string_stream_init (&stream, str, size);
  667. int ret = fmt_vxprintf (&stream.base, format, ap);
  668. if (ret >= 0)
  669. stream_putc (&stream.base, '\0');
  670. return (ret);
  671. }
  672. static char
  673. fmt_atoi (char c)
  674. {
  675. assert (fmt_isxdigit (c));
  676. if (fmt_isdigit (c))
  677. return (c - '0');
  678. else if (c >= 'a' && c <= 'f')
  679. return (10 + (c - 'a'));
  680. else
  681. return (10 + (c - 'A'));
  682. }
  683. static bool
  684. fmt_isspace (char c)
  685. {
  686. return (c == ' ' || (c >= '\t' && c <= '\f'));
  687. }
  688. static void
  689. fmt_istate_init (struct fmt_istate *state, struct stream *stream,
  690. const char *format, va_list ap)
  691. {
  692. state->format = format;
  693. state->flags = 0;
  694. state->width = 0;
  695. va_copy (state->ap, ap);
  696. state->nr_convs = 0;
  697. state->stream = stream;
  698. state->nr_chars = 0;
  699. state->cur_ch = FMT_NOPUTBACK;
  700. stream_lock (state->stream);
  701. }
  702. static int
  703. fmt_istate_finalize (struct fmt_istate *state)
  704. {
  705. va_end (state->ap);
  706. stream_unlock (state->stream);
  707. return (state->nr_convs);
  708. }
  709. static void
  710. fmt_istate_report_conv (struct fmt_istate *state)
  711. {
  712. if (state->nr_convs != EOF)
  713. ++state->nr_convs;
  714. else
  715. state->nr_convs = 1;
  716. }
  717. static void
  718. fmt_istate_report_error (struct fmt_istate *state)
  719. {
  720. if (!state->nr_convs)
  721. state->nr_convs = EOF;
  722. }
  723. static void
  724. fmt_istate_putback (struct fmt_istate *state, int ch)
  725. {
  726. state->cur_ch = ch;
  727. }
  728. static int
  729. fmt_istate_consume_char (struct fmt_istate *state)
  730. {
  731. int ch;
  732. if (state->cur_ch != FMT_NOPUTBACK)
  733. {
  734. ch = state->cur_ch;
  735. state->cur_ch = FMT_NOPUTBACK;
  736. }
  737. else
  738. {
  739. char byte = '\0';
  740. int n = stream_read_unlocked (state->stream, &byte, 1);
  741. ch = n > 0 && byte ? (int)byte : EOF;
  742. }
  743. ++state->nr_chars;
  744. return ch;
  745. }
  746. static void
  747. fmt_istate_skip_space (struct fmt_istate *state)
  748. {
  749. while (1)
  750. {
  751. int ch = fmt_istate_consume_char (state);
  752. if (ch < 0 || !fmt_isspace (ch))
  753. {
  754. fmt_istate_putback (state, ch);
  755. break;
  756. }
  757. }
  758. }
  759. static char
  760. fmt_istate_consume_string (struct fmt_istate *state)
  761. {
  762. int c = fmt_istate_consume_char (state);
  763. if (state->flags & FMT_FORMAT_CHECK_WIDTH)
  764. {
  765. if (state->width == 0)
  766. c = EOF;
  767. else
  768. --state->width;
  769. }
  770. return (c);
  771. }
  772. static void
  773. fmt_istate_restore_string (struct fmt_istate *state, int ch)
  774. {
  775. assert (state->cur_ch == FMT_NOPUTBACK);
  776. state->cur_ch = ch;
  777. }
  778. static char
  779. fmt_istate_consume_format (struct fmt_istate *state)
  780. {
  781. return (*state->format++);
  782. }
  783. static void
  784. fmt_istate_restore_format (struct fmt_istate *state)
  785. {
  786. --state->format;
  787. }
  788. static void
  789. fmt_istate_consume_flags (struct fmt_istate *state)
  790. {
  791. bool found = true;
  792. state->flags = 0;
  793. do
  794. {
  795. int c = fmt_istate_consume_format (state);
  796. switch (c)
  797. {
  798. case '*':
  799. state->flags |= FMT_FORMAT_DISCARD;
  800. break;
  801. default:
  802. found = false;
  803. break;
  804. }
  805. }
  806. while (found);
  807. fmt_istate_restore_format (state);
  808. }
  809. static void
  810. fmt_istate_consume_width (struct fmt_istate *state)
  811. {
  812. state->width = 0;
  813. while (1)
  814. {
  815. int c = fmt_istate_consume_format (state);
  816. if (!fmt_isdigit (c))
  817. break;
  818. state->width = state->width * 10 + (c - '0');
  819. }
  820. if (state->width != 0)
  821. state->flags |= FMT_FORMAT_CHECK_WIDTH;
  822. fmt_istate_restore_format (state);
  823. }
  824. static void
  825. fmt_istate_consume_modifier (struct fmt_istate *state)
  826. {
  827. int c2, c = fmt_istate_consume_format (state);
  828. switch (c)
  829. {
  830. case 'h':
  831. case 'l':
  832. c2 = fmt_istate_consume_format (state);
  833. if (c == c2)
  834. state->modifier = c == 'h' ?
  835. FMT_MODIFIER_CHAR : FMT_MODIFIER_LONGLONG;
  836. else
  837. {
  838. state->modifier = c == 'h' ?
  839. FMT_MODIFIER_SHORT : FMT_MODIFIER_LONG;
  840. fmt_istate_restore_format (state);
  841. }
  842. break;
  843. case 'z':
  844. state->modifier = FMT_MODIFIER_SIZE;
  845. break;
  846. case 't':
  847. state->modifier = FMT_MODIFIER_PTRDIFF;
  848. break;
  849. default:
  850. state->modifier = FMT_MODIFIER_NONE;
  851. fmt_istate_restore_format (state);
  852. break;
  853. }
  854. }
  855. static void
  856. fmt_istate_consume_specifier (struct fmt_istate *state)
  857. {
  858. int c = fmt_istate_consume_format (state);
  859. switch (c)
  860. {
  861. case 'i':
  862. state->base = 0;
  863. state->flags |= FMT_FORMAT_CONV_SIGNED;
  864. state->specifier = FMT_SPECIFIER_INT;
  865. break;
  866. case 'd':
  867. state->flags |= FMT_FORMAT_CONV_SIGNED;
  868. __fallthrough;
  869. case 'u':
  870. state->base = 10;
  871. state->specifier = FMT_SPECIFIER_INT;
  872. break;
  873. case 'o':
  874. state->base = 8;
  875. state->specifier = FMT_SPECIFIER_INT;
  876. break;
  877. case 'p':
  878. state->modifier = FMT_MODIFIER_PTR;
  879. __fallthrough;
  880. case 'x':
  881. case 'X':
  882. state->base = 16;
  883. state->specifier = FMT_SPECIFIER_INT;
  884. break;
  885. case 'c':
  886. state->specifier = FMT_SPECIFIER_CHAR;
  887. break;
  888. case 's':
  889. state->specifier = FMT_SPECIFIER_STR;
  890. break;
  891. case 'n':
  892. state->specifier = FMT_SPECIFIER_NRCHARS;
  893. break;
  894. case '%':
  895. state->specifier = FMT_SPECIFIER_PERCENT;
  896. break;
  897. default:
  898. state->specifier = FMT_SPECIFIER_INVALID;
  899. fmt_istate_restore_format (state);
  900. break;
  901. }
  902. }
  903. static int
  904. fmt_istate_discard_char (struct fmt_istate *state, int c)
  905. {
  906. if (fmt_isspace (c))
  907. {
  908. fmt_istate_skip_space (state);
  909. return (0);
  910. }
  911. int c2 = fmt_istate_consume_string (state);
  912. if (c != c2)
  913. {
  914. if (!c2 && !state->nr_convs)
  915. state->nr_convs = EOF;
  916. return (EINVAL);
  917. }
  918. return (0);
  919. }
  920. static int
  921. fmt_istate_consume (struct fmt_istate *state)
  922. {
  923. state->flags = 0;
  924. int c = fmt_istate_consume_format (state);
  925. if (! c)
  926. return (ENOENT);
  927. else if (c != '%')
  928. {
  929. int error = fmt_istate_discard_char (state, c);
  930. return (error ?: EAGAIN);
  931. }
  932. fmt_istate_consume_flags (state);
  933. fmt_istate_consume_width (state);
  934. fmt_istate_consume_modifier (state);
  935. fmt_istate_consume_specifier (state);
  936. return (0);
  937. }
  938. static int
  939. fmt_istate_produce_int (struct fmt_istate *state)
  940. {
  941. fmt_istate_skip_space (state);
  942. int c = fmt_istate_consume_string (state);
  943. bool negative = false;
  944. if (c == '-')
  945. {
  946. negative = true;
  947. c = fmt_istate_consume_string (state);
  948. }
  949. if (c == '0')
  950. {
  951. c = fmt_istate_consume_string (state);
  952. if (c == 'x' || c == 'X')
  953. {
  954. if (state->base == 0)
  955. state->base = 16;
  956. if (state->base == 16)
  957. c = fmt_istate_consume_string (state);
  958. else
  959. {
  960. fmt_istate_restore_string (state, c);
  961. c = '0';
  962. }
  963. }
  964. else
  965. {
  966. if (state->base == 0)
  967. state->base = 8;
  968. if (state->base != 8)
  969. {
  970. fmt_istate_restore_string (state, c);
  971. c = '0';
  972. }
  973. }
  974. }
  975. size_t i = 0;
  976. char buf[FMT_MAX_NUM_SIZE];
  977. for (; c; ++i)
  978. {
  979. if (state->base == 8)
  980. {
  981. if (!(c >= '0' && c <= '7'))
  982. break;
  983. }
  984. else if (state->base == 16)
  985. {
  986. if (!fmt_isxdigit (c))
  987. break;
  988. }
  989. else
  990. {
  991. if (!fmt_isdigit (c))
  992. break;
  993. }
  994. // XXX Standard sscanf provides no way to cleanly handle overflows.
  995. if (i < ARRAY_SIZE (buf) - 1)
  996. buf[i] = c;
  997. else if (i == ARRAY_SIZE (buf) - 1)
  998. {
  999. buf[0] = '1', buf[1] = '\0';
  1000. negative = true;
  1001. }
  1002. c = fmt_istate_consume_string (state);
  1003. }
  1004. fmt_istate_restore_string (state, c);
  1005. if (state->flags & FMT_FORMAT_DISCARD)
  1006. return (0);
  1007. if (! i)
  1008. {
  1009. if (! c)
  1010. {
  1011. fmt_istate_report_error (state);
  1012. return (EINVAL);
  1013. }
  1014. buf[i++] = '0';
  1015. }
  1016. if (i < ARRAY_SIZE (buf))
  1017. buf[i--] = '\0';
  1018. else
  1019. i = (int)strlen (buf) - 1;
  1020. uint64_t n = 0;
  1021. #ifndef __LP64__
  1022. if (state->modifier == FMT_MODIFIER_LONGLONG)
  1023. {
  1024. #endif
  1025. uint64_t m = 1, tmp = 0;
  1026. for (; &buf[i] >= buf; --i)
  1027. {
  1028. tmp += fmt_atoi (buf[i]) * m;
  1029. if (tmp < n)
  1030. {
  1031. n = 1;
  1032. negative = true;
  1033. break;
  1034. }
  1035. n = tmp;
  1036. m *= state->base;
  1037. }
  1038. #ifndef __LP64__
  1039. }
  1040. else
  1041. {
  1042. uint32_t ln = 0, lm = 1, ltmp = 0;
  1043. for (; &buf[i] >= buf; --i)
  1044. {
  1045. ltmp += fmt_atoi (buf[i]) * lm;
  1046. if (ltmp < ln)
  1047. {
  1048. ln = 1;
  1049. negative = true;
  1050. break;
  1051. }
  1052. ln = ltmp;
  1053. lm *= state->base;
  1054. }
  1055. n = ln;
  1056. }
  1057. #endif
  1058. if (negative)
  1059. n = -n;
  1060. switch (state->modifier)
  1061. {
  1062. case FMT_MODIFIER_CHAR:
  1063. if (state->flags & FMT_FORMAT_CONV_SIGNED)
  1064. *va_arg(state->ap, char *) = n;
  1065. else
  1066. *va_arg(state->ap, unsigned char *) = n;
  1067. break;
  1068. case FMT_MODIFIER_SHORT:
  1069. if (state->flags & FMT_FORMAT_CONV_SIGNED)
  1070. *va_arg(state->ap, short *) = n;
  1071. else
  1072. *va_arg(state->ap, unsigned short *) = n;
  1073. break;
  1074. case FMT_MODIFIER_LONG:
  1075. if (state->flags & FMT_FORMAT_CONV_SIGNED)
  1076. *va_arg(state->ap, long *) = n;
  1077. else
  1078. *va_arg(state->ap, unsigned long *) = n;
  1079. break;
  1080. case FMT_MODIFIER_LONGLONG:
  1081. if (state->flags & FMT_FORMAT_CONV_SIGNED)
  1082. *va_arg(state->ap, long long *) = n;
  1083. else
  1084. *va_arg(state->ap, unsigned long long *) = n;
  1085. break;
  1086. case FMT_MODIFIER_PTR:
  1087. *va_arg(state->ap, uintptr_t *) = n;
  1088. break;
  1089. case FMT_MODIFIER_SIZE:
  1090. *va_arg(state->ap, size_t *) = n;
  1091. break;
  1092. case FMT_MODIFIER_PTRDIFF:
  1093. *va_arg(state->ap, ptrdiff_t *) = n;
  1094. break;
  1095. default:
  1096. if (state->flags & FMT_FORMAT_CONV_SIGNED)
  1097. *va_arg(state->ap, int *) = n;
  1098. else
  1099. *va_arg(state->ap, unsigned int *) = n;
  1100. }
  1101. fmt_istate_report_conv (state);
  1102. return (0);
  1103. }
  1104. static int
  1105. fmt_istate_produce_char (struct fmt_istate *state)
  1106. {
  1107. char dummy, *dest;
  1108. int i, off = 1;
  1109. if (state->flags & FMT_FORMAT_DISCARD)
  1110. dest = &dummy, off = 0;
  1111. else
  1112. dest = va_arg (state->ap, char *);
  1113. int c, width = (state->flags & FMT_FORMAT_CHECK_WIDTH) ? state->width : 1;
  1114. for (i = 0; i < width; i++)
  1115. {
  1116. c = fmt_istate_consume_string (state);
  1117. if (!c || c == EOF)
  1118. break;
  1119. *dest = c;
  1120. dest += off;
  1121. }
  1122. if (i < width)
  1123. fmt_istate_restore_string (state, c);
  1124. if (off && i)
  1125. fmt_istate_report_conv (state);
  1126. return (0);
  1127. }
  1128. static int
  1129. fmt_istate_produce_str (struct fmt_istate *state)
  1130. {
  1131. int off = 1, orig = state->nr_chars;
  1132. fmt_istate_skip_space (state);
  1133. char dummy, *dest;
  1134. if (state->flags & FMT_FORMAT_DISCARD)
  1135. {
  1136. dest = &dummy;
  1137. off = 0;
  1138. }
  1139. else
  1140. dest = va_arg (state->ap, char *);
  1141. int c;
  1142. while (1)
  1143. {
  1144. c = fmt_istate_consume_string (state);
  1145. if (!c || c == ' ' || c == EOF)
  1146. break;
  1147. *dest = c;
  1148. dest += off;
  1149. }
  1150. fmt_istate_restore_string (state, c);
  1151. if (state->nr_chars == orig)
  1152. {
  1153. fmt_istate_report_error (state);
  1154. return (EINVAL);
  1155. }
  1156. else if (off)
  1157. {
  1158. *dest = '\0';
  1159. fmt_istate_report_conv (state);
  1160. }
  1161. return (0);
  1162. }
  1163. static int
  1164. fmt_istate_produce_nrchars (struct fmt_istate *state)
  1165. {
  1166. *va_arg(state->ap, int *) = state->nr_chars;
  1167. return (0);
  1168. }
  1169. static int
  1170. fmt_istate_produce (struct fmt_istate *state)
  1171. {
  1172. switch (state->specifier)
  1173. {
  1174. case FMT_SPECIFIER_INT:
  1175. return (fmt_istate_produce_int (state));
  1176. case FMT_SPECIFIER_CHAR:
  1177. return (fmt_istate_produce_char (state));
  1178. case FMT_SPECIFIER_STR:
  1179. return (fmt_istate_produce_str (state));
  1180. case FMT_SPECIFIER_NRCHARS:
  1181. return (fmt_istate_produce_nrchars (state));
  1182. case FMT_SPECIFIER_PERCENT:
  1183. fmt_istate_skip_space (state);
  1184. return (fmt_istate_discard_char (state, '%'));
  1185. default:
  1186. fmt_istate_report_error (state);
  1187. return (EINVAL);
  1188. }
  1189. }
  1190. int
  1191. fmt_vxscanf (struct stream *stream, const char *format, va_list ap)
  1192. {
  1193. struct fmt_istate state;
  1194. fmt_istate_init (&state, stream, format, ap);
  1195. while (1)
  1196. {
  1197. int error = fmt_istate_consume (&state);
  1198. if (error == EAGAIN)
  1199. continue;
  1200. else if (error)
  1201. break;
  1202. error = fmt_istate_produce (&state);
  1203. if (error)
  1204. break;
  1205. }
  1206. return (fmt_istate_finalize (&state));
  1207. }
  1208. int
  1209. fmt_xscanf (struct stream *stream, const char *format, ...)
  1210. {
  1211. va_list ap;
  1212. va_start (ap, format);
  1213. int ret = fmt_vxscanf (stream, format, ap);
  1214. va_end (ap);
  1215. return (ret);
  1216. }
  1217. int
  1218. fmt_sscanf (const char *str, const char *format, ...)
  1219. {
  1220. va_list ap;
  1221. va_start (ap, format);
  1222. int ret = fmt_vsscanf (str, format, ap);
  1223. va_end (ap);
  1224. return (ret);
  1225. }
  1226. int
  1227. fmt_vsscanf (const char *str, const char *format, va_list ap)
  1228. {
  1229. struct string_stream stream;
  1230. string_stream_init (&stream, (char *)str, SIZE_MAX);
  1231. return (fmt_vxscanf (&stream.base, format, ap));
  1232. }