all repos — openbox @ 7aae14e9b83242c2778e57c069fb8f299b8172f3

openbox fork - make it a bit more like ryudo

beginning of obcl. the parser works with semicolons after statements
for now, there is much left to change and do.
Marius Nita marius@cs.pdx.edu
commit

7aae14e9b83242c2778e57c069fb8f299b8172f3

parent

69854023a4f36deb80c7c3dee891acc48f8ae6da

7 files changed, 379 insertions(+), 0 deletions(-)

jump to
A obcl/Makefile

@@ -0,0 +1,23 @@

+CFLAGS=-ansi -pedantic -Wall `pkg-config --cflags glib-2.0` +LIBS=`pkg-config --libs glib-2.0` -ll + +targets = cltest + +sources = obcl.c main.c parse.c lex.c +headers = obcl.h + +.PHONY: all clean + +all: $(targets) + +$(targets): $(sources:.c=.o) + $(CC) -o $@ $^ $(LIBS) + +parse.c: parse.y + $(YACC) -d -o$@ $^ + +lex.c: lex.l + $(LEX) -o$@ $^ + +clean: + $(RM) $(targets) *.o core *~ lex.c parse.c parse.h
A obcl/foo.conf

@@ -0,0 +1,21 @@

+include "meh.conf"; +include "bummy.conf"; + +section mouse { + mbind titlebar, frame { + event click; + button middle; + action lower; + } + + mbind frame { + event click; + button right; + action launch_nukes; + } +} + +section theme { + theme "merry"; + font "tahoma-12 bold"; +}
A obcl/lex.l

@@ -0,0 +1,86 @@

