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