printf-parse.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  1. /* Formatted output to strings.
  2. Copyright (C) 1999-2000, 2002-2003, 2006 Free Software Foundation, Inc.
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2, or (at your option)
  6. any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License along
  12. with this program; if not, write to the Free Software Foundation,
  13. Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
  14. #include <config.h>
  15. /* Specification. */
  16. #if WIDE_CHAR_VERSION
  17. # include "wprintf-parse.h"
  18. #else
  19. # include "printf-parse.h"
  20. #endif
  21. /* Get size_t, NULL. */
  22. #include <stddef.h>
  23. /* Get intmax_t. */
  24. #if HAVE_STDINT_H_WITH_UINTMAX
  25. # include <stdint.h>
  26. #endif
  27. #if HAVE_INTTYPES_H_WITH_UINTMAX
  28. # include <inttypes.h>
  29. #endif
  30. /* malloc(), realloc(), free(). */
  31. #include <stdlib.h>
  32. /* Checked size_t computations. */
  33. #include "xsize.h"
  34. #if WIDE_CHAR_VERSION
  35. # define PRINTF_PARSE wprintf_parse
  36. # define CHAR_T wchar_t
  37. # define DIRECTIVE wchar_t_directive
  38. # define DIRECTIVES wchar_t_directives
  39. #else
  40. # define PRINTF_PARSE printf_parse
  41. # define CHAR_T char
  42. # define DIRECTIVE char_directive
  43. # define DIRECTIVES char_directives
  44. #endif
  45. #ifdef STATIC
  46. STATIC
  47. #endif
  48. int
  49. PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
  50. {
  51. const CHAR_T *cp = format; /* pointer into format */
  52. size_t arg_posn = 0; /* number of regular arguments consumed */
  53. size_t d_allocated; /* allocated elements of d->dir */
  54. size_t a_allocated; /* allocated elements of a->arg */
  55. size_t max_width_length = 0;
  56. size_t max_precision_length = 0;
  57. d->count = 0;
  58. d_allocated = 1;
  59. d->dir = (DIRECTIVE *) malloc (d_allocated * sizeof (DIRECTIVE));
  60. if (d->dir == NULL)
  61. /* Out of memory. */
  62. return -1;
  63. a->count = 0;
  64. a_allocated = 0;
  65. a->arg = NULL;
  66. #define REGISTER_ARG(_index_,_type_) \
  67. { \
  68. size_t n = (_index_); \
  69. if (n >= a_allocated) \
  70. { \
  71. size_t memory_size; \
  72. argument *memory; \
  73. \
  74. a_allocated = xtimes (a_allocated, 2); \
  75. if (a_allocated <= n) \
  76. a_allocated = xsum (n, 1); \
  77. memory_size = xtimes (a_allocated, sizeof (argument)); \
  78. if (size_overflow_p (memory_size)) \
  79. /* Overflow, would lead to out of memory. */ \
  80. goto error; \
  81. memory = (argument *) (a->arg \
  82. ? realloc (a->arg, memory_size) \
  83. : malloc (memory_size)); \
  84. if (memory == NULL) \
  85. /* Out of memory. */ \
  86. goto error; \
  87. a->arg = memory; \
  88. } \
  89. while (a->count <= n) \
  90. a->arg[a->count++].type = TYPE_NONE; \
  91. if (a->arg[n].type == TYPE_NONE) \
  92. a->arg[n].type = (_type_); \
  93. else if (a->arg[n].type != (_type_)) \
  94. /* Ambiguous type for positional argument. */ \
  95. goto error; \
  96. }
  97. while (*cp != '\0')
  98. {
  99. CHAR_T c = *cp++;
  100. if (c == '%')
  101. {
  102. size_t arg_index = ARG_NONE;
  103. DIRECTIVE *dp = &d->dir[d->count];/* pointer to next directive */
  104. /* Initialize the next directive. */
  105. dp->dir_start = cp - 1;
  106. dp->flags = 0;
  107. dp->width_start = NULL;
  108. dp->width_end = NULL;
  109. dp->width_arg_index = ARG_NONE;
  110. dp->precision_start = NULL;
  111. dp->precision_end = NULL;
  112. dp->precision_arg_index = ARG_NONE;
  113. dp->arg_index = ARG_NONE;
  114. /* Test for positional argument. */
  115. if (*cp >= '0' && *cp <= '9')
  116. {
  117. const CHAR_T *np;
  118. for (np = cp; *np >= '0' && *np <= '9'; np++)
  119. ;
  120. if (*np == '$')
  121. {
  122. size_t n = 0;
  123. for (np = cp; *np >= '0' && *np <= '9'; np++)
  124. n = xsum (xtimes (n, 10), *np - '0');
  125. if (n == 0)
  126. /* Positional argument 0. */
  127. goto error;
  128. if (size_overflow_p (n))
  129. /* n too large, would lead to out of memory later. */
  130. goto error;
  131. arg_index = n - 1;
  132. cp = np + 1;
  133. }
  134. }
  135. /* Read the flags. */
  136. for (;;)
  137. {
  138. if (*cp == '\'')
  139. {
  140. dp->flags |= FLAG_GROUP;
  141. cp++;
  142. }
  143. else if (*cp == '-')
  144. {
  145. dp->flags |= FLAG_LEFT;
  146. cp++;
  147. }
  148. else if (*cp == '+')
  149. {
  150. dp->flags |= FLAG_SHOWSIGN;
  151. cp++;
  152. }
  153. else if (*cp == ' ')
  154. {
  155. dp->flags |= FLAG_SPACE;
  156. cp++;
  157. }
  158. else if (*cp == '#')
  159. {
  160. dp->flags |= FLAG_ALT;
  161. cp++;
  162. }
  163. else if (*cp == '0')
  164. {
  165. dp->flags |= FLAG_ZERO;
  166. cp++;
  167. }
  168. else
  169. break;
  170. }
  171. /* Parse the field width. */
  172. if (*cp == '*')
  173. {
  174. dp->width_start = cp;
  175. cp++;
  176. dp->width_end = cp;
  177. if (max_width_length < 1)
  178. max_width_length = 1;
  179. /* Test for positional argument. */
  180. if (*cp >= '0' && *cp <= '9')
  181. {
  182. const CHAR_T *np;
  183. for (np = cp; *np >= '0' && *np <= '9'; np++)
  184. ;
  185. if (*np == '$')
  186. {
  187. size_t n = 0;
  188. for (np = cp; *np >= '0' && *np <= '9'; np++)
  189. n = xsum (xtimes (n, 10), *np - '0');
  190. if (n == 0)
  191. /* Positional argument 0. */
  192. goto error;
  193. if (size_overflow_p (n))
  194. /* n too large, would lead to out of memory later. */
  195. goto error;
  196. dp->width_arg_index = n - 1;
  197. cp = np + 1;
  198. }
  199. }
  200. if (dp->width_arg_index == ARG_NONE)
  201. {
  202. dp->width_arg_index = arg_posn++;
  203. if (dp->width_arg_index == ARG_NONE)
  204. /* arg_posn wrapped around. */
  205. goto error;
  206. }
  207. REGISTER_ARG (dp->width_arg_index, TYPE_INT);
  208. }
  209. else if (*cp >= '0' && *cp <= '9')
  210. {
  211. size_t width_length;
  212. dp->width_start = cp;
  213. for (; *cp >= '0' && *cp <= '9'; cp++)
  214. ;
  215. dp->width_end = cp;
  216. width_length = dp->width_end - dp->width_start;
  217. if (max_width_length < width_length)
  218. max_width_length = width_length;
  219. }
  220. /* Parse the precision. */
  221. if (*cp == '.')
  222. {
  223. cp++;
  224. if (*cp == '*')
  225. {
  226. dp->precision_start = cp - 1;
  227. cp++;
  228. dp->precision_end = cp;
  229. if (max_precision_length < 2)
  230. max_precision_length = 2;
  231. /* Test for positional argument. */
  232. if (*cp >= '0' && *cp <= '9')
  233. {
  234. const CHAR_T *np;
  235. for (np = cp; *np >= '0' && *np <= '9'; np++)
  236. ;
  237. if (*np == '$')
  238. {
  239. size_t n = 0;
  240. for (np = cp; *np >= '0' && *np <= '9'; np++)
  241. n = xsum (xtimes (n, 10), *np - '0');
  242. if (n == 0)
  243. /* Positional argument 0. */
  244. goto error;
  245. if (size_overflow_p (n))
  246. /* n too large, would lead to out of memory
  247. later. */
  248. goto error;
  249. dp->precision_arg_index = n - 1;
  250. cp = np + 1;
  251. }
  252. }
  253. if (dp->precision_arg_index == ARG_NONE)
  254. {
  255. dp->precision_arg_index = arg_posn++;
  256. if (dp->precision_arg_index == ARG_NONE)
  257. /* arg_posn wrapped around. */
  258. goto error;
  259. }
  260. REGISTER_ARG (dp->precision_arg_index, TYPE_INT);
  261. }
  262. else
  263. {
  264. size_t precision_length;
  265. dp->precision_start = cp - 1;
  266. for (; *cp >= '0' && *cp <= '9'; cp++)
  267. ;
  268. dp->precision_end = cp;
  269. precision_length = dp->precision_end - dp->precision_start;
  270. if (max_precision_length < precision_length)
  271. max_precision_length = precision_length;
  272. }
  273. }
  274. {
  275. arg_type type;
  276. /* Parse argument type/size specifiers. */
  277. {
  278. int flags = 0;
  279. for (;;)
  280. {
  281. if (*cp == 'h')
  282. {
  283. flags |= (1 << (flags & 1));
  284. cp++;
  285. }
  286. else if (*cp == 'L')
  287. {
  288. flags |= 4;
  289. cp++;
  290. }
  291. else if (*cp == 'l')
  292. {
  293. flags += 8;
  294. cp++;
  295. }
  296. #ifdef HAVE_INTMAX_T
  297. else if (*cp == 'j')
  298. {
  299. if (sizeof (intmax_t) > sizeof (long))
  300. {
  301. /* intmax_t = long long */
  302. flags += 16;
  303. }
  304. else if (sizeof (intmax_t) > sizeof (int))
  305. {
  306. /* intmax_t = long */
  307. flags += 8;
  308. }
  309. cp++;
  310. }
  311. #endif
  312. else if (*cp == 'z' || *cp == 'Z')
  313. {
  314. /* 'z' is standardized in ISO C 99, but glibc uses 'Z'
  315. because the warning facility in gcc-2.95.2 understands
  316. only 'Z' (see gcc-2.95.2/gcc/c-common.c:1784). */
  317. if (sizeof (size_t) > sizeof (long))
  318. {
  319. /* size_t = long long */
  320. flags += 16;
  321. }
  322. else if (sizeof (size_t) > sizeof (int))
  323. {
  324. /* size_t = long */
  325. flags += 8;
  326. }
  327. cp++;
  328. }
  329. else if (*cp == 't')
  330. {
  331. if (sizeof (ptrdiff_t) > sizeof (long))
  332. {
  333. /* ptrdiff_t = long long */
  334. flags += 16;
  335. }
  336. else if (sizeof (ptrdiff_t) > sizeof (int))
  337. {
  338. /* ptrdiff_t = long */
  339. flags += 8;
  340. }
  341. cp++;
  342. }
  343. else
  344. break;
  345. }
  346. /* Read the conversion character. */
  347. c = *cp++;
  348. switch (c)
  349. {
  350. case 'd': case 'i':
  351. #ifdef HAVE_LONG_LONG_INT
  352. /* If 'long long' exists and is larger than 'long': */
  353. if (flags >= 16 || (flags & 4))
  354. type = TYPE_LONGLONGINT;
  355. else
  356. #endif
  357. /* If 'long long' exists and is the same as 'long', we parse
  358. "lld" into TYPE_LONGINT. */
  359. if (flags >= 8)
  360. type = TYPE_LONGINT;
  361. else if (flags & 2)
  362. type = TYPE_SCHAR;
  363. else if (flags & 1)
  364. type = TYPE_SHORT;
  365. else
  366. type = TYPE_INT;
  367. break;
  368. case 'o': case 'u': case 'x': case 'X':
  369. #ifdef HAVE_LONG_LONG_INT
  370. /* If 'long long' exists and is larger than 'long': */
  371. if (flags >= 16 || (flags & 4))
  372. type = TYPE_ULONGLONGINT;
  373. else
  374. #endif
  375. /* If 'unsigned long long' exists and is the same as
  376. 'unsigned long', we parse "llu" into TYPE_ULONGINT. */
  377. if (flags >= 8)
  378. type = TYPE_ULONGINT;
  379. else if (flags & 2)
  380. type = TYPE_UCHAR;
  381. else if (flags & 1)
  382. type = TYPE_USHORT;
  383. else
  384. type = TYPE_UINT;
  385. break;
  386. case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
  387. case 'a': case 'A':
  388. #ifdef HAVE_LONG_DOUBLE
  389. if (flags >= 16 || (flags & 4))
  390. type = TYPE_LONGDOUBLE;
  391. else
  392. #endif
  393. type = TYPE_DOUBLE;
  394. break;
  395. case 'c':
  396. if (flags >= 8)
  397. #ifdef HAVE_WINT_T
  398. type = TYPE_WIDE_CHAR;
  399. #else
  400. goto error;
  401. #endif
  402. else
  403. type = TYPE_CHAR;
  404. break;
  405. #ifdef HAVE_WINT_T
  406. case 'C':
  407. type = TYPE_WIDE_CHAR;
  408. c = 'c';
  409. break;
  410. #endif
  411. case 's':
  412. if (flags >= 8)
  413. #ifdef HAVE_WCHAR_T
  414. type = TYPE_WIDE_STRING;
  415. #else
  416. goto error;
  417. #endif
  418. else
  419. type = TYPE_STRING;
  420. break;
  421. #ifdef HAVE_WCHAR_T
  422. case 'S':
  423. type = TYPE_WIDE_STRING;
  424. c = 's';
  425. break;
  426. #endif
  427. case 'p':
  428. type = TYPE_POINTER;
  429. break;
  430. case 'n':
  431. #ifdef HAVE_LONG_LONG_INT
  432. /* If 'long long' exists and is larger than 'long': */
  433. if (flags >= 16 || (flags & 4))
  434. type = TYPE_COUNT_LONGLONGINT_POINTER;
  435. else
  436. #endif
  437. /* If 'long long' exists and is the same as 'long', we parse
  438. "lln" into TYPE_COUNT_LONGINT_POINTER. */
  439. if (flags >= 8)
  440. type = TYPE_COUNT_LONGINT_POINTER;
  441. else if (flags & 2)
  442. type = TYPE_COUNT_SCHAR_POINTER;
  443. else if (flags & 1)
  444. type = TYPE_COUNT_SHORT_POINTER;
  445. else
  446. type = TYPE_COUNT_INT_POINTER;
  447. break;
  448. case '%':
  449. type = TYPE_NONE;
  450. break;
  451. default:
  452. /* Unknown conversion character. */
  453. goto error;
  454. }
  455. }
  456. if (type != TYPE_NONE)
  457. {
  458. dp->arg_index = arg_index;
  459. if (dp->arg_index == ARG_NONE)
  460. {
  461. dp->arg_index = arg_posn++;
  462. if (dp->arg_index == ARG_NONE)
  463. /* arg_posn wrapped around. */
  464. goto error;
  465. }
  466. REGISTER_ARG (dp->arg_index, type);
  467. }
  468. dp->conversion = c;
  469. dp->dir_end = cp;
  470. }
  471. d->count++;
  472. if (d->count >= d_allocated)
  473. {
  474. size_t memory_size;
  475. DIRECTIVE *memory;
  476. d_allocated = xtimes (d_allocated, 2);
  477. memory_size = xtimes (d_allocated, sizeof (DIRECTIVE));
  478. if (size_overflow_p (memory_size))
  479. /* Overflow, would lead to out of memory. */
  480. goto error;
  481. memory = (DIRECTIVE *) realloc (d->dir, memory_size);
  482. if (memory == NULL)
  483. /* Out of memory. */
  484. goto error;
  485. d->dir = memory;
  486. }
  487. }
  488. }
  489. d->dir[d->count].dir_start = cp;
  490. d->max_width_length = max_width_length;
  491. d->max_precision_length = max_precision_length;
  492. return 0;
  493. error:
  494. if (a->arg)
  495. free (a->arg);
  496. if (d->dir)
  497. free (d->dir);
  498. return -1;
  499. }
  500. #undef DIRECTIVES
  501. #undef DIRECTIVE
  502. #undef CHAR_T
  503. #undef PRINTF_PARSE