~alexandre-hardy/linuxjoymap/linuxjoymap

« back to all changes in this revision

Viewing changes to mapparser.c

  • Committer: Alexandre Hardy
  • Date: 2013-10-26 23:06:51 UTC
  • Revision ID: alexandre.hardy@gmail.com-20131026230651-aebhxz6it8sk0425
Change tabs to spaces

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
static int error=0;
13
13
 
14
14
static struct reserved reserved[]={
15
 
        {"shift", SHIFT},
16
 
        {"button", BUTTON},
17
 
        {"axis", AXIS},
18
 
        {"code", CODE},
19
 
        {"script", SCRIPT},
20
 
        {"include", INCLUDE},
21
 
        {"joysticks", JOYSTICKS},
22
 
        {"joystick", JOYSTICK},
23
 
        {NULL, 0}
 
15
    {"shift", SHIFT},
 
16
    {"button", BUTTON},
 
17
    {"axis", AXIS},
 
18
    {"code", CODE},
 
19
    {"script", SCRIPT},
 
20
    {"include", INCLUDE},
 
21
    {"joysticks", JOYSTICKS},
 
22
    {"joystick", JOYSTICK},
 
23
    {NULL, 0}
24
24
};
25
25
 
26
26
static char *known_keys[]={
27
 
        "id",
28
 
        "vendor",
29
 
        "product",
30
 
        "src", 
31
 
        "target",
32
 
        "axis",
33
 
        "plus",
34
 
        "minus",
35
 
        "device",
36
 
        "flags",
37
 
        "button",
38
 
        "axes",
39
 
        "buttons",
40
 
        NULL
 
27
    "id",
 
28
    "vendor",
 
29
    "product",
 
30
    "src", 
 
31
    "target",
 
32
    "axis",
 
33
    "plus",
 
34
    "minus",
 
35
    "device",
 
36
    "flags",
 
37
    "button",
 
38
    "axes",
 
39
    "buttons",
 
40
    NULL
41
41
};
42
42
 
43
43
FILE *pfile=NULL;
67
67
static char compile[256]="";
68
68
 
69
69
static int ishex(char *s) {
70
 
        char c;
71
 
        if (*s!='0') return 0;
72
 
        s++;
73
 
        if (*s!='x') return 0;
74
 
        s++;
75
 
        while (*s!='\0') {
76
 
                c=*s;
77
 
                if ((('A'<=c)&&(c<='F'))||
78
 
                    (('a'<=c)&&(c<='f'))||
79
 
                    (('0'<=c)&&(c<='9'))) s++;
80
 
                else return 0;
81
 
        }
82
 
        return 1;
 
70
    char c;
 
71
    if (*s!='0') return 0;
 
72
    s++;
 
73
    if (*s!='x') return 0;
 
74
    s++;
 
75
    while (*s!='\0') {
 
76
        c=*s;
 
77
        if ((('A'<=c)&&(c<='F'))||
 
78
            (('a'<=c)&&(c<='f'))||
 
79
            (('0'<=c)&&(c<='9'))) s++;
 
80
        else return 0;
 
81
    }
 
82
    return 1;
83
83
}
84
84
 
85
85
static int isnum(char *s) {
86
 
        char c;
87
 
        while (*s!='\0') {
88
 
                c=*s;
89
 
                if (('0'<=c)&&(c<='9')) s++;
90
 
                else return 0;
91
 
        }
92
 
        return 1;
 
86
    char c;
 
87
    while (*s!='\0') {
 
88
        c=*s;
 
89
        if (('0'<=c)&&(c<='9')) s++;
 
90
        else return 0;
 
91
    }
 
92
    return 1;
93
93
}
94
94
 
95
95
int numeric(char *s) {
96
 
        int r=0;
97
 
        char msg[256];
98
 
        if (s==NULL) return 0;
99
 
        if (ishex(s)) {
100
 
                r=strtol(s, NULL, 16);
101
 
        } else if (isnum(s)) {
102
 
                r=strtol(s, NULL, 10);
103
 
        } else {
104
 
                sprintf(msg, "Expected a number, got %s instead", s);
105
 
                report(msg);
106
 
                return 0;
107
 
        }
108
 
        return r;
 
96
    int r=0;
 
97
    char msg[256];
 
98
    if (s==NULL) return 0;
 
99
    if (ishex(s)) {
 
100
        r=strtol(s, NULL, 16);
 
101
    } else if (isnum(s)) {
 
102
        r=strtol(s, NULL, 10);
 
103
    } else {
 
104
        sprintf(msg, "Expected a number, got %s instead", s);
 
105
        report(msg);
 
106
        return 0;
 
107
    }
 
108
    return r;
109
109
}
110
110
 
111
111
static int get_device(char *s) {
112
 
        char msg[256];
113
 
        if (s==NULL) report("Device expected!");
114
 
        if (strcmp(s, "joyaxis")==0) return DEVICE_JOYSTICK;
115
 
        if (strcmp(s, "joybtn")==0) return DEVICE_JOYSTICK;
116
 
        if (strcmp(s, "joystick")==0) return DEVICE_JOYSTICK;
117
 
        if (strcmp(s, "kbd")==0) return DEVICE_KBD;
118
 
        if (strcmp(s, "mouse")==0) return DEVICE_MOUSE;
119
 
        sprintf(msg, "Expecting a device type:joyaxis,joybtn,joystick,kbd,mouse. Found %s instead", s);
120
 
        report(msg);
121
 
        return 255;
 
112
    char msg[256];
 
113
    if (s==NULL) report("Device expected!");
 
114
    if (strcmp(s, "joyaxis")==0) return DEVICE_JOYSTICK;
 
115
    if (strcmp(s, "joybtn")==0) return DEVICE_JOYSTICK;
 
116
    if (strcmp(s, "joystick")==0) return DEVICE_JOYSTICK;
 
117
    if (strcmp(s, "kbd")==0) return DEVICE_KBD;
 
118
    if (strcmp(s, "mouse")==0) return DEVICE_MOUSE;
 
119
    sprintf(msg, "Expecting a device type:joyaxis,joybtn,joystick,kbd,mouse. Found %s instead", s);
 
120
    report(msg);
 
121
    return 255;
122
122
}
123
123
 
124
124
static int get_type(char *s, dictionary d) {
125
 
        char *button, *axis;
126
 
        if (s==NULL) return 255;
127
 
        if (strcmp(s, "joyaxis")==0) return TYPE_AXIS;
128
 
        if (strcmp(s, "joybtn")==0) return TYPE_BUTTON;
129
 
        button=lookup_dictionary(d, "button");
130
 
        axis=lookup_dictionary(d, "axis");
131
 
        if ((button!=NULL)&&(axis!=NULL)) {
132
 
                report("Only one of the keys 'button' and 'axis' may be specified");
133
 
                return 255;
134
 
        }
135
 
        if (button!=NULL) return TYPE_BUTTON;
136
 
        if (axis!=NULL) return TYPE_AXIS;
137
 
        return 255;
 
125
    char *button, *axis;
 
126
    if (s==NULL) return 255;
 
127
    if (strcmp(s, "joyaxis")==0) return TYPE_AXIS;
 
128
    if (strcmp(s, "joybtn")==0) return TYPE_BUTTON;
 
129
    button=lookup_dictionary(d, "button");
 
130
    axis=lookup_dictionary(d, "axis");
 
131
    if ((button!=NULL)&&(axis!=NULL)) {
 
132
        report("Only one of the keys 'button' and 'axis' may be specified");
 
133
        return 255;
 
134
    }
 
135
    if (button!=NULL) return TYPE_BUTTON;
 
136
    if (axis!=NULL) return TYPE_AXIS;
 
137
    return 255;
138
138
}
139
139
 
