parser.cpp revision 81f5d3ebef2c3789737bf718fc2a2cdd7b9e8b33
1#include "parser.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
125