X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fquotearg.c;h=9d4395977ed4adacd3334d87cd68de750b626a01;hb=488cf84c63fbbffa44143d0ebf56e5a6c26d4383;hp=7ccb7599d7bdd6b6946335f909b27ed441cd3cca;hpb=12cdbeb96a97dd3690073cb955c002b4e7adf16d;p=gnulib.git diff --git a/lib/quotearg.c b/lib/quotearg.c index 7ccb7599d..9d4395977 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 @@ -60,15 +63,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 && HAVE_WCHAR_H -size_t mbrtowc (); -# if !HAVE_MBSTATE_T_OBJECT -# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) -# 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)) @@ -86,15 +94,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 { @@ -115,6 +122,7 @@ char const *const quoting_style_args[] = "c", "escape", "locale", + "clocale", 0 }; @@ -126,7 +134,8 @@ enum quoting_style const quoting_style_vals[] = shell_always_quoting_style, c_quoting_style, escape_quoting_style, - locale_quoting_style + locale_quoting_style, + clocale_quoting_style }; /* The default quoting options. */ @@ -175,13 +184,15 @@ set_char_quoting (struct quoting_options *o, char c, int i) return r; } -/* Return the translation of MSGID if there is one, and - DEFAULT_TRANSLATION otherwise. */ +/* MSGID approximates a quotation mark. Return its translation if it + has one; otherwise, return either it or "\"", depending on S. */ static char const * -gettext_default (char const *msgid, char const *default_translation) +gettext_quote (char const *msgid, enum quoting_style s) { char const *translation = _(msgid); - return translation == msgid ? default_translation : translation; + if (translation == msgid && s == clocale_quoting_style) + translation = "\""; + return translation; } /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of @@ -208,6 +219,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 \ @@ -232,30 +244,25 @@ quotearg_buffer_restyled (char *buffer, size_t buffersize, break; case locale_quoting_style: + case clocale_quoting_style: { /* Get translations for open and closing quotation marks. - The message catalog should translate "{LEFT QUOTATION - MARK}" to a left quotation mark suitable for the locale, - and similarly for "{RIGHT QUOTATION MARK}". If the catalog - has no translation, the code below uses a neutral - (vertical) quotation mark instead, as it is the most - appropriate for the C locale. + The message catalog should translate "`" to a left + quotation mark suitable for the locale, and similarly for + "'". If the catalog has no translation, + locale_quoting_style quotes `like this', and + clocale_quoting_style quotes "like this". For example, an American English Unicode locale should - translate the string "{LEFT QUOTATION MARK}" to the - character U+201C (LEFT DOUBLE QUOTATION MARK), and should - translate the string "{RIGHT QUOTATION MARK}" to the - character 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. */ - - static char const quotation_mark[] = "\""; - char const *left = gettext_default (N_("{LEFT QUOTATION MARK}"), - quotation_mark); - char const *right = gettext_default (N_("{RIGHT QUOTATION MARK}"), - quotation_mark); + translate "`" to U+201C (LEFT DOUBLE QUOTATION MARK), and + 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. */ + + 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; @@ -398,57 +405,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; - - int printable = 1; - mbstate_t mbstate; - memset (&mbstate, 0, sizeof mbstate); + size_t m; - if (argsize == (size_t) -1) - argsize = strlen (arg); + int printable; - 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 +468,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,12 +531,17 @@ 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; + struct slotvec { size_t size; char *val; - } *slotvec; + }; + static struct slotvec slotvec0 = {sizeof slot0, slot0}; + static struct slotvec *slotvec = &slotvec0; if (nslots <= n) { @@ -535,6 +549,11 @@ quotearg_n_options (int n, char const *arg, size_t s = n1 * sizeof (struct slotvec); if (! (0 < n1 && n1 == s / sizeof (struct slotvec))) abort (); + if (slotvec == &slotvec0) + { + slotvec = (struct slotvec *) xmalloc (sizeof (struct slotvec)); + *slotvec = slotvec0; + } slotvec = (struct slotvec *) xrealloc (slotvec, s); memset (slotvec + nslots, 0, (n1 - nslots) * sizeof (struct slotvec)); nslots = n; @@ -548,7 +567,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); }