blob: 7e05a0a74fe1283f7fa27c1b12f1fc22e8194eb5 [file] [log] [blame]
Tom Cherry67dee622017-07-27 12:54:48 -07001#include "tokenizer.h"
2
Tom Cherryae8a6b92018-09-19 14:34:51 -07003#include <android-base/macros.h>
4
Tom Cherry67dee622017-07-27 12:54:48 -07005namespace android {
6namespace init {
7
8int next_token(struct parse_state *state)
9{
10 char *x = state->ptr;
11 char *s;
12
13 if (state->nexttoken) {
14 int t = state->nexttoken;
15 state->nexttoken = 0;
16 return t;
17 }
18
19 for (;;) {
20 switch (*x) {
21 case 0:
22 state->ptr = x;
23 return T_EOF;
24 case '\n':
25 x++;
26 state->ptr = x;
27 return T_NEWLINE;
28 case ' ':
29 case '\t':
30 case '\r':
31 x++;
32 continue;
33 case '#':
34 while (*x && (*x != '\n')) x++;
35 if (*x == '\n') {
36 state->ptr = x+1;
37 return T_NEWLINE;
38 } else {
39 state->ptr = x;
40 return T_EOF;
41 }
42 default:
43 goto text;
44 }
45 }
46
47textdone:
48 state->ptr = x;
49 *s = 0;
50 return T_TEXT;
51text:
52 state->text = s = x;
53textresume:
54 for (;;) {
55 switch (*x) {
56 case 0:
57 goto textdone;
58 case ' ':
59 case '\t':
60 case '\r':
61 x++;
62 goto textdone;
63 case '\n':
64 state->nexttoken = T_NEWLINE;
65 x++;
66 goto textdone;
67 case '"':
68 x++;
69 for (;;) {
70 switch (*x) {
71 case 0:
72 /* unterminated quoted thing */
73 state->ptr = x;
74 return T_EOF;
75 case '"':
76 x++;
77 goto textresume;
78 default:
79 *s++ = *x++;
80 }
81 }
82 break;
83 case '\\':
84 x++;
85 switch (*x) {
86 case 0:
87 goto textdone;
88 case 'n':
89 *s++ = '\n';
liwugang332afef2018-06-25 16:04:33 +080090 x++;
Tom Cherry67dee622017-07-27 12:54:48 -070091 break;
92 case 'r':
93 *s++ = '\r';
liwugang332afef2018-06-25 16:04:33 +080094 x++;
Tom Cherry67dee622017-07-27 12:54:48 -070095 break;
96 case 't':
97 *s++ = '\t';
liwugang332afef2018-06-25 16:04:33 +080098 x++;
Tom Cherry67dee622017-07-27 12:54:48 -070099 break;
100 case '\\':
101 *s++ = '\\';
liwugang332afef2018-06-25 16:04:33 +0800102 x++;
Tom Cherry67dee622017-07-27 12:54:48 -0700103 break;
104 case '\r':
105 /* \ <cr> <lf> -> line continuation */
106 if (x[1] != '\n') {
107 x++;
108 continue;
109 }
liwugang332afef2018-06-25 16:04:33 +0800110 x++;
Tom Cherryae8a6b92018-09-19 14:34:51 -0700111 FALLTHROUGH_INTENDED;
Tom Cherry67dee622017-07-27 12:54:48 -0700112 case '\n':
113 /* \ <lf> -> line continuation */
114 state->line++;
115 x++;
116 /* eat any extra whitespace */
117 while((*x == ' ') || (*x == '\t')) x++;
118 continue;
119 default:
120 /* unknown escape -- just copy */
121 *s++ = *x++;
122 }
123 continue;
124 default:
125 *s++ = *x++;
126 }
127 }
128 return T_EOF;
129}
130
131} // namespace init
132} // namespace android