X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fquotearg.c;h=f7f326ac5017475d76046d39962aa0b48f3ad09e;hb=5d0b385594bc914e6233988bfb6bc1b92a2184b5;hp=fe747fb0b91e6e97ecb3b19e720146938a60e8b8;hpb=3056a5662ebe35d3cf762ab637c4ed7a95c58cbe;p=gnulib.git diff --git a/lib/quotearg.c b/lib/quotearg.c index fe747fb0b..f7f326ac5 100644 --- a/lib/quotearg.c +++ b/lib/quotearg.c @@ -1,7 +1,7 @@ /* quotearg.c - quote arguments for output - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software - Foundation, Inc. + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007 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 @@ -15,13 +15,11 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Written by Paul Eggert */ -#if HAVE_CONFIG_H -# include -#endif +#include #include "quotearg.h" @@ -30,28 +28,24 @@ #include #include #include +#include #include #include +#include +#include #include "gettext.h" #define _(msgid) gettext (msgid) #define N_(msgid) msgid -#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 /* 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 +# undef mbstate_t +# define mbstate_t int # define mbrtowc(pwc, s, n, ps) ((*(pwc) = *(s)) != 0) # define iswprint(wc) isprint ((unsigned char) (wc)) # undef HAVE_MBSINIT @@ -61,15 +55,6 @@ # define mbsinit(ps) 1 #endif -#ifndef iswprint -# if HAVE_WCTYPE_H -# include -# endif -# if !defined iswprint && !HAVE_ISWPRINT -# define iswprint(wc) 1 -# endif -#endif - #ifndef SIZE_MAX # define SIZE_MAX ((size_t) -1) #endif @@ -83,7 +68,7 @@ struct quoting_options /* Quote the characters indicated by this bit vector even if the quoting style would not normally require them to be quoted. */ - int quote_these_too[(UCHAR_MAX / INT_BITS) + 1]; + unsigned int quote_these_too[(UCHAR_MAX / INT_BITS) + 1]; }; /* Names of quoting styles. */ @@ -121,8 +106,8 @@ struct quoting_options * clone_quoting_options (struct quoting_options *o) { int e = errno; - struct quoting_options *p = xmalloc (sizeof *p); - *p = *(o ? o : &default_quoting_options); + struct quoting_options *p = xmemdup (o ? o : &default_quoting_options, + sizeof *o); errno = e; return p; } @@ -151,7 +136,8 @@ int set_char_quoting (struct quoting_options *o, char c, int i) { unsigned char uc = c; - int *p = (o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS; + unsigned int *p = + (o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS; int shift = uc % INT_BITS; int r = (*p >> shift) & 1; *p ^= ((i & 1) ^ r) << shift; @@ -192,8 +178,8 @@ quotearg_buffer_restyled (char *buffer, size_t buffersize, size_t len = 0; char const *quote_string = 0; size_t quote_string_len = 0; - int backslash_escapes = 0; - int unibyte_locale = MB_CUR_MAX == 1; + bool backslash_escapes = false; + bool unibyte_locale = MB_CUR_MAX == 1; #define STORE(c) \ do \ @@ -208,19 +194,20 @@ quotearg_buffer_restyled (char *buffer, size_t buffersize, { case c_quoting_style: STORE ('"'); - backslash_escapes = 1; + backslash_escapes = true; quote_string = "\""; quote_string_len = 1; break; case escape_quoting_style: - backslash_escapes = 1; + backslash_escapes = true; break; case locale_quoting_style: case clocale_quoting_style: { - /* Get translations for open and closing quotation marks. + /* TRANSLATORS: + Get translations for open and closing quotation marks. The message catalog should translate "`" to a left quotation mark suitable for the locale, and similarly for @@ -233,13 +220,17 @@ quotearg_buffer_restyled (char *buffer, size_t buffersize, should translate "'" to U+201D (RIGHT DOUBLE QUOTATION MARK). A British English Unicode locale should instead translate these to U+2018 (LEFT SINGLE QUOTATION MARK) and - U+2019 (RIGHT SINGLE QUOTATION MARK), respectively. */ + U+2019 (RIGHT SINGLE QUOTATION MARK), respectively. + + If you don't know what to put here, please see + + and use glyphs suitable for your language. */ char const *left = gettext_quote (N_("`"), quoting_style); char const *right = gettext_quote (N_("'"), quoting_style); for (quote_string = left; *quote_string; quote_string++) STORE (*quote_string); - backslash_escapes = 1; + backslash_escapes = true; quote_string = right; quote_string_len = strlen (quote_string); } @@ -300,6 +291,9 @@ quotearg_buffer_restyled (char *buffer, size_t buffersize, STORE ('\\'); STORE ('?'); break; + + default: + break; } break; @@ -396,12 +390,12 @@ quotearg_buffer_restyled (char *buffer, size_t buffersize, /* Length of multibyte sequence found so far. */ size_t m; - int printable; + bool printable; if (unibyte_locale) { m = 1; - printable = isprint (c); + printable = isprint (c) != 0; } else { @@ -409,7 +403,7 @@ quotearg_buffer_restyled (char *buffer, size_t buffersize, memset (&mbstate, 0, sizeof mbstate); m = 0; - printable = 1; + printable = true; if (argsize == SIZE_MAX) argsize = strlen (arg); @@ -422,12 +416,12 @@ quotearg_buffer_restyled (char *buffer, size_t buffersize, break; else if (bytes == (size_t) -1) { - printable = 0; + printable = false; break; } else if (bytes == (size_t) -2) { - printable = 0; + printable = false; while (i + m < argsize && arg[i + m]) m++; break; @@ -447,11 +441,14 @@ quotearg_buffer_restyled (char *buffer, size_t buffersize, case '[': case '\\': case '^': case '`': case '|': goto use_shell_always_quoting_style; + + default: + break; } } - + if (! iswprint (w)) - printable = 0; + printable = false; m += bytes; } } @@ -541,12 +538,47 @@ quotearg_alloc (char const *arg, size_t argsize, { int e = errno; size_t bufsize = quotearg_buffer (0, 0, arg, argsize, o) + 1; - char *buf = xmalloc (bufsize); + char *buf = xcharalloc (bufsize); quotearg_buffer (buf, bufsize, arg, argsize, o); errno = e; return buf; } +/* A storage slot with size and pointer to a value. */ +struct slotvec +{ + size_t size; + char *val; +}; + +/* 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; +static struct slotvec slotvec0 = {sizeof slot0, slot0}; +static struct slotvec *slotvec = &slotvec0; + +void +quotearg_free (void) +{ + struct slotvec *sv = slotvec; + unsigned int i; + for (i = 1; i < nslots; i++) + free (sv[i].val); + if (sv[0].val != slot0) + { + free (sv[0].val); + slotvec0.size = sizeof slot0; + slotvec0.val = slot0; + } + if (sv != &slotvec0) + { + free (sv); + slotvec = &slotvec0; + } + nslots = 1; +} + /* Use storage slot N to return a quoted version of argument ARG. ARG is of size ARGSIZE, but if that is SIZE_MAX, ARG is a null-terminated string. @@ -561,50 +593,43 @@ quotearg_n_options (int n, char const *arg, size_t argsize, { int e = errno; - /* 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; - }; - static struct slotvec slotvec0 = {sizeof slot0, slot0}; - static struct slotvec *slotvec = &slotvec0; + struct slotvec *sv = slotvec; if (n < 0) abort (); if (nslots <= n0) { - unsigned int n1 = n0 + 1; - - if (xalloc_oversized (n1, sizeof *slotvec)) + /* FIXME: technically, the type of n1 should be `unsigned int', + but that evokes an unsuppressible warning from gcc-4.0.1 and + older. If gcc ever provides an option to suppress that warning, + revert to the original type, so that the test in xalloc_oversized + is once again performed only at compile time. */ + size_t n1 = n0 + 1; + bool preallocated = (sv == &slotvec0); + + if (xalloc_oversized (n1, sizeof *sv)) xalloc_die (); - if (slotvec == &slotvec0) - { - slotvec = xmalloc (sizeof *slotvec); - *slotvec = slotvec0; - } - slotvec = xrealloc (slotvec, n1 * sizeof *slotvec); - memset (slotvec + nslots, 0, (n1 - nslots) * sizeof *slotvec); + slotvec = sv = xrealloc (preallocated ? NULL : sv, n1 * sizeof *sv); + if (preallocated) + *sv = slotvec0; + memset (sv + nslots, 0, (n1 - nslots) * sizeof *sv); nslots = n1; } { - size_t size = slotvec[n].size; - char *val = slotvec[n].val; + size_t size = sv[n].size; + char *val = sv[n].val; size_t qsize = quotearg_buffer (val, size, arg, argsize, options); if (size <= qsize) { - slotvec[n].size = size = qsize + 1; + sv[n].size = size = qsize + 1; if (val != slot0) free (val); - slotvec[n].val = val = xmalloc (size); + sv[n].val = val = xcharalloc (size); quotearg_buffer (val, size, arg, argsize, options); }