From: Pavel Charvat Date: Mon, 24 Apr 2006 11:56:13 +0000 (+0200) Subject: Simple parser for escape sequences. X-Git-Tag: holmes-import~645^2~11^2~56 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=feb4a9d0c53a92e8880bc973363150b894224006;p=libucw.git Simple parser for escape sequences. --- diff --git a/lib/Makefile b/lib/Makefile index e4126c7f..216da3c1 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -26,7 +26,8 @@ LIBUCW_MODS= \ md5 md5hex \ base64 base224 \ sync \ - qache + qache \ + string LIBUCW_INCLUDES= \ lib.h config.h math.h \ diff --git a/lib/lib.h b/lib/lib.h index 06a42ece..9f7f59d4 100644 --- a/lib/lib.h +++ b/lib/lib.h @@ -250,4 +250,8 @@ struct sigaction; void handle_signal(int signum, struct sigaction *oldact); void unhandle_signal(int signum, struct sigaction *oldact); +/* string.c */ + +byte *str_unesc(byte *dest, byte *src); + #endif diff --git a/lib/stkstring.h b/lib/stkstring.h index 8f58aec7..22808cc7 100644 --- a/lib/stkstring.h +++ b/lib/stkstring.h @@ -18,6 +18,7 @@ #define stk_strarraycat(s,n) ({ char **_s=(s); int _n=(n); char *_x=alloca(stk_array_len(_s,_n)); stk_array_copy(_x, _s, _n); _x; }) #define stk_printf(f...) ({ uns _l=stk_printf_internal(f); char *_x=alloca(_l); memcpy(_x, stk_printf_buf, _l); _x; }) #define stk_hexdump(s,n) ({ uns _n=(n); char *_x=alloca(3*_n+1); stk_hexdump_internal(_x,(byte*)(s),_n); _x; }) +#define stk_str_unesc(s) ({ byte *_s=(s); byte *_d=alloca(strlen(_s)+1); str_unesc(_d, _s); _d; }) uns stk_array_len(char **s, uns cnt); void stk_array_copy(char *x, char **s, uns cnt); diff --git a/lib/string.c b/lib/string.c new file mode 100644 index 00000000..01685f82 --- /dev/null +++ b/lib/string.c @@ -0,0 +1,66 @@ +/* + * UCW Library -- String Routines + * + * (c) 2006 Pavel Charvat + * + * This software may be freely distributed and used according to the terms + * of the GNU Lesser General Public License. + */ + +#include "lib/lib.h" +#include "lib/chartype.h" + +/* Expands C99-like escape sequences. + * It is safe to use the same buffer for both input and output. */ +byte * +str_unesc(byte *d, byte *s) +{ + while (*s) + { + if (*s == '\\') + switch (s[1]) + { + case 'a': *d++ = '\a'; s += 2; break; + case 'b': *d++ = '\b'; s += 2; break; + case 'f': *d++ = '\f'; s += 2; break; + case 'n': *d++ = '\n'; s += 2; break; + case 'r': *d++ = '\r'; s += 2; break; + case 't': *d++ = '\t'; s += 2; break; + case 'v': *d++ = '\v'; s += 2; break; + case '\?': *d++ = '\?'; s += 2; break; + case '\'': *d++ = '\''; s += 2; break; + case '\"': *d++ = '\"'; s += 2; break; + case '\\': *d++ = '\\'; s += 2; break; + case '0': + if (s[2] < '0' || s[2] > '7') + *d++ = *s++; + else + { + uns v = 0; + for (s += 2; *s >= '0' && *s <= '7' && v < 32; s++) + v = (v << 3) + *s - '0'; + *d++ = v; + } + break; + case 'x': + if (!Cxdigit(s[2])) + *d++ = *s++; + else + { + uns v = 0; + for (s += 2; Cxdigit(*s) && v < 16; s++) + v = (v << 4) + (Cdigit(*s) ? (*s - '0') : ((*s | 32) - 'A' + 10)); + *d++ = v; + } + break; + default: + *d++ = *s++; + break; + } + else + *d++ = *s++; + } + *d = 0; + return d; +} +