initial import
authorroot <root@Thermopile.lan>
Tue, 11 May 2010 21:53:30 +0000 (17:53 -0400)
committerroot <root@Thermopile.lan>
Tue, 11 May 2010 21:53:30 +0000 (17:53 -0400)
Makefile [new file with mode: 0644]
main.c [new file with mode: 0644]
obtheme.h [new file with mode: 0644]
obtheme.l [new file with mode: 0644]
obtheme.y [new file with mode: 0644]
theme.obtheme [new file with mode: 0644]

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..610580e
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,17 @@
+CFLAGS=-g -Wall -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include
+
+.PRECIOUS: %.tab.h %.lex.c %.tab.c
+
+%.tab.h %.tab.c: %.y %.h
+       bison -t -p $* -d $<
+
+%.lex.c: %.l %.tab.h %.h
+       flex -P$* -o$@ $<
+
+all: obtheme
+
+obtheme: main.o obtheme.tab.o obtheme.lex.o obtheme.tab.h
+       $(CC) $(CFLAGS) -o obtheme main.o obtheme.tab.o obtheme.lex.o -lm -lglib-2.0
+
+clean:
+       rm -f obtheme *.lex.* *.tab.* *.o obtheme.c
diff --git a/main.c b/main.c
new file mode 100644 (file)
index 0000000..b93ef08
--- /dev/null
+++ b/main.c
@@ -0,0 +1,56 @@
+#include <stdio.h>
+#include <string.h>
+#include <glib.h>
+#include "obtheme.h"
+
+static void decor_print(gpointer data, gpointer user_data)
+{
+       struct decor *decor = data;
+       printf("    decor id %s\n", decor->name);
+       printf("      anchor (%d %d %d)\n", decor->space.anchor.x, decor->space.anchor.y, decor->space.anchor.z);
+       printf("      up     (%d %d %d)\n", decor->space.up.x, decor->space.up.y, decor->space.up.z);
+       if (decor->children)
+               g_slist_foreach(decor->children, decor_print, NULL);
+}
+
+static void class_print(gpointer key, gpointer value, gpointer user_data)
+{
+       char *classname = key;
+       struct class *class = value;
+
+       printf("  Class %s\n", classname);
+       g_slist_foreach(class->tree, decor_print, NULL);
+}
+
+static void theme_print(gpointer key, gpointer value, gpointer user_data)
+{
+       char *name = key;
+       struct theme *thm = value;
+       printf("name = %s\n", name);
+       g_hash_table_foreach(thm->classes, class_print, NULL);
+}
+
+static void material_print(gpointer key, gpointer value, gpointer user_data)
+{
+       char *name = key;
+       struct material *mat = value;
+       printf("name = %s\n", name);
+       printf(" opacity = %f\n", mat->opacity);
+}
+
+int main(int argc, char **argv)
+{
+       int err;
+       struct obthemedata themedata;
+
+       themedata.themes = g_hash_table_new(g_str_hash, g_str_equal);
+       themedata.materials = g_hash_table_new(g_str_hash, g_str_equal);
+       err = obtheme_parse(&themedata, argv[1]);
+       printf("err = %d\n", err);
+
+       g_hash_table_foreach(themedata.materials, material_print, NULL);
+
+       g_hash_table_foreach(themedata.themes, theme_print, NULL);
+
+       return 0;
+}
diff --git a/obtheme.h b/obtheme.h
new file mode 100644 (file)
index 0000000..6c67788
--- /dev/null
+++ b/obtheme.h
@@ -0,0 +1,68 @@
+#ifndef __THEME_PARSE_H__
+#define __THEME_PARSE_H__
+
+#include <glib.h>
+
+#undef YY_DECL
+#define YY_DECL int obthemelex(YYSTYPE *yylval, struct parser_control *pc)
+
+#define YYDEBUG 1
+#define YYLEX_PARAM pc
+
+#define MAX_INCLUDE_DEPTH 32
+#define LINE pc->currline[pc->include_stack_ptr]
+
+extern int themedebug;
+
+struct material {
+       float opacity;
+};
+
+struct class {
+       char *name;
+       GSList *tree;
+};
+
+struct obthemedata {
+       GHashTable *themes;
+       GHashTable *materials;
+};
+
+struct theme {
+       char *name;
+       GHashTable *classes;
+};
+
+struct vector {
+       int x;
+       int y;
+       int z;
+};
+
+struct space {
+       struct vector anchor;
+       struct vector up;
+};
+
+struct decor {
+       char *name;
+       GSList *children;
+       struct space space;
+};
+
+struct parser_control {
+       struct yy_buffer_state *include_stack[MAX_INCLUDE_DEPTH];
+       int currline[MAX_INCLUDE_DEPTH];
+       char currfile[MAX_INCLUDE_DEPTH][501];
+       int include_stack_ptr;
+       char error_buf[4096];
+       struct obthemedata *target;
+};
+
+void obthemeerror(struct parser_control *pc, char *s);
+int obtheme_parse(struct obthemedata *td, const char *filename);
+struct parser_control *parser_init(struct obthemedata *td);
+int obthemeparse(struct parser_control *);
+void parser_finish(struct parser_control *);
+
+#endif /* __THEME_PARSE_H__ */
diff --git a/obtheme.l b/obtheme.l
new file mode 100644 (file)
index 0000000..c87dc4d
--- /dev/null
+++ b/obtheme.l
@@ -0,0 +1,156 @@
+%{
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include "obtheme.h"
+#include "obtheme.tab.h"
+
+int yylex(YYSTYPE *yylval, struct parser_control *pc);
+
+void obthemeerror(struct parser_control *pc, char *s)
+{
+       printf("Parse error in file %s on line %d\n%s"
+               , pc->currfile[pc->include_stack_ptr]
+               , pc->currline[pc->include_stack_ptr] + 1
+               , pc->error_buf);
+}
+
+extern int parserparse(void *);
+
+int yywrap(void)
+{
+       return 1;
+}
+
+int obtheme_parse(struct obthemedata *td, const char *filename)
+{
+       FILE *input;
+       int ret;
+       struct parser_control *pc;
+//illdebug = 1;
+       pc = parser_init(td);
+       input = fopen(filename, "r");
+       if (!input)
+               return 2;
+       yyin = input;
+       yyrestart(input);
+       BEGIN 0;
+       pc->include_stack_ptr = 0;
+       pc->currline[pc->include_stack_ptr] = 0;
+       strncpy(pc->currfile[pc->include_stack_ptr], filename, 500);
+       ret = obthemeparse(pc);
+       if (ret != 0) {
+       //XXX I THINK I NEED TO CLOSE ALL INCLUDE FILES HERE
+       //probably also fclose input and call parser_finish?
+               return ret;
+       }
+       fclose(input);
+       parser_finish(pc);
+       return ret;
+}
+
+%}
+%x comment
+%x incl
+%%
+
+include                        BEGIN(incl);
+<incl>[ \t]*           /* eat the whitespace */
+<incl>[^ \t\n]+                { /* got the include file name */
+       char *incfile;
+       if ( pc->include_stack_ptr >= MAX_INCLUDE_DEPTH) {
+               fprintf( stderr, "Includes nested too deeply" );
+               exit(1);
+       }
+
+       pc->include_stack[pc->include_stack_ptr++] = YY_CURRENT_BUFFER;
+       incfile = malloc(strlen(yytext) + strlen("include/")+ 1);
+       strcpy(incfile, "include/");
+       strcat(incfile, yytext);
+       yyin = fopen( incfile, "r" );
+       free(incfile);
+       strncpy(pc->currfile[pc->include_stack_ptr], yytext, 500);
+       pc->currline[pc->include_stack_ptr] = 0;
+       if ( ! yyin ) {
+               printf("Could not find include file %s (%s)\n", yytext, incfile);
+               exit(1);
+       }
+       yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
+
+       BEGIN(INITIAL);
+       }
+
+<<EOF>> {
+        if ( --(pc->include_stack_ptr) < 0 )
+            {
+                       yy_delete_buffer(YY_CURRENT_BUFFER);
+            yyterminate();
+            }
+
+        else
+            {
+            yy_delete_buffer( YY_CURRENT_BUFFER );
+                       fclose(yyin);
+                       yy_switch_to_buffer(
+                 pc->include_stack[pc->include_stack_ptr] );
+            }
+        }
+
+
+"//"+[^\n]*            ;
+"/*"                   BEGIN(comment);
+<comment>[^*\n]*       ;
+<comment>"*"+[^*/\n]*   ;
+<comment>"*"+"/"       BEGIN(INITIAL);
+<comment>\n            LINE++;
+
+theme                  return THEME;
+frame                  return FRAME;
+decor                  return DECOR;
+space                  return SPACE;
+geometry               return GEOMETRY;
+material               return MATERIAL;
+gradient               return GRADIENT;
+context                        return CONTEXT;
+cursor                 return CURSOR;
+class                  return CLASS;
+up                     return UP;
+anchor                 return ANCHOR;
+opacity                        return OPACITY;
+shapeof                        return SHAPEOF;
+texture                        return TEXTURE;
+
+0x[0-9A-Z]+            yylval->integer = strtol(yytext, (char **)NULL, 16); return NUMBER;
+[0-9]+                 yylval->integer = atoi(yytext); return NUMBER;
+[a-zA-Z_][a-zA-Z0-9_]* yylval->string = g_strdup(yytext); return ID;
+\".*\" {
+                       yylval->string = g_strdup(yytext+1); 
+                       yylval->string[strlen(yylval->string)-1] = 0;
+                       return STRING;
+               }
+\`[^`]*\` {
+                       yylval->string = g_strdup(yytext+1); 
+                       yylval->string[strlen(yylval->string)-1] = 0;
+                       return STRING;
+               }
+
+\$[a-zA-Z_][a-zA-Z0-9_]*       yylval->string = g_strdup(yytext+1); return ID;
+\$[0-9]*               yylval->integer = strtol(yytext + 1, (char **)NULL, 16); return SUBST;
+\@                     return AT;
+:                      return COLON;
+;                      return SEMICOLON;
+"+"                    return PLUS;
+"-"                    return MINUS;
+"}"                    return RCB;
+"{"                    return LCB;
+")"                    return RB;
+"("                    return LB;
+"<-"                   return LEFT_ARROW;
+"->"                   return RIGHT_ARROW;
+"<->"                  return DOUBLE_ARROW;
+\n                     LINE++; /* zap EOL */
+[ \t]+                 ; /* and whitespace */
+.                      return 0;
+%%
diff --git a/obtheme.y b/obtheme.y
new file mode 100644 (file)
index 0000000..2146130
--- /dev/null
+++ b/obtheme.y
@@ -0,0 +1,206 @@
+%pure-parser
+%name-prefix "obtheme"
+%parse-param {struct parser_control *pc}
+%{
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <limits.h>
+#include <unistd.h>
+#include "obtheme.h"
+#include "obtheme.tab.h"
+
+YY_DECL;
+
+struct parser_control *parser_init(struct obthemedata *otd)
+{
+       struct parser_control *out;
+       out = calloc(1, sizeof(struct parser_control));
+       out->include_stack_ptr = 0;
+       out->target = otd;
+       return out;
+}
+
+void parser_finish(struct parser_control *c)
+{
+       free(c);
+}
+
+%}
+%start theme_objects
+
+%union {
+       int integer;
+       float realnum;
+       char *string;
+       struct decor decor;
+       struct space space;
+       struct theme theme;
+       struct material material;
+       struct class class;
+       GSList *list;
+       GHashTable *hash;
+       struct vector vector;
+}
+
+%token LCB RCB LB RB
+%token LEFT_ARROW RIGHT_ARROW DOUBLE_ARROW
+%token SEMICOLON AT COLON DEFAULT NOT
+%token PLUS MINUS
+%token <string> STRING ID
+%token <integer> NUMBER SUBST BULK BIG LITTLE
+%token THEME FRAME SPACE GEOMETRY MATERIAL GRADIENT
+%token CONTEXT CURSOR UP ANCHOR CLASS TEXTURE OPACITY
+%token SHAPEOF DECOR
+%type <decor> decor
+%type <decor> decoritems classitem
+%type <space> space
+%type <class> class classitems
+%type <hash> classes
+%type <material> material_props
+%type <realnum> opacity
+%type <space> spaceconstraints
+%type <vector> up anchor
+%%
+
+theme_object   : material_decl
+               | theme
+               ;
+
+theme_objects  : /* empty */
+               | theme_objects theme_object
+               ;
+
+theme          : THEME ID LCB classes RCB {
+                       struct theme *out;
+                       out = malloc(sizeof(struct theme));
+                       out->name = $2;
+                       out->classes = $4;
+                       g_hash_table_insert(pc->target->themes, $2, out);
+               }
+               ;
+
+opacity                : OPACITY LB NUMBER RB { $$ = $3; }
+               ;
+
+material_props : /* empty */ { memset(&$$, 0, sizeof($$)); }
+               | material_props opacity {
+                       $$ = $1;
+                       $$.opacity = $2;
+               }
+               ;
+
+material_decl  : MATERIAL ID LCB material_props RCB {
+                       struct material *out;
+                       out = malloc(sizeof(struct material));
+                       *out = $4;
+                       g_hash_table_insert(pc->target->materials, $2, out);
+               }
+               ;
+
+anchor         : ANCHOR LB NUMBER NUMBER NUMBER RB {
+                       $$.x = $3;
+                       $$.y = $4;
+                       $$.z = $5;
+               }
+               ;
+
+up             : UP LB NUMBER NUMBER NUMBER RB {
+                       $$.x = $3;
+                       $$.y = $4;
+                       $$.z = $5;
+               }
+               ;
+
+spaceconstraints: /* empty */ { memset(&$$, 0, sizeof($$)); }
+               | spaceconstraints anchor { $1.anchor = $2; $$ = $1; }
+               | spaceconstraints up     { $1.up = $2; $$ = $1; }
+               ;
+
+space          : SPACE LCB spaceconstraints RCB {
+                       $$ = $3;
+               }
+               ;
+
+shape          : SHAPEOF LB ID RB
+               ;
+
+geometry_item  : /* empty */
+               | shape
+               ;
+
+geometry       : GEOMETRY LCB geometry_item RCB
+               ;
+
+material_use   : MATERIAL LB ID RB
+               ;
+
+classitem      : decor
+               ;
+
+classitems     : /* empty */ { $$.tree = NULL; $$.name = NULL; }
+               | classitems classitem {
+                       struct decor *out = malloc(sizeof(struct decor));
+                       *out = $2;
+                       $1.tree = g_slist_prepend($1.tree, out);
+                       $$ = $1;
+               }
+               ;
+
+classes                : /* empty */ { $$ = g_hash_table_new(g_str_hash, g_str_equal); }
+               | classes class {
+                       struct class *out = malloc(sizeof(struct class));
+                       *out = $2;
+                       $$ = $1;
+                       g_hash_table_insert($1, out->name, out);
+               }
+               ;
+
+class          : CLASS ID LCB classitems RCB {
+                       $$ = $4;
+                       $$.name = $2;
+               }
+               ;
+
+decoritems     : /* empty */ {
+                       memset(&$$, 0, sizeof($$));
+                       $$.space.up.y = -1;
+               }
+               | decoritems decor {
+                       struct decor *out = malloc(sizeof(struct decor));
+                       *out = $2;
+                       $$ = $1;
+                       $$.children = g_slist_append($1.children, out);
+               }
+               | decoritems space { $1.space = $2; $$ = $1; }
+               | decoritems material_use
+               | decoritems geometry
+               | decoritems texture
+               | decoritems context
+               | decoritems gradient
+               | decoritems cursor
+               ;
+
+               ;
+
+decor          : DECOR ID LCB decoritems RCB {
+                       $$ = $4;
+                       $$.name = $2;
+               }
+               ;
+
+texture                : TEXTURE LCB RCB
+               ;
+
+context                : CONTEXT LB ID RB
+               ;
+
+cursor         : CURSOR LB ID RB
+
+gradient       : GRADIENT LB ID RB
+               ;
+
+%%
diff --git a/theme.obtheme b/theme.obtheme
new file mode 100644 (file)
index 0000000..8d574fa
--- /dev/null
@@ -0,0 +1,62 @@
+//#include materials.obtheme
+
+material flat {
+       opacity(1)
+}
+
+theme awesome {
+       class regular_window {
+               decor clientwindow {
+                       space {
+                               anchor(10 9 8)
+                               up(1 0 0)
+                       }
+                       geometry {
+                               shapeof(client)
+                       }
+                       material(flat)
+                       texture { //$CLIENT.contents
+                       }
+
+                       decor titlebar {
+                               context(OB_FRAME_CONTEXT_TITLEBAR)
+                               geometry {
+                               //      box (0, 0, 0) to (100% of $CLIENT, 100%, 0)
+                               }
+                               material(flat)
+                               gradient(split)
+//texture {
+                               decor title {
+                                       geometry {
+//                                             text(client.title)
+//                                             justify(center)
+                                       }
+                               }
+                               decor minbutton {
+                                       material(none)
+                                       context(OB_FRAME_CONTEXT_MINIMIZE)
+                               }
+                               decor maxbutton {
+                                       material(none)
+                                       context(OB_FRAME_CONTEXT_MAXIMIZE)
+                               }
+                       }
+                       decor handle {
+                               space {
+                                       anchor(0 0 0)
+                                       up(0 0 0)
+                               }
+                               decor leftgrip {
+                                       context(OB_FRAME_CONTEXT_BLCORNER)
+                                       cursor(SOUTHWEST)
+                               }
+                               decor rightgrip {
+                                       context(OB_FRAME_CONTEXT_BRCORNER)
+                                       cursor(SOUTHEAST)
+                               }
+                               context(OB_FRAME_CONTEXT_BOTTOM)
+                               cursor(SOUTH)
+                       }
+               }
+       }
+}