140
140
static int parse_flags(char *s) {
141
 
        int flags=FLAG_NONE;
142
 
        char *p=s;
143
 
        int more=1;
144
 
        char msg[256];
145
 
        if (s==NULL) return flags;
146
 
        while (more) {
147
 
                while ((*p!='\0')&&(*p!=',')&&(*p!=';')) p++;
148
 
                if (*p=='\0') more=0;
149
 
                *p='\0';
150
 
                if (strcmp(s, "autorelease")==0) flags|=FLAG_AUTO_RELEASE;
151
 
                else if (strcmp(s, "release")==0) flags|=FLAG_RELEASE;
152
 
                else if (strcmp(s, "press")==0) flags|=FLAG_PRESS;
153
 
                else if (strcmp(s, "shift")==0) flags|=FLAG_SHIFT;
154
 
                else if (strcmp(s, "invert")==0) flags|=FLAG_INVERT;
155
 
                else {
156
 
                        sprintf(msg, "Unknown flag %s", s);
157
 
                        report(msg);
158
 
                }
159
 
                s=p+1;
160
 
        }
161
 
        return flags;
 
141
    int flags=FLAG_NONE;
 
142
    char *p=s;
 
143
    int more=1;
 
144
    char msg[256];
 
145
    if (s==NULL) return flags;
 
146
    while (more) {
 
147
        while ((*p!='\0')&&(*p!=',')&&(*p!=';')) p++;
 
148
        if (*p=='\0') more=0;
 
149
        *p='\0';
 
150
        if (strcmp(s, "autorelease")==0) flags|=FLAG_AUTO_RELEASE;
 
151
        else if (strcmp(s, "release")==0) flags|=FLAG_RELEASE;
 
152
        else if (strcmp(s, "press")==0) flags|=FLAG_PRESS;
 
153
        else if (strcmp(s, "shift")==0) flags|=FLAG_SHIFT;
 
154
        else if (strcmp(s, "invert")==0) flags|=FLAG_INVERT;
 
155
        else {
 
156
            sprintf(msg, "Unknown flag %s", s);
 
157
            report(msg);
 
158
        }
 
159
        s=p+1;
 
160
    }
 
161
    return flags;
162
162
}
163
163
 
164
164
static void parse_sequence(__u16 *sequence, char *s, int base, int type) {
165
 
        char *p;
166
 
        int releaseflag=0;
167
 
        int value;
168
 
        int i;
169
 
        int n=0;
170
 
        char msg[256];
171
 
        if (s==NULL) return;
172
 
        if (isnum(s)) {
173
 
                if ((base==DEVICE_JOYSTICK)&&(type==TYPE_BUTTON)) {
174
 
                        base=BTN_JOYSTICK;
175
 
                } else if ((base==DEVICE_MOUSE)&&(type==TYPE_BUTTON)) {
176
 
                        base=BTN_MOUSE;
177
 
                } else base=0;
178
 
                sequence[0]=numeric(s)+base;
179
 
                sequence[1]=SEQUENCE_DONE;
180
 
        } else {
181
 
                p=s;
182
 
                while (*p!='\0') {
183
 
                        //skip whitespace
184
 
                        while ((*p!='\0')&&(isspace(*p))) p++;
185
 
                        s=p;
186
 
                        while ((*p!='\0')&&(!(isspace(*p)))) p++;
187
 
                        if (*p!='\0') {
188
 
                                *p='\0';
189
 
                                p++;
190
 
                        }
191
 
                        value=-1;
192
 
                        if (strcmp(s, "REL")==0) releaseflag=RELEASEMASK;
193
 
                        else {
194
 
                                i=0;
195
 
                                while (keymap[i].value!=-1) {
196
 
                                        if (strcmp(keymap[i].key, s)==0) 
197
 
                                                value=keymap[i].value;
198
 
                                        i++;
199
 
                                }
200
 
                                if (value==-1) {
201
 
                                        parse_err=1;
202
 
                                        sprintf(msg, "Unknown key %s", s);
203
 
                                        report(msg);
204
 
                                } else {
205
 
                                        sequence[n]=value|releaseflag;
206
 
                                        releaseflag=0;
207
 
                                        n++;
208
 
                                }
209
 
                        }
210
 
                        s=p;
211
 
                }
212
 
                sequence[n]=SEQUENCE_DONE;
213
 
        }
 
165
    char *p;
 
166
    int releaseflag=0;
 
167
    int value;
 
168
    int i;
 
169
    int n=0;
 
170
    char msg[256];
 
171
    if (s==NULL) return;
 
172
    if (isnum(s)) {
 
173
        if ((base==DEVICE_JOYSTICK)&&(type==TYPE_BUTTON)) {
 
174
            base=BTN_JOYSTICK;
 
175
        } else if ((base==DEVICE_MOUSE)&&(type==TYPE_BUTTON)) {
 
176
            base=BTN_MOUSE;
 
177
        } else base=0;
 
178
        sequence[0]=numeric(s)+base;
 
179
        sequence[1]=SEQUENCE_DONE;
 
180
    } else {
 
181
        p=s;
 
182
        while (*p!='\0') {
 
183
            //skip whitespace
 
184
            while ((*p!='\0')&&(isspace(*p))) p++;
 
185
            s=p;
 
186
            while ((*p!='\0')&&(!(isspace(*p)))) p++;
 
187
            if (*p!='\0') {
 
188
                *p='\0';
 
189
                p++;
 
190
            }
 
191
            value=-1;
 
192
            if (strcmp(s, "REL")==0) releaseflag=RELEASEMASK;
 
193
            else {
 
194
                i=0;
 
195
                while (keymap[i].value!=-1) {
 
196
                    if (strcmp(keymap[i].key, s)==0) 
 
197
                        value=keymap[i].value;
 
198
                    i++;
 
199
                }
 
200
                if (value==-1) {
 
201
                    parse_err=1;
 
202
                    sprintf(msg, "Unknown key %s", s);
 
203
                    report(msg);
 
204
                } else {
 
205
                    sequence[n]=value|releaseflag;
 
206
                    releaseflag=0;
 
207
                    n++;
 
208
                }
 
209
            }
 
210
            s=p;
 
211
        }
 
212
        sequence[n]=SEQUENCE_DONE;
 
213
    }
214
214
}
215
215
 
216
216
static void show_dictionary(dictionary dict) {
217
 
        dictionary d=dict;
218
 
        char *entry;
219
 
        entry=get_current(d);
220
 
        while (entry!=NULL) {
221
 
                printf("%s ", entry);
222
 
                d=next_entry(d);
223
 
                entry=get_current(d);
224
 
        }
 
217
    dictionary d=dict;
 
218
    char *entry;
 
219
    entry=get_current(d);
 
220
    while (entry!=NULL) {
 
221
        printf("%s ", entry);
 
222
        d=next_entry(d);
 
223
        entry=get_current(d);
 
224
    }
225
225
}
226
226
 
227
227
static int has_required(dictionary dict, ...) {
228
 
        va_list ap;
229
 
        char *s;
230
 
        char *entry;
231
 
        char msg[256];
 
228
    va_list ap;
 
229
    char *s;
 
230
    char *entry;
 
231
    char msg[256];
232
232
 
233
 
        va_start(ap, dict);
234
 
        s=va_arg(ap, char *);
235
 
        while (s!=NULL) {
236
 
                entry=lookup_dictionary(dict, s);
237
 
                if (entry==NULL) {
238
 
                        sprintf(msg, "Missing key:%s", s);
239
 
                        report(msg);
240
 
                        printf("Defined keys: ");
241
 
                        show_dictionary(dict);
242
 
                        printf("\n");
243
 
                        va_end(ap);
244
 
                        return 0;
245
 
                }
246
 
                s=va_arg(ap, char *);
247
 
        }
248
 
        va_end(ap);
249
 
        return 1;
 
233
    va_start(ap, dict);
 
234
    s=va_arg(ap, char *);
 
235
    while (s!=NULL) {
 
236
        entry=lookup_dictionary(dict, s);
 
237
        if (entry==NULL) {
 
238
            sprintf(msg, "Missing key:%s", s);
 
239
            report(msg);
 
240
            printf("Defined keys: ");
 
241
            show_dictionary(dict);
 
242
            printf("\n");
 
243
            va_end(ap);
 
244
            return 0;
 
245
        }
 
246
        s=va_arg(ap, char *);
 
247
    }
 
248
    va_end(ap);
 
249
    return 1;
250
250
}
251
251
 
