summaryrefslogtreecommitdiffstats
path: root/lexer
diff options
context:
space:
mode:
authorDave Davenport <qball@gmpclient.org>2017-03-13 08:54:55 +0100
committerDave Davenport <qball@gmpclient.org>2017-03-13 08:54:55 +0100
commitbe036f086d578146a7d9d1f119fb1d3eb4bd5bab (patch)
treea37c4205f10ad21d4795e93514d51f5fd8028bd3 /lexer
parentb7f4b7484ff755febb471b7c46df2a47993c1e34 (diff)
Reset location when importing, correctly resolve relative path
Diffstat (limited to 'lexer')
-rw-r--r--lexer/theme-lexer.l28
-rw-r--r--lexer/theme-parser.y7
2 files changed, 27 insertions, 8 deletions
diff --git a/lexer/theme-lexer.l b/lexer/theme-lexer.l
index 038d2a03..fae85b1b 100644
--- a/lexer/theme-lexer.l
+++ b/lexer/theme-lexer.l
@@ -29,12 +29,14 @@ typedef struct _ParseObject {
/** File pointer */
FILE *filein;
+ char *filename;
/** Length of string */
int str_len;
/** String */
const char *input_str;
-
+ /** Position in file */
+ YYLTYPE location;
} ParseObject;
GQueue *file_queue = NULL;
@@ -182,23 +184,37 @@ if ( queue == NULL ){
<INCLUDE>\"{STRING}\" {
yytext[yyleng-1] = '\0';
+ ParseObject *top = g_queue_peek_head ( file_queue );
+ g_assert ( top != NULL );
char *filename = rofi_expand_path ( &yytext[1] );
+ // If no absolute path specified, expand it.
+ if ( ! g_path_is_absolute ( filename ) && top->type == PT_FILE ) {
+ char *basedir = g_path_get_dirname ( top->filename );
+ char *path = g_build_filename ( basedir, filename, NULL );
+ g_free ( filename);
+ filename = path;
+ g_free ( basedir );
+ }
FILE *f = fopen ( filename, "rb" );
if ( f ) {
+ top->location = *yylloc;
ParseObject *po = g_malloc0(sizeof(ParseObject));
po->type = PT_FILE;
+ po->filename = filename;
po->filein = f;
current = po;
g_queue_push_head ( file_queue, po );
yypush_buffer_state (yy_create_buffer ( 0, YY_BUF_SIZE ));
+ yylloc->first_line = yylloc->last_line = 1;
+ yylloc->first_column = yylloc->last_column = 1;
} 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);
}
- g_free(filename);
// Pop out of include. */
BEGIN(GPOINTER_TO_INT(g_queue_pop_head ( queue )));
}
@@ -408,6 +424,7 @@ if ( queue == NULL ){
if ( po ) {
if ( po->type == PT_FILE ){
fclose ( po->filein );
+ g_free ( po->filename );
}
g_free ( po );
}
@@ -420,6 +437,7 @@ if ( queue == NULL ){
} else {
yypop_buffer_state();
current = po;
+ *yylloc = current->location;
BEGIN(GPOINTER_TO_INT ( g_queue_pop_head ( queue )));
}
}
@@ -447,8 +465,8 @@ if ( queue == NULL ){
<DEFAULTS>. {
return T_ERROR_DEFAULTS;
}
-<*>. {
- return T_ERROR;
+<INCLUDE>. {
+ return T_ERROR_INCLUDE;
}
%%
@@ -469,13 +487,13 @@ gboolean rofi_theme_parse_file ( const char *file )
file_queue = g_queue_new ();
ParseObject *po = g_malloc0(sizeof(ParseObject));
po->type = PT_FILE;
+ po->filename = filename;
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.
diff --git a/lexer/theme-parser.y b/lexer/theme-parser.y
index fcbc0f49..81a91486 100644
--- a/lexer/theme-parser.y
+++ b/lexer/theme-parser.y
@@ -1,9 +1,9 @@
%define api.pure
+%define parse.error verbose
%locations
%glr-parser
%skeleton "glr.c"
%debug
-%error-verbose
%parse-param {const char *what}
%code requires {
#include "theme.h"
@@ -25,7 +25,7 @@ int yylex (YYSTYPE *, YYLTYPE *);
char *sval;
int bval;
ThemeColor colorval;
- ThemeWidget *theme;
+ ThemeWidget *theme;
GList *name_path;
Property *property;
GHashTable *property_list;
@@ -38,6 +38,7 @@ int yylex (YYSTYPE *, YYLTYPE *);
%token <ival> T_ERROR_ENTRY 3 "invalid property name"
%token <ival> T_ERROR_NAMESTRING 4 "invalid element name"
%token <ival> T_ERROR_DEFAULTS 5 "invalid defaults name"
+%token <ival> T_ERROR_INCLUDE 6 "invalid import value"
%token <ival> T_INT
%token <fval> T_DOUBLE
%token <sval> T_STRING
@@ -56,7 +57,7 @@ int yylex (YYSTYPE *, YYLTYPE *);
%token PSEP "property separator"
%token PCLOSE "property close"
%token NSEP "Name separator"
-%token NAME_PREFIX "Name element prefix ('#')"
+%token NAME_PREFIX "Element section ('# {name} { ... }')"
%token WHITESPACE "White space"
%token PDEFAULTS "Default settings section ( '* { ... }')"