9
#include "dictionary.h"
10
#include "validkeys.h"
14
static struct reserved reserved[]={
21
{"joysticks", JOYSTICKS},
22
{"joystick", JOYSTICK},
26
static char *known_keys[]={
47
static int nextchar=NONE;
49
static dictionary dict=NULL;
50
static struct program_button_remap map;
51
static struct program_axis_remap amap;
52
static struct scriptmap script;
53
struct program_code program;
54
struct program_button_remap buttons[MAX_ASSIGN];
55
struct program_axis_remap axes[MAX_ASSIGN];
56
struct scriptmap scriptassign[MAX_ASSIGN];
57
static int parse_err=0;
62
struct joystick joysticks[8];
66
static char *id, *vendor, *product, *src, *target, *button, *device, *flags, *axis, *plus, *minus;
67
static char compile[256]="";
69
static int ishex(char *s) {
71
if (*s!='0') return 0;
73
if (*s!='x') return 0;
77
if ((('A'<=c)&&(c<='F'))||
78
(('a'<=c)&&(c<='f'))||
79
(('0'<=c)&&(c<='9'))) s++;
85
static int isnum(char *s) {
89
if (('0'<=c)&&(c<='9')) s++;
95
int numeric(char *s) {
98
if (s==NULL) return 0;
100
r=strtol(s, NULL, 16);
101
} else if (isnum(s)) {
102
r=strtol(s, NULL, 10);
104
sprintf(msg, "Expected a number, got %s instead", s);
111
static int get_device(char *s) {
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);
124
static int get_type(char *s, dictionary d) {
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");
135
if (button!=NULL) return TYPE_BUTTON;
136
if (axis!=NULL) return TYPE_AXIS;
140
static int parse_flags(char *s) {
145
if (s==NULL) return flags;
147
while ((*p!='\0')&&(*p!=',')&&(*p!=';')) p++;
148
if (*p=='\0') more=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;
156
sprintf(msg, "Unknown flag %s", s);
164
static void parse_sequence(__u16 *sequence, char *s, int base, int type) {
173
if ((base==DEVICE_JOYSTICK)&&(type==TYPE_BUTTON)) {
175
} else if ((base==DEVICE_MOUSE)&&(type==TYPE_BUTTON)) {
178
sequence[0]=numeric(s)+base;
179
sequence[1]=SEQUENCE_DONE;
184
while ((*p!='\0')&&(isspace(*p))) p++;
186
while ((*p!='\0')&&(!(isspace(*p)))) p++;
192
if (strcmp(s, "REL")==0) releaseflag=RELEASEMASK;
195
while (keymap[i].value!=-1) {
196
if (strcmp(keymap[i].key, s)==0)
197
value=keymap[i].value;
202
sprintf(msg, "Unknown key %s", s);
205
sequence[n]=value|releaseflag;
212
sequence[n]=SEQUENCE_DONE;
216
static void show_dictionary(dictionary dict) {
219
entry=get_current(d);
220
while (entry!=NULL) {
221
printf("%s ", entry);
223
entry=get_current(d);
227
static int has_required(dictionary dict, ...) {
234
s=va_arg(ap, char *);
236
entry=lookup_dictionary(dict, s);
238
sprintf(msg, "Missing key:%s", s);
243
s=va_arg(ap, char *);
249
void report(char *message) {
251
fprintf(stderr, "%d:%d %s.\n", line, cpos, message);
254
void reportline(int line, int cpos, char *message) {
256
fprintf(stderr, "%d:%d %s.\n", line, cpos, message);
260
if (nextchar!=NONE) return nextchar;
261
nextchar=fgetc(pfile);
266
if (nextchar=='\n') {
280
static struct token newline() {
285
strcpy(t.value, "\n");
290
static struct token eof() {
295
strcpy(t.value, "end of file");
299
static void parse_comment() {
300
//first character was #
304
while ((nc!='\n')&&(nc!=EOF)) {
310
static void skipwhite() {
312
while (isspace(nc)&&(nc!='\n')) {
318
static struct token parse_string() {
319
//opening quote has been read
320
//read until closing quote
332
report("Unexpected end of file while parsing a string literal");
342
static struct token parse_value(struct token t, int pos) {
347
while (isalnum(nc)||(nc==',')||(nc==';')) {
355
while (reserved[nc].token!=NULL) {
356
if (strcmp(reserved[nc].token, t.value)==0) {
357
t.type=reserved[nc].value;
365
static struct token parse_id(struct token t, int pos) {
369
while (isalnum(nc)||(nc=='_')) {
377
report("Expected an \"=\"");
383
static struct token parse_id_or_value() {
392
if (nc=='_') return parse_id(t, pos);
393
if (nc=='=') return parse_id(t, pos);
394
if (nc==',') return parse_value(t, pos);
395
if (nc==';') return parse_value(t, pos);
399
if (nc=='=') return parse_id(t, pos);
402
return parse_value(t, pos);
407
sprintf(message, "Unexpected character \"%c\".", nc);
421
static struct token maptoken() {
430
else if ((nc!='\n')&&isspace(nc))
434
if (nc=='\n') return newline();
435
if (nc==EOF) return eof();
436
if (nc=='"') return parse_string();
437
if (nc==',') return parse_value(t,0);
438
if (nc==';') return parse_value(t,0);
439
if (nc=='_') return parse_value(t,0);
440
if (isdigit(nc)) return parse_value(t,0);
441
if (isalnum(nc)) return parse_id_or_value();
442
sprintf(message, "Unexpected character \"%c\".", nc);
453
struct token (*tokenizer)()=NULL;
454
static struct token nexttoken;
455
struct token peektoken() {
456
if (nexttoken.type!=NONE) return nexttoken;
457
nexttoken=tokenizer();
462
if (nexttoken.type!=EOF) nexttoken.type=NONE;
465
struct token readtoken() {
472
void init_tokenizer() {
479
static int known_key(char *s) {
482
while (known_keys[i]!=NULL) {
483
if (strcmp(known_keys[i], s)==0) return 1;
489
static void parse_valuepairs() {
494
while ((key.type!=NL)||(key.type!=EOF)) {
495
if (key.type==NL) break;
496
if (key.type==EOF) break;
498
if (!known_key(key.value)) {
499
sprintf(message, "Unknown key \"%s\"", key.value);
500
reportline(key.line, key.pos, message);
503
if ((value.type==STRING)||(value.type==VALUE)) {
504
dict=add_entry(dict, key.value, value.value);
506
sprintf(message, "Unexpected token \"%s\"", value.value);
507
reportline(value.line, value.pos, message);
510
sprintf(message, "Unexpected token \"%s\"", key.value);
511
reportline(key.line, key.pos, message);
517
static void parse_shift() {
522
show_dictionary(dict);
524
id=lookup_dictionary(dict, "id");
525
vendor=lookup_dictionary(dict, "vendor");
526
product=lookup_dictionary(dict, "product");
527
src=lookup_dictionary(dict, "src");
528
if ((id==NULL)&&((vendor==NULL)||(product==NULL))) {
529
reportline(t.line, t.pos, "Must have id, or vendor and product");
531
if (has_required(dict, "src", NULL)) {
532
map.program=PROGRAM_BUTTON_REMAP;
534
map.joystick=numeric(id);
537
map.vendor=numeric(vendor);
538
map.product=numeric(product);
539
map.srcbutton=numeric(src);
542
buttons[nbuttons]=map;
546
free_dictionary(dict);
550
static void parse_script() {
555
show_dictionary(dict);
557
id=lookup_dictionary(dict, "id");
558
vendor=lookup_dictionary(dict, "vendor");
559
product=lookup_dictionary(dict, "product");
560
device=lookup_dictionary(dict, "device");
561
if ((id==NULL)&&((vendor==NULL)||(product==NULL))) {
562
reportline(t.line, t.pos, "Must have id, or vendor and product");
564
if (has_required(dict, "device", NULL)) {
566
script.id=numeric(id);
569
script.vendor=numeric(vendor);
570
script.product=numeric(product);
571
script.device=numeric(device);
572
scriptassign[nscript]=script;
576
free_dictionary(dict);
580
static void parse_button() {
585
id=lookup_dictionary(dict, "id");
586
vendor=lookup_dictionary(dict, "vendor");
587
product=lookup_dictionary(dict, "product");
588
src=lookup_dictionary(dict, "src");
589
target=lookup_dictionary(dict, "target");
590
button=lookup_dictionary(dict, "button");
591
axis=lookup_dictionary(dict, "axis");
592
device=lookup_dictionary(dict, "device");
593
flags=lookup_dictionary(dict, "flags");
594
if ((id==NULL)&&((vendor==NULL)||(product==NULL))) {
595
reportline(t.line, t.pos, "Must have id, or vendor and product");
597
if (has_required(dict, "src", "target", NULL)) {
599
show_dictionary(dict);
601
map.program=PROGRAM_BUTTON_REMAP;
603
map.joystick=numeric(id);
606
map.vendor=numeric(vendor);
607
map.product=numeric(product);
608
base=get_device(target);
609
map.device=base+(numeric(device)&0xF);
610
map.type=get_type(target,dict);
611
if (base==DEVICE_JOYSTICK) {
614
report("Maximum of 8 joysticks allowed");
616
if (num>=njoysticks) {
619
if (map.type==TYPE_AXIS) {
620
if (joysticks[num].axes<=numeric(axis))
621
joysticks[num].axes=numeric(axis)+1;
623
if (map.type==TYPE_BUTTON) {
624
if (joysticks[num].buttons<=numeric(button))
625
joysticks[num].buttons=numeric(button)+1;
629
map.srcbutton=numeric(src)+BTN_JOYSTICK;
630
map.flags=parse_flags(flags);
632
parse_sequence(map.sequence, button, base, map.type);
634
parse_sequence(map.sequence, axis, base, map.type);
635
buttons[nbuttons]=map;
637
if (!((map.flags&FLAG_PRESS)||(map.flags&FLAG_RELEASE))&&
638
(map.sequence[1]==SEQUENCE_DONE)) {
639
if (map.sequence[0]&RELEASEMASK) {
640
map.sequence[0]&=~RELEASEMASK;
642
map.sequence[0]|=RELEASEMASK;
644
map.flags|=FLAG_RELEASE;
645
buttons[nbuttons]=map;
650
free_dictionary(dict);
654
static void parse_axis() {
660
show_dictionary(dict);
662
id=lookup_dictionary(dict, "id");
663
vendor=lookup_dictionary(dict, "vendor");
664
product=lookup_dictionary(dict, "product");
665
src=lookup_dictionary(dict, "src");
666
target=lookup_dictionary(dict, "target");
667
axis=lookup_dictionary(dict, "axis");
668
plus=lookup_dictionary(dict, "plus");
669
minus=lookup_dictionary(dict, "minus");
670
device=lookup_dictionary(dict, "device");
671
flags=lookup_dictionary(dict, "flags");
672
if ((id==NULL)&&((vendor==NULL)||(product==NULL))) {
673
reportline(t.line, t.pos, "Must have id, or vendor and product");
675
if (has_required(dict, "src", "target", NULL)) {
676
amap.program=PROGRAM_AXIS_REMAP;
678
amap.joystick=numeric(id);
681
amap.vendor=numeric(vendor);
682
amap.product=numeric(product);
683
amap.srcaxis=numeric(src);
684
base=get_device(target);
685
amap.device=base+(numeric(device)&0xF);
686
amap.type=get_type(target,dict);
687
if (base==DEVICE_JOYSTICK) {
690
report("Maximum of 8 joysticks allowed");
692
if (num>=njoysticks) {
695
if (amap.type==TYPE_AXIS) {
696
if (joysticks[num].axes<=numeric(axis))
697
joysticks[num].axes=numeric(axis)+1;
699
if (amap.type==TYPE_BUTTON) {
700
if (joysticks[num].buttons<=numeric(plus))
701
joysticks[num].buttons=numeric(plus)+1;
702
if (joysticks[num].buttons<=numeric(minus))
703
joysticks[num].buttons=numeric(minus)+1;
707
if ((base==DEVICE_JOYSTICK)&&(amap.type==TYPE_BUTTON)) {
709
} else if ((base==DEVICE_MOUSE)&&(amap.type==TYPE_BUTTON)) {
712
amap.plus=numeric(plus)+base;
713
amap.minus=numeric(minus)+base;
714
amap.axis=numeric(axis);
715
amap.flags=parse_flags(flags);
720
free_dictionary(dict);
724
static void parse_joystick() {
726
char *axes; char *buttons;
730
axes=lookup_dictionary(dict, "axes");
731
buttons=lookup_dictionary(dict, "buttons");
732
device=lookup_dictionary(dict, "device");
734
reportline(t.line, t.pos, "Must have device");
737
if ((num<0)||(num>7)) reportline(t.line, t.pos, "Joystick must be 0-7");
739
show_dictionary(dict);
740
if (num>=njoysticks) njoysticks=num+1;
743
joysticks[num].axes=numeric(axes);
745
joysticks[num].axes=0;
747
joysticks[num].buttons=numeric(buttons);
749
joysticks[num].buttons=0;
751
free_dictionary(dict);
755
static void parse_code() {
760
if (t.type!=STRING) {
761
reportline(t.line, t.pos, "String expected");
762
} else strcpy(compile, t.value);
764
while ((t.type!=NL)&&(t.type!=EOF)) {
765
reportline(t.line, t.pos, "No further token expected on this line");
767
printf("\"%s\"\n", compile);
770
static void parse_joysticks() {
775
printf("joysticks ");
777
reportline(t.line, t.pos, "Value expected");
778
} else num=numeric(t.value);
780
while ((t.type!=NL)&&(t.type!=EOF)) {
781
reportline(t.line, t.pos, "No further token expected on this line");
783
if (num<0) reportline(t.line, t.pos, "Only positive numbers allowed");
784
if (num>8) reportline(t.line, t.pos, "Maximum 8 joysticks allowed");
786
printf("\"%d\"\n", num);
789
static void parse_lines();
790
static void parse_include() {
792
char include[256]="";
797
if (t.type!=STRING) {
798
reportline(t.line, t.pos, "String expected");
799
} else strcpy(include, t.value);
801
while ((t.type!=NL)&&(t.type!=EOF)) {
802
reportline(t.line, t.pos, "No further token expected on this line");
804
printf("\"%s\"\n", include);
806
pfile=fopen(include, "r");
807
if (pfile==NULL) reportline(t.line, t.pos, "Could not find specified file");
812
static void parse_lines() {
816
while (t.type!=EOF) {
820
} else if (t.type==EOF) {
823
} else if (t.type==CODE) {
825
} else if (t.type==BUTTON) {
827
} else if (t.type==AXIS) {
829
} else if (t.type==SHIFT) {
831
} else if (t.type==SCRIPT) {
833
} else if (t.type==JOYSTICK) {
835
} else if (t.type==JOYSTICKS) {
837
} else if (t.type==INCLUDE) {
843
sprintf(message, "Unexpected token \"%s\"", t.value);
844
reportline(t.line, t.pos, message);
845
while ((t.type!=EOF)&&(t.type!=NL)) {
854
int parse_map(void) {
859
free_dictionary(dict);
861
if (fmap!=stdin) fclose(fmap);
862
if (strlen(compile)>0) {
863
fprintf(stderr, "parsing program %s\n", compile);
864
if (parse_program(compile, &program)!=0) error=1;