From 9dd975e9742e95a0058ad60ba69bdeb8d3576cea Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sun, 13 Sep 2009 14:16:39 +0200 Subject: [PATCH 1/6] Add first version of lexer/parser to git, update Makefile --- Makefile | 20 ++++- src/cfgparse.l | 59 +++++++++++++++ src/cfgparse.y | 193 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 268 insertions(+), 4 deletions(-) create mode 100644 src/cfgparse.l create mode 100644 src/cfgparse.y diff --git a/Makefile b/Makefile index 419dc561..f14cdb44 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,9 @@ TOPDIR=$(shell pwd) include $(TOPDIR)/common.mk # Depend on the object files of all source-files in src/*.c and on all header files -FILES=$(patsubst %.c,%.o,$(wildcard src/*.c)) +AUTOGENERATED:=src/cfgparse.tab.c src/cfgparse.yy.c +FILES:=$(filter-out $(AUTOGENERATED),$(wildcard src/*.c)) +FILES:=$(FILES:.c=.o) HEADERS=$(wildcard include/*.h) # Depend on the specific file (.c for each .o) and on all headers @@ -11,13 +13,23 @@ src/%.o: src/%.c ${HEADERS} echo "CC $<" $(CC) $(CFLAGS) -c -o $@ $< -all: ${FILES} +all: src/cfgparse.y.o src/cfgparse.yy.o ${FILES} echo "LINK i3" - $(CC) -o i3 ${FILES} $(LDFLAGS) + $(CC) -o i3 ${FILES} src/cfgparse.y.o src/cfgparse.yy.o $(LDFLAGS) echo "" echo "SUBDIR i3-msg" $(MAKE) TOPDIR=$(TOPDIR) -C i3-msg +src/cfgparse.yy.o: src/cfgparse.l + echo "LEX $<" + lex -i -o $(@:.o=.c) $< + $(CC) $(CFLAGS) -c -o $@ $(@:.o=.c) + +src/cfgparse.y.o: src/cfgparse.y + echo "YACC $<" + yacc -b $(basename $< .y) -d $< + $(CC) $(CFLAGS) -c -o $@ $(<:.y=.tab.c) + install: all echo "INSTALL" $(INSTALL) -d -m 0755 $(DESTDIR)/usr/bin @@ -46,7 +58,7 @@ dist: distclean rm -rf i3-${VERSION} clean: - rm -f src/*.o + rm -f src/*.o src/cfgparse.tab.{c,h} src/cfgparse.yy.c $(MAKE) -C docs clean $(MAKE) -C man clean $(MAKE) TOPDIR=$(TOPDIR) -C i3-msg clean diff --git a/src/cfgparse.l b/src/cfgparse.l new file mode 100644 index 00000000..af26c6ae --- /dev/null +++ b/src/cfgparse.l @@ -0,0 +1,59 @@ +%{ +#include +#include "cfgparse.tab.h" +#include + +enum { + BIND_NONE = 0, + BIND_SHIFT = XCB_MOD_MASK_SHIFT, /* (1 << 0) */ + BIND_CONTROL = XCB_MOD_MASK_CONTROL, /* (1 << 2) */ + BIND_MOD1 = XCB_MOD_MASK_1, /* (1 << 3) */ + BIND_MOD2 = XCB_MOD_MASK_2, /* (1 << 4) */ + BIND_MOD3 = XCB_MOD_MASK_3, /* (1 << 5) */ + BIND_MOD4 = XCB_MOD_MASK_4, /* (1 << 6) */ + BIND_MOD5 = XCB_MOD_MASK_5, /* (1 << 7) */ + BIND_MODE_SWITCH = (1 << 8) +}; + +%} + +%Start BIND_COND BIND_AWS_COND BIND_A2WS_COND ASSIGN_COND + +%% +[0-9]+ yylval.number = atoi(yytext); return NUMBER; +[0-9a-fA-F]+ { yylval.string = strdup(yytext); return HEX; } +bind { BEGIN(BIND_COND); return TOKBIND; } +bindsym { BEGIN(BIND_COND); return TOKBINDSYM; } +floating_modifier return TOKFLOATING_MODIFIER; +workspace return TOKWORKSPACE; +screen return TOKSCREEN; +assign { BEGIN(ASSIGN_COND); return TOKASSIGN; } +set { BEGIN(BIND_COND); return TOKSET; } +ipc-socket { BEGIN(BIND_AWS_COND); return TOKIPCSOCKET; } +exec { BEGIN(BIND_AWS_COND); return TOKEXEC; } +client.focused { /* TODO: lval pointer */ return TOKCOLOR; } +Mod1 yylval.number = BIND_MOD1; return MODIFIER; +Mod2 yylval.number = BIND_MOD2; return MODIFIER; +Mod3 yylval.number = BIND_MOD3; return MODIFIER; +Mod4 yylval.number = BIND_MOD4; return MODIFIER; +Mod5 yylval.number = BIND_MOD5; return MODIFIER; +control return TOKCONTROL; +shift return TOKSHIFT; +→ return TOKARROW; +\n /* ignore end of line */; +[ \t]+ { BEGIN(BIND_AWS_COND); return WHITESPACE; } +[ \t]+ { BEGIN(BIND_A2WS_COND); return WHITESPACE; } +[ \t]+ return WHITESPACE; +[^\n]+ { BEGIN(INITIAL); yylval.string = strdup(yytext); return STRING; } +[^ \t]+ { BEGIN(INITIAL); yylval.string = strdup(yytext); return STRING_NG; } +[a-zA-Z]+ yylval.string = strdup(yytext); return WORD; +[a-zA-Z0-9_-]+ yylval.string = strdup(yytext); return VARNAME; +\"[^\"]+\" { + /* yylval will be the string, but without quotes */ + char *copy = strdup(yytext+1); + copy[strlen(copy)-1] = '\0'; + yylval.string = copy; + return QUOTEDSTRING; + } +. return (int) yytext[0]; +%% diff --git a/src/cfgparse.y b/src/cfgparse.y new file mode 100644 index 00000000..2cf408a7 --- /dev/null +++ b/src/cfgparse.y @@ -0,0 +1,193 @@ +%{ +#include +#include +#include + +enum { + BIND_NONE = 0, + BIND_SHIFT = XCB_MOD_MASK_SHIFT, /* (1 << 0) */ + BIND_CONTROL = XCB_MOD_MASK_CONTROL, /* (1 << 2) */ + BIND_MOD1 = XCB_MOD_MASK_1, /* (1 << 3) */ + BIND_MOD2 = XCB_MOD_MASK_2, /* (1 << 4) */ + BIND_MOD3 = XCB_MOD_MASK_3, /* (1 << 5) */ + BIND_MOD4 = XCB_MOD_MASK_4, /* (1 << 6) */ + BIND_MOD5 = XCB_MOD_MASK_5, /* (1 << 7) */ + BIND_MODE_SWITCH = (1 << 8) +}; + + +int yydebug = 1; + +void yyerror(const char *str) +{ + fprintf(stderr,"error: %s\n",str); +} + +int yywrap() +{ + return 1; +} + +#if 0 +main() +{ + yyparse(); + printf("parsing done\n"); +} +#endif + +%} + +%union { + int number; + char *string; +} + +%token NUMBER +%token WORD +%token STRING +%token STRING_NG +%token VARNAME +%token HEX +%token TOKBIND +%token TOKBINDSYM +%token MODIFIER +%token TOKCONTROL +%token TOKSHIFT +%token WHITESPACE +%token TOKFLOATING_MODIFIER +%token QUOTEDSTRING +%token TOKWORKSPACE +%token TOKSCREEN +%token TOKASSIGN +%token TOKSET +%token TOKIPCSOCKET +%token TOKEXEC +%token TOKCOLOR +%token TOKARROW + +%% + +lines: /* empty */ + | lines WHITESPACE line + | lines line + ; + +line: + bind + | bindsym + | floating_modifier + | workspace + | assign + | set + | ipcsocket + | exec + | color + ; + +command: + STRING + ; + +bind: + TOKBIND WHITESPACE binding_modifiers '+' NUMBER WHITESPACE command + { + printf("\tFound binding mod%d with key %d and command %s\n", $3, $5, $7); + } + ; + +bindsym: + TOKBINDSYM WHITESPACE binding_modifiers '+' WORD WHITESPACE command + { + printf("\tFound symbolic mod%d with key %s and command %s\n", $3, $5, $7); + } + ; + +floating_modifier: + TOKFLOATING_MODIFIER WHITESPACE binding_modifiers + { + printf("\tfloating modifier %d\n", $3); + } + ; + +workspace: + TOKWORKSPACE WHITESPACE NUMBER WHITESPACE TOKSCREEN WHITESPACE screen + { + printf("\t workspace %d to screen %d\n", $3, $7); + } + | TOKWORKSPACE WHITESPACE NUMBER WHITESPACE TOKSCREEN WHITESPACE screen WHITESPACE QUOTEDSTRING + { + printf("\t quoted: %s\n", $9); + } + ; + +screen: + NUMBER + ; + + +assign: + TOKASSIGN WHITESPACE window_class WHITESPACE optional_arrow NUMBER + { + printf("assignment of %s to %d\n", $3, $6); + } + ; + +window_class: + QUOTEDSTRING + | STRING_NG + ; + +optional_arrow: + /* NULL */ + | TOKARROW WHITESPACE + ; + +set: + TOKSET WHITESPACE variable WHITESPACE STRING + { + printf("set %s to %s\n", $3, $5); + } + ; + +variable: + '$' WORD { asprintf(&$$, "$%s", $2); } + | '$' VARNAME { asprintf(&$$, "$%s", $2); } + ; + +ipcsocket: + TOKIPCSOCKET WHITESPACE STRING + { + printf("ipc %s\n", $3); + } + ; + +exec: + TOKEXEC WHITESPACE STRING + { + printf("exec %s\n", $3); + } + ; + +color: + TOKCOLOR WHITESPACE '#' HEX + { + printf("color %s\n", $4); + } + ; + + +binding_modifiers: + binding_modifier + | + binding_modifiers '+' binding_modifier + { + $$ = $1 | $3; + } + ; + +binding_modifier: + MODIFIER { $$ = $1; } + | TOKCONTROL { $$ = BIND_CONTROL; } + | TOKSHIFT { $$ = BIND_SHIFT; } + ; From 268bf712221de86612ec628a44d1e85ba83db519 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sun, 13 Sep 2009 14:54:27 +0200 Subject: [PATCH 2/6] Implement option -p to test if the lexer/parser can parse your configfile (specify -c before) --- src/cfgparse.l | 25 +++++++----------- src/cfgparse.y | 72 +++++++++++++++++++++++++++++++++++--------------- src/mainx.c | 8 +++++- 3 files changed, 66 insertions(+), 39 deletions(-) diff --git a/src/cfgparse.l b/src/cfgparse.l index af26c6ae..c11028a6 100644 --- a/src/cfgparse.l +++ b/src/cfgparse.l @@ -3,35 +3,29 @@ #include "cfgparse.tab.h" #include -enum { - BIND_NONE = 0, - BIND_SHIFT = XCB_MOD_MASK_SHIFT, /* (1 << 0) */ - BIND_CONTROL = XCB_MOD_MASK_CONTROL, /* (1 << 2) */ - BIND_MOD1 = XCB_MOD_MASK_1, /* (1 << 3) */ - BIND_MOD2 = XCB_MOD_MASK_2, /* (1 << 4) */ - BIND_MOD3 = XCB_MOD_MASK_3, /* (1 << 5) */ - BIND_MOD4 = XCB_MOD_MASK_4, /* (1 << 6) */ - BIND_MOD5 = XCB_MOD_MASK_5, /* (1 << 7) */ - BIND_MODE_SWITCH = (1 << 8) -}; +#include "data.h" %} -%Start BIND_COND BIND_AWS_COND BIND_A2WS_COND ASSIGN_COND +%Start BIND_COND BIND_AWS_COND BIND_A2WS_COND ASSIGN_COND COLOR_COND %% +[^\n]+ { BEGIN(INITIAL); yylval.string = strdup(yytext); return STR; } +#[^\n]* return TOKCOMMENT; [0-9]+ yylval.number = atoi(yytext); return NUMBER; -[0-9a-fA-F]+ { yylval.string = strdup(yytext); return HEX; } +[0-9a-fA-F]+ { yylval.string = strdup(yytext); return HEX; } bind { BEGIN(BIND_COND); return TOKBIND; } bindsym { BEGIN(BIND_COND); return TOKBINDSYM; } floating_modifier return TOKFLOATING_MODIFIER; workspace return TOKWORKSPACE; screen return TOKSCREEN; +terminal { BEGIN(BIND_AWS_COND); return TOKTERMINAL; } +font { BEGIN(BIND_AWS_COND); return TOKFONT; } assign { BEGIN(ASSIGN_COND); return TOKASSIGN; } set { BEGIN(BIND_COND); return TOKSET; } ipc-socket { BEGIN(BIND_AWS_COND); return TOKIPCSOCKET; } exec { BEGIN(BIND_AWS_COND); return TOKEXEC; } -client.focused { /* TODO: lval pointer */ return TOKCOLOR; } +client.focused { BEGIN(COLOR_COND); /* TODO: lval pointer */ return TOKCOLOR; } Mod1 yylval.number = BIND_MOD1; return MODIFIER; Mod2 yylval.number = BIND_MOD2; return MODIFIER; Mod3 yylval.number = BIND_MOD3; return MODIFIER; @@ -44,8 +38,7 @@ shift return TOKSHIFT; [ \t]+ { BEGIN(BIND_AWS_COND); return WHITESPACE; } [ \t]+ { BEGIN(BIND_A2WS_COND); return WHITESPACE; } [ \t]+ return WHITESPACE; -[^\n]+ { BEGIN(INITIAL); yylval.string = strdup(yytext); return STRING; } -[^ \t]+ { BEGIN(INITIAL); yylval.string = strdup(yytext); return STRING_NG; } +[^ \t]+ { BEGIN(INITIAL); yylval.string = strdup(yytext); return STR_NG; } [a-zA-Z]+ yylval.string = strdup(yytext); return WORD; [a-zA-Z0-9_-]+ yylval.string = strdup(yytext); return VARNAME; \"[^\"]+\" { diff --git a/src/cfgparse.y b/src/cfgparse.y index 2cf408a7..4e09e2b1 100644 --- a/src/cfgparse.y +++ b/src/cfgparse.y @@ -3,31 +3,34 @@ #include #include -enum { - BIND_NONE = 0, - BIND_SHIFT = XCB_MOD_MASK_SHIFT, /* (1 << 0) */ - BIND_CONTROL = XCB_MOD_MASK_CONTROL, /* (1 << 2) */ - BIND_MOD1 = XCB_MOD_MASK_1, /* (1 << 3) */ - BIND_MOD2 = XCB_MOD_MASK_2, /* (1 << 4) */ - BIND_MOD3 = XCB_MOD_MASK_3, /* (1 << 5) */ - BIND_MOD4 = XCB_MOD_MASK_4, /* (1 << 6) */ - BIND_MOD5 = XCB_MOD_MASK_5, /* (1 << 7) */ - BIND_MODE_SWITCH = (1 << 8) -}; +#include "data.h" +extern int yylex(void); +extern FILE *yyin; int yydebug = 1; -void yyerror(const char *str) -{ +void yyerror(const char *str) { fprintf(stderr,"error: %s\n",str); } -int yywrap() -{ +int yywrap() { return 1; } +void parse_file(const char *f) { + printf("opening %s\n", f); + if ((yyin = fopen(f, "r")) == NULL) { + perror("fopen"); + exit(1); + } + if (yyparse() != 0) { + fprintf(stderr, "Could not parse configfile\n"); + exit(1); + } + fclose(yyin); +} + #if 0 main() { @@ -45,11 +48,14 @@ main() %token NUMBER %token WORD -%token STRING -%token STRING_NG +%token STR +%token STR_NG %token VARNAME %token HEX %token TOKBIND +%token TOKTERMINAL +%token TOKCOMMENT +%token TOKFONT %token TOKBINDSYM %token MODIFIER %token TOKCONTROL @@ -83,10 +89,17 @@ line: | ipcsocket | exec | color + | terminal + | font + | comment ; +comment: + TOKCOMMENT + ; + command: - STRING + STR ; bind: @@ -135,7 +148,7 @@ assign: window_class: QUOTEDSTRING - | STRING_NG + | STR_NG ; optional_arrow: @@ -144,7 +157,7 @@ optional_arrow: ; set: - TOKSET WHITESPACE variable WHITESPACE STRING + TOKSET WHITESPACE variable WHITESPACE STR { printf("set %s to %s\n", $3, $5); } @@ -156,19 +169,34 @@ variable: ; ipcsocket: - TOKIPCSOCKET WHITESPACE STRING + TOKIPCSOCKET WHITESPACE STR { printf("ipc %s\n", $3); } ; exec: - TOKEXEC WHITESPACE STRING + TOKEXEC WHITESPACE STR { printf("exec %s\n", $3); } ; +terminal: + TOKTERMINAL WHITESPACE STR + { + printf("terminal %s\n", $3); + } + ; + +font: + TOKFONT WHITESPACE STR + { + printf("font %s\n", $3); + } + ; + + color: TOKCOLOR WHITESPACE '#' HEX { diff --git a/src/mainx.c b/src/mainx.c index db3d184a..cb385c89 100644 --- a/src/mainx.c +++ b/src/mainx.c @@ -165,7 +165,7 @@ int main(int argc, char *argv[], char *env[]) { start_argv = argv; - while ((opt = getopt_long(argc, argv, "c:vah", long_options, &option_index)) != -1) { + while ((opt = getopt_long(argc, argv, "c:vahp", long_options, &option_index)) != -1) { switch (opt) { case 'a': LOG("Autostart disabled using -a\n"); @@ -177,6 +177,12 @@ int main(int argc, char *argv[], char *env[]) { case 'v': printf("i3 version " I3_VERSION " © 2009 Michael Stapelberg and contributors\n"); exit(EXIT_SUCCESS); + case 'p': + { + printf("parsing\n"); + parse_file(override_configpath); + exit(0); + } default: fprintf(stderr, "Usage: %s [-c configfile] [-a] [-v]\n", argv[0]); fprintf(stderr, "\n"); From 2986636e03e5726e4935ac1b17735b5b47760b0e Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sun, 13 Sep 2009 18:40:35 +0200 Subject: [PATCH 3/6] Fix some parsing problems, retab! --- Makefile | 2 +- src/cfgparse.l | 102 ++++++++++++++--------- src/cfgparse.y | 215 +++++++++++++++++++++++++------------------------ 3 files changed, 174 insertions(+), 145 deletions(-) diff --git a/Makefile b/Makefile index f14cdb44..3baea500 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ src/cfgparse.yy.o: src/cfgparse.l src/cfgparse.y.o: src/cfgparse.y echo "YACC $<" - yacc -b $(basename $< .y) -d $< + yacc --debug --verbose -b $(basename $< .y) -d $< $(CC) $(CFLAGS) -c -o $@ $(<:.y=.tab.c) install: all diff --git a/src/cfgparse.l b/src/cfgparse.l index c11028a6..e3bacae5 100644 --- a/src/cfgparse.l +++ b/src/cfgparse.l @@ -4,49 +4,71 @@ #include #include "data.h" +#include "config.h" %} -%Start BIND_COND BIND_AWS_COND BIND_A2WS_COND ASSIGN_COND COLOR_COND +%Start BIND_COND +%Start BIND_AWS_COND +%Start BIND_A2WS_COND +%Start ASSIGN_COND +%Start COLOR_COND +%Start SET_COND +%Start SET_AWS_COND +%Start SCREEN_COND +%Start SCREEN_AWS_COND %% -[^\n]+ { BEGIN(INITIAL); yylval.string = strdup(yytext); return STR; } -#[^\n]* return TOKCOMMENT; -[0-9]+ yylval.number = atoi(yytext); return NUMBER; -[0-9a-fA-F]+ { yylval.string = strdup(yytext); return HEX; } -bind { BEGIN(BIND_COND); return TOKBIND; } -bindsym { BEGIN(BIND_COND); return TOKBINDSYM; } -floating_modifier return TOKFLOATING_MODIFIER; -workspace return TOKWORKSPACE; -screen return TOKSCREEN; -terminal { BEGIN(BIND_AWS_COND); return TOKTERMINAL; } -font { BEGIN(BIND_AWS_COND); return TOKFONT; } -assign { BEGIN(ASSIGN_COND); return TOKASSIGN; } -set { BEGIN(BIND_COND); return TOKSET; } -ipc-socket { BEGIN(BIND_AWS_COND); return TOKIPCSOCKET; } -exec { BEGIN(BIND_AWS_COND); return TOKEXEC; } -client.focused { BEGIN(COLOR_COND); /* TODO: lval pointer */ return TOKCOLOR; } -Mod1 yylval.number = BIND_MOD1; return MODIFIER; -Mod2 yylval.number = BIND_MOD2; return MODIFIER; -Mod3 yylval.number = BIND_MOD3; return MODIFIER; -Mod4 yylval.number = BIND_MOD4; return MODIFIER; -Mod5 yylval.number = BIND_MOD5; return MODIFIER; -control return TOKCONTROL; -shift return TOKSHIFT; -→ return TOKARROW; -\n /* ignore end of line */; -[ \t]+ { BEGIN(BIND_AWS_COND); return WHITESPACE; } -[ \t]+ { BEGIN(BIND_A2WS_COND); return WHITESPACE; } -[ \t]+ return WHITESPACE; -[^ \t]+ { BEGIN(INITIAL); yylval.string = strdup(yytext); return STR_NG; } -[a-zA-Z]+ yylval.string = strdup(yytext); return WORD; -[a-zA-Z0-9_-]+ yylval.string = strdup(yytext); return VARNAME; -\"[^\"]+\" { - /* yylval will be the string, but without quotes */ - char *copy = strdup(yytext+1); - copy[strlen(copy)-1] = '\0'; - yylval.string = copy; - return QUOTEDSTRING; - } -. return (int) yytext[0]; +[^\n]+ { BEGIN(INITIAL); yylval.string = strdup(yytext); return STR; } +^#[^\n]* { return TOKCOMMENT; } +[0-9]+ { yylval.number = atoi(yytext); return NUMBER; } +[0-9a-fA-F]+ { yylval.string = strdup(yytext); return HEX; } +bind { BEGIN(BIND_COND); return TOKBIND; } +bindsym { BEGIN(BIND_COND); return TOKBINDSYM; } +floating_modifier { return TOKFLOATING_MODIFIER; } +workspace { BEGIN(INITIAL); return TOKWORKSPACE; } +screen { BEGIN(SCREEN_COND); return TOKSCREEN; } +terminal { BEGIN(BIND_AWS_COND); return TOKTERMINAL; } +font { BEGIN(BIND_AWS_COND); return TOKFONT; } +assign { BEGIN(ASSIGN_COND); return TOKASSIGN; } +set { BEGIN(SET_COND); return TOKSET; } +ipc-socket { BEGIN(BIND_AWS_COND); return TOKIPCSOCKET; } +exec { BEGIN(BIND_AWS_COND); return TOKEXEC; } +client.focused { BEGIN(COLOR_COND); yylval.color = &config.client.focused; return TOKCOLOR; } +client.focused_inactive { BEGIN(COLOR_COND); yylval.color = &config.client.focused_inactive; return TOKCOLOR; } +client.unfocused { BEGIN(COLOR_COND); yylval.color = &config.client.unfocused; return TOKCOLOR; } +client.urgent { BEGIN(COLOR_COND); yylval.color = &config.client.urgent; return TOKCOLOR; } +bar.focused { BEGIN(COLOR_COND); yylval.color = &config.client.focused; return TOKCOLOR; } +bar.unfocused { BEGIN(COLOR_COND); yylval.color = &config.client.unfocused; return TOKCOLOR; } +bar.urgent { BEGIN(COLOR_COND); yylval.color = &config.client.urgent; return TOKCOLOR; } +Mod1 { yylval.number = BIND_MOD1; return MODIFIER; } +Mod2 { yylval.number = BIND_MOD2; return MODIFIER; } +Mod3 { yylval.number = BIND_MOD3; return MODIFIER; } +Mod4 { yylval.number = BIND_MOD4; return MODIFIER; } +Mod5 { yylval.number = BIND_MOD5; return MODIFIER; } +control { return TOKCONTROL; } +shift { return TOKSHIFT; } +→ { return TOKARROW; } +\n /* ignore end of line */; +x { return (int)yytext[0]; } +[ \t]+ { BEGIN(BIND_AWS_COND); return WHITESPACE; } +[ \t]+ { BEGIN(SET_AWS_COND); return WHITESPACE; } +[ \t]+ { BEGIN(BIND_A2WS_COND); return WHITESPACE; } +[ \t]+ { BEGIN(BIND_A2WS_COND); return WHITESPACE; } +[ \t]+ { BEGIN(SCREEN_AWS_COND); return WHITESPACE; } +[ \t]+ { BEGIN(BIND_A2WS_COND); return WHITESPACE; } +[ \t]+ { return WHITESPACE; } +\"[^\"]+\" { + /* if ASSIGN_COND then */ + BEGIN(INITIAL); + /* yylval will be the string, but without quotes */ + char *copy = strdup(yytext+1); + copy[strlen(copy)-1] = '\0'; + yylval.string = copy; + return QUOTEDSTRING; + } +[^ \t]+ { BEGIN(INITIAL); yylval.string = strdup(yytext); return STR_NG; } +[a-zA-Z]+ { yylval.string = strdup(yytext); return WORD; } +[a-zA-Z0-9_-]+ { yylval.string = strdup(yytext); return VARNAME; } +. { return (int)yytext[0]; } %% diff --git a/src/cfgparse.y b/src/cfgparse.y index 4e09e2b1..eab11484 100644 --- a/src/cfgparse.y +++ b/src/cfgparse.y @@ -4,6 +4,7 @@ #include #include "data.h" +#include "config.h" extern int yylex(void); extern FILE *yyin; @@ -19,31 +20,32 @@ int yywrap() { } void parse_file(const char *f) { - printf("opening %s\n", f); + printf("opening %s\n", f); if ((yyin = fopen(f, "r")) == NULL) { - perror("fopen"); - exit(1); - } - if (yyparse() != 0) { - fprintf(stderr, "Could not parse configfile\n"); - exit(1); - } - fclose(yyin); + perror("fopen"); + exit(1); + } + if (yyparse() != 0) { + fprintf(stderr, "Could not parse configfile\n"); + exit(1); + } + fclose(yyin); } #if 0 main() { yyparse(); - printf("parsing done\n"); + printf("parsing done\n"); } #endif %} %union { - int number; - char *string; + int number; + char *string; + struct Colortriple *color; } %token NUMBER @@ -76,146 +78,151 @@ main() lines: /* empty */ | lines WHITESPACE line - | lines line + | lines line ; line: bind - | bindsym - | floating_modifier - | workspace - | assign - | set - | ipcsocket - | exec - | color - | terminal - | font - | comment + | bindsym + | floating_modifier + | workspace + | assign + | set + | ipcsocket + | exec + | color + | terminal + | font + | comment ; comment: - TOKCOMMENT - ; + TOKCOMMENT + ; command: - STR - ; + STR + ; bind: - TOKBIND WHITESPACE binding_modifiers '+' NUMBER WHITESPACE command + TOKBIND WHITESPACE binding_modifiers NUMBER WHITESPACE command { - printf("\tFound binding mod%d with key %d and command %s\n", $3, $5, $7); + printf("\tFound binding mod%d with key %d and command %s\n", $3, $4, $6); } ; bindsym: - TOKBINDSYM WHITESPACE binding_modifiers '+' WORD WHITESPACE command + TOKBINDSYM WHITESPACE binding_modifiers WORD WHITESPACE command { - printf("\tFound symbolic mod%d with key %s and command %s\n", $3, $5, $7); + printf("\tFound symbolic mod%d with key %s and command %s\n", $3, $4, $6); } ; floating_modifier: - TOKFLOATING_MODIFIER WHITESPACE binding_modifiers - { - printf("\tfloating modifier %d\n", $3); - } - ; + TOKFLOATING_MODIFIER WHITESPACE binding_modifiers + { + printf("\tfloating modifier %d\n", $3); + } + ; workspace: - TOKWORKSPACE WHITESPACE NUMBER WHITESPACE TOKSCREEN WHITESPACE screen - { - printf("\t workspace %d to screen %d\n", $3, $7); - } - | TOKWORKSPACE WHITESPACE NUMBER WHITESPACE TOKSCREEN WHITESPACE screen WHITESPACE QUOTEDSTRING - { - printf("\t quoted: %s\n", $9); - } - ; + TOKWORKSPACE WHITESPACE NUMBER WHITESPACE TOKSCREEN WHITESPACE screen + { + printf("\t workspace %d to screen %s\n", $3, $7); + } + | TOKWORKSPACE WHITESPACE NUMBER WHITESPACE TOKSCREEN WHITESPACE screen WHITESPACE workspace_name + { + printf("\t quoted: %s\n", $9); + } + ; + +workspace_name: + QUOTEDSTRING + | STR + ; screen: - NUMBER - ; - + NUMBER { asprintf(&$$, "%d", $1); } + | NUMBER 'x' { asprintf(&$$, "%d", $1); } + | NUMBER 'x' NUMBER { asprintf(&$$, "%dx%d", $1, $3); } + | 'x' NUMBER { asprintf(&$$, "x%d", $2); } + ; assign: - TOKASSIGN WHITESPACE window_class WHITESPACE optional_arrow NUMBER - { - printf("assignment of %s to %d\n", $3, $6); - } - ; + TOKASSIGN WHITESPACE window_class WHITESPACE optional_arrow NUMBER + { + printf("assignment of %s to %d\n", $3, $6); + } + ; window_class: - QUOTEDSTRING - | STR_NG - ; + QUOTEDSTRING + | STR_NG + ; optional_arrow: - /* NULL */ - | TOKARROW WHITESPACE - ; + /* NULL */ + | TOKARROW WHITESPACE + ; set: - TOKSET WHITESPACE variable WHITESPACE STR - { - printf("set %s to %s\n", $3, $5); - } - ; + TOKSET WHITESPACE variable WHITESPACE STR + { + printf("set %s to %s\n", $3, $5); + } + ; variable: - '$' WORD { asprintf(&$$, "$%s", $2); } - | '$' VARNAME { asprintf(&$$, "$%s", $2); } - ; + '$' WORD { asprintf(&$$, "$%s", $2); } + | '$' VARNAME { asprintf(&$$, "$%s", $2); } + ; ipcsocket: - TOKIPCSOCKET WHITESPACE STR - { - printf("ipc %s\n", $3); - } - ; + TOKIPCSOCKET WHITESPACE STR + { + printf("ipc %s\n", $3); + } + ; exec: - TOKEXEC WHITESPACE STR - { - printf("exec %s\n", $3); - } - ; + TOKEXEC WHITESPACE STR + { + printf("exec %s\n", $3); + } + ; terminal: - TOKTERMINAL WHITESPACE STR - { - printf("terminal %s\n", $3); - } - ; + TOKTERMINAL WHITESPACE STR + { + printf("terminal %s\n", $3); + } + ; font: - TOKFONT WHITESPACE STR - { - printf("font %s\n", $3); - } - ; + TOKFONT WHITESPACE STR + { + printf("font %s\n", $3); + } + ; color: - TOKCOLOR WHITESPACE '#' HEX - { - printf("color %s\n", $4); - } - ; + TOKCOLOR WHITESPACE '#' HEX WHITESPACE '#' HEX WHITESPACE '#' HEX + { + printf("color %p, %s and %s and %s\n", $1, $4, $7, $10); + } + ; binding_modifiers: - binding_modifier - | - binding_modifiers '+' binding_modifier - { - $$ = $1 | $3; - } - ; + /* NULL */ { $$ = 0; } + | binding_modifier + | binding_modifiers '+' binding_modifier { $$ = $1 | $3; } + | binding_modifiers '+' { $$ = $1; } + ; binding_modifier: - MODIFIER { $$ = $1; } - | TOKCONTROL { $$ = BIND_CONTROL; } - | TOKSHIFT { $$ = BIND_SHIFT; } - ; + MODIFIER { $$ = $1; } + | TOKCONTROL { $$ = BIND_CONTROL; } + | TOKSHIFT { $$ = BIND_SHIFT; } + ; From 7fda4a2c32336e0887fc33c6614acdd84b58ece7 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sun, 13 Sep 2009 21:32:58 +0200 Subject: [PATCH 4/6] Make variable expansion work with the new parsing --- include/config.h | 1 + src/cfgparse.l | 8 +-- src/cfgparse.y | 142 ++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 118 insertions(+), 33 deletions(-) diff --git a/include/config.h b/include/config.h index 100faa4c..f94d9a40 100644 --- a/include/config.h +++ b/include/config.h @@ -40,6 +40,7 @@ struct Colortriple { struct Variable { char *key; char *value; + char *next_match; SLIST_ENTRY(Variable) variables; }; diff --git a/src/cfgparse.l b/src/cfgparse.l index e3bacae5..ac2a71b0 100644 --- a/src/cfgparse.l +++ b/src/cfgparse.l @@ -5,7 +5,6 @@ #include "data.h" #include "config.h" - %} %Start BIND_COND @@ -13,8 +12,6 @@ %Start BIND_A2WS_COND %Start ASSIGN_COND %Start COLOR_COND -%Start SET_COND -%Start SET_AWS_COND %Start SCREEN_COND %Start SCREEN_AWS_COND @@ -31,7 +28,7 @@ screen { BEGIN(SCREEN_COND); return TOKSCREEN; } terminal { BEGIN(BIND_AWS_COND); return TOKTERMINAL; } font { BEGIN(BIND_AWS_COND); return TOKFONT; } assign { BEGIN(ASSIGN_COND); return TOKASSIGN; } -set { BEGIN(SET_COND); return TOKSET; } +set[^\n]* { return TOKCOMMENT; } ipc-socket { BEGIN(BIND_AWS_COND); return TOKIPCSOCKET; } exec { BEGIN(BIND_AWS_COND); return TOKEXEC; } client.focused { BEGIN(COLOR_COND); yylval.color = &config.client.focused; return TOKCOLOR; } @@ -52,9 +49,7 @@ shift { return TOKSHIFT; } \n /* ignore end of line */; x { return (int)yytext[0]; } [ \t]+ { BEGIN(BIND_AWS_COND); return WHITESPACE; } -[ \t]+ { BEGIN(SET_AWS_COND); return WHITESPACE; } [ \t]+ { BEGIN(BIND_A2WS_COND); return WHITESPACE; } -[ \t]+ { BEGIN(BIND_A2WS_COND); return WHITESPACE; } [ \t]+ { BEGIN(SCREEN_AWS_COND); return WHITESPACE; } [ \t]+ { BEGIN(BIND_A2WS_COND); return WHITESPACE; } [ \t]+ { return WHITESPACE; } @@ -69,6 +64,5 @@ shift { return TOKSHIFT; } } [^ \t]+ { BEGIN(INITIAL); yylval.string = strdup(yytext); return STR_NG; } [a-zA-Z]+ { yylval.string = strdup(yytext); return WORD; } -[a-zA-Z0-9_-]+ { yylval.string = strdup(yytext); return VARNAME; } . { return (int)yytext[0]; } %% diff --git a/src/cfgparse.y b/src/cfgparse.y index eab11484..59ecd977 100644 --- a/src/cfgparse.y +++ b/src/cfgparse.y @@ -2,9 +2,17 @@ #include #include #include +#include +#include +#include +#include +#include +#include #include "data.h" #include "config.h" +#include "util.h" +#include "queue.h" extern int yylex(void); extern FILE *yyin; @@ -20,25 +28,121 @@ int yywrap() { } void parse_file(const char *f) { - printf("opening %s\n", f); - if ((yyin = fopen(f, "r")) == NULL) { - perror("fopen"); - exit(1); + SLIST_HEAD(variables_head, Variable) variables = SLIST_HEAD_INITIALIZER(&variables); + int fd, ret, read_bytes = 0; + struct stat stbuf; + char *buf; + FILE *fstr; + char buffer[1026], key[512], value[512]; + + if ((fd = open(f, O_RDONLY)) == -1) + die("Could not open configuration file: %s\n", strerror(errno)); + + if (fstat(fd, &stbuf) == -1) + die("Could not fstat file: %s\n", strerror(errno)); + + buf = smalloc(stbuf.st_size * sizeof(char)); + while (read_bytes < stbuf.st_size) { + if ((ret = read(fd, buf + read_bytes, (stbuf.st_size - read_bytes))) < 0) + die("Could not read(): %s\n", strerror(errno)); + read_bytes += ret; } + + if (lseek(fd, 0, SEEK_SET) == (off_t)-1) + die("Could not lseek: %s\n", strerror(errno)); + + if ((fstr = fdopen(fd, "r")) == NULL) + die("Could not fdopen: %s\n", strerror(errno)); + + while (!feof(fstr)) { + if (fgets(buffer, 1024, fstr) == NULL) { + if (feof(fstr)) + break; + die("Could not read configuration file\n"); + } + + /* sscanf implicitly strips whitespace. Also, we skip comments and empty lines. */ + if (sscanf(buffer, "%s %[^\n]", key, value) < 1 || + key[0] == '#' || strlen(key) < 3) + continue; + + if (strcasecmp(key, "set") == 0) { + if (value[0] != '$') + die("Malformed variable assignment, name has to start with $\n"); + + /* get key/value for this variable */ + char *v_key = value, *v_value; + if ((v_value = strstr(value, " ")) == NULL) + die("Malformed variable assignment, need a value\n"); + + *(v_value++) = '\0'; + + struct Variable *new = scalloc(sizeof(struct Variable)); + new->key = sstrdup(v_key); + new->value = sstrdup(v_value); + SLIST_INSERT_HEAD(&variables, new, variables); + LOG("Got new variable %s = %s\n", v_key, v_value); + continue; + } + } + + /* For every custom variable, see how often it occurs in the file and + * how much extra bytes it requires when replaced. */ + struct Variable *current, *nearest; + int extra_bytes = 0; + SLIST_FOREACH(current, &variables, variables) { + int extra = (strlen(current->value) - strlen(current->key)); + char *next; + for (next = buf; + (next = strcasestr(buf + (next - buf), current->key)) != NULL; + next += strlen(current->key)) + extra_bytes += extra; + } + + /* Then, allocate a new buffer and copy the file over to the new one, + * but replace occurences of our variables */ + char *walk = buf, *destwalk; + char *new = smalloc((stbuf.st_size + extra_bytes) * sizeof(char)); + destwalk = new; + while (walk < (buf + stbuf.st_size)) { + /* Find the next variable */ + SLIST_FOREACH(current, &variables, variables) + current->next_match = strcasestr(walk, current->key); + nearest = NULL; + int distance = stbuf.st_size; + SLIST_FOREACH(current, &variables, variables) { + if (current->next_match == NULL) + continue; + if ((current->next_match - walk) < distance) { + distance = (current->next_match - walk); + nearest = current; + } + } + if (nearest == NULL) { + /* If there are no more variables, we just copy the rest */ + strncpy(destwalk, walk, (buf + stbuf.st_size) - walk); + destwalk += (buf + stbuf.st_size) - walk; + *destwalk = '\0'; + break; + } else { + /* Copy until the next variable, then copy its value */ + strncpy(destwalk, walk, distance); + strncpy(destwalk + distance, nearest->value, strlen(nearest->value)); + walk += distance + strlen(nearest->key); + destwalk += distance + strlen(nearest->value); + } + } + + yy_scan_string(new); + if (yyparse() != 0) { fprintf(stderr, "Could not parse configfile\n"); exit(1); } - fclose(yyin); -} -#if 0 -main() -{ - yyparse(); - printf("parsing done\n"); + free(new); + free(buf); } -#endif %} @@ -52,7 +156,6 @@ main() %token WORD %token STR %token STR_NG -%token VARNAME %token HEX %token TOKBIND %token TOKTERMINAL @@ -87,7 +190,6 @@ line: | floating_modifier | workspace | assign - | set | ipcsocket | exec | color @@ -165,18 +267,6 @@ optional_arrow: | TOKARROW WHITESPACE ; -set: - TOKSET WHITESPACE variable WHITESPACE STR - { - printf("set %s to %s\n", $3, $5); - } - ; - -variable: - '$' WORD { asprintf(&$$, "$%s", $2); } - | '$' VARNAME { asprintf(&$$, "$%s", $2); } - ; - ipcsocket: TOKIPCSOCKET WHITESPACE STR { From 207ad0a7dfdd51ec364e14275aeded14fabfe800 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sun, 13 Sep 2009 22:13:28 +0200 Subject: [PATCH 5/6] Implement most code to actually set the configuration settings --- src/cfgparse.y | 64 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 49 insertions(+), 15 deletions(-) diff --git a/src/cfgparse.y b/src/cfgparse.y index 59ecd977..f3c552f9 100644 --- a/src/cfgparse.y +++ b/src/cfgparse.y @@ -11,8 +11,10 @@ #include "data.h" #include "config.h" +#include "i3.h" #include "util.h" #include "queue.h" +#include "table.h" extern int yylex(void); extern FILE *yyin; @@ -210,6 +212,13 @@ bind: TOKBIND WHITESPACE binding_modifiers NUMBER WHITESPACE command { printf("\tFound binding mod%d with key %d and command %s\n", $3, $4, $6); + Binding *new = scalloc(sizeof(Binding)); + + new->keycode = $4; + new->mods = $3; + new->command = sstrdup($6); + + TAILQ_INSERT_TAIL(&bindings, new, bindings); } ; @@ -217,30 +226,42 @@ bindsym: TOKBINDSYM WHITESPACE binding_modifiers WORD WHITESPACE command { printf("\tFound symbolic mod%d with key %s and command %s\n", $3, $4, $6); + Binding *new = scalloc(sizeof(Binding)); + + new->symbol = sstrdup($4); + new->mods = $3; + new->command = sstrdup($6); + + TAILQ_INSERT_TAIL(&bindings, new, bindings); } ; floating_modifier: TOKFLOATING_MODIFIER WHITESPACE binding_modifiers { - printf("\tfloating modifier %d\n", $3); + LOG("floating modifier = %d\n", $3); + config.floating_modifier = $3; } ; workspace: - TOKWORKSPACE WHITESPACE NUMBER WHITESPACE TOKSCREEN WHITESPACE screen + TOKWORKSPACE WHITESPACE NUMBER WHITESPACE TOKSCREEN WHITESPACE screen workspace_name { - printf("\t workspace %d to screen %s\n", $3, $7); - } - | TOKWORKSPACE WHITESPACE NUMBER WHITESPACE TOKSCREEN WHITESPACE screen WHITESPACE workspace_name - { - printf("\t quoted: %s\n", $9); + int ws_num = $3; + if (ws_num < 1 || ws_num > 10) { + LOG("Invalid workspace assignment, workspace number %d out of range\n", ws_num); + } else { + workspaces[ws_num - 1].preferred_screen = sstrdup($7); + if ($8 != NULL) + workspace_set_name(&(workspaces[ws_num - 1]), $8); + } } ; workspace_name: - QUOTEDSTRING - | STR + /* NULL */ { $$ = NULL; } + | WHITESPACE QUOTEDSTRING { $$ = $2; } + | WHITESPACE STR { $$ = $2; } ; screen: @@ -253,6 +274,7 @@ screen: assign: TOKASSIGN WHITESPACE window_class WHITESPACE optional_arrow NUMBER { + /* TODO */ printf("assignment of %s to %d\n", $3, $6); } ; @@ -270,39 +292,51 @@ optional_arrow: ipcsocket: TOKIPCSOCKET WHITESPACE STR { - printf("ipc %s\n", $3); + config.ipc_socket_path = sstrdup($3); } ; exec: TOKEXEC WHITESPACE STR { - printf("exec %s\n", $3); + struct Autostart *new = smalloc(sizeof(struct Autostart)); + new->command = sstrdup($3); + TAILQ_INSERT_TAIL(&autostarts, new, autostarts); } ; terminal: TOKTERMINAL WHITESPACE STR { - printf("terminal %s\n", $3); + config.terminal = sstrdup($3); + printf("terminal %s\n", config.terminal); } ; font: TOKFONT WHITESPACE STR { - printf("font %s\n", $3); + config.font = sstrdup($3); + printf("font %s\n", config.font); } ; color: - TOKCOLOR WHITESPACE '#' HEX WHITESPACE '#' HEX WHITESPACE '#' HEX + TOKCOLOR WHITESPACE colorpixel WHITESPACE colorpixel WHITESPACE colorpixel { - printf("color %p, %s and %s and %s\n", $1, $4, $7, $10); + struct Colortriple *dest = $1; + + dest->border = $3; + dest->background = $5; + dest->text = $7; } ; +colorpixel: + '#' HEX { $$ = get_colorpixel(global_conn, $2); } + ; + binding_modifiers: /* NULL */ { $$ = 0; } From ca472559b93213b3330a16c674333dc441f01911 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sat, 19 Sep 2009 19:05:15 +0200 Subject: [PATCH 6/6] Finish configfile parsing with lexer, implement -l to use the lexer. Every user is encouraged to use -l to switch to the new lexer and see if there are any problems. --- include/config.h | 1 + src/cfgparse.l | 1 + src/cfgparse.y | 31 +++++++++++++++++++++++++++++-- src/config.c | 28 +++++++++++++++++++++++++--- src/mainx.c | 11 ++++------- 5 files changed, 60 insertions(+), 12 deletions(-) diff --git a/include/config.h b/include/config.h index f94d9a40..c0105cee 100644 --- a/include/config.h +++ b/include/config.h @@ -20,6 +20,7 @@ typedef struct Config Config; extern Config config; +extern bool config_use_lexer; /** * Part of the struct Config. It makes sense to group colors for background, diff --git a/src/cfgparse.l b/src/cfgparse.l index ac2a71b0..2332055a 100644 --- a/src/cfgparse.l +++ b/src/cfgparse.l @@ -43,6 +43,7 @@ Mod2 { yylval.number = BIND_MOD2; return MODIFIER; } Mod3 { yylval.number = BIND_MOD3; return MODIFIER; } Mod4 { yylval.number = BIND_MOD4; return MODIFIER; } Mod5 { yylval.number = BIND_MOD5; return MODIFIER; } +Mode_switch { yylval.number = BIND_MODE_SWITCH; return MODIFIER; } control { return TOKCONTROL; } shift { return TOKSHIFT; } → { return TOKARROW; } diff --git a/src/cfgparse.y b/src/cfgparse.y index f3c552f9..4b7224b5 100644 --- a/src/cfgparse.y +++ b/src/cfgparse.y @@ -152,6 +152,7 @@ void parse_file(const char *f) { int number; char *string; struct Colortriple *color; + struct Assignment *assignment; } %token NUMBER @@ -272,13 +273,39 @@ screen: ; assign: - TOKASSIGN WHITESPACE window_class WHITESPACE optional_arrow NUMBER + TOKASSIGN WHITESPACE window_class WHITESPACE optional_arrow assign_target { - /* TODO */ printf("assignment of %s to %d\n", $3, $6); + + struct Assignment *new = $6; + new->windowclass_title = strdup($3); + TAILQ_INSERT_TAIL(&assignments, new, assignments); } ; +assign_target: + NUMBER + { + struct Assignment *new = scalloc(sizeof(struct Assignment)); + new->workspace = $1; + new->floating = ASSIGN_FLOATING_NO; + $$ = new; + } + | '~' + { + struct Assignment *new = scalloc(sizeof(struct Assignment)); + new->floating = ASSIGN_FLOATING_ONLY; + $$ = new; + } + | '~' NUMBER + { + struct Assignment *new = scalloc(sizeof(struct Assignment)); + new->workspace = $2; + new->floating = ASSIGN_FLOATING; + $$ = new; + } + ; + window_class: QUOTEDSTRING | STR_NG diff --git a/src/config.c b/src/config.c index dd2f70c1..ffc8b7ed 100644 --- a/src/config.c +++ b/src/config.c @@ -28,6 +28,8 @@ Config config; +bool config_use_lexer = false; + /* * This function resolves ~ in pathnames. * @@ -226,6 +228,25 @@ void load_configuration(xcb_connection_t *conn, const char *override_configpath, config.bar.urgent.background = get_colorpixel(conn, "#900000"); config.bar.urgent.text = get_colorpixel(conn, "#ffffff"); + if (config_use_lexer) { + /* Yes, this will be cleaned up soon. */ + if (override_configpath != NULL) { + parse_file(override_configpath); + } else { + FILE *handle; + char *globbed = glob_path("~/.i3/config"); + if ((handle = fopen(globbed, "r")) == NULL) { + if ((handle = fopen("/etc/i3/config", "r")) == NULL) { + die("Neither \"%s\" nor /etc/i3/config could be opened\n", globbed); + } else { + parse_file("/etc/i3/config"); + } + } else { + parse_file(globbed); + } + } + } else { + FILE *handle; if (override_configpath != NULL) { if ((handle = fopen(override_configpath, "r")) == NULL) @@ -508,9 +529,6 @@ void load_configuration(xcb_connection_t *conn, const char *override_configpath, grab_all_keys(conn); fclose(handle); - REQUIRED_OPTION(terminal); - REQUIRED_OPTION(font); - while (!SLIST_EMPTY(&variables)) { struct Variable *v = SLIST_FIRST(&variables); SLIST_REMOVE_HEAD(&variables, variables); @@ -518,6 +536,10 @@ void load_configuration(xcb_connection_t *conn, const char *override_configpath, free(v->value); free(v); } + } + + REQUIRED_OPTION(terminal); + REQUIRED_OPTION(font); /* Set an empty name for every workspace which got no name */ for (int i = 0; i < 10; i++) { diff --git a/src/mainx.c b/src/mainx.c index cb385c89..329aae29 100644 --- a/src/mainx.c +++ b/src/mainx.c @@ -165,7 +165,7 @@ int main(int argc, char *argv[], char *env[]) { start_argv = argv; - while ((opt = getopt_long(argc, argv, "c:vahp", long_options, &option_index)) != -1) { + while ((opt = getopt_long(argc, argv, "c:vahl", long_options, &option_index)) != -1) { switch (opt) { case 'a': LOG("Autostart disabled using -a\n"); @@ -177,12 +177,9 @@ int main(int argc, char *argv[], char *env[]) { case 'v': printf("i3 version " I3_VERSION " © 2009 Michael Stapelberg and contributors\n"); exit(EXIT_SUCCESS); - case 'p': - { - printf("parsing\n"); - parse_file(override_configpath); - exit(0); - } + case 'l': + config_use_lexer = true; + break; default: fprintf(stderr, "Usage: %s [-c configfile] [-a] [-v]\n", argv[0]); fprintf(stderr, "\n");