252
252
void report(char *message) {
253
 
        error=1;
254
 
        fprintf(stderr, "%d:%d %s.\n", line, cpos, message);
 
253
    error=1;
 
254
    fprintf(stderr, "%d:%d %s.\n", line, cpos, message);
255
255
}
256
256
 
257
257
void reportline(int line, int cpos, char *message) {
258
 
        error=1;
259
 
        fprintf(stderr, "%d:%d %s.\n", line, cpos, message);
 
258
    error=1;
 
259
    fprintf(stderr, "%d:%d %s.\n", line, cpos, message);
260
260
}
261
261
 
262
262
int peekchar() {
263
 
        if (nextchar!=NONE) return nextchar;
264
 
        nextchar=fgetc(pfile);
265
 
        return nextchar;
 
263
    if (nextchar!=NONE) return nextchar;
 
264
    nextchar=fgetc(pfile);
 
265
    return nextchar;
266
266
}
267
267
 
268
268
void eatchar() {
269
 
        if (nextchar=='\n') {
270
 
                line++;
271
 
                cpos=1;
272
 
        } else cpos++;
273
 
        if (nextchar!=EOF)
274
 
                nextchar=NONE;
 
269
    if (nextchar=='\n') {
 
270
        line++;
 
271
        cpos=1;
 
272
    } else cpos++;
 
273
    if (nextchar!=EOF)
 
274
        nextchar=NONE;
275
275
}
276
276
 
277
277
int readchar() {
278
 
        int c=peekchar();
279
 
        eatchar();
280
 
        return c;
 
278
    int c=peekchar();
 
279
    eatchar();
 
280
    return c;
281
281
}
282
282
 
283
283
static struct token newline() {
284
 
        struct token t;
285
 
        t.line=line;
286
 
        t.pos=cpos;
287
 
        t.type=NL;
288
 
        strcpy(t.value, "\n");
289
 
        eatchar();
290
 
        return t;
 
284
    struct token t;
 
285
    t.line=line;
 
286
    t.pos=cpos;
 
287
    t.type=NL;
 
288
    strcpy(t.value, "\n");
 
289
    eatchar();
 
290
    return t;
291
291
}
292
292
 
293
293
static struct token eof() {
294
 
        struct token t;
295
 
        t.line=line;
296
 
        t.pos=cpos;
297
 
        t.type=EOF;
298
 
        strcpy(t.value, "end of file");
299
 
        return t;
 
294
    struct token t;
 
295
    t.line=line;
 
296
    t.pos=cpos;
 
297
    t.type=EOF;
 
298
    strcpy(t.value, "end of file");
 
299
    return t;
300
300
}
301
301
 
302
302
static void parse_comment() {
303
 
        //first character was #
304
 
        //read until newline
305
 
        int nc;
306
 
        nc=peekchar();
307
 
        while ((nc!='\n')&&(nc!=EOF)) {
308
 
                eatchar();
309
 
                nc=peekchar();
310
 
        }
 
303
    //first character was #
 
304
    //read until newline
 
305
    int nc;
 
306
    nc=peekchar();
 
307
    while ((nc!='\n')&&(nc!=EOF)) {
 
308
        eatchar();
 
309
        nc=peekchar();
 
310
    }
311
311
}
312
312
 
313
313
static void skipwhite() {
314
 
        int nc=peekchar();
315
 
        while (isspace(nc)&&(nc!='\n')) {
316
 
                eatchar();
317
 
                nc=peekchar();
318
 
        }
 
314
    int nc=peekchar();
 
315
    while (isspace(nc)&&(nc!='\n')) {
 
316
        eatchar();
 
317
        nc=peekchar();
 
318
    }
319
319
}
320
320
 
321
321
static struct token parse_string() {
322
 
        //opening quote has been read
323
 
        //read until closing quote
324
 
        struct token t;
325
 
        int pos=0;
326
 
        int nc;
327
 
        t.line=line;
328
 
        t.pos=cpos;
329
 
        t.type=STRING;
 
322
    //opening quote has been read
 
323
    //read until closing quote
 
324
    struct token t;
 
325
    int pos=0;
 
326
    int nc;
 
327
    t.line=line;
 
328
    t.pos=cpos;
 
329
    t.type=STRING;
330
330
 
331
 
        nc=readchar();
332
 
        nc=readchar();
333
 
        while (nc!='"') {
334
 
                if (nc==EOF) {
335
 
                        report("Unexpected end of file while parsing a string literal");
336
 
                        break;
337
 
                }
338
 
                t.value[pos++]=nc;
339
 
                nc=readchar();
340
 
        }
341
 
        t.value[pos]='\0';
342
 
        return t;
 
331
    nc=readchar();
 
332
    nc=readchar();
 
333
    while (nc!='"') {
 
334
        if (nc==EOF) {
 
335
            report("Unexpected end of file while parsing a string literal");
 
336
            break;
 
337
        }
 
338
        t.value[pos++]=nc;
 
339
        nc=readchar();
 
340
    }
 
341
    t.value[pos]='\0';
 
342
    return t;
343
343
}
344
344
 
345
345
static struct token parse_value(struct token t, int pos) {
346
 
        int nc;
347
 
        t.type=VALUE;
348
 
        if (pos>=0) {
349
 
                nc=peekchar();
350
 
                while (isalnum(nc)||(nc==',')||(nc==';')) {
351
 
                        t.value[pos++]=nc;
352
 
                        eatchar();
353
 
                        nc=peekchar();
354
 
                }
355
 
                t.value[pos]='\0';
356
 
        }
357
 
        nc=0;
358
 
        while (reserved[nc].token!=NULL) {
359
 
                if (strcmp(reserved[nc].token, t.value)==0) {
360
 
                        t.type=reserved[nc].value;
361
 
                        break;
362
 
                }
363
 
                nc++;
364
 
        }
365
 
        return t;
 
346
    int nc;
 
347
    t.type=VALUE;
 
348
    if (pos>=0) {
 
349
        nc=peekchar();
 
350
        while (isalnum(nc)||(nc==',')||(nc==';')) {
 
351
            t.value[pos++]=nc;
 
352
            eatchar();
 
353
            nc=peekchar();
 
354
        }
 
355
        t.value[pos]='\0';
 
356
    }
 
357
    nc=0;
 
358
    while (reserved[nc].token!=NULL) {
 
359
        if (strcmp(reserved[nc].token, t.value)==0) {
 
360
            t.type=reserved[nc].value;
 
361
            break;
 
362
        }
 
363
        nc++;
 
364
    }
 
365
    return t;
366
366
}
367
367
 
368
368
static struct token parse_id(struct token t, int pos) {
369
 
        int nc;
370
 
        t.type=ID;
371
 
        nc=peekchar();
372
 
        while (isalnum(nc)||(nc=='_')) {
373
 
                t.value[pos++]=nc;
374
 
                eatchar();
375
 
                nc=peekchar();
376
 
        }
377
 
        t.value[pos]='\0';
378
 
        nc=peekchar();
379
 
        if (nc!='=') {
380
 
                report("Expected an \"=\"");
381
 
        } else eatchar();
382
 
        
383
 
        return t;
 
369
    int nc;
 
370
    t.type=ID;
 
371
    nc=peekchar();
 
372
    while (isalnum(nc)||(nc=='_')) {
 
373
        t.value[pos++]=nc;
 
374
        eatchar();
 
375
        nc=peekchar();
 
376
    }
 
377
    t.value[pos]='\0';
 
378
    nc=peekchar();
 
379
    if (nc!='=') {
 
380
        report("Expected an \"=\"");
 
381
    } else eatchar();
 
382
    
 
383
    return t;
384
384
}
385
385
 
