The R Project SVN R

Rev

Rev 41539 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 41539 Rev 43972
Line 1... Line 1...
1
/* Formatted output to strings.
1
/* Formatted output to strings.
2
   Copyright (C) 1999-2000, 2002-2003, 2006 Free Software Foundation, Inc.
2
   Copyright (C) 1999-2000, 2002-2003, 2006-2007 Free Software Foundation, Inc.
3
 
3
 
4
   This program is free software; you can redistribute it and/or modify it
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
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)
6
   by the Free Software Foundation; either version 2, or (at your option)
7
   any later version.
7
   any later version.
Line 14... Line 14...
14
   You should have received a copy of the GNU Library General Public
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
15
   License along with this program; if not, write to the Free Software
16
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
16
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
17
   USA.  */
17
   USA.  */
18
 
18
 
-
 
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
 
19
#ifdef HAVE_CONFIG_H
32
#ifndef PRINTF_PARSE
20
# include <config.h>
33
# include <config.h>
21
#endif
34
#endif
22
 
35
 
23
/* Specification.  */
36
/* Specification.  */
24
#if WIDE_CHAR_VERSION
37
#ifndef PRINTF_PARSE
25
# include "wprintf-parse.h"
-
 
26
#else
-
 
27
# include "printf-parse.h"
38
# include "printf-parse.h"
28
#endif
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
/* Get size_t, NULL.  */
49
/* Get size_t, NULL.  */
31
#include <stddef.h>
50
#include <stddef.h>
32
 
51
 
33
/* Get intmax_t.  */
52
/* Get intmax_t.  */
-
 
53
#if defined IN_LIBINTL || defined IN_LIBASPRINTF
34
#if HAVE_STDINT_H_WITH_UINTMAX
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
# include <stdint.h>
61
# include <stdint.h>
36
#endif
62
#endif
37
#if HAVE_INTTYPES_H_WITH_UINTMAX
-
 
38
# include <inttypes.h>
-
 
39
#endif
-
 
40
 
63
 
41
/* malloc(), realloc(), free().  */
64
/* malloc(), realloc(), free().  */
42
#include <stdlib.h>
65
#include <stdlib.h>
43
 
66
 
-
 
67
/* errno.  */
-
 
68
#include <errno.h>
-
 
69
 
44
/* Checked size_t computations.  */
70
/* Checked size_t computations.  */
45
#include "xsize.h"
71
#include "xsize.h"
46
 
72
 
47
#if WIDE_CHAR_VERSION
73
#if CHAR_T_ONLY_ASCII
48
# define PRINTF_PARSE wprintf_parse
-
 
49
# define CHAR_T wchar_t
74
/* c_isascii().  */
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
75
# include "c-ctype.h"
55
# define DIRECTIVE char_directive
-
 
56
# define DIRECTIVES char_directives
-
 
57
#endif
76
#endif
58
 
77
 
59
#ifdef STATIC
78
#ifdef STATIC
60
STATIC
79
STATIC
61
#endif
80
#endif
Line 69... Line 88...
69
  size_t max_width_length = 0;
88
  size_t max_width_length = 0;
70
  size_t max_precision_length = 0;
89
  size_t max_precision_length = 0;
71
 
90
 
72
  d->count = 0;
91
  d->count = 0;
73
  d_allocated = 1;
92
  d_allocated = 1;
74
  d->dir = malloc (d_allocated * sizeof (DIRECTIVE));
93
  d->dir = (DIRECTIVE *) malloc (d_allocated * sizeof (DIRECTIVE));
75
  if (d->dir == NULL)
94
  if (d->dir == NULL)
76
    /* Out of memory.  */
95
    /* Out of memory.  */
77
    return -1;
96
    goto out_of_memory_1;
78
 
97
 
79
  a->count = 0;
98
  a->count = 0;
80
  a_allocated = 0;
99
  a_allocated = 0;
81
  a->arg = NULL;
100
  a->arg = NULL;
