X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fquotearg.c;h=bd053eecad69b015ed75a569cbf811ca2ec4855e;hb=4b4109233097408185555b472eb302c8d3da33b9;hp=0f2cc49194049aec8cd62ab52a657448925c8f0c;hpb=a62b804c8a03f67d228d22adb6298f9ce33ec979;p=gnulib.git diff --git a/lib/quotearg.c b/lib/quotearg.c index 0f2cc4919..bd053eeca 100644 --- a/lib/quotearg.c +++ b/lib/quotearg.c @@ -1,5 +1,5 @@ /* quotearg.c - quote arguments for output - Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,6 +21,9 @@ # include #endif +#if HAVE_STDDEF_H +# include /* For the definition of size_t on windows w/MSVC. */ +#endif #include #include #include @@ -41,9 +44,15 @@ #ifndef CHAR_BIT # define CHAR_BIT 8 #endif +#ifndef SIZE_MAX +# define SIZE_MAX ((size_t) -1) +#endif #ifndef UCHAR_MAX # define UCHAR_MAX ((unsigned char) -1) #endif +#ifndef UINT_MAX +# define UINT_MAX ((unsigned int) -1) +#endif #if HAVE_C_BACKSLASH_A # define ALERT_CHAR '\a' @@ -60,16 +69,20 @@ #endif #if HAVE_WCHAR_H + +/* BSD/OS 4.1 wchar.h requires FILE and struct tm to be declared. */ +# include +# include + # include #endif -#if HAVE_MBRTOWC -size_t mbrtowc (); -# ifdef mbstate_t -# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) -# define mbsinit(ps) 1 -# endif -#else +#if !HAVE_MBRTOWC +/* Disable multibyte processing entirely. Since MB_CUR_MAX is 1, the + other macros are defined only for documentation and to satisfy C + syntax. */ +# undef MB_CUR_MAX +# define MB_CUR_MAX 1 # define mbrtowc(pwc, s, n, ps) ((*(pwc) = *(s)) != 0) # define mbsinit(ps) 1 # define iswprint(wc) ISPRINT ((unsigned char) (wc)) @@ -87,15 +100,14 @@ size_t mbrtowc (); #define INT_BITS (sizeof (int) * CHAR_BIT) #if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII)) -/* Undefine to protect against the definition in wctype.h of solaris2.6. */ -# undef ISASCII -# define ISASCII(c) 1 +# define IN_CTYPE_DOMAIN(c) 1 #else -# define ISASCII(c) isascii (c) +# define IN_CTYPE_DOMAIN(c) isascii(c) #endif + /* Undefine to protect against the definition in wctype.h of solaris2.6. */ #undef ISPRINT -#define ISPRINT(c) (ISASCII (c) && isprint (c)) +#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint (c)) struct quoting_options { @@ -213,6 +225,7 @@ quotearg_buffer_restyled (char *buffer, size_t buffersize, char const *quote_string = 0; size_t quote_string_len = 0; int backslash_escapes = 0; + int unibyte_locale = MB_CUR_MAX == 1; #define STORE(c) \ do \ @@ -398,57 +411,59 @@ quotearg_buffer_restyled (char *buffer, size_t buffersize, we can't easily escape single characters within it. */ { /* Length of multibyte sequence found so far. */ - size_t m = 0; + size_t m; - int printable = 1; - mbstate_t mbstate; - memset (&mbstate, 0, sizeof mbstate); + int printable; - if (argsize == (size_t) -1) - argsize = strlen (arg); - - do + if (unibyte_locale) { - wchar_t w; - size_t bytes = mbrtowc (&w, &arg[i + m], - argsize - (i + m), &mbstate); - if (bytes == 0) - break; - else if (bytes == (size_t) -1) - { - printable = 0; - break; - } - else if (bytes == (size_t) -2) - { - printable = 0; - while (i + m < argsize && arg[i + m]) - m++; - break; - } - else - { - if (! iswprint (w)) - printable = 0; - m += bytes; - } + m = 1; + printable = ISPRINT (c); } - while (! mbsinit (&mbstate)); - - if (m <= 1) + else { - /* Escape a unibyte character like a multibyte - sequence if using backslash escapes, and if the - character is not printable. */ - m = backslash_escapes && ! ISPRINT (c); - printable = 0; + mbstate_t mbstate; + memset (&mbstate, 0, sizeof mbstate); + + m = 0; + printable = 1; + if (argsize == (size_t) -1) + argsize = strlen (arg); + + do + { + wchar_t w; + size_t bytes = mbrtowc (&w, &arg[i + m], + argsize - (i + m), &mbstate); + if (bytes == 0) + break; + else if (bytes == (size_t) -1) + { + printable = 0; + break; + } + else if (bytes == (size_t) -2) + { + printable = 0; + while (i + m < argsize && arg[i + m]) + m++; + break; + } + else + { + if (! iswprint (w)) + printable = 0; + m += bytes; + } + } + while (! mbsinit (&mbstate)); } - if (m) + if (1 < m || (backslash_escapes && ! printable)) { /* Output a multibyte sequence, or an escaped unprintable unibyte character. */ - size_t imax = i + m - 1; + size_t ilim = i + m; for (;;) { @@ -459,7 +474,7 @@ quotearg_buffer_restyled (char *buffer, size_t buffersize, STORE ('0' + ((c >> 3) & 7)); c = '0' + (c & 7); } - if (i == imax) + if (ilim <= i + 1) break; STORE (c); c = arg[++i]; @@ -522,22 +537,39 @@ static char * quotearg_n_options (int n, char const *arg, struct quoting_options const *options) { - static unsigned int nslots; - static struct slotvec + /* Preallocate a slot 0 buffer, so that the caller can always quote + one small component of a "memory exhausted" message in slot 0. */ + static char slot0[256]; + static unsigned int nslots = 1; + unsigned int n0 = n; + struct slotvec { size_t size; char *val; - } *slotvec; + }; + static struct slotvec slotvec0 = {sizeof slot0, slot0}; + static struct slotvec *slotvec = &slotvec0; + + if (n < 0) + abort (); - if (nslots <= n) + if (nslots <= n0) { - int n1 = n + 1; - size_t s = n1 * sizeof (struct slotvec); - if (! (0 < n1 && n1 == s / sizeof (struct slotvec))) - abort (); + unsigned int n1 = n0 + 1; + size_t s = n1 * sizeof *slotvec; + + if (SIZE_MAX / UINT_MAX <= sizeof *slotvec + && n1 != s / sizeof *slotvec) + xalloc_die (); + + if (slotvec == &slotvec0) + { + slotvec = (struct slotvec *) xmalloc (sizeof *slotvec); + *slotvec = slotvec0; + } slotvec = (struct slotvec *) xrealloc (slotvec, s); - memset (slotvec + nslots, 0, (n1 - nslots) * sizeof (struct slotvec)); - nslots = n; + memset (slotvec + nslots, 0, (n1 - nslots) * sizeof *slotvec); + nslots = n1; } { @@ -548,7 +580,7 @@ quotearg_n_options (int n, char const *arg, if (size <= qsize) { slotvec[n].size = size = qsize + 1; - slotvec[n].val = val = xrealloc (val, size); + slotvec[n].val = val = xrealloc (val == slot0 ? 0 : val, size); quotearg_buffer (val, size, arg, (size_t) -1, options); } @@ -557,7 +589,7 @@ quotearg_n_options (int n, char const *arg, } char * -quotearg_n (unsigned int n, char const *arg) +quotearg_n (int n, char const *arg) { return quotearg_n_options (n, arg, &default_quoting_options); } @@ -569,7 +601,7 @@ quotearg (char const *arg) } char * -quotearg_n_style (unsigned int n, enum quoting_style s, char const *arg) +quotearg_n_style (int n, enum quoting_style s, char const *arg) { struct quoting_options o; o.style = s;