386
386
static struct token parse_id_or_value() {
387
 
        struct token t;
388
 
        int pos=0;
389
 
        int nc;
390
 
        char message[256];
391
 
        t.line=line;
392
 
        t.pos=cpos;
393
 
        nc=peekchar();
394
 
        while (nc!=EOF) {
395
 
                if (nc=='_') return parse_id(t, pos);
396
 
                if (nc=='=') return parse_id(t, pos);
397
 
                if (nc==',') return parse_value(t, pos);
398
 
                if (nc==';') return parse_value(t, pos);
399
 
                if (isspace(nc)) {
400
 
                        skipwhite();
401
 
                        nc=peekchar();
402
 
                        if (nc=='=') return parse_id(t, pos);
403
 
                        t.value[pos]='\0';
404
 
                        pos=-1;
405
 
                        return parse_value(t, pos);
406
 
                }
407
 
                if (isalnum(nc)) {
408
 
                        t.value[pos++]=nc;
409
 
                } else {
410
 
                        sprintf(message, "Unexpected character \"%c\".", nc);
411
 
                        report(message);
412
 
                        eatchar();
413
 
                        break;
414
 
                }
415
 
                t.value[pos]='\0';
416
 
                eatchar();
417
 
                nc=peekchar();
418
 
        }
419
 
        t.type=ID;
420
 
        report("Missing =");
421
 
        return t;
 
387
    struct token t;
 
388
    int pos=0;
 
389
    int nc;
 
390
    char message[256];
 
391
    t.line=line;
 
392
    t.pos=cpos;
 
393
    nc=peekchar();
 
394
    while (nc!=EOF) {
 
395
        if (nc=='_') return parse_id(t, pos);
 
396
        if (nc=='=') return parse_id(t, pos);
 
397
        if (nc==',') return parse_value(t, pos);
 
398
        if (nc==';') return parse_value(t, pos);
 
399
        if (isspace(nc)) {
 
400
            skipwhite();
 
401
            nc=peekchar();
 
402
            if (nc=='=') return parse_id(t, pos);
 
403
            t.value[pos]='\0';
 
404
            pos=-1;
 
405
            return parse_value(t, pos);
 
406
        }
 
407
        if (isalnum(nc)) {
 
408
            t.value[pos++]=nc;
 
409
        } else {
 
410
            sprintf(message, "Unexpected character \"%c\".", nc);
 
411
            report(message);
 
412
            eatchar();
 
413
            break;
 
414
        }
 
415
        t.value[pos]='\0';
 
416
        eatchar();
 
417
        nc=peekchar();
 
418
    }
 
419
    t.type=ID;
 
420
    report("Missing =");
 
421
    return t;
422
422
}
423
423
 
424
424
static struct token maptoken() {
425
 
        int skip=1;
426
 
        int nc;
427
 
        struct token t;
428
 
        char message[256];
429
 
        while (skip) {
430
 
                nc=peekchar();
431
 
                if (nc=='#') 
432
 
                        parse_comment();
433
 
                else if ((nc!='\n')&&isspace(nc)) 
434
 
                        skipwhite();
435
 
                else skip=0;
436
 
        }
437
 
        if (nc=='\n') return newline();
438
 
        if (nc==EOF) return eof();
439
 
        if (nc=='"') return parse_string();
440
 
        if (nc==',') return parse_value(t,0);
441
 
        if (nc==';') return parse_value(t,0);
442
 
        if (nc=='_') return parse_value(t,0);
443
 
        if (isdigit(nc)) return parse_value(t,0);
444
 
        if (isalnum(nc)) return parse_id_or_value();
445
 
        sprintf(message, "Unexpected character \"%c\".", nc);
446
 
        report(message);
447
 
        t.type=ERROR;
448
 
        t.line=line;
449
 
        t.pos=cpos;
450
 
        t.value[0]=nc;
451
 
        t.value[1]='\0';
452
 
        eatchar();
453
 
        return t;
 
425
    int skip=1;
 
426
    int nc;
 
427
    struct token t;
 
428
    char message[256];
 
429
    while (skip) {
 
430
        nc=peekchar();
 
431
        if (nc=='#') 
 
432
            parse_comment();
 
433
        else if ((nc!='\n')&&isspace(nc)) 
 
434
            skipwhite();
 
435
        else skip=0;
 
436
    }
 
437
    if (nc=='\n') return newline();
 
438
    if (nc==EOF) return eof();
 
439
    if (nc=='"') return parse_string();
 
440
    if (nc==',') return parse_value(t,0);
 
441
    if (nc==';') return parse_value(t,0);
 
442
    if (nc=='_') return parse_value(t,0);
 
443
    if (isdigit(nc)) return parse_value(t,0);
 
444
    if (isalnum(nc)) return parse_id_or_value();
 
445
    sprintf(message, "Unexpected character \"%c\".", nc);
 
446
    report(message);
 
447
    t.type=ERROR;
 
448
    t.line=line;
 
449
    t.pos=cpos;
 
450
    t.value[0]=nc;
 
451
    t.value[1]='\0';
 
452
    eatchar();
 
453
    return t;
454
454
}
455
455
 
456
456
struct token (*tokenizer)()=NULL;
457
457
static struct token nexttoken;
458
458
struct token peektoken() {
459
 
        if (nexttoken.type!=NONE) return nexttoken;
460
 
        nexttoken=tokenizer();
461
 
        return nexttoken;
 
459
    if (nexttoken.type!=NONE) return nexttoken;
 
460
    nexttoken=tokenizer();
 
461
    return nexttoken;
462
462
}
463
463
 
464
464
void eattoken() {
465
 
        if (nexttoken.type!=EOF) nexttoken.type=NONE;
 
465
    if (nexttoken.type!=EOF) nexttoken.type=NONE;
466
466
}
467
467
 
468
468
struct token readtoken() {
469
 
        struct token t;
470
 
        t=peektoken();
471
 
        eattoken();
472
 
        return t;
 
469
    struct token t;
 
470
    t=peektoken();
 
471
    eattoken();
 
472
    return t;
473
473
}
474
474
 
475
475
void init_tokenizer() {
476
 
        nextchar=NONE;
477
 
        nexttoken.type=NONE;
478
 
        line=1;
479
 
        cpos=1;
 
476
    nextchar=NONE;
 
477
    nexttoken.type=NONE;
 
478
    line=1;
 
479
    cpos=1;
480
480
}
481
481
 
482
482
static int known_key(char *s) {
483
 
        int i;
484
 
        i=0;
485
 
        while (known_keys[i]!=NULL) {
486
 
                if (strcmp(known_keys[i], s)==0) return 1;
487
 
                i++;
488
 
        }
489
 
        return 0;
 
483
    int i;
 
484
    i=0;
 
485
    while (known_keys[i]!=NULL) {
 
486
        if (strcmp(known_keys[i], s)==0) return 1;
 
487
        i++;
 
488
    }
 
489
    return 0;
490
490
}
491
491
 