82
 
101
 
Line 92... Line 111...
92
	if (a_allocated <= n)						\
111
	if (a_allocated <= n)						\
93
	  a_allocated = xsum (n, 1);					\
112
	  a_allocated = xsum (n, 1);					\
94
	memory_size = xtimes (a_allocated, sizeof (argument));		\
113
	memory_size = xtimes (a_allocated, sizeof (argument));		\
95
	if (size_overflow_p (memory_size))				\
114
	if (size_overflow_p (memory_size))				\
96
	  /* Overflow, would lead to out of memory.  */			\
115
	  /* Overflow, would lead to out of memory.  */			\
97
	  goto error;							\
116
	  goto out_of_memory;						\
98
	memory = (a->arg						\
117
	memory = (argument *) (a->arg					\
99
		  ? realloc (a->arg, memory_size)			\
118
			       ? realloc (a->arg, memory_size)		\
100
		  : malloc (memory_size));				\
119
			       : malloc (memory_size));			\
101
	if (memory == NULL)						\
120
	if (memory == NULL)						\
102
	  /* Out of memory.  */						\
121
	  /* Out of memory.  */						\
103
	  goto error;							\
122
	  goto out_of_memory;						\
104
	a->arg = memory;						\
123
	a->arg = memory;						\
105
      }									\
124
      }									\
106
    while (a->count <= n)						\
125
    while (a->count <= n)						\
107
      a->arg[a->count++].type = TYPE_NONE;				\
126
      a->arg[a->count++].type = TYPE_NONE;				\
108
    if (a->arg[n].type == TYPE_NONE)					\
127
    if (a->arg[n].type == TYPE_NONE)					\
