~ubuntu-branches/ubuntu/saucy/m17n-lib/saucy

« back to all changes in this revision

Viewing changes to intl/printf-parse.c

  • Committer: Bazaar Package Importer
  • Author(s): Harshula Jayasuriya
  • Date: 2010-11-23 01:39:29 UTC
  • mfrom: (1.2.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20101123013929-rs3kpqgu4kr3qx32
Tags: 1.6.2-1
* New upstream release 1.6.2.
* Update Standards-Version to Debian Policy 3.9.1. (No changes)
* debian/control: Depends: m17n-db and m17n-contrib. (Closes: #599643)
* PATCH: (make_locale): Don't call setlocale.  Just parse the arg NAME.
         (Closes: #601858)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* Formatted output to strings.
2
 
   Copyright (C) 1999-2000, 2002-2003 Free Software Foundation, Inc.
 
2
   Copyright (C) 1999-2000, 2002-2003, 2006-2007 Free Software Foundation, Inc.
3
3
 
4
4
   This program is free software; you can redistribute it and/or modify it
5
5
   under the terms of the GNU Library General Public License as published
13
13
 
14
14
   You should have received a copy of the GNU Library General Public
15
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,
 
16
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
17
17
   USA.  */
18
18
 
19
 
#ifdef HAVE_CONFIG_H
 
19
/* This file can be parametrized with the following macros:
 
20
     CHAR_T             The element type of the format string.
 
21
     CHAR_T_ONLY_ASCII  Set to 1 to enable verification that all characters
 
22
                        in the format string are ASCII.
 
23
     DIRECTIVE          Structure denoting a format directive.
 
24
                        Depends on CHAR_T.
 
25
     DIRECTIVES         Structure denoting the set of format directives of a
 
26
                        format string.  Depends on CHAR_T.
 
27
     PRINTF_PARSE       Function that parses a format string.
 
28
                        Depends on CHAR_T.
 
29
     STATIC             Set to 'static' to declare the function static.
 
30
     ENABLE_UNISTDIO    Set to 1 to enable the unistdio extensions.  */
 
31
 
 
32
#ifndef PRINTF_PARSE
20
33
# include <config.h>
21
34
#endif
22
35
 
23
36
/* Specification.  */
24
 
#if WIDE_CHAR_VERSION
25
 
# include "wprintf-parse.h"
26
 
#else
 
37
#ifndef PRINTF_PARSE
27
38
# include "printf-parse.h"
28
39
#endif
29
40
 
 
41
/* Default parameters.  */
 
42
#ifndef PRINTF_PARSE
 
43
# define PRINTF_PARSE printf_parse
 
44
# define CHAR_T char
 
45
# define DIRECTIVE char_directive
 
46
# define DIRECTIVES char_directives
 
47
#endif
 
48
 
30
49
/* Get size_t, NULL.  */
31
50
#include <stddef.h>
32
51
 
33
52
/* Get intmax_t.  */
34
 
#if HAVE_STDINT_H_WITH_UINTMAX
 
53
#if defined IN_LIBINTL || defined IN_LIBASPRINTF
 
54
# if HAVE_STDINT_H_WITH_UINTMAX
 
55
#  include <stdint.h>
 
56
# endif
 
57
# if HAVE_INTTYPES_H_WITH_UINTMAX
 
58
#  include <inttypes.h>
 
59
# endif
 
60
#else
35
61
# include <stdint.h>
36
62
#endif
37
 
#if HAVE_INTTYPES_H_WITH_UINTMAX
38
 
# include <inttypes.h>
39
 
#endif
40
63
 
41
64
/* malloc(), realloc(), free().  */
42
65
#include <stdlib.h>
43
66
 
 
67
/* errno.  */
 
68
#include <errno.h>
 
69
 
44
70
/* Checked size_t computations.  */
45
71
#include "xsize.h"
46
72
 
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
 
73
#if CHAR_T_ONLY_ASCII
 
74
/* c_isascii().  */
 
75
# include "c-ctype.h"
57
76
#endif
58
77
 
59
78
#ifdef STATIC
71
90
 
72
91
  d->count = 0;
73
92
  d_allocated = 1;
74
 
  d->dir = malloc (d_allocated * sizeof (DIRECTIVE));
 
93
  d->dir = (DIRECTIVE *) malloc (d_allocated * sizeof (DIRECTIVE));
75
94
  if (d->dir == NULL)
76
95
    /* Out of memory.  */
77
 
    return -1;
 
96
    goto out_of_memory_1;
78
97
 
79
98
  a->count = 0;
80
99
  a_allocated = 0;
94
113
        memory_size = xtimes (a_allocated, sizeof (argument));          \
95
114
        if (size_overflow_p (memory_size))                              \
96
115
          /* Overflow, would lead to out of memory.  */                 \
97
 
          goto error;                                                   \
98
 
        memory = (a->arg                                                \
99
 
                  ? realloc (a->arg, memory_size)                       \
100
 
                  : malloc (memory_size));                              \
 
116
          goto out_of_memory;                                           \
 
117
        memory = (argument *) (a->arg                                   \
 
118
                               ? realloc (a->arg, memory_size)          \
 
119
                               : malloc (memory_size));                 \
101
120
        if (memory == NULL)                                             \
102
121
          /* Out of memory.  */                                         \
103
 
          goto error;                                                   \
 
122
          goto out_of_memory;                                           \
104
123
        a->arg = memory;                                                \
105
124
      }                                                                 \
106
125
    while (a->count <= n)                                               \
118
137
      if (c == '%')
119
138
        {
120
139
          size_t arg_index = ARG_NONE;
121
 
          DIRECTIVE *dp = &d->dir[d->count];/* pointer to next directive */
 
140
          DIRECTIVE *dp = &d->dir[d->count]; /* pointer to next directive */
122
141
 
123
142
          /* Initialize the next directive.  */
124
143
          dp->dir_start = cp - 1;
329
348
                      flags += 8;
330
349
                      cp++;
331
350
                    }
332
 
#ifdef HAVE_INTMAX_T
333
351
                  else if (*cp == 'j')
334
352
                    {
335
353
                      if (sizeof (intmax_t) > sizeof (long))
344
362
                        }
345
363
                      cp++;
346
364
                    }
347
 
#endif
348
365
                  else if (*cp == 'z' || *cp == 'Z')
349
366
                    {
350
367
                      /* 'z' is standardized in ISO C 99, but glibc uses 'Z'
385
402
              switch (c)
386
403
                {
387
404
                case 'd': case 'i':
388
 
#ifdef HAVE_LONG_LONG
 
405
#if HAVE_LONG_LONG_INT
 
406
                  /* If 'long long' exists and is larger than 'long':  */
389
407
                  if (flags >= 16 || (flags & 4))
390
408
                    type = TYPE_LONGLONGINT;
391
409
                  else
392
410
#endif
 
411
                  /* If 'long long' exists and is the same as 'long', we parse
 
412
                     "lld" into TYPE_LONGINT.  */
393
413
                  if (flags >= 8)
394
414
                    type = TYPE_LONGINT;
395
415
                  else if (flags & 2)
400
420
                    type = TYPE_INT;
401
421
                  break;
402
422
                case 'o': case 'u': case 'x': case 'X':
403
 
#ifdef HAVE_LONG_LONG
 
423
#if HAVE_LONG_LONG_INT
 
424
                  /* If 'long long' exists and is larger than 'long':  */
404
425
                  if (flags >= 16 || (flags & 4))
405
426
                    type = TYPE_ULONGLONGINT;
406
427
                  else
407
428
#endif
 
429
                  /* If 'unsigned long long' exists and is the same as
 
430
                     'unsigned long', we parse "llu" into TYPE_ULONGINT.  */
408
431
                  if (flags >= 8)
409
432
                    type = TYPE_ULONGINT;
410
433
                  else if (flags & 2)
416
439
                  break;
417
440
                case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
418
441
                case 'a': case 'A':
419
 
#ifdef HAVE_LONG_DOUBLE
420
442
                  if (flags >= 16 || (flags & 4))
421
443
                    type = TYPE_LONGDOUBLE;
422
444
                  else
423
 
#endif
424
 
                  type = TYPE_DOUBLE;
 
445
                    type = TYPE_DOUBLE;
425
446
                  break;
426
447
                case 'c':
427
448
                  if (flags >= 8)
428
 
#ifdef HAVE_WINT_T
 
449
#if HAVE_WINT_T
429
450
                    type = TYPE_WIDE_CHAR;
430
451
#else
431
452
                    goto error;
433
454
                  else
434
455
                    type = TYPE_CHAR;
435
456
                  break;
436
 
#ifdef HAVE_WINT_T
 
457
#if HAVE_WINT_T
437
458
                case 'C':
438
459
                  type = TYPE_WIDE_CHAR;
439
460
                  c = 'c';
441
462
#endif
442
463
                case 's':
443
464
                  if (flags >= 8)
444
 
#ifdef HAVE_WCHAR_T
 
465
#if HAVE_WCHAR_T
445
466
                    type = TYPE_WIDE_STRING;
446
467
#else
447
468
                    goto error;
449
470
                  else
450
471
                    type = TYPE_STRING;
451
472
                  break;
452
 
#ifdef HAVE_WCHAR_T
 
473
#if HAVE_WCHAR_T
453
474
                case 'S':
454
475
                  type = TYPE_WIDE_STRING;
455
476
                  c = 's';
459
480
                  type = TYPE_POINTER;
460
481
                  break;
461
482
                case 'n':
462
 
#ifdef HAVE_LONG_LONG
 
483
#if HAVE_LONG_LONG_INT
 
484
                  /* If 'long long' exists and is larger than 'long':  */
463
485
                  if (flags >= 16 || (flags & 4))
464
486
                    type = TYPE_COUNT_LONGLONGINT_POINTER;
465
487
                  else
466
488
#endif
 
489
                  /* If 'long long' exists and is the same as 'long', we parse
 
490
                     "lln" into TYPE_COUNT_LONGINT_POINTER.  */
467
491
                  if (flags >= 8)
468
492
                    type = TYPE_COUNT_LONGINT_POINTER;
469
493
                  else if (flags & 2)
473
497
                  else
474
498
                    type = TYPE_COUNT_INT_POINTER;
475
499
                  break;
 
500
#if ENABLE_UNISTDIO
 
501
                /* The unistdio extensions.  */
 
502
                case 'U':
 
503
                  if (flags >= 16)
 
504
                    type = TYPE_U32_STRING;
 
505
                  else if (flags >= 8)
 
506
                    type = TYPE_U16_STRING;
 
507
                  else
 
508
                    type = TYPE_U8_STRING;
 
509
                  break;
 
510
#endif
476
511
                case '%':
477
512
                  type = TYPE_NONE;
478
513
                  break;
508
543
              memory_size = xtimes (d_allocated, sizeof (DIRECTIVE));
509
544
              if (size_overflow_p (memory_size))
510
545
                /* Overflow, would lead to out of memory.  */
511
 
                goto error;
512
 
              memory = realloc (d->dir, memory_size);
 
546
                goto out_of_memory;
 
547
              memory = (DIRECTIVE *) realloc (d->dir, memory_size);
513
548
              if (memory == NULL)
514
549
                /* Out of memory.  */
515
 
                goto error;
 
550
                goto out_of_memory;
516
551
              d->dir = memory;
517
552
            }
518
553
        }
 
554
#if CHAR_T_ONLY_ASCII
 
555
      else if (!c_isascii (c))
 
556
        {
 
557
          /* Non-ASCII character.  Not supported.  */
 
558
          goto error;
 
559
        }
 
560
#endif
519
561
    }
520
562
  d->dir[d->count].dir_start = cp;
521
563
 
528
570
    free (a->arg);
529
571
  if (d->dir)
530
572
    free (d->dir);
 
573
  errno = EINVAL;
 
574
  return -1;
 
575
 
 
576
out_of_memory:
 
577
  if (a->arg)
 
578
    free (a->arg);
 
579
  if (d->dir)
 
580
    free (d->dir);
 
581
out_of_memory_1:
 
582
  errno = ENOMEM;
531
583
  return -1;
532
584
}
533
585
 
 
586
#undef PRINTF_PARSE
534
587
#undef DIRECTIVES
535
588
#undef DIRECTIVE
 
589
#undef CHAR_T_ONLY_ASCII
536
590
#undef CHAR_T
537
 
#undef PRINTF_PARSE