+%{ +#include "obcl.h" +#include "parse.h" +%} + +%option yylineno + +DGT [0-9] +ID [a-zA-Z_][a-zA-Z_\.\-0-9]* + + + /* string bummy */ +%x str +%% + + char str_buf[1024]; + char *str_buf_ptr; + int str_char; + + /* begin a string */ +[\"\'] { + str_buf_ptr = str_buf; + str_char = yytext[0]; + BEGIN(str); + } + + /* end a string */ +<str>[\"\'] { + if (yytext[0] == str_char) { + BEGIN(INITIAL); + *str_buf_ptr = '\0'; + yylval.string = g_strdup(str_buf); + return TOK_STRING; + } else { + *str_buf_ptr++ = yytext[0]; + } + } + + /* can't have newlines in strings */ +<str>\n { + printf("Error: Unterminated string constant.\n"); + BEGIN(INITIAL); + } + + /* handle \" and \' */ +<str>"\\"[\"\'] { + if (yytext[1] == str_char) + *str_buf_ptr++ = yytext[1]; + else { + *str_buf_ptr++ = yytext[0]; + *str_buf_ptr++ = yytext[1]; + } + } + + /* eat valid string contents */ +<str>[^\\\n\'\"]+ { + char *yptr = yytext; + while (*yptr) { + *str_buf_ptr++ = *yptr++; + } + } + + /* numberz */ +{DGT}+ { + yylval.num = atof(yytext); + return TOK_NUM; + } + + /* real numbers */ +{DGT}+"."{DGT}* { + yylval.num = atof(yytext); + return TOK_NUM; + } + + /* identifiers -- names without spaces and other crap in them */ +{ID} { + yylval.string = g_strdup(yytext); + return TOK_ID; + } + + /* skip comments */ +"#".*\n ; + /* skip other whitespace */ +[ \n\t]+ ; +. { return yytext[0]; } +%%
A obcl/main.c

@@ -0,0 +1,8 @@

+#include "obcl.h" + +int main() +{ + GList *lst = cl_parse("foo.conf"); + cl_print_tree(lst,0); + return 0; +}
M obcl/obcl.cobcl/obcl.c

@@ -0,0 +1,57 @@

+#include "obcl.h" + +void free_cl_tree(GList *tree) +{ + +} + +GList *cl_parse(gchar *file) +{ + FILE *fh = fopen(file, "r"); + if (fh) + return cl_parse_fh(fh); + else { + printf("can't open file %s\n", file); + return 0; + } +} + +void cl_print_tree(GList *tree, int depth) +{ + CLNode *tmp; + int tmpd = depth; + + for (; tree; tree = tree->next) { + tmp = (CLNode*)tree->data; + + while (tmpd-- > 0) + printf(" "); + tmpd = depth; + + switch(tmp->type) { + case CL_ID: + printf("--ID-- %s\n", tmp->u.str); + break; + case CL_STR: + printf("--STR-- %s\n", tmp->u.str); + break; + case CL_NUM: + printf("--NUM-- %.2f\n", tmp->u.num); + break; + case CL_LIST: + printf("--LIST-- %s\n", tmp->u.lb.id); + cl_print_tree(tmp->u.lb.list, depth+2); + break; + case CL_BLOCK: + printf("--BLOCK-- %s\n", tmp->u.lb.id); + cl_print_tree(tmp->u.lb.block, depth+2); + break; + case CL_LISTBLOCK: + printf("--LISTBLOCK-- %s\n", tmp->u.lb.id); + cl_print_tree(tmp->u.lb.list, depth+2); + printf("\n"); + cl_print_tree(tmp->u.lb.block, depth+2); + break; + } + } +}
A obcl/obcl.h

@@ -0,0 +1,38 @@

+#ifndef __obcl_h +#define __obcl_h + +#include <stdio.h> +#include <stdlib.h> +#include <glib.h> + +typedef enum CLNodeType { + CL_ID, + CL_NUM, + CL_STR, + CL_LIST, + CL_BLOCK, + CL_LISTBLOCK +} CLNodeType; + +typedef struct CLNode { + CLNodeType type; + union { + struct { + gchar *id; + GList *list; + GList *block; + } lb; + double num; + gchar *str; + } u; + +} CLNode; + +void free_cl_tree(GList *tree); +GList *cl_parse(gchar *file); +GList *cl_parse_fh(FILE *file); +void cl_print_tree(GList *tree, int depth); + +GList *parse_file(FILE *fh); + +#endif /* __obcl_h */
A obcl/parse.y

@@ -0,0 +1,146 @@

+%{ +#include "obcl.h" + +int yylex(void); +void yyerror(char *msg, ...); + +extern int yylineno; +extern char *yytext; +GList *config; /* this is what we parse into */ + +%} + +%union { + double num; + gchar *string; + CLNode *node; + GList *glist; +}; + +%token <num> TOK_NUM +%token <string> TOK_ID TOK_STRING +%token TOK_SEP + +%type <glist> config +%type <glist> stmts +%type <node> stmt +%type <glist> list +%type <glist> block +%type <node> value + +%expect 2 /* for now */ + +%% + +config: stmts + { + config = $$ = $1; + } + ; + +stmts: + { $$ = NULL; } + | stmt + { $$ = g_list_append(NULL, $1); } + | stmts stmt + { $$ = g_list_append($1, $2); } + ; + +stmt: TOK_ID list ';' + { + CLNode *s = g_new(CLNode,1); + s->type = CL_LIST; + s->u.lb.list = $2; + s->u.lb.id = $1; + $$ = s; + } + | TOK_ID list block + { + CLNode *s = g_new(CLNode,1); + s->type = CL_LISTBLOCK; + s->u.lb.list = $2; + s->u.lb.block = $3; + s->u.lb.id = $1; + $$ = s; + } + | TOK_ID block + { + CLNode *s = g_new(CLNode,1); + s->type = CL_BLOCK; + s->u.lb.block = $2; + s->u.lb.id = $1; + $$ = s; + } + ; + +list: value + { + $$ = g_list_append(NULL, $1); + } + | list ',' value + { + $$ = g_list_append($1, $3); + } + ; + +block: '{' stmts '}' + { + $$ = $2; + } + ; + +value: TOK_ID + { + CLNode *node = g_new(CLNode,1); + node->type = CL_ID; + node->u.str = $1; + $$ = node; + } + | TOK_STRING + { + CLNode *node = g_new(CLNode,1); + node->type = CL_STR; + node->u.str = $1; + $$ = node; + } + | TOK_NUM + { + CLNode *node = g_new(CLNode,1); + node->type = CL_NUM; + node->u.num = $1; + $$ = node; + } + ; + +%% + +int yywrap() +{ + return 1; +} + +/* void yyerror(const char *err) */ +/* { */ +/* fprintf(stderr, "Parse error on line %d, near '%s': %s\n", */ +/* yylineno, yytext, err); */ +/* } */ + +void yyerror(char *msg, ...) +{ + va_list args; + va_start(args,msg); + + fprintf(stderr, "Error on line %d, near '%s': ", yylineno, yytext); + vfprintf(stderr, msg, args); + fprintf(stderr,"\n"); + + va_end(args); +} + +GList *cl_parse_fh(FILE *fh) +{ + extern FILE *yyin; + yyin = fh; + yyparse(); + return config; +}