Line 116... Line 135...
116
    {
135
    {
117
      CHAR_T c = *cp++;
136
      CHAR_T c = *cp++;
118
      if (c == '%')
137
      if (c == '%')
119
	{
138
	{
120
	  size_t arg_index = ARG_NONE;
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
	  /* Initialize the next directive.  */
142
	  /* Initialize the next directive.  */
124
	  dp->dir_start = cp - 1;
143
	  dp->dir_start = cp - 1;
125
	  dp->flags = 0;
144
	  dp->flags = 0;
126
	  dp->width_start = NULL;
145
	  dp->width_start = NULL;
Line 327... Line 346...
327
		  else if (*cp == 'l')
346
		  else if (*cp == 'l')
328
		    {
347
		    {
329
		      flags += 8;
348
		      flags += 8;
330
		      cp++;
349
		      cp++;
331
		    }
350
		    }
332
#ifdef HAVE_INTMAX_T
-
 
333
		  else if (*cp == 'j')
351
		  else if (*cp == 'j')
334
		    {
352
		    {
335
		      if (sizeof (intmax_t) > sizeof (long))
353
		      if (sizeof (intmax_t) > sizeof (long))
336
			{
354
			{
337
			  /* intmax_t = long long */
355
			  /* intmax_t = long long */
Line 342... Line 360...
342
			  /* intmax_t = long */
360
			  /* intmax_t = long */
343
			  flags += 8;
361
			  flags += 8;
344
			}
362
			}
345
		      cp++;
363
		      cp++;
346
		    }
364
		    }
347
#endif
-
 
348
		  else if (*cp == 'z' || *cp == 'Z')
365
		  else if (*cp == 'z' || *cp == 'Z')
349
		    {
366
		    {
350
		      /* 'z' is standardized in ISO C 99, but glibc uses 'Z'
367
		      /* 'z' is standardized in ISO C 99, but glibc uses 'Z'
351
			 because the warning facility in gcc-2.95.2 understands
368
			 because the warning facility in gcc-2.95.2 understands
352
			 only 'Z' (see gcc-2.95.2/gcc/c-common.c:1784).  */
369
			 only 'Z' (see gcc-2.95.2/gcc/c-common.c:1784).  */
Line 383... Line 400...
383
	      /* Read the conversion character.  */
400
	      /* Read the conversion character.  */
384
	      c = *cp++;
401
	      c = *cp++;
385
	      switch (c)
402
	      switch (c)
386
		{
403
		{
387
		case 'd': case 'i':
404
		case 'd': case 'i':
388
#ifdef HAVE_LONG_LONG_INT
405
#if HAVE_LONG_LONG_INT
389
		  /* If 'long long' exists and is larger than 'long':  */
406
		  /* If 'long long' exists and is larger than 'long':  */
390
		  if (flags >= 16 || (flags & 4))
407
		  if (flags >= 16 || (flags & 4))
391
		    type = TYPE_LONGLONGINT;
408
		    type = TYPE_LONGLONGINT;
392
		  else
409
		  else
393
#endif
410
#endif
Line 401... Line 418...
401
		    type = TYPE_SHORT;
418
		    type = TYPE_SHORT;
402
		  else
419
		  else
403
		    type = TYPE_INT;
420
		    type = TYPE_INT;
404
		  break;
421
		  break;
405
		case 'o': case 'u': case 'x': case 'X':
422
		case 'o': case 'u': case 'x': case 'X':
406
#ifdef HAVE_LONG_LONG_INT
423
#if HAVE_LONG_LONG_INT
407
		  /* If 'long long' exists and is larger than 'long':  */
424
		  /* If 'long long' exists and is larger than 'long':  */
408
		  if (flags >= 16 || (flags & 4))
425
		  if (flags >= 16 || (flags & 4))
409
		    type = TYPE_ULONGLONGINT;
426
		    type = TYPE_ULONGLONGINT;
410
		  else
427
		  else
411
#endif
428
#endif
Line 420... Line 437...
420
		  else
437
		  else
421
		    type = TYPE_UINT;
438
		    type = TYPE_UINT;
422
		  break;
439
		  break;
423
		case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
440
		case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
424
		case 'a': case 'A':
441
		case 'a': case 'A':
425
#ifdef HAVE_LONG_DOUBLE
-
 
426
		  if (flags >= 16 || (flags & 4))
442
		  if (flags >= 16 || (flags & 4))
427
		    type = TYPE_LONGDOUBLE;
443
		    type = TYPE_LONGDOUBLE;
428
		  else
444
		  else
429
#endif
-
 
430
		  type = TYPE_DOUBLE;
445
		    type = TYPE_DOUBLE;
431
		  break;
446
		  break;
432
		case 'c':
447
		case 'c':
433
		  if (flags >= 8)
448
		  if (flags >= 8)
434
#ifdef HAVE_WINT_T
449
#if HAVE_WINT_T
435
		    type = TYPE_WIDE_CHAR;
450
		    type = TYPE_WIDE_CHAR;
436
#else
451
#else
437
		    goto error;
452
		    goto error;
438
#endif
453
#endif
439
		  else
454
		  else
440
		    type = TYPE_CHAR;
455
		    type = TYPE_CHAR;
441
		  break;
456
		  break;
442
#ifdef HAVE_WINT_T
457
#if HAVE_WINT_T
443
		case 'C':
458
		case 'C':
444
		  type = TYPE_WIDE_CHAR;
459
		  type = TYPE_WIDE_CHAR;
445
		  c = 'c';
460
		  c = 'c';
446
		  break;
461
		  break;
447
#endif
462
#endif
448
		case 's':
463
		case 's':
449
		  if (flags >= 8)
464
		  if (flags >= 8)
450
#ifdef HAVE_WCHAR_T
465
#if HAVE_WCHAR_T
451
		    type = TYPE_WIDE_STRING;
466
		    type = TYPE_WIDE_STRING;
452
#else
467
#else
453
		    goto error;
468
		    goto error;
454
#endif
469
#endif
455
		  else
470
		  else
456
		    type = TYPE_STRING;
471
		    type = TYPE_STRING;
457
		  break;
472
		  break;
458
#ifdef HAVE_WCHAR_T
473
#if HAVE_WCHAR_T
459
		case 'S':
474
		case 'S':
460
		  type = TYPE_WIDE_STRING;
475
		  type = TYPE_WIDE_STRING;
461
		  c = 's';
476
		  c = 's';
462
		  break;
477
		  break;
463
#endif
478
#endif
464
		case 'p':
479
		case 'p':
465
		  type = TYPE_POINTER;
480
		  type = TYPE_POINTER;
466
		  break;
481
		  break;
467
		case 'n':
482
		case 'n':
468
#ifdef HAVE_LONG_LONG_INT
483
#if HAVE_LONG_LONG_INT
469
		  /* If 'long long' exists and is larger than 'long':  */
484
		  /* If 'long long' exists and is larger than 'long':  */
470
		  if (flags >= 16 || (flags & 4))
485
		  if (flags >= 16 || (flags & 4))
471
		    type = TYPE_COUNT_LONGLONGINT_POINTER;
486
		    type = TYPE_COUNT_LONGLONGINT_POINTER;
472
		  else
487
		  else
473
#endif
488
#endif
Line 480... Line 495...
480
		  else if (flags & 1)
495
		  else if (flags & 1)
481
		    type = TYPE_COUNT_SHORT_POINTER;
496
		    type = TYPE_COUNT_SHORT_POINTER;
482
		  else
497
		  else
483
		    type = TYPE_COUNT_INT_POINTER;
498
		    type = TYPE_COUNT_INT_POINTER;
484
		  break;
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
485
		case '%':
511
		case '%':
486
		  type = TYPE_NONE;
512
		  type = TYPE_NONE;
487
		  break;
513
		  break;
488
		default:
514
		default:
489
		  /* Unknown conversion character.  */
515
		  /* Unknown conversion character.  */
Line 515... Line 541...
515
 
541
 
516
	      d_allocated = xtimes (d_allocated, 2);
542
	      d_allocated = xtimes (d_allocated, 2);
517
	      memory_size = xtimes (d_allocated, sizeof (DIRECTIVE));
543
	      memory_size = xtimes (d_allocated, sizeof (DIRECTIVE));
518
	      if (size_overflow_p (memory_size))
544
	      if (size_overflow_p (memory_size))
519
		/* Overflow, would lead to out of memory.  */
545
		/* Overflow, would lead to out of memory.  */
520
		goto error;
546
		goto out_of_memory;
521
	      memory = realloc (d->dir, memory_size);
547
	      memory = (DIRECTIVE *) realloc (d->dir, memory_size);
522
	      if (memory == NULL)
548
	      if (memory == NULL)
523
		/* Out of memory.  */
549
		/* Out of memory.  */
524
		goto error;
550
		goto out_of_memory;
525
	      d->dir = memory;
551
	      d->dir = memory;
526
	    }
552
	    }
527
	}
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
528
    }
561
    }
529
  d->dir[d->count].dir_start = cp;
562
  d->dir[d->count].dir_start = cp;
530
 
563
 
531
  d->max_width_length = max_width_length;
564
  d->max_width_length = max_width_length;
532
  d->max_precision_length = max_precision_length;
565
  d->max_precision_length = max_precision_length;
Line 535... Line 568...
535
error:
568
error:
536
  if (a->arg)
569
  if (a->arg)
537
    free (a->arg);
570
    free (a->arg);
538
  if (d->dir)
571
  if (d->dir)
539
    free (d->dir);
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;
540
  return -1;
583
  return -1;
541
}
584
}
542
 
585
 
-
 
586
#undef PRINTF_PARSE
543
#undef DIRECTIVES
587
#undef DIRECTIVES
544
#undef DIRECTIVE
588
#undef DIRECTIVE
-
 
589
#undef CHAR_T_ONLY_ASCII
545
#undef CHAR_T
590
#undef CHAR_T
546
#undef PRINTF_PARSE
-