~ubuntu-branches/ubuntu/oneiric/gnupg2/oneiric-updates

« back to all changes in this revision

Viewing changes to intl/printf-parse.c

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Viehmann
  • Date: 2008-10-04 10:25:53 UTC
  • mfrom: (5.1.15 intrepid)
  • Revision ID: james.westby@ubuntu.com-20081004102553-fv62pp8dsitxli47
Tags: 2.0.9-3.1
* Non-maintainer upload.
* agent/gpg-agent.c: Deinit the threading library before exec'ing
  the command to run in --daemon mode. And because that still doesn't
  restore the sigprocmask, do that manually. Closes: #499569

Show diffs side-by-side

added added

removed removed

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