492
492
static void parse_valuepairs() {
493
 
        struct token key;
494
 
        struct token value;
495
 
        char message[256];
496
 
        key=readtoken();
497
 
        while ((key.type!=NL)||(key.type!=EOF)) {
498
 
                if (key.type==NL) break;
499
 
                if (key.type==EOF) break;
500
 
                if (key.type==ID) {
501
 
                        if (!known_key(key.value)) {
502
 
                                sprintf(message, "Unknown key \"%s\"", key.value);
503
 
                                reportline(key.line, key.pos, message);
504
 
                        }
505
 
                        value=readtoken();
506
 
                        if ((value.type==STRING)||(value.type==VALUE)) {
507
 
                                dict=add_entry(dict, key.value, value.value);
508
 
                        } else {
509
 
                                sprintf(message, "Unexpected token \"%s\"", value.value);
510
 
                                reportline(value.line, value.pos, message);
511
 
                        }
512
 
                } else {
513
 
                        sprintf(message, "Unexpected token \"%s\"", key.value);
514
 
                        reportline(key.line, key.pos, message);
515
 
                }
516
 
                key=readtoken();
517
 
        }
 
493
    struct token key;
 
494
    struct token value;
 
495
    char message[256];
 
496
    key=readtoken();
 
497
    while ((key.type!=NL)||(key.type!=EOF)) {
 
498
        if (key.type==NL) break;
 
499
        if (key.type==EOF) break;
 
500
        if (key.type==ID) {
 
501
            if (!known_key(key.value)) {
 
502
                sprintf(message, "Unknown key \"%s\"", key.value);
 
503
                reportline(key.line, key.pos, message);
 
504
            }
 
505
            value=readtoken();
 
506
            if ((value.type==STRING)||(value.type==VALUE)) {
 
507
                dict=add_entry(dict, key.value, value.value);
 
508
            } else {
 
509
                sprintf(message, "Unexpected token \"%s\"", value.value);
 
510
                reportline(value.line, value.pos, message);
 
511
            }
 
512
        } else {
 
513
            sprintf(message, "Unexpected token \"%s\"", key.value);
 
514
            reportline(key.line, key.pos, message);
 
515
        }
 
516
        key=readtoken();
 
517
    }
518
518
}
519
519
 
520
520
static void parse_shift() {
521
 
        struct token t;
522
 
        t=readtoken();
523
 
        parse_valuepairs();
524
 
        //printf("shift ");
525
 
        //show_dictionary(dict);
526
 
        //printf("\n");
527
 
        id=lookup_dictionary(dict, "id");
528
 
        vendor=lookup_dictionary(dict, "vendor");
529
 
        product=lookup_dictionary(dict, "product");
530
 
        src=lookup_dictionary(dict, "src");
531
 
        if ((id==NULL)&&((vendor==NULL)||(product==NULL))) {
532
 
                reportline(t.line, t.pos, "Must have id, or vendor and product");
533
 
        } else {
534
 
                if (has_required(dict, "src", NULL)) {
535
 
                        map.program=PROGRAM_BUTTON_REMAP;
536
 
                        if (id!=NULL)
537
 
                                map.joystick=numeric(id);
538
 
                        else
539
 
                                map.joystick=255;
540
 
                        map.vendor=numeric(vendor);
541
 
                        map.product=numeric(product);
542
 
                        map.srcbutton=numeric(src);
543
 
                        map.type=TYPE_SHIFT;
544
 
                        map.flags=FLAG_NONE;
545
 
                        buttons[nbuttons]=map;
546
 
                        nbuttons++;
547
 
                }       
548
 
        }
549
 
        free_dictionary(dict);
550
 
        dict=NULL;
 
521
    struct token t;
 
522
    t=readtoken();
 
523
    parse_valuepairs();
 
524
    //printf("shift ");
 
525
    //show_dictionary(dict);
 
526
    //printf("\n");
 
527
    id=lookup_dictionary(dict, "id");
 
528
    vendor=lookup_dictionary(dict, "vendor");
 
529
    product=lookup_dictionary(dict, "product");
 
530
    src=lookup_dictionary(dict, "src");
 
531
    if ((id==NULL)&&((vendor==NULL)||(product==NULL))) {
 
532
        reportline(t.line, t.pos, "Must have id, or vendor and product");
 
533
    } else {
 
534
        if (has_required(dict, "src", NULL)) {
 
535
            map.program=PROGRAM_BUTTON_REMAP;
 
536
            if (id!=NULL)
 
537
                map.joystick=numeric(id);
 
538
            else
 
539
                map.joystick=255;
 
540
            map.vendor=numeric(vendor);
 
541
            map.product=numeric(product);
 
542
            map.srcbutton=numeric(src);
 
543
            map.type=TYPE_SHIFT;
 
544
            map.flags=FLAG_NONE;
 
545
            buttons[nbuttons]=map;
 
546
            nbuttons++;
 
547
        }    
 
548
    }
 
549
    free_dictionary(dict);
 
550
    dict=NULL;
551
551
}
552
552
 
553
553
static void parse_script() {
554
 
        struct token t;
555
 
        t=readtoken();
556
 
        parse_valuepairs();
557
 
        //printf("script ");
558
 
        //show_dictionary(dict);
559
 
        //printf("\n");
560
 
        id=lookup_dictionary(dict, "id");
561
 
        vendor=lookup_dictionary(dict, "vendor");
562
 
        product=lookup_dictionary(dict, "product");
563
 
        device=lookup_dictionary(dict, "device");
564
 
        if ((id==NULL)&&((vendor==NULL)||(product==NULL))) {
565
 
                reportline(t.line, t.pos, "Must have id, or vendor and product");
566
 
        } else {
567
 
                if (has_required(dict, "device", NULL)) {
568
 
                        if (id!=NULL)
569
 
                                script.id=numeric(id);
570
 
                        else
571
 
                                script.id=-1;   
572
 
                        script.vendor=numeric(vendor);
573
 
                        script.product=numeric(product);
574
 
                        script.device=numeric(device);
575
 
                        scriptassign[nscript]=script;
576
 
                        nscript++;
577
 
                }       
578
 
        }
579
 
        free_dictionary(dict);
580
 
        dict=NULL;
 
554
    struct token t;
 
555
    t=readtoken();
 
556
    parse_valuepairs();
 
557
    //printf("script ");
 
558
    //show_dictionary(dict);
 
559
    //printf("\n");
 
560
    id=lookup_dictionary(dict, "id");
 
561
    vendor=lookup_dictionary(dict, "vendor");
 
562
    product=lookup_dictionary(dict, "product");
 
563
    device=lookup_dictionary(dict, "device");
 
564
    if ((id==NULL)&&((vendor==NULL)||(product==NULL))) {
 
565
        reportline(t.line, t.pos, "Must have id, or vendor and product");
 
566
    } else {
 
567
        if (has_required(dict, "device", NULL)) {
 
568
            if (id!=NULL)
 
569
                script.id=numeric(id);
 
570
            else
 
571
                script.id=-1;    
 
572
            script.vendor=numeric(vendor);
 
573
            script.product=numeric(product);
 
574
            script.device=numeric(device);
 
575
            scriptassign[nscript]=script;
 
576
            nscript++;
 
577
        }    
 
578
    }
 
579
    free_dictionary(dict);
 
580
    dict=NULL;
581
581
}
582
582
 
