X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=src%2Fsrc%2Fstring.c;h=0e73e2c79c73ef2e65783b46b47e06fbfbb16bbe;hb=ae96393855f6ea395a53a1767cc049d1f6ae9683;hp=1c1f2dd83304cb2b65712b5d73c75b8fabb43c70;hpb=3634fc257bd0667daef14d72005cd87c735bbb24;p=exim.git diff --git a/src/src/string.c b/src/src/string.c index 1c1f2dd83..0e73e2c79 100644 --- a/src/src/string.c +++ b/src/src/string.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2009 */ +/* Copyright (c) University of Cambridge 1995 - 2012 */ /* See the file NOTICE for conditions of use and distribution. */ /* Miscellaneous string-handling functions. Some are not required for @@ -210,7 +210,6 @@ return yield; -#ifndef COMPILE_UTILITY /************************************************* * Interpret escape sequence * *************************************************/ @@ -227,6 +226,9 @@ Returns: the value of the character escape int string_interpret_escape(uschar **pp) { +#ifdef COMPILE_UTILITY +const uschar *hex_digits= CUS"0123456789abcdef"; +#endif int ch; uschar *p = *pp; ch = *(++p); @@ -242,9 +244,12 @@ if (isdigit(ch) && ch != '8' && ch != '9') } else switch(ch) { + case 'b': ch = '\b'; break; + case 'f': ch = '\f'; break; case 'n': ch = '\n'; break; case 'r': ch = '\r'; break; case 't': ch = '\t'; break; + case 'v': ch = '\v'; break; case 'x': ch = 0; if (isxdigit(p[1])) @@ -259,7 +264,6 @@ else switch(ch) *pp = p; return ch; } -#endif /* COMPILE_UTILITY */ @@ -331,6 +335,72 @@ return ss; } #endif /* COMPILE_UTILITY */ +/************************************************* +* Undo printing escapes in string * +*************************************************/ + +/* This function is the reverse of string_printing2. It searches for +backslash characters and if any are found, it makes a new copy of the +string with escape sequences parsed. Otherwise it returns the original +string. + +Arguments: + s the input string + +Returns: string with printing escapes parsed back +*/ + +uschar * +string_unprinting(uschar *s) +{ +uschar *p, *q, *r, *ss; +int len, off; + +p = Ustrchr(s, '\\'); +if (!p) return s; + +len = Ustrlen(s) + 1; +ss = store_get(len); + +q = ss; +off = p - s; +if (off) + { + memcpy(q, s, off); + q += off; + } + +while (*p) + { + if (*p == '\\') + { + *q = string_interpret_escape(&p); + } + else + { + r = Ustrchr(p, '\\'); + if (!r) + { + off = Ustrlen(p); + memcpy(q, p, off); + p += off; + q += off; + break; + } + else + { + off = r - p; + memcpy(q, p, off); + q += off; + p = r; + } + } + } +*q = '\0'; + +return ss; +} + @@ -345,7 +415,7 @@ Returns: copy of string in new store */ uschar * -string_copy(uschar *s) +string_copy(const uschar *s) { int len = Ustrlen(s) + 1; uschar *ss = store_get(len); @@ -646,7 +716,7 @@ uschar buffer[STRING_SPRINTF_BUFFER_SIZE]; va_start(ap, format); if (!string_vformat(buffer, sizeof(buffer), format, ap)) log_write(0, LOG_MAIN|LOG_PANIC_DIE, - "string_sprintf expansion was longer than %d", sizeof(buffer)); + "string_sprintf expansion was longer than " SIZE_T_FMT, sizeof(buffer)); va_end(ap); return string_copy(buffer); } @@ -1064,7 +1134,8 @@ return yield; BOOL string_vformat(uschar *buffer, int buflen, const char *format, va_list ap) { -enum { L_NORMAL, L_SHORT, L_LONG, L_LONGLONG, L_LONGDOUBLE }; +/* We assume numbered ascending order, C does not guarantee that */ +enum { L_NORMAL=1, L_SHORT=2, L_LONG=3, L_LONGLONG=4, L_LONGDOUBLE=5, L_SIZE=6 }; BOOL yield = TRUE; int width, precision; @@ -1134,7 +1205,7 @@ while (*fp != 0) } } - /* Skip over 'h', 'L', 'l', and 'll', remembering the item length */ + /* Skip over 'h', 'L', 'l', 'll' and 'z', remembering the item length */ if (*fp == 'h') { fp++; length = L_SHORT; } @@ -1153,6 +1224,8 @@ while (*fp != 0) length = L_LONG; } } + else if (*fp == 'z') + { fp++; length = L_SIZE; } /* Handle each specific format type. */ @@ -1182,6 +1255,7 @@ while (*fp != 0) case L_NORMAL: sprintf(CS p, newformat, va_arg(ap, int)); break; case L_LONG: sprintf(CS p, newformat, va_arg(ap, long int)); break; case L_LONGLONG: sprintf(CS p, newformat, va_arg(ap, LONGLONG_T)); break; + case L_SIZE: sprintf(CS p, newformat, va_arg(ap, size_t)); break; } while (*p) p++; break;