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
#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);
--- /dev/null
+/*
+ * UCW Library -- String Routines
+ *
+ * (c) 2006 Pavel Charvat <pchar@ucw.cz>
+ *
+ * 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;
+}
+