1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h>
2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdarg.h>
3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h>
4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
5ca7648ddfb46347c60014a849b0150a74df4e1d2Colin Cross#include "parser.h"
6ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross#include "log.h"
7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define RAW(x...) log_write(6, x)
9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid DUMP(void)
11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if 0
13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct service *svc;
14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct action *act;
15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct command *cmd;
16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct listnode *node;
17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct listnode *node2;
18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct socketinfo *si;
19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int n;
20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    list_for_each(node, &service_list) {
22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        svc = node_to_item(node, struct service, slist);
23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        RAW("service %s\n", svc->name);
24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        RAW("  class '%s'\n", svc->classname);
25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        RAW("  exec");
26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        for (n = 0; n < svc->nargs; n++) {
27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            RAW(" '%s'", svc->args[n]);
28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        RAW("\n");
30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        for (si = svc->sockets; si; si = si->next) {
31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            RAW("  socket %s %s 0%o\n", si->name, si->type, si->perm);
32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    list_for_each(node, &action_list) {
36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        act = node_to_item(node, struct action, alist);
37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        RAW("on %s\n", act->name);
38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        list_for_each(node2, &act->commands) {
39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            cmd = node_to_item(node2, struct command, clist);
40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            RAW("  %p", cmd->func);
41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            for (n = 0; n < cmd->nargs; n++) {
42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                RAW(" %s", cmd->args[n]);
43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            RAW("\n");
45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        RAW("\n");
47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid parse_error(struct parse_state *state, const char *fmt, ...)
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    va_list ap;
54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char buf[128];
55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int off;
56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    snprintf(buf, 128, "%s: %d: ", state->filename, state->line);
58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    buf[127] = 0;
59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    off = strlen(buf);
60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    va_start(ap, fmt);
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    vsnprintf(buf + off, 128 - off, fmt, ap);
63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    va_end(ap);
64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    buf[127] = 0;
65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ERROR("%s", buf);
66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint next_token(struct parse_state *state)
69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *x = state->ptr;
71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *s;
72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (state->nexttoken) {
74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int t = state->nexttoken;
75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        state->nexttoken = 0;
76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return t;
77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (;;) {
80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        switch (*x) {
81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case 0:
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            state->ptr = x;
83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return T_EOF;
84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case '\n':
85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            x++;
86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            state->ptr = x;
87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return T_NEWLINE;
88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case ' ':
89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case '\t':
90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case '\r':
91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            x++;
92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            continue;
93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case '#':
94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            while (*x && (*x != '\n')) x++;
951be6968d9d51f43fdb00535708a6fed0be6bfbcaBruce Beare            if (*x == '\n') {
961be6968d9d51f43fdb00535708a6fed0be6bfbcaBruce Beare                state->ptr = x+1;
971be6968d9d51f43fdb00535708a6fed0be6bfbcaBruce Beare                return T_NEWLINE;
981be6968d9d51f43fdb00535708a6fed0be6bfbcaBruce Beare            } else {
991be6968d9d51f43fdb00535708a6fed0be6bfbcaBruce Beare                state->ptr = x;
1001be6968d9d51f43fdb00535708a6fed0be6bfbcaBruce Beare                return T_EOF;
1011be6968d9d51f43fdb00535708a6fed0be6bfbcaBruce Beare            }
102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        default:
103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            goto text;
104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttextdone:
108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    state->ptr = x;
109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    *s = 0;
110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return T_TEXT;
111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttext:
112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    state->text = s = x;
113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttextresume:
114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (;;) {
115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        switch (*x) {
116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case 0:
117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            goto textdone;
118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case ' ':
119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case '\t':
120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case '\r':
121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            x++;
122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            goto textdone;
123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case '\n':
124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            state->nexttoken = T_NEWLINE;
125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            x++;
126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            goto textdone;
127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case '"':
128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            x++;
129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            for (;;) {
130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                switch (*x) {
131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                case 0:
132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        /* unterminated quoted thing */
133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    state->ptr = x;
134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    return T_EOF;
135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                case '"':
136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    x++;
137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    goto textresume;
138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                default:
139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    *s++ = *x++;
140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                }
141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case '\\':
144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            x++;
145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            switch (*x) {
146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            case 0:
147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                goto textdone;
148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            case 'n':
149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                *s++ = '\n';
150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                break;
151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            case 'r':
152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                *s++ = '\r';
153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                break;
154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            case 't':
155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                *s++ = '\t';
156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                break;
157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            case '\\':
158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                *s++ = '\\';
159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                break;
160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            case '\r':
161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    /* \ <cr> <lf> -> line continuation */
162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                if (x[1] != '\n') {
163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    x++;
164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    continue;
165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                }
166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            case '\n':
167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    /* \ <lf> -> line continuation */
168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                state->line++;
169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                x++;
170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    /* eat any extra whitespace */
171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                while((*x == ' ') || (*x == '\t')) x++;
172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                continue;
173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            default:
174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    /* unknown escape -- just copy */
175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                *s++ = *x++;
176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            continue;
178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        default:
179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            *s++ = *x++;
180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return T_EOF;
183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
184