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 +#include +#include +#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 + */ +{INCLUDE} { + g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); + BEGIN(INCLUDE); +} +{WHITESPACE} {} + +\"{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: %s\nError: %s", + 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 + */ + {ASTERIX} { g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); BEGIN(DEFAULTS); @@ -324,10 +404,24 @@ if ( queue == NULL ){ return T_HIGHLIGHT_STYLE; } <> { - 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: %s\nError: %s", + 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: %s\nError: %s", - 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 ) {