X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fquotearg.c;h=c9e89bf28855b613874af41e834599a74611e892;hb=53ed71f6a1cc4207b1972b73e4b5e1e830c8119d;hp=381f00acc13cc41bb3ed293f82d4788f117fa75f;hpb=0632e115747ff96e93330c88f536d7354a7ce507;p=gnulib.git diff --git a/lib/quotearg.c b/lib/quotearg.c index 381f00acc..c9e89bf28 100644 --- a/lib/quotearg.c +++ b/lib/quotearg.c @@ -1,6 +1,6 @@ /* quotearg.c - quote arguments for output - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006 Free + 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 @@ -31,26 +31,20 @@ #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 @@ -60,14 +54,7 @@ # define mbsinit(ps) 1 #endif -#ifndef iswprint -# if HAVE_WCTYPE_H -# include -# endif -# if !defined iswprint && !HAVE_ISWPRINT -# define iswprint(wc) 1 -# endif -#endif +#include #ifndef SIZE_MAX # define SIZE_MAX ((size_t) -1) @@ -120,8 +107,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; } @@ -552,12 +539,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. @@ -572,18 +594,8 @@ 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 (); @@ -596,31 +608,29 @@ quotearg_n_options (int n, char const *arg, size_t argsize, 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 *slotvec)) + 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); }