583
583
static void parse_button() {
584
 
        struct token t;
585
 
        int num;
586
 
        t=readtoken();
587
 
        parse_valuepairs();
588
 
        id=lookup_dictionary(dict, "id");
589
 
        vendor=lookup_dictionary(dict, "vendor");
590
 
        product=lookup_dictionary(dict, "product");
591
 
        src=lookup_dictionary(dict, "src");
592
 
        target=lookup_dictionary(dict, "target");
593
 
        button=lookup_dictionary(dict, "button");
594
 
        axis=lookup_dictionary(dict, "axis");
595
 
        device=lookup_dictionary(dict, "device");
596
 
        flags=lookup_dictionary(dict, "flags");
597
 
        if ((id==NULL)&&((vendor==NULL)||(product==NULL))) {
598
 
                reportline(t.line, t.pos, "Must have id, or vendor and product");
599
 
        } else {
600
 
                if (has_required(dict, "src", "target", NULL)) {
601
 
                        //printf("button ");
602
 
                        //show_dictionary(dict);
603
 
                        //printf("\n");
604
 
                        map.program=PROGRAM_BUTTON_REMAP;
605
 
                        if (id!=NULL)
606
 
                                map.joystick=numeric(id);
607
 
                        else
608
 
                                map.joystick=255;
609
 
                        map.vendor=numeric(vendor);
610
 
                        map.product=numeric(product);
611
 
                        base=get_device(target);
612
 
                        map.device=base+(numeric(device)&0xF);
613
 
                        map.type=get_type(target,dict);
614
 
                        if  (base==DEVICE_JOYSTICK) {
615
 
                                num=numeric(device);
616
 
                                if (num>8) {
617
 
                                        report("Maximum of 8 joysticks allowed");
618
 
                                } else {
619
 
                                        if (num>=njoysticks) {
620
 
                                                njoysticks=num+1;
621
 
                                        }
622
 
                                        if (map.type==TYPE_AXIS) {
623
 
                                                if (joysticks[num].axes<=numeric(axis))
624
 
                                                        joysticks[num].axes=numeric(axis)+1;
625
 
                                        }
626
 
                                        if (map.type==TYPE_BUTTON) {
627
 
                                                if (joysticks[num].buttons<=numeric(button))
628
 
                                                        joysticks[num].buttons=numeric(button)+1;
629
 
                                        }
630
 
                                }
631
 
                        }
632
 
                        map.srcbutton=numeric(src)+BTN_JOYSTICK;
633
 
                        map.flags=parse_flags(flags);
634
 
                        if (button!=NULL)
635
 
                                parse_sequence(map.sequence, button, base, map.type);
636
 
                        else if (axis!=NULL)
637
 
                                parse_sequence(map.sequence, axis, base, map.type);
638
 
                        buttons[nbuttons]=map;
639
 
                        nbuttons++;
640
 
                        if (!((map.flags&FLAG_PRESS)||(map.flags&FLAG_RELEASE))&&
641
 
                                (map.sequence[1]==SEQUENCE_DONE)) {
642
 
                                if (map.sequence[0]&RELEASEMASK) {
643
 
                                        map.sequence[0]&=~RELEASEMASK;
644
 
                                } else {
645
 
                                        map.sequence[0]|=RELEASEMASK;
646
 
                                }
647
 
                                map.flags|=FLAG_RELEASE;
648
 
                                buttons[nbuttons]=map;
649
 
                                nbuttons++;
650
 
                        }
651
 
                }
652
 
        }
653
 
        free_dictionary(dict);
654
 
        dict=NULL;
 
584
    struct token t;
 
585
    int num;
 
586
    t=readtoken();
 
587
    parse_valuepairs();
 
588
    id=lookup_dictionary(dict, "id");
 
589
    vendor=lookup_dictionary(dict, "vendor");
 
590
    product=lookup_dictionary(dict, "product");
 
591
    src=lookup_dictionary(dict, "src");
 
592
    target=lookup_dictionary(dict, "target");
 
593
    button=lookup_dictionary(dict, "button");
 
594
    axis=lookup_dictionary(dict, "axis");
 
595
    device=lookup_dictionary(dict, "device");
 
596
    flags=lookup_dictionary(dict, "flags");
 
597
    if ((id==NULL)&&((vendor==NULL)||(product==NULL))) {
 
598
        reportline(t.line, t.pos, "Must have id, or vendor and product");
 
599
    } else {
 
600
        if (has_required(dict, "src", "target", NULL)) {
 
601
            //printf("button ");
 
602
            //show_dictionary(dict);
 
603
            //printf("\n");
 
604
            map.program=PROGRAM_BUTTON_REMAP;
 
605
            if (id!=NULL)
 
606
                map.joystick=numeric(id);
 
607
            else
 
608
                map.joystick=255;
 
609
            map.vendor=numeric(vendor);
 
610
            map.product=numeric(product);
 
611
            base=get_device(target);
 
612
            map.device=base+(numeric(device)&0xF);
 
613
            map.type=get_type(target,dict);
 
614
            if  (base==DEVICE_JOYSTICK) {
 
615
                num=numeric(device);
 
616
                if (num>8) {
 
617
                    report("Maximum of 8 joysticks allowed");
 
618
                } else {
 
619
                    if (num>=njoysticks) {
 
620
                        njoysticks=num+1;
 
621
                    }
 
622
                    if (map.type==TYPE_AXIS) {
 
623
                        if (joysticks[num].axes<=numeric(axis))
 
624
                            joysticks[num].axes=numeric(axis)+1;
 
625
                    }
 
626
                    if (map.type==TYPE_BUTTON) {
 
627
                        if (joysticks[num].buttons<=numeric(button))
 
628
                            joysticks[num].buttons=numeric(button)+1;
 
629
                    }
 
630
                }
 
631
            }
 
632
            map.srcbutton=numeric(src)+BTN_JOYSTICK;
 
633
            map.flags=parse_flags(flags);
 
634
            if (button!=NULL)
 
635
                parse_sequence(map.sequence, button, base, map.type);
 
636
            else if (axis!=NULL)
 
637
                parse_sequence(map.sequence, axis, base, map.type);
 
638
            buttons[nbuttons]=map;
 
639
            nbuttons++;
 
640
            if (!((map.flags&FLAG_PRESS)||(map.flags&FLAG_RELEASE))&&
 
641
                (map.sequence[1]==SEQUENCE_DONE)) {
 
642
                if (map.sequence[0]&RELEASEMASK) {
 
643
                    map.sequence[0]&=~RELEASEMASK;
 
644
                } else {
 
645
                    map.sequence[0]|=RELEASEMASK;
 
646
                }
 
647
                map.flags|=FLAG_RELEASE;
 
648
                buttons[nbuttons]=map;
 
649
                nbuttons++;
 
650
            }
 
651
        }
 
652
    }
 
653
    free_dictionary(dict);
 
654
    dict=NULL;
655
655
}
656
656
 
