2017-07-27 21:54:48 +02:00
|
|
|
#include "tokenizer.h"
|
|
|
|
|
2018-09-19 23:34:51 +02:00
|
|
|
#include <android-base/macros.h>
|
|
|
|
|
2017-07-27 21:54:48 +02:00
|
|
|
namespace android {
|
|
|
|
namespace init {
|
|
|
|
|
|
|
|
int next_token(struct parse_state *state)
|
|
|
|
{
|
|
|
|
char *x = state->ptr;
|
|
|
|
char *s;
|
|
|
|
|
|
|
|
if (state->nexttoken) {
|
|
|
|
int t = state->nexttoken;
|
|
|
|
state->nexttoken = 0;
|
|
|
|
return t;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
switch (*x) {
|
|
|
|
case 0:
|
|
|
|
state->ptr = x;
|
|
|
|
return T_EOF;
|
|
|
|
case '\n':
|
|
|
|
x++;
|
|
|
|
state->ptr = x;
|
|
|
|
return T_NEWLINE;
|
|
|
|
case ' ':
|
|
|
|
case '\t':
|
|
|
|
case '\r':
|
|
|
|
x++;
|
|
|
|
continue;
|
|
|
|
case '#':
|
|
|
|
while (*x && (*x != '\n')) x++;
|
|
|
|
if (*x == '\n') {
|
|
|
|
state->ptr = x+1;
|
|
|
|
return T_NEWLINE;
|
|
|
|
} else {
|
|
|
|
state->ptr = x;
|
|
|
|
return T_EOF;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
goto text;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
textdone:
|
|
|
|
state->ptr = x;
|
|
|
|
*s = 0;
|
|
|
|
return T_TEXT;
|
|
|
|
text:
|
|
|
|
state->text = s = x;
|
|
|
|
textresume:
|
|
|
|
for (;;) {
|
|
|
|
switch (*x) {
|
|
|
|
case 0:
|
|
|
|
goto textdone;
|
|
|
|
case ' ':
|
|
|
|
case '\t':
|
|
|
|
case '\r':
|
|
|
|
x++;
|
|
|
|
goto textdone;
|
|
|
|
case '\n':
|
|
|
|
state->nexttoken = T_NEWLINE;
|
|
|
|
x++;
|
|
|
|
goto textdone;
|
|
|
|
case '"':
|
|
|
|
x++;
|
|
|
|
for (;;) {
|
|
|
|
switch (*x) {
|
|
|
|
case 0:
|
|
|
|
/* unterminated quoted thing */
|
|
|
|
state->ptr = x;
|
|
|
|
return T_EOF;
|
|
|
|
case '"':
|
|
|
|
x++;
|
|
|
|
goto textresume;
|
|
|
|
default:
|
|
|
|
*s++ = *x++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case '\\':
|
|
|
|
x++;
|
|
|
|
switch (*x) {
|
|
|
|
case 0:
|
|
|
|
goto textdone;
|
|
|
|
case 'n':
|
|
|
|
*s++ = '\n';
|
2018-06-25 10:04:33 +02:00
|
|
|
x++;
|
2017-07-27 21:54:48 +02:00
|
|
|
break;
|
|
|
|
case 'r':
|
|
|
|
*s++ = '\r';
|
2018-06-25 10:04:33 +02:00
|
|
|
x++;
|
2017-07-27 21:54:48 +02:00
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
*s++ = '\t';
|
2018-06-25 10:04:33 +02:00
|
|
|
x++;
|
2017-07-27 21:54:48 +02:00
|
|
|
break;
|
|
|
|
case '\\':
|
|
|
|
*s++ = '\\';
|
2018-06-25 10:04:33 +02:00
|
|
|
x++;
|
2017-07-27 21:54:48 +02:00
|
|
|
break;
|
|
|
|
case '\r':
|
|
|
|
/* \ <cr> <lf> -> line continuation */
|
|
|
|
if (x[1] != '\n') {
|
|
|
|
x++;
|
|
|
|
continue;
|
|
|
|
}
|
2018-06-25 10:04:33 +02:00
|
|
|
x++;
|
2018-09-19 23:34:51 +02:00
|
|
|
FALLTHROUGH_INTENDED;
|
2017-07-27 21:54:48 +02:00
|
|
|
case '\n':
|
|
|
|
/* \ <lf> -> line continuation */
|
|
|
|
state->line++;
|
|
|
|
x++;
|
|
|
|
/* eat any extra whitespace */
|
|
|
|
while((*x == ' ') || (*x == '\t')) x++;
|
|
|
|
continue;
|
|
|
|
default:
|
|
|
|
/* unknown escape -- just copy */
|
|
|
|
*s++ = *x++;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
default:
|
|
|
|
*s++ = *x++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return T_EOF;
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace init
|
|
|
|
} // namespace android
|