make parser more robuust, add string literals and escapes
[ccc.git] / util.c
diff --git a/util.c b/util.c
index 4b77f53..91166fd 100644 (file)
--- a/util.c
+++ b/util.c
@@ -50,6 +50,71 @@ int list_length(struct list *r)
        return i;
 }
 
+int fromHex(char c)
+{
+       if (c >= '0' && c <= '9')
+               return c-'0';
+       if (c >= 'a' && c <= 'f')
+               return c-'a'+10;
+       if (c >= 'A' && c <= 'F')
+               return c-'A'+10;
+       return -1;
+}
+
+char *escape_char(char c, char *buf, bool str)
+{
+       buf = buf == NULL ? safe_malloc(10) : buf;
+       switch (c) {
+       case '\0': strcpy(buf, "\\0"); break;
+       case '\a': strcpy(buf, "\\a"); break;
+       case '\b': strcpy(buf, "\\b"); break;
+       case '\t': strcpy(buf, "\\t"); break;
+       case '\n': strcpy(buf, "\\n"); break;
+       case '\v': strcpy(buf, "\\v"); break;
+       case '\f': strcpy(buf, "\\f"); break;
+       case '\r': strcpy(buf, "\\r"); break;
+       case '\'': strcpy(buf, str ? "'" : "\\'"); break;
+       case '"': strcpy(buf, str ? "\\\"" : "\""); break;
+       default:
+               if (c >= ' ' && c < 127) {
+                       sprintf(buf, "%c", c);
+               } else {
+                       sprintf(buf, "\\x%02x", (unsigned char)c);
+               }
+               break;
+       }
+       return buf;
+}
+
+char *unescape_char(char *c)
+{
+       //escape
+       if (c[0] == '\\') {
+               switch (c[1]) {
+               case '0': c[1] = '\0'; break;
+               case '\'': c[1] = '\''; break;
+               case '\\': c[1] = '\\'; break;
+               case '"': c[1] = '"'; break;
+               case 'a': c[1] = '\a'; break;
+               case 'b': c[1] = '\b'; break;
+               case 't': c[1] = '\t'; break;
+               case 'v': c[1] = '\v'; break;
+               case 'f': c[1] = '\f'; break;
+               case 'r': c[1] = '\r'; break;
+               case 'x': c[3] = (fromHex(c[2])<<4)+fromHex(c[3]); c+=2; break;
+               }
+               c++;
+       }
+       return c;
+}
+
+char *trimquotes(char *c)
+{
+       char *r = c+1;
+       r[strlen(r)-1] = '\0';
+       return r;
+}
+
 void pdie(const char *msg)
 {
        perror(msg);