blob: 81937291d47fb5d4fb1788ffd741f6ab420d4a3c [file] [log] [blame]
Elliott Hughesc0e919c2015-02-04 14:46:36 -08001#include "parser.h"
2
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08003#include <stdarg.h>
Elliott Hughesc0e919c2015-02-04 14:46:36 -08004#include <stdio.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08005#include <string.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08006
Colin Crossed8a7d82010-04-19 17:05:34 -07007#include "log.h"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08008
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08009void parse_error(struct parse_state *state, const char *fmt, ...)
10{
11 va_list ap;
12 char buf[128];
13 int off;
Elliott Hughesc0e919c2015-02-04 14:46:36 -080014
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080015 snprintf(buf, 128, "%s: %d: ", state->filename, state->line);
16 buf[127] = 0;
17 off = strlen(buf);
18
19 va_start(ap, fmt);
20 vsnprintf(buf + off, 128 - off, fmt, ap);
21 va_end(ap);
22 buf[127] = 0;
23 ERROR("%s", buf);
24}
25
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080026int next_token(struct parse_state *state)
27{
28 char *x = state->ptr;
29 char *s;
30
31 if (state->nexttoken) {
32 int t = state->nexttoken;
33 state->nexttoken = 0;
34 return t;
35 }
36
37 for (;;) {
38 switch (*x) {
39 case 0:
40 state->ptr = x;
41 return T_EOF;
42 case '\n':
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080043 x++;
44 state->ptr = x;
45 return T_NEWLINE;
46 case ' ':
47 case '\t':
48 case '\r':
49 x++;
50 continue;
51 case '#':
52 while (*x && (*x != '\n')) x++;
Bruce Beare1be69682010-12-26 09:55:10 -080053 if (*x == '\n') {
54 state->ptr = x+1;
55 return T_NEWLINE;
56 } else {
57 state->ptr = x;
58 return T_EOF;
59 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080060 default:
61 goto text;
62 }
63 }
64
65textdone:
66 state->ptr = x;
67 *s = 0;
68 return T_TEXT;
69text:
70 state->text = s = x;
71textresume:
72 for (;;) {
73 switch (*x) {
74 case 0:
75 goto textdone;
76 case ' ':
77 case '\t':
78 case '\r':
79 x++;
80 goto textdone;
81 case '\n':
82 state->nexttoken = T_NEWLINE;
83 x++;
84 goto textdone;
85 case '"':
86 x++;
87 for (;;) {
88 switch (*x) {
89 case 0:
90 /* unterminated quoted thing */
91 state->ptr = x;
92 return T_EOF;
93 case '"':
94 x++;
95 goto textresume;
96 default:
97 *s++ = *x++;
98 }
99 }
100 break;
101 case '\\':
102 x++;
103 switch (*x) {
104 case 0:
105 goto textdone;
106 case 'n':
107 *s++ = '\n';
108 break;
109 case 'r':
110 *s++ = '\r';
111 break;
112 case 't':
113 *s++ = '\t';
114 break;
115 case '\\':
116 *s++ = '\\';
117 break;
118 case '\r':
119 /* \ <cr> <lf> -> line continuation */
120 if (x[1] != '\n') {
121 x++;
122 continue;
123 }
124 case '\n':
125 /* \ <lf> -> line continuation */
126 state->line++;
127 x++;
128 /* eat any extra whitespace */
129 while((*x == ' ') || (*x == '\t')) x++;
130 continue;
131 default:
132 /* unknown escape -- just copy */
133 *s++ = *x++;
134 }
135 continue;
136 default:
137 *s++ = *x++;
138 }
139 }
140 return T_EOF;
141}