• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "tokenizer.h"
2 
3 #include <android-base/macros.h>
4 
5 namespace android {
6 namespace init {
7 
next_token(struct parse_state * state)8 int 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 
47 textdone:
48     state->ptr = x;
49     *s = 0;
50     return T_TEXT;
51 text:
52     state->text = s = x;
53 textresume:
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';
90                 x++;
91                 break;
92             case 'r':
93                 *s++ = '\r';
94                 x++;
95                 break;
96             case 't':
97                 *s++ = '\t';
98                 x++;
99                 break;
100             case '\\':
101                 *s++ = '\\';
102                 x++;
103                 break;
104             case '\r':
105                     /* \ <cr> <lf> -> line continuation */
106                 if (x[1] != '\n') {
107                     x++;
108                     continue;
109                 }
110                 x++;
111                 FALLTHROUGH_INTENDED;
112             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
133