strfuncs.c revision d2f5aacd3d549c3d39dae41b6522d585244b016d
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen strfuncs.c : String manipulation functions (note: LGPL, because the )
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen Copyright (C) 2001-2002 Timo Sirainen
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen printf_string_upper_bound() code is taken from GLIB:
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen Modified by the GLib Team and others 1997-1999.
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen This library is free software; you can redistribute it and/or
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen modify it under the terms of the GNU Library General Public
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen License as published by the Free Software Foundation; either
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen version 2 of the License, or (at your option) any later version.
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen This library is distributed in the hope that it will be useful,
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen but WITHOUT ANY WARRANTY; without even the implied warranty of
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen Library General Public License for more details.
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen You should have received a copy of the GNU Library General Public
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen License along with this library; if not, write to the
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen Free Software Foundation, Inc., 59 Temple Place - Suite 330,
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen Boston, MA 02111-1307, USA.
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainenstatic void *tp_malloc(Pool pool __attr_unused__, size_t size)
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen/* multiply with base2 exponent to get base10 exponent (nomal numbers) */
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen#define G_LOG_2_BASE_10 (0.30102999566398119521)
bbd51f171bb2f4abd437910c720579a4eaf65c85Sergey Kitov#else /* !G_LITTLE_ENDIAN && !G_BIG_ENDIAN */
bbd51f171bb2f4abd437910c720579a4eaf65c85Sergey Kitov#endif /* !G_LITTLE_ENDIAN && !G_BIG_ENDIAN */
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainentypedef struct
3abc26e06e053228d283503a8583657dfca0f2e0Timo Sirainen int alternate_format, zero_padding, adjust_left, locale_grouping;
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen int add_space, add_sign, possible_sign, seen_precision;
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainensize_t printf_string_upper_bound(const char *format, va_list args)
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen register char c = *format++;
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen if (c != '%')
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen else /* (c == '%') */
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen unsigned int conv_len = 0;
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen unsigned int v_uint;
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen /* beware of positional parameters
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen "(): unable to handle positional parameters (%%n$)");
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen len += 1024; /* try adding some safety padding */
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen /* parse flags
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen /* parse output size specifications
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen spec.precision = I_MAX (spec.precision, v_uint);
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen spec.min_width = I_MAX (spec.min_width, v_uint);
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen /* forget about negative precision */
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen spec.precision = I_MAX ((int)spec.precision, v_int);
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen spec.min_width = I_MAX ((int)spec.min_width, v_int);
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen /* parse type modifiers
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen /* else, fall through */
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen#endif /* GLIB_SIZEOF_SIZE_T > 4 */
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen#endif /* GLIB_SIZEOF_PTRDIFF_T > 4 */
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen#endif /* GLIB_SIZEOF_INTMAX_T > 4 */
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen /* parse output conversions
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen /* some C libraries feature long variants for these as well? */
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen /* fall through */
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen /* fall through */
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen /* fall through */
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen /* fall through */
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen /* fall through */
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen /* n . dddddddddddddddddddddddd E +- eeee */
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen conv_len += 1 + 1 + I_MAX (24, spec.precision) + 1 + 1 + 4;
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen "(): unable to handle long double, collecting double only");
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen#error need to implement special handling for long double
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen /* %f can expand up to all significant digits before '.' (308) */
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen if (c == 'f' &&
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen u_double.mpn.biased_exponent > 0 && u_double.mpn.biased_exponent < 2047)
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen /* some printf() implementations require extra padding for rounding */
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen /* we can't really handle locale specific grouping here */
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen /* fall through */
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen /* fall through */
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen "(): unable to handle wide char strings");
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen len += 1024; /* try adding some safety padding */
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen /* fall through */
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen /* fall through */
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen /* there's not much we can do to be clever */
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen /* handle invalid cases
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen /* no conversion specification, bad bad */
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen "(): unable to handle `%c' while parsing format",
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen /* handle width specifications */
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen conv_len = I_MAX (conv_len, I_MAX (spec.precision, spec.min_width));
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen /* handle flags */
dee1520b5166708bd8dd4230c279c950bf01029aTimo Sirainen conv_len += (spec.add_space || spec.add_sign || spec.possible_sign);
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen /* finally done */
dee1520b5166708bd8dd4230c279c950bf01029aTimo Sirainen } /* else (c == '%') */
dee1520b5166708bd8dd4230c279c950bf01029aTimo Sirainen } /* while (*format) */
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainenstatic const char *fix_format_real(const char *fmt, const char *p)
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen while (*p != '\0') {
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen/* replace %m with strerror() */
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen const char *p;
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainenint i_snprintf(char *str, size_t max_chars, const char *format, ...)
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen ret = vsnprintf(str, max_chars, fix_format(format), args);
return ret;
char *buf;
int len;
return len;
void *mem; \
len++; \
len++; \
return mem; \
} STMT_END
return NULL;
return NULL;
return NULL;
return NULL;
return NULL;
return NULL; \
} STMT_END
char *mem;
return mem;
char *mem;
return mem;
char *mem;
return NULL;
len = 0;
len++;
return mem;
char *ret;
return ret;
const char *ret;
return ret;
char *ret;
return NULL;
return ret;
const char *str;
char *temp;
return NULL;
if (len == 0)
return temp;
const char *temp;
char *ret;
return ret;
const char *ret;
return ret;
if (*p == cutchar)
return str;
return FALSE;
return FALSE;
str++;
return TRUE;
*p = i_toupper(*p);
return str;
*p = i_tolower(*p);
return str;
char *ret;
return NULL;
(*str)++;
(*str)++;
return ret;
char *dest;
int len;
len = 0;
while (*array) {
len++;
array++;
return len;
int index;
return index;
char **array;
char *str;
str++;
return (char *const *) array;
const char *arg;
char *data;
return NULL;
return data;
if (number == 0)
if (size == 0)
pos++;