commit ad2faad
uint
·
2026-10-24 13:45:41 +0000 UTC
parent 87e16ec
Add string escaping
1 files changed,
+36,
-2
M
expl.c
M
expl.c
+36,
-2
1@@ -7,6 +7,8 @@
2
3 #define current_char(p, c) ((p)->src[(p)->pos] == (c))
4 #define advance(p) ((p)->pos++)
5+#define pos(p) ((p)->pos)
6+#define peek(p) ((p)->pos + 1)
7
8 typedef struct {
9 const char* src;
10@@ -20,6 +22,7 @@ static expl_node* value(parser* p, expl_type type);
11
12 static void skipspace(parser* p);
13 static char* _strndup(const char* src, size_t len);
14+static void unescape(char* src);
15
16 static expl_node* newnode(expl_type type);
17 static void freenode(expl_node* node);
18@@ -128,8 +131,10 @@ value(parser* p, expl_type type)
19 return NULL;
20 }
21
22- if (type == EXPL_TYPE_STRING)
23+ if (type == EXPL_TYPE_STRING) {
24+ unescape(node->value);
25 advance(p);
26+ }
27
28 return node;
29 }
30@@ -163,6 +168,35 @@ _strndup(const char* src, size_t len)
31 return str;
32 }
33
34+static void
35+unescape(char* src)
36+{
37+ char* dst = src;
38+
39+ while (*src) {
40+ if (*src == '\\' && src[1]) {
41+ src++;
42+ switch (*src) {
43+ case 'n': *dst++ = '\n'; break;
44+ case 't': *dst++ = '\t'; break;
45+ case 'r': *dst++ = '\r'; break;
46+ case '\\': *dst++ = '\\'; break;
47+ case '"': *dst++ = '"'; break;
48+ default:
49+ *dst++ = '\\';
50+ *dst++ = *src;
51+ }
52+ }
53+ else {
54+ *dst++ = *src;
55+ }
56+
57+ src++;
58+ }
59+
60+ *dst = '\0';
61+}
62+
63 static expl_node*
64 newnode(expl_type type)
65 {
66@@ -251,7 +285,7 @@ expl_print(const expl_node* node, int depth)
67 int
68 main(void)
69 {
70- expl_node* node = expl_parse("(fn (\"hi\" x) (* x x))");
71+ expl_node* node = expl_parse("(fn (\"hi\n\n\n\" x) (* x x))");
72 expl_print(node, 0);
73 freenode(node);
74 return EXIT_SUCCESS;