657
657
static void parse_axis() {
658
 
        struct token t;
659
 
        int num;
660
 
        t=readtoken();
661
 
        parse_valuepairs();
662
 
        //printf("axis ");
663
 
        //show_dictionary(dict);
664
 
        //printf("\n");
665
 
        id=lookup_dictionary(dict, "id");
666
 
        vendor=lookup_dictionary(dict, "vendor");
667
 
        product=lookup_dictionary(dict, "product");
668
 
        src=lookup_dictionary(dict, "src");
669
 
        target=lookup_dictionary(dict, "target");
670
 
        axis=lookup_dictionary(dict, "axis");
671
 
        plus=lookup_dictionary(dict, "plus");
672
 
        minus=lookup_dictionary(dict, "minus");
673
 
        device=lookup_dictionary(dict, "device");
674
 
        flags=lookup_dictionary(dict, "flags");
675
 
        if ((id==NULL)&&((vendor==NULL)||(product==NULL))) {
676
 
                reportline(t.line, t.pos, "Must have id, or vendor and product");
677
 
        } else {
678
 
                if (has_required(dict, "src", "target", NULL)) {
679
 
                        amap.program=PROGRAM_AXIS_REMAP;
680
 
                        if (id!=NULL)
681
 
                                amap.joystick=numeric(id);
682
 
                        else
683
 
                                amap.joystick=255;
684
 
                        amap.vendor=numeric(vendor);
685
 
                        amap.product=numeric(product);
686
 
                        amap.srcaxis=numeric(src);
687
 
                        base=get_device(target);
688
 
                        amap.device=base+(numeric(device)&0xF);
689
 
                        amap.type=get_type(target,dict);
690
 
                        if  (base==DEVICE_JOYSTICK) {
691
 
                                num=numeric(device);
692
 
                                if (num>8) {
693
 
                                        report("Maximum of 8 joysticks allowed");
694
 
                                } else {
695
 
                                        if (num>=njoysticks) {
696
 
                                                njoysticks=num+1;
697
 
                                        }
698
 
                                        if (amap.type==TYPE_AXIS) {
699
 
                                                if (joysticks[num].axes<=numeric(axis))
700
 
                                                        joysticks[num].axes=numeric(axis)+1;
701
 
                                        }
702
 
                                        if (amap.type==TYPE_BUTTON) {
703
 
                                                if (joysticks[num].buttons<=numeric(plus))
704
 
                                                        joysticks[num].buttons=numeric(plus)+1;
705
 
                                                if (joysticks[num].buttons<=numeric(minus))
706
 
                                                        joysticks[num].buttons=numeric(minus)+1;
707
 
                                        }
708
 
                                }
709
 
                        }
710
 
                        if ((base==DEVICE_JOYSTICK)&&(amap.type==TYPE_BUTTON)) {
711
 
                                base=BTN_JOYSTICK;
712
 
                        } else if ((base==DEVICE_MOUSE)&&(amap.type==TYPE_BUTTON)) {
713
 
                                base=BTN_MOUSE;
714
 
                        } else base=0;
715
 
                        amap.plus=numeric(plus)+base;
716
 
                        amap.minus=numeric(minus)+base;
717
 
                        amap.axis=numeric(axis);
718
 
                        amap.flags=parse_flags(flags);
719
 
                        axes[naxes]=amap;
720
 
                        naxes++;
721
 
                }
722
 
        }
723
 
        free_dictionary(dict);
724
 
        dict=NULL;
 
658
    struct token t;
 
659
    int num;
 
660
    t=readtoken();
 
661
    parse_valuepairs();
 
662
    //printf("axis ");
 
663
    //show_dictionary(dict);
 
664
    //printf("\n");
 
665
    id=lookup_dictionary(dict, "id");
 
666
    vendor=lookup_dictionary(dict, "vendor");
 
667
    product=lookup_dictionary(dict, "product");
 
668
    src=lookup_dictionary(dict, "src");
 
669
    target=lookup_dictionary(dict, "target");
 
670
    axis=lookup_dictionary(dict, "axis");
 
671
    plus=lookup_dictionary(dict, "plus");
 
672
    minus=lookup_dictionary(dict, "minus");
 
673
    device=lookup_dictionary(dict, "device");
 
674
    flags=lookup_dictionary(dict, "flags");
 
675
    if ((id==NULL)&&((vendor==NULL)||(product==NULL))) {
 
676
        reportline(t.line, t.pos, "Must have id, or vendor and product");
 
677
    } else {
 
678
        if (has_required(dict, "src", "target", NULL)) {
 
679
            amap.program=PROGRAM_AXIS_REMAP;
 
680
            if (id!=NULL)
 
681
                amap.joystick=numeric(id);
 
682
            else
 
683
                amap.joystick=255;
 
684
            amap.vendor=numeric(vendor);
 
685
            amap.product=numeric(product);
 
686
            amap.srcaxis=numeric(src);
 
687
            base=get_device(target);
 
688
            amap.device=base+(numeric(device)&0xF);
 
689
            amap.type=get_type(target,dict);
 
690
            if  (base==DEVICE_JOYSTICK) {
 
691
                num=numeric(device);
 
692
                if (num>8) {
 
693
                    report("Maximum of 8 joysticks allowed");
 
694
                } else {
 
695
                    if (num>=njoysticks) {
 
696
                        njoysticks=num+1;
 
697
                    }
 
698
                    if (amap.type==TYPE_AXIS) {
 
699
                        if (joysticks[num].axes<=numeric(axis))
 
700
                            joysticks[num].axes=numeric(axis)+1;
 
701
                    }
 
702
                    if (amap.type==TYPE_BUTTON) {
 
703
                        if (joysticks[num].buttons<=numeric(plus))
 
704
                            joysticks[num].buttons=numeric(plus)+1;
 
705
                        if (joysticks[num].buttons<=numeric(minus))
 
706
                            joysticks[num].buttons=numeric(minus)+1;
 
707
                    }
 
708
                }
 
709
            }
 
710
            if ((base==DEVICE_JOYSTICK)&&(amap.type==TYPE_BUTTON)) {
 
711
                base=BTN_JOYSTICK;
 
712
            } else if ((base==DEVICE_MOUSE)&&(amap.type==TYPE_BUTTON)) {
 
713
                base=BTN_MOUSE;
 
714
            } else base=0;
 
715
            amap.plus=numeric(plus)+base;
 
716
            amap.minus=numeric(minus)+base;
 
717
            amap.axis=numeric(axis);
 
718
            amap.flags=parse_flags(flags);
 
719
            axes[naxes]=amap;
 
720
            naxes++;
 
721
        }
 
722
    }
 
723
    free_dictionary(dict);
 
724
    dict=NULL;
725
725
}
726
726
 
727
727
static void parse_joystick() {
728
 
        struct token t;
729
 
        char *axes; char *buttons;
730
 
        int num;
731
 
        t=readtoken();
732
 
        parse_valuepairs();
733
 
        axes=lookup_dictionary(dict, "axes");
734
 
        buttons=lookup_dictionary(dict, "buttons");
735
 
        device=lookup_dictionary(dict, "device");
736
 
        if (device==NULL) {
737
 
                reportline(t.line, t.pos, "Must have device");
738
 
        } else {
739
 
                num=numeric(device);
740
 
                if ((num<0)||(num>7)) reportline(t.line, t.pos, "Joystick must be 0-7");
741
 
                //printf("joystick ");
742
 
                //show_dictionary(dict);
743
 
                //printf("\n");
744
 
                if (num>=njoysticks) njoysticks=num+1;
745
 
                if (axes!=NULL)
746
 
                        joysticks[num].axes=numeric(axes);
747
 
                else
748
 
                        joysticks[num].axes=0;
749
 
                if (buttons!=NULL)
750
 
                        joysticks[num].buttons=numeric(buttons);
751
 
                else
752
 
                        joysticks[num].buttons=0;
753
 
        }
754
 
        free_dictionary(dict);
755
 
        dict=NULL;
 
728
    struct token t;
 
729
    char *axes; char *buttons;
 
730
    int num;
 
731
    t=readtoken();
 
732
    parse_valuepairs();
 
733
    axes=lookup_dictionary(dict, "axes");
 
734
    buttons=lookup_dictionary(dict, "buttons");
 
735
    device=lookup_dictionary(dict, "device");
 
736
    if (device==NULL) {
 
737
        reportline(t.line, t.pos, "Must have device");
 
738
    } else {
 
739
        num=numeric(device);
 
740
        if ((num<0)||(num>7)) reportline(t.line, t.pos, "Joystick must be 0-7");
 
741
        //printf("joystick ");
 
742
        //show_dictionary(dict);
 
743
        //printf("\n");
 
744
        if (num>=njoysticks) njoysticks=num+1;
 
745
        if (axes!=NULL)
 
746
            joysticks[num].axes=numeric(axes);
 
747
        else
 
748
            joysticks[num].axes=0;
 
749
        if (buttons!=NULL)
 
750
            joysticks[num].buttons=numeric(buttons);
 
751
        else
 
752
            joysticks[num].buttons=0;
 
753
    }
 
754
    free_dictionary(dict);
 
755
    dict=NULL;
756
756
}
757
757
 
758
758
static void parse_code() {
759
 
        struct token t;
760
 
        t=readtoken();
761
 
        t=readtoken();
762
 
        //printf("code ");
763
 
        if (t.type!=STRING) {
764
 
                reportline(t.line, t.pos, "String expected");
765
 
        } else strcpy(compile, t.value);
766
 
        t=readtoken();
767
 
        while ((t.type!=NL)&&(t.type!=EOF)) {
768
 
                reportline(t.line, t.pos, "No further token expected on this line");
769
 
        }
770
 
        //printf("\"%s\"\n", compile);
 
759
    struct token t;
 
760
    t=readtoken();
 
761
    t=readtoken();
 
762
    //printf("code ");
 
763
    if (t.type!=STRING) {
 
764
        reportline(t.line, t.pos, "String expected");
 
765
    } else strcpy(compile, t.value);
 
766
    t=readtoken();
 
767
    while ((t.type!=NL)&&(t.type!=EOF)) {
 
768
        reportline(t.line, t.pos, "No further token expected on this line");
 
769
    }
 
770
    //printf("\"%s\"\n", compile);
771
771
}
772
772
 
