2016-12-12 15:55:31 +00:00
|
|
|
%define api.pure
|
2017-03-13 07:54:55 +00:00
|
|
|
%define parse.error verbose
|
2017-01-09 21:29:31 +00:00
|
|
|
%locations
|
2016-12-12 22:40:43 +00:00
|
|
|
%glr-parser
|
2016-12-11 13:08:28 +00:00
|
|
|
%skeleton "glr.c"
|
2016-12-09 18:49:49 +00:00
|
|
|
%debug
|
2017-01-09 21:29:31 +00:00
|
|
|
%parse-param {const char *what}
|
2016-12-09 18:49:49 +00:00
|
|
|
%code requires {
|
|
|
|
#include "theme.h"
|
2017-03-13 15:42:17 +00:00
|
|
|
|
|
|
|
typedef struct YYLTYPE {
|
|
|
|
int first_line;
|
|
|
|
int first_column;
|
|
|
|
int last_line;
|
|
|
|
int last_column;
|
|
|
|
char *filename;
|
|
|
|
} YYLTYPE;
|
|
|
|
# define YYLTYPE_IS_DECLARED 1 /* alert the parser that we have our own definition */
|
|
|
|
|
|
|
|
# define YYLLOC_DEFAULT(Current, Rhs, N) \
|
|
|
|
do \
|
|
|
|
if (N) \
|
|
|
|
{ \
|
|
|
|
(Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
|
|
|
|
(Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
|
|
|
|
(Current).last_line = YYRHSLOC (Rhs, N).last_line; \
|
|
|
|
(Current).last_column = YYRHSLOC (Rhs, N).last_column; \
|
|
|
|
(Current).filename = YYRHSLOC (Rhs, 1).filename; \
|
|
|
|
} \
|
|
|
|
else \
|
|
|
|
{ /* empty RHS */ \
|
|
|
|
(Current).first_line = (Current).last_line = \
|
|
|
|
YYRHSLOC (Rhs, 0).last_line; \
|
|
|
|
(Current).first_column = (Current).last_column = \
|
|
|
|
YYRHSLOC (Rhs, 0).last_column; \
|
|
|
|
(Current).filename = NULL; /* new */ \
|
|
|
|
} \
|
|
|
|
while (0)
|
2016-12-09 18:49:49 +00:00
|
|
|
}
|
|
|
|
%{
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2016-12-31 20:37:19 +00:00
|
|
|
#include <glib.h>
|
2016-12-09 18:49:49 +00:00
|
|
|
|
2016-12-12 15:55:31 +00:00
|
|
|
#include "lexer/theme-parser.h"
|
2017-01-01 17:08:49 +00:00
|
|
|
ThemeWidget *rofi_theme = NULL;
|
2017-01-09 21:29:31 +00:00
|
|
|
void yyerror(YYLTYPE *yylloc, const char *what, const char* s);
|
2016-12-12 15:55:31 +00:00
|
|
|
int yylex (YYSTYPE *, YYLTYPE *);
|
2016-12-09 18:49:49 +00:00
|
|
|
%}
|
|
|
|
|
|
|
|
%union {
|
|
|
|
int ival;
|
|
|
|
double fval;
|
|
|
|
char *sval;
|
|
|
|
int bval;
|
2016-12-10 18:48:44 +00:00
|
|
|
ThemeColor colorval;
|
2017-03-13 07:54:55 +00:00
|
|
|
ThemeWidget *theme;
|
2016-12-09 18:49:49 +00:00
|
|
|
GList *name_path;
|
|
|
|
Property *property;
|
|
|
|
GHashTable *property_list;
|
2016-12-31 21:47:22 +00:00
|
|
|
Distance distance;
|
2016-12-09 18:49:49 +00:00
|
|
|
}
|
|
|
|
|
2017-01-09 21:29:31 +00:00
|
|
|
%token <ival> T_END 0 "end of file"
|
|
|
|
%token <ival> T_ERROR 1 "error from file parser"
|
|
|
|
%token <ival> T_ERROR_PROPERTY 2 "invalid property value"
|
2017-03-13 09:49:33 +00:00
|
|
|
%token <ival> T_ERROR_SECTION 3 "invalid property name"
|
2017-01-09 21:29:31 +00:00
|
|
|
%token <ival> T_ERROR_NAMESTRING 4 "invalid element name"
|
|
|
|
%token <ival> T_ERROR_DEFAULTS 5 "invalid defaults name"
|
2017-03-13 07:54:55 +00:00
|
|
|
%token <ival> T_ERROR_INCLUDE 6 "invalid import value"
|
2016-12-09 18:49:49 +00:00
|
|
|
%token <ival> T_INT
|
2016-12-09 21:16:31 +00:00
|
|
|
%token <fval> T_DOUBLE
|
2016-12-09 18:49:49 +00:00
|
|
|
%token <sval> T_STRING
|
2017-01-09 21:29:31 +00:00
|
|
|
%token <sval> N_STRING "property name"
|
2017-01-06 23:23:39 +00:00
|
|
|
%token <ival> T_POSITION;
|
2017-01-08 23:09:02 +00:00
|
|
|
%token <ival> T_HIGHLIGHT_STYLE
|
2017-01-08 15:09:24 +00:00
|
|
|
%token <sval> NAME_ELEMENT "Element name"
|
2016-12-09 18:49:49 +00:00
|
|
|
%token <bval> T_BOOLEAN
|
|
|
|
%token <colorval> T_COLOR
|
2016-12-31 21:47:22 +00:00
|
|
|
%token <distance> T_PIXEL
|
2017-01-05 17:22:34 +00:00
|
|
|
%token <sval> T_LINK
|
2016-12-12 22:40:43 +00:00
|
|
|
%token <sval> FIRST_NAME
|
2016-12-09 18:49:49 +00:00
|
|
|
|
2017-01-09 17:32:26 +00:00
|
|
|
%token BOPEN "bracket open"
|
|
|
|
%token BCLOSE "bracket close"
|
|
|
|
%token PSEP "property separator"
|
|
|
|
%token PCLOSE "property close"
|
|
|
|
%token NSEP "Name separator"
|
2017-03-13 07:54:55 +00:00
|
|
|
%token NAME_PREFIX "Element section ('# {name} { ... }')"
|
2017-01-09 17:32:26 +00:00
|
|
|
%token WHITESPACE "White space"
|
|
|
|
%token PDEFAULTS "Default settings section ( '* { ... }')"
|
2017-03-27 07:04:55 +00:00
|
|
|
%token CONFIGURATION "Configuration block"
|
2016-12-09 18:49:49 +00:00
|
|
|
|
2017-01-08 23:09:02 +00:00
|
|
|
%type <ival> highlight_styles
|
2016-12-09 21:16:31 +00:00
|
|
|
%type <sval> entry
|
2016-12-09 18:49:49 +00:00
|
|
|
%type <sval> pvalue
|
2016-12-09 21:16:31 +00:00
|
|
|
%type <theme> entries
|
2016-12-09 18:49:49 +00:00
|
|
|
%type <name_path> name_path
|
|
|
|
%type <property> property
|
|
|
|
%type <property_list> property_list
|
|
|
|
%type <property_list> optional_properties
|
2017-01-06 23:23:39 +00:00
|
|
|
%start entries
|
2016-12-09 18:49:49 +00:00
|
|
|
|
|
|
|
%%
|
|
|
|
|
|
|
|
entries:
|
2016-12-09 21:16:31 +00:00
|
|
|
%empty {
|
2016-12-09 18:49:49 +00:00
|
|
|
// There is always a base widget.
|
2017-01-08 15:09:24 +00:00
|
|
|
if (rofi_theme == NULL ){
|
2017-03-04 19:09:19 +00:00
|
|
|
$$ = rofi_theme = g_slice_new0 ( ThemeWidget );
|
2017-01-08 15:09:24 +00:00
|
|
|
rofi_theme->name = g_strdup ( "Root" );
|
|
|
|
}
|
2016-12-09 18:49:49 +00:00
|
|
|
}
|
2016-12-16 08:28:13 +00:00
|
|
|
| entries
|
|
|
|
entry {
|
|
|
|
}
|
2016-12-09 18:49:49 +00:00
|
|
|
;
|
|
|
|
|
|
|
|
entry:
|
2017-01-06 22:25:55 +00:00
|
|
|
NAME_PREFIX name_path BOPEN optional_properties BCLOSE
|
2016-12-12 20:14:57 +00:00
|
|
|
{
|
2017-01-01 17:08:49 +00:00
|
|
|
ThemeWidget *widget = rofi_theme;
|
2016-12-12 20:14:57 +00:00
|
|
|
for ( GList *iter = g_list_first ( $2 ); iter ; iter = g_list_next ( iter ) ) {
|
2017-01-04 14:05:39 +00:00
|
|
|
widget = rofi_theme_find_or_create_name ( widget, iter->data );
|
2016-12-12 20:14:57 +00:00
|
|
|
}
|
|
|
|
g_list_foreach ( $2, (GFunc)g_free , NULL );
|
|
|
|
g_list_free ( $2 );
|
2016-12-12 23:09:51 +00:00
|
|
|
widget->set = TRUE;
|
2017-01-06 22:25:55 +00:00
|
|
|
rofi_theme_widget_add_properties ( widget, $4);
|
2017-01-06 22:41:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
PDEFAULTS BOPEN optional_properties BCLOSE {
|
|
|
|
rofi_theme_widget_add_properties ( rofi_theme, $3);
|
|
|
|
}
|
2017-03-27 07:04:55 +00:00
|
|
|
| CONFIGURATION BOPEN optional_properties BCLOSE {
|
|
|
|
GHashTableIter iter;
|
|
|
|
g_hash_table_iter_init ( &iter, $3 );
|
|
|
|
gpointer key,value;
|
|
|
|
while ( g_hash_table_iter_next ( &iter, &key, &value ) ) {
|
|
|
|
Property *p = (Property *) value;
|
|
|
|
switch ( p ->type )
|
|
|
|
{
|
|
|
|
case P_STRING:
|
|
|
|
config_parser_set_option ( p->name, p->value.s);
|
|
|
|
break;
|
|
|
|
case P_BOOLEAN:
|
|
|
|
config_parser_set_option ( p->name, p->value.b?"true":"false");
|
|
|
|
break;
|
|
|
|
case P_INTEGER:
|
|
|
|
{
|
|
|
|
char *str = g_strdup_printf("%d", p->value.i);
|
|
|
|
config_parser_set_option ( p->name, str );
|
|
|
|
g_free(str);
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-01-06 22:41:10 +00:00
|
|
|
;
|
2016-12-09 18:49:49 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* properties
|
|
|
|
*/
|
|
|
|
optional_properties
|
|
|
|
: %empty { $$ = NULL; }
|
|
|
|
| property_list { $$ = $1; }
|
2016-12-09 21:16:31 +00:00
|
|
|
;
|
2016-12-09 18:49:49 +00:00
|
|
|
|
2016-12-09 21:16:31 +00:00
|
|
|
property_list:
|
2016-12-09 18:49:49 +00:00
|
|
|
property {
|
2016-12-09 21:16:31 +00:00
|
|
|
$$ = g_hash_table_new_full ( g_str_hash, g_str_equal, NULL, (GDestroyNotify)rofi_theme_property_free );
|
2016-12-09 18:49:49 +00:00
|
|
|
g_hash_table_replace ( $$, $1->name, $1 );
|
|
|
|
}
|
|
|
|
| property_list property {
|
|
|
|
// Old will be free'ed, and key/value will be replaced.
|
|
|
|
g_hash_table_replace ( $$, $2->name, $2 );
|
|
|
|
}
|
|
|
|
;
|
|
|
|
|
|
|
|
property
|
|
|
|
: pvalue PSEP T_INT PCLOSE {
|
|
|
|
$$ = rofi_theme_property_create ( P_INTEGER );
|
|
|
|
$$->name = $1;
|
2016-12-09 21:16:31 +00:00
|
|
|
$$->value.i = $3;
|
2016-12-09 18:49:49 +00:00
|
|
|
}
|
2016-12-09 21:16:31 +00:00
|
|
|
| pvalue PSEP T_DOUBLE PCLOSE {
|
|
|
|
$$ = rofi_theme_property_create ( P_DOUBLE );
|
2016-12-09 18:49:49 +00:00
|
|
|
$$->name = $1;
|
2016-12-09 21:16:31 +00:00
|
|
|
$$->value.f = $3;
|
2016-12-09 18:49:49 +00:00
|
|
|
}
|
2016-12-09 21:16:31 +00:00
|
|
|
| pvalue PSEP T_COLOR PCLOSE {
|
2016-12-09 18:49:49 +00:00
|
|
|
$$ = rofi_theme_property_create ( P_COLOR );
|
|
|
|
$$->name = $1;
|
2016-12-09 21:16:31 +00:00
|
|
|
$$->value.color = $3;
|
2016-12-09 18:49:49 +00:00
|
|
|
}
|
2016-12-09 21:16:31 +00:00
|
|
|
| pvalue PSEP T_STRING PCLOSE {
|
2016-12-09 18:49:49 +00:00
|
|
|
$$ = rofi_theme_property_create ( P_STRING );
|
|
|
|
$$->name = $1;
|
2016-12-09 21:16:31 +00:00
|
|
|
$$->value.s = $3;
|
2016-12-09 18:49:49 +00:00
|
|
|
}
|
2017-01-05 17:22:34 +00:00
|
|
|
| pvalue PSEP T_LINK PCLOSE {
|
|
|
|
$$ = rofi_theme_property_create ( P_LINK );
|
|
|
|
$$->name = $1;
|
|
|
|
$$->value.link.name = $3;
|
|
|
|
}
|
2016-12-09 18:49:49 +00:00
|
|
|
| pvalue PSEP T_BOOLEAN PCLOSE {
|
|
|
|
$$ = rofi_theme_property_create ( P_BOOLEAN );
|
|
|
|
$$->name = $1;
|
2016-12-09 21:16:31 +00:00
|
|
|
$$->value.b = $3;
|
2016-12-09 18:49:49 +00:00
|
|
|
}
|
2016-12-31 20:37:19 +00:00
|
|
|
| pvalue PSEP T_PIXEL PCLOSE {
|
|
|
|
$$ = rofi_theme_property_create ( P_PADDING );
|
|
|
|
$$->name = $1;
|
2016-12-31 21:47:22 +00:00
|
|
|
$$->value.padding = (Padding){ $3, $3, $3, $3 };
|
2016-12-31 20:37:19 +00:00
|
|
|
}
|
2017-01-01 00:31:25 +00:00
|
|
|
| pvalue PSEP T_PIXEL T_PIXEL PCLOSE {
|
|
|
|
$$ = rofi_theme_property_create ( P_PADDING );
|
|
|
|
$$->name = $1;
|
|
|
|
$$->value.padding = (Padding){ $3, $4, $3, $4 };
|
|
|
|
}
|
|
|
|
| pvalue PSEP T_PIXEL T_PIXEL T_PIXEL PCLOSE {
|
|
|
|
$$ = rofi_theme_property_create ( P_PADDING );
|
|
|
|
$$->name = $1;
|
|
|
|
$$->value.padding = (Padding){ $3, $4, $5, $4 };
|
|
|
|
}
|
2016-12-31 20:37:19 +00:00
|
|
|
| pvalue PSEP T_PIXEL T_PIXEL T_PIXEL T_PIXEL PCLOSE {
|
|
|
|
$$ = rofi_theme_property_create ( P_PADDING );
|
|
|
|
$$->name = $1;
|
2016-12-31 21:47:22 +00:00
|
|
|
$$->value.padding = (Padding){ $3, $4, $5, $6 };
|
2016-12-31 20:37:19 +00:00
|
|
|
}
|
2017-01-06 18:04:25 +00:00
|
|
|
| pvalue PSEP T_POSITION PCLOSE{
|
|
|
|
$$ = rofi_theme_property_create ( P_POSITION );
|
|
|
|
$$->name = $1;
|
|
|
|
$$->value.i = $3;
|
|
|
|
}
|
2017-01-08 23:09:02 +00:00
|
|
|
| pvalue PSEP highlight_styles T_COLOR PCLOSE {
|
|
|
|
$$ = rofi_theme_property_create ( P_HIGHLIGHT );
|
|
|
|
$$->name = $1;
|
|
|
|
$$->value.highlight.style = $3|HL_COLOR;
|
|
|
|
$$->value.highlight.color = $4;
|
|
|
|
}
|
|
|
|
| pvalue PSEP highlight_styles PCLOSE {
|
|
|
|
$$ = rofi_theme_property_create ( P_HIGHLIGHT );
|
|
|
|
$$->name = $1;
|
|
|
|
$$->value.highlight.style = $3;
|
|
|
|
}
|
2016-12-09 18:49:49 +00:00
|
|
|
;
|
|
|
|
|
2017-01-08 23:09:02 +00:00
|
|
|
highlight_styles:
|
|
|
|
T_HIGHLIGHT_STYLE { $$ = $1; }
|
|
|
|
| highlight_styles T_HIGHLIGHT_STYLE {
|
|
|
|
$$ = $1 | $2;
|
|
|
|
}
|
|
|
|
;
|
2016-12-09 18:49:49 +00:00
|
|
|
pvalue: N_STRING { $$ = $1; }
|
|
|
|
|
|
|
|
name_path:
|
2016-12-12 22:40:43 +00:00
|
|
|
NAME_ELEMENT { $$ = g_list_append ( NULL, $1 );}
|
|
|
|
| name_path NSEP NAME_ELEMENT { $$ = g_list_append ( $1, $3);}
|
2017-01-06 22:25:55 +00:00
|
|
|
| name_path NSEP { $$ = $1; }
|
2016-12-09 18:49:49 +00:00
|
|
|
;
|
|
|
|
|
|
|
|
%%
|
|
|
|
|