summaryrefslogtreecommitdiff
path: root/utils/StringEscape.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils/StringEscape.c')
-rw-r--r--utils/StringEscape.c114
1 files changed, 114 insertions, 0 deletions
diff --git a/utils/StringEscape.c b/utils/StringEscape.c
new file mode 100644
index 000000000..be5ec55c3
--- /dev/null
+++ b/utils/StringEscape.c
@@ -0,0 +1,114 @@
+#include <stddef.h>
+
+//FIXME out gets silently truncated if outsize is too small
+
+size_t escape(char* in, char* out, size_t outsize) {
+ size_t l = 0;
+ while(*in && l + 3 < outsize) {
+ switch(*in) {
+ case '\n':
+ *out++ = '\\';
+ l++;
+ *out = 'n';
+ break;
+ case '\r':
+ *out++ = '\\';
+ l++;
+ *out = 'r';
+ break;
+ case '\t':
+ *out++ = '\\';
+ l++;
+ *out = 't';
+ break;
+ case '\\':
+ *out++ = '\\';
+ l++;
+ *out = '\\';
+ break;
+ case '"':
+ *out++ = '\\';
+ l++;
+ *out = '"';
+ break;
+ case '\v':
+ *out++ = '\\';
+ l++;
+ *out = '\v';
+ break;
+ case '\?':
+ *out++ = '\\';
+ l++;
+ *out = '\?';
+ break;
+ case '\f':
+ *out++ = '\\';
+ l++;
+ *out = '\f';
+ break;
+ default:
+ *out = *in;
+ }
+ in++;
+ out++;
+ l++;
+ }
+ *out = 0;
+ return l;
+}
+#include <assert.h>
+#include <stdlib.h>
+size_t unescape(char* in, char *out, size_t outsize) {
+ size_t l = 0;
+ while(*in && l + 2 < outsize) {
+ switch (*in) {
+ case '\\':
+ ++in;
+ assert(*in);
+ switch(*in) {
+ case 'n':
+ *out='\n';
+ break;
+ case 'r':
+ *out='\r';
+ break;
+ case 't':
+ *out='\t';
+ break;
+ case '\\':
+ *out='\\';
+ break;
+ case '"':
+ *out='"';
+ break;
+ case 'v':
+ *out='\v';
+ break;
+ case '\?':
+ *out = '\?';
+ break;
+ case 'f':
+ *out = '\f';
+ break;
+ case '\'':
+ *out = '\'';
+ break;
+ case 'b':
+ *out = '\b';
+ break;
+ // FIXME add handling of hex and octal
+ default:
+ abort();
+ }
+ break;
+ default:
+ *out=*in;
+ }
+ in++;
+ out++;
+ l++;
+ }
+ *out = 0;
+ return l;
+}
+