773
773
static void parse_joysticks() {
774
 
        struct token t;
775
 
        int num;
776
 
        t=readtoken();
777
 
        t=readtoken();
778
 
        printf("joysticks ");
779
 
        if (t.type!=VALUE) {
780
 
                reportline(t.line, t.pos, "Value expected");
781
 
        } else num=numeric(t.value);
782
 
        t=readtoken();
783
 
        while ((t.type!=NL)&&(t.type!=EOF)) {
784
 
                reportline(t.line, t.pos, "No further token expected on this line");
785
 
        }
786
 
        if (num<0) reportline(t.line, t.pos, "Only positive numbers allowed");
787
 
        if (num>8) reportline(t.line, t.pos, "Maximum 8 joysticks allowed");
788
 
        njoysticks=num;
789
 
        printf("\"%d\"\n", num);
 
774
    struct token t;
 
775
    int num;
 
776
    t=readtoken();
 
777
    t=readtoken();
 
778
    printf("joysticks ");
 
779
    if (t.type!=VALUE) {
 
780
        reportline(t.line, t.pos, "Value expected");
 
781
    } else num=numeric(t.value);
 
782
    t=readtoken();
 
783
    while ((t.type!=NL)&&(t.type!=EOF)) {
 
784
        reportline(t.line, t.pos, "No further token expected on this line");
 
785
    }
 
786
    if (num<0) reportline(t.line, t.pos, "Only positive numbers allowed");
 
787
    if (num>8) reportline(t.line, t.pos, "Maximum 8 joysticks allowed");
 
788
    njoysticks=num;
 
789
    printf("\"%d\"\n", num);
790
790
}
791
791
 
792
792
static void parse_lines();
793
793
static void parse_include() {
794
 
        struct token t;
795
 
        char include[256]="";
796
 
        FILE *backup;
797
 
        t=readtoken();
798
 
        t=readtoken();
799
 
        //printf("include ");
800
 
        if (t.type!=STRING) {
801
 
                reportline(t.line, t.pos, "String expected");
802
 
        } else strcpy(include, t.value);
803
 
        t=readtoken();
804
 
        while ((t.type!=NL)&&(t.type!=EOF)) {
805
 
                reportline(t.line, t.pos, "No further token expected on this line");
806
 
        }
807
 
        //printf("\"%s\"\n", include);
808
 
        backup=pfile;
809
 
        pfile=fopen(include, "r");
810
 
        if (pfile==NULL) reportline(t.line, t.pos, "Could not find specified file");
811
 
        else parse_lines();
812
 
        pfile=backup;
 
794
    struct token t;
 
795
    char include[256]="";
 
796
    FILE *backup;
 
797
    t=readtoken();
 
798
    t=readtoken();
 
799
    //printf("include ");
 
800
    if (t.type!=STRING) {
 
801
        reportline(t.line, t.pos, "String expected");
 
802
    } else strcpy(include, t.value);
 
803
    t=readtoken();
 
804
    while ((t.type!=NL)&&(t.type!=EOF)) {
 
805
        reportline(t.line, t.pos, "No further token expected on this line");
 
806
    }
 
807
    //printf("\"%s\"\n", include);
 
808
    backup=pfile;
 
809
    pfile=fopen(include, "r");
 
810
    if (pfile==NULL) reportline(t.line, t.pos, "Could not find specified file");
 
811
    else parse_lines();
 
812
    pfile=backup;
813
813
}
814
814
 
815
815
static void parse_lines() {
816
 
        struct token t;
817
 
        char message[256];
818
 
        t=peektoken();
819
 
        while (t.type!=EOF) {
820
 
                if (t.type==NL) {
821
 
                        t=readtoken();
822
 
                        //do nothing
823
 
                } else if (t.type==EOF) {
824
 
                        t=readtoken();
825
 
                        //do nothing
826
 
                } else if (t.type==CODE) {
827
 
                        parse_code();
828
 
                } else if (t.type==BUTTON) {
829
 
                        parse_button();
830
 
                } else if (t.type==AXIS) {
831
 
                        parse_axis();
832
 
                } else if (t.type==SHIFT) {
833
 
                        parse_shift();
834
 
                } else if (t.type==SCRIPT) {
835
 
                        parse_script();
836
 
                } else if (t.type==JOYSTICK) {
837
 
                        parse_joystick();
838
 
                } else if (t.type==JOYSTICKS) {
839
 
                        parse_joysticks();
840
 
                } else if (t.type==INCLUDE) {
841
 
                        parse_include();
842
 
                } else {
843
 
                        t=readtoken();
844
 
                        error=1;
845
 
                        if (t.type!=ERROR) {
846
 
                                sprintf(message, "Unexpected token \"%s\"", t.value);
847
 
                                reportline(t.line, t.pos, message);
848
 
                                while ((t.type!=EOF)&&(t.type!=NL)) {
849
 
                                        t=readtoken();
850
 
                                }
851
 
                        }
852
 
                }
853
 
                t=peektoken();
854
 
        }
 
816
    struct token t;
 
817
    char message[256];
 
818
    t=peektoken();
 
819
    while (t.type!=EOF) {
 
820
        if (t.type==NL) {
 
821
            t=readtoken();
 
822
            //do nothing
 
823
        } else if (t.type==EOF) {
 
824
            t=readtoken();
 
825
            //do nothing
 
826
        } else if (t.type==CODE) {
 
827
            parse_code();
 
828
        } else if (t.type==BUTTON) {
 
829
            parse_button();
 
830
        } else if (t.type==AXIS) {
 
831
            parse_axis();
 
832
        } else if (t.type==SHIFT) {
 
833
            parse_shift();
 
834
        } else if (t.type==SCRIPT) {
 
835
            parse_script();
 
836
        } else if (t.type==JOYSTICK) {
 
837
            parse_joystick();
 
838
        } else if (t.type==JOYSTICKS) {
 
839
            parse_joysticks();
 
840
        } else if (t.type==INCLUDE) {
 
841
            parse_include();
 
842
        } else {
 
843
            t=readtoken();
 
844
            error=1;
 
845
            if (t.type!=ERROR) {
 
846
                sprintf(message, "Unexpected token \"%s\"", t.value);
 
847
                reportline(t.line, t.pos, message);
 
848
                while ((t.type!=EOF)&&(t.type!=NL)) {
 
849
                    t=readtoken();
 
850
                }
 
851
            }
 
852
        }
 
853
        t=peektoken();
 
854
    }
855
855
}
856
856
 
857
857
int parse_map(void) {
858
 
        pfile=fmap;
859
 
        tokenizer=maptoken;
860
 
        init_tokenizer();
861
 
        parse_lines();
862
 
        free_dictionary(dict);
863
 
        dict=NULL;
864
 
        if (fmap!=stdin) fclose(fmap);
865
 
        if (strlen(compile)>0) {
866
 
                fprintf(stderr, "parsing program %s\n", compile);
867
 
                if (parse_program(compile, &program)!=0) error=1;
868
 
        }
869
 
        return error;
 
858
    pfile=fmap;
 
859
    tokenizer=maptoken;
 
860
    init_tokenizer();
 
861
    parse_lines();
 
862
    free_dictionary(dict);
 
863
    dict=NULL;
 
864
    if (fmap!=stdin) fclose(fmap);
 
865
    if (strlen(compile)>0) {
 
866
        fprintf(stderr, "parsing program %s\n", compile);
 
867
        if (parse_program(compile, &program)!=0) error=1;
 
868
    }
 
869
    return error;
870
870
}
871
871