summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Davenport <qball@gmpclient.org>2017-03-11 17:06:06 +0100
committerDave Davenport <qball@gmpclient.org>2017-03-11 17:06:06 +0100
commitb7f4b7484ff755febb471b7c46df2a47993c1e34 (patch)
tree7e1beeca9e69931a0a3f05e52f143cebe1a7c6ad
parent048d601a85089ee7a3020bc59a83be2ff0ee3296 (diff)
Some initial support for @import in theme and try to fall back when theme fails to load
-rw-r--r--include/theme.h5
-rw-r--r--lexer/theme-lexer.l214
-rw-r--r--source/rofi.c6
-rw-r--r--source/theme.c53
-rw-r--r--test/box-test.c4
-rw-r--r--test/scrollbar-test.c4
6 files changed, 212 insertions, 74 deletions
diff --git a/include/theme.h b/include/theme.h
index ae1fdf5d..6030b0e0 100644
--- a/include/theme.h
+++ b/include/theme.h
@@ -410,4 +410,9 @@ ThemeWidget *rofi_theme_find_widget ( const char *name, const char *state, gbool
*/
Property *rofi_theme_find_property ( ThemeWidget *widget, PropertyType type, const char *property, gboolean exact );
+/**
+ * Checks if a theme is set, or is empty.
+ * @returns TRUE when empty.
+ */
+gboolean rofi_theme_is_empty ( void );
#endif
diff --git a/lexer/theme-lexer.l b/lexer/theme-lexer.l
index 2f288367..038d2a03 100644
--- a/lexer/theme-lexer.l
+++ b/lexer/theme-lexer.l
@@ -3,41 +3,82 @@
%{
#include <stdio.h>
+#include <glib.h>
+#include <helper.h>
+#include "rofi.h"
#include "lexer/theme-parser.h"
int last_state = 0;
+
+/**
+ * Type of Object to parse.
+ */
+typedef enum {
+ /** Parse a file */
+ PT_FILE,
+ /** Parse a string */
+ PT_STRING
+} ParseType;
+
+/**
+ * Parse object
+ */
+typedef struct _ParseObject {
+ /** Type */
+ ParseType type;
+
+ /** File pointer */
+ FILE *filein;
+
+ /** Length of string */
+ int str_len;
+ /** String */
+ const char *input_str;
+
+} ParseObject;
+
+GQueue *file_queue = NULL;
GQueue *queue = NULL;
+ParseObject *current = NULL;
+
%}
%{
-int str_len = 0;
-char *input_str = NULL;
-
#define YY_INPUT(buf,result,max_size) \
{\
- if ( input_str == NULL ) { \
- errno =0; \
- while ( (result = (int) fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
- { \
- if( errno != EINTR) \
- { \
- YY_FATAL_ERROR( "input in flex scanner failed" ); \
- break; \
- } \
- errno=0; \
- clearerr(yyin); \
- } \
+ if ( current == NULL ) {\
+ result = YY_NULL;\
} else {\
- yy_size_t len = MIN (max_size, str_len);\
- if ( len > 0 ){\
- memcpy (buf, input_str, len);\
- input_str+=len;\
- str_len-=len;\
- result = len;\
- } else {\
- result = YY_NULL;\
- } \
+ switch ( current->type ) { \
+ case PT_FILE:\
+ {\
+ errno =0; \
+ while ( (result = (int) fread(buf, 1, max_size, current->filein))==0 && ferror(current->filein)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(current->filein); \
+ } \
+ break;\
+ }\
+ case PT_STRING:\
+ {\
+ yy_size_t len = MIN (max_size, current->str_len);\
+ if ( len > 0 ){\
+ memcpy (buf, current->input_str, len);\
+ current->input_str+=len;\
+ current->str_len-=len;\
+ result = len;\
+ } else {\
+ result = YY_NULL;\
+ } \
+ }\
+ }\
}\
}
@@ -77,6 +118,9 @@ ITALIC "italic"
LS_DASH "dash"
LS_SOLID "solid"
+INCLUDE "@import"
+
+%x INCLUDE
%x PROPERTIES
%x NAMESTR
%x ENTRY
@@ -94,7 +138,7 @@ if ( queue == NULL ){
<*>"//" {
int c;
- while ((c = input()) != EOF){
+ while ((c = input()) != 0){
if (c == '\n') {
yylloc->last_column = 1;
yylloc->last_line ++;
@@ -118,7 +162,7 @@ if ( queue == NULL ){
yylloc->last_line ++;
break;
}
- case EOF: nesting_depth = 0; break;
+ case 0: nesting_depth = 0; break;
default:
yylloc->last_column++;
;
@@ -127,6 +171,42 @@ if ( queue == NULL ){
YY_LLOC_START
}
+ /**
+ * HANDLE INCLUDES
+ */
+<INITIAL>{INCLUDE} {
+ g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) );
+ BEGIN(INCLUDE);
+}
+<INCLUDE>{WHITESPACE} {}
+
+<INCLUDE>\"{STRING}\" {
+ yytext[yyleng-1] = '\0';
+ char *filename = rofi_expand_path ( &yytext[1] );
+ FILE *f = fopen ( filename, "rb" );
+ if ( f ) {
+ ParseObject *po = g_malloc0(sizeof(ParseObject));
+ po->type = PT_FILE;
+ po->filein = f;
+ current = po;
+ g_queue_push_head ( file_queue, po );
+
+ yypush_buffer_state (yy_create_buffer ( 0, YY_BUF_SIZE ));
+ } else {
+ char *str = g_markup_printf_escaped ( "Failed to open theme: <i>%s</i>\nError: <b>%s</b>",
+ filename, strerror ( errno ) );
+ rofi_add_error_message ( g_string_new ( str ) );
+ g_free ( str );
+ }
+ g_free(filename);
+ // Pop out of include. */
+ BEGIN(GPOINTER_TO_INT(g_queue_pop_head ( queue )));
+}
+
+ /**
+ * END INCLUDES
+ */
+
<INITIAL>{ASTERIX} {
g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) );
BEGIN(DEFAULTS);
@@ -324,10 +404,24 @@ if ( queue == NULL ){
return T_HIGHLIGHT_STYLE;
}
<INITIAL><<EOF>> {
- g_queue_free ( queue );
- // Reset pointer to NULL
- queue = NULL;
- yyterminate();
+ ParseObject *po = g_queue_pop_head ( file_queue );
+ if ( po ) {
+ if ( po->type == PT_FILE ){
+ fclose ( po->filein );
+ }
+ g_free ( po );
+ }
+ po = g_queue_peek_head ( file_queue );
+ if ( po == NULL ) {
+ g_queue_free ( queue );
+ // Reset pointer to NULL
+ queue = NULL;
+ yyterminate();
+ } else {
+ yypop_buffer_state();
+ current = po;
+ BEGIN(GPOINTER_TO_INT ( g_queue_pop_head ( queue )));
+ }
}
<*>\n {
@@ -356,5 +450,63 @@ if ( queue == NULL ){
<*>. {
return T_ERROR;
}
-
%%
+
+gboolean rofi_theme_parse_file ( const char *file )
+{
+ char *filename = rofi_expand_path ( file );
+ yyin = fopen ( filename, "rb" );
+ if ( yyin == NULL ) {
+ char *str = g_markup_printf_escaped ( "Failed to open theme: <i>%s</i>\nError: <b>%s</b>",
+ filename, strerror ( errno ) );
+ rofi_add_error_message ( g_string_new ( str ) );
+ g_free ( str );
+ g_free ( filename );
+ return TRUE;
+ }
+
+ /** Add Parse object */
+ file_queue = g_queue_new ();
+ ParseObject *po = g_malloc0(sizeof(ParseObject));
+ po->type = PT_FILE;
+ po->filein = yyin;
+ current = po;
+ g_queue_push_head ( file_queue, po );
+
+ int parser_retv = yyparse ( file );
+ yylex_destroy ();
+ g_free ( filename );
+ yyin = NULL;
+
+ // Free up.
+ g_queue_free ( file_queue );
+ file_queue = NULL;
+ if ( parser_retv != 0 ) {
+ return TRUE;
+ }
+ return FALSE;
+}
+gboolean rofi_theme_parse_string ( const char *string )
+{
+ yyin = NULL;
+
+ /** Add Parse object */
+ file_queue = g_queue_new ();
+ ParseObject *po = g_malloc0(sizeof(ParseObject));
+ po->type = PT_STRING;
+ po->input_str = string;
+ po->str_len = strlen(string);
+ current = po;
+ g_queue_push_head ( file_queue, po );
+
+ int parser_retv = yyparse ( string );
+ yylex_destroy ();
+
+ // Free up.
+ g_queue_free ( file_queue );
+ file_queue = NULL;
+ if ( parser_retv != 0 ) {
+ return TRUE;
+ }
+ return FALSE;
+}
diff --git a/source/rofi.c b/source/rofi.c
index 7540dd9a..c2e4fc16 100644
--- a/source/rofi.c
+++ b/source/rofi.c
@@ -1090,9 +1090,6 @@ int main ( int argc, char *argv[] )
}
TICK_N ( "Parsed theme" );
}
- else {
- rofi_theme_convert_old_theme ( );
- }
const char ** theme_str = find_arg_strv ( "-theme-str" );
if ( theme_str ) {
@@ -1104,6 +1101,9 @@ int main ( int argc, char *argv[] )
}
g_free ( theme_str );
}
+ if ( rofi_theme_is_empty ( ) ) {
+ rofi_theme_convert_old_theme ( );
+ }
if ( find_arg ( "-dump-theme" ) >= 0 ) {
rofi_theme_print ( rofi_theme );
diff --git a/source/theme.c b/source/theme.c
index 4e33a9a1..8839128b 100644
--- a/source/theme.c
+++ b/source/theme.c
@@ -556,6 +556,18 @@ void distance_get_linestyle ( Distance d, cairo_t *draw )
}
}
+gboolean rofi_theme_is_empty ( void )
+{
+ if ( rofi_theme == NULL ) {
+ return TRUE;
+ }
+ if ( rofi_theme->properties == NULL && rofi_theme->num_widgets == 0 ) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
#ifdef THEME_CONVERTER
static Property* rofi_theme_convert_get_color ( const char *color, const char *name )
@@ -580,7 +592,7 @@ static void rofi_theme_convert_create_property_ht ( ThemeWidget *widget )
void rofi_theme_convert_old_theme ( void )
{
if ( rofi_theme != NULL ) {
- return;
+ rofi_theme_free ( rofi_theme );
}
rofi_theme = (ThemeWidget *) g_slice_new0 ( ThemeWidget );
rofi_theme->name = g_strdup ( "Root" );
@@ -857,43 +869,4 @@ void rofi_theme_convert_old_theme ( void )
}
}
}
-gboolean rofi_theme_parse_file ( const char *file )
-{
- char *filename = rofi_expand_path ( file );
- yyin = fopen ( filename, "rb" );
- if ( yyin == NULL ) {
- char *str = g_markup_printf_escaped ( "Failed to open theme: <i>%s</i>\nError: <b>%s</b>",
- filename, strerror ( errno ) );
- rofi_add_error_message ( g_string_new ( str ) );
- g_free ( str );
- g_free ( filename );
- return TRUE;
- }
- extern int str_len;
- extern const char*input_str;
- str_len = 0;
- input_str = NULL;
- int parser_retv = yyparse ( file );
- yylex_destroy ();
- g_free ( filename );
- yyin = NULL;
- if ( parser_retv != 0 ) {
- return TRUE;
- }
- return FALSE;
-}
-gboolean rofi_theme_parse_string ( const char *string )
-{
- extern int str_len;
- extern const char*input_str;
- yyin = NULL;
- input_str = string;
- str_len = strlen ( string );
- int parser_retv = yyparse ( string );
- yylex_destroy ();
- if ( parser_retv != 0 ) {
- return TRUE;
- }
- return FALSE;
-}
#endif
diff --git a/test/box-test.c b/test/box-test.c
index a4f038c1..0e943d24 100644
--- a/test/box-test.c
+++ b/test/box-test.c
@@ -23,6 +23,10 @@ unsigned int test =0;
} \
}
+char * rofi_expand_path ( const char *path )
+{
+
+}
void rofi_add_error_message ( GString *msg )
{
}
diff --git a/test/scrollbar-test.c b/test/scrollbar-test.c
index 43b77539..297bff98 100644
--- a/test/scrollbar-test.c
+++ b/test/scrollbar-test.c
@@ -25,6 +25,10 @@ unsigned int test =0;
void rofi_add_error_message ( GString *msg )
{}
+char * rofi_expand_path ( const char *path )
+{
+
+}
int textbox_get_estimated_char_height ( void );
int textbox_get_estimated_char_height ( void )
{