1
0
Fork 0
mirror of https://github.com/davatorium/rofi.git synced 2024-11-11 13:50:48 -05:00
rofi/lexer/theme-lexer.l

743 lines
22 KiB
Text
Raw Normal View History

/*
* rofi
*
* MIT/X11 License
* Copyright 2013-2017 Qball Cow <qball@gmpclient.org>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
%option nodefault noyywrap
%option nostdinit
%option nounput
%option never-interactive
2016-12-12 10:55:31 -05:00
%option bison-locations
2016-12-09 13:49:49 -05:00
%{
#include <stdio.h>
#include <glib.h>
#include <gio/gio.h>
#include <helper.h>
#include <math.h>
#include "rofi.h"
2017-05-04 01:56:40 -04:00
#include "theme.h"
2016-12-09 13:49:49 -05:00
#include "theme-parser.h"
2017-03-13 05:49:33 -04:00
#define LOG_DOMAIN "Parser"
2016-12-17 10:16:28 -05:00
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;
char *filename;
/** Length of string */
int str_len;
/** String */
const char *input_str;
/** Position in file */
YYLTYPE location;
} ParseObject;
2017-03-13 05:49:33 -04:00
GList *imported_files = NULL;
2017-03-13 05:49:33 -04:00
GList *prev_imported_files = NULL;
GQueue *file_queue = NULL;
2016-12-17 10:16:28 -05:00
GQueue *queue = NULL;
2016-12-09 13:49:49 -05:00
ParseObject *current = NULL;
static char * rofi_theme_parse_prepare_file ( const char *file, const char *parent_file );
#define IN_RANGE(index,low,high) ( ( (index) > (low) )? ( ( (index) < (high) )? (index):(high) ) : ( low ) )
static double hue2rgb(double p, double q, double t){
t += (t<0)?1:0;
t -= (t>1)?1:0;
if( t < (1/6.0) ) {
return p + (q - p) * 6 * t;
}
if( t < (1/2.0) ) {
return q;
}
if( t < (2/3.0) ) {
return p + (q - p) * (2/3.0 - t) * 6;
}
return p;
}
static ThemeColor hsl_to_rgb ( double h, double s, double l )
{
ThemeColor colour;
if(s < 0.001 && s > -0.001){
colour.red = colour.green = colour.blue = l; // achromatic
}else{
double q = l < 0.5 ? l * (1 + s) : l + s - l * s;
double p = 2 * l - q;
colour.red = hue2rgb(p, q, h + 1/3.0);
colour.green = hue2rgb(p, q, h);
colour.blue = hue2rgb(p, q, h - 1/3.0);
}
return colour;
}
2016-12-12 10:55:31 -05:00
%}
%{
#define YY_INPUT(buf,result,max_size) \
{\
if ( current == NULL ) {\
result = 0;\
} else {\
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 = 0;\
}\
}\
}\
}\
}
2016-12-12 10:55:31 -05:00
#define YY_USER_ACTION {\
yylloc->last_column+= yyleng;\
}
#define YY_LLOC_START {\
2017-01-05 16:04:39 -05:00
yylloc->first_line = yylloc->last_line;\
yylloc->first_column = yylloc->last_column;\
2016-12-12 10:55:31 -05:00
}
2016-12-09 13:49:49 -05:00
%}
ASC [\x00-\x7f]
ASCN [\x00-\t\v-\x7f]
U [\x80-\xbf]
U2 [\xc2-\xdf]
U3 [\xe0-\xef]
U4 [\xf0-\xf4]
// UANY {ASC}|{U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U}
UANYN {ASCN}|{U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U}
// UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U}
2017-01-05 16:04:39 -05:00
WHITESPACE [[:blank:]]
WSO [[:blank:]]*
WORD [[:alnum:]-]+
STRING {UANYN}+
HEX [[:xdigit:]]
NUMBER [[:digit:]]
2017-01-11 17:19:29 -05:00
PNNUMBER [-+]?[[:digit:]]+
REAL [-+]?[[:digit:]]+(\.[[:digit:]]+)?
PX (px)
2016-12-31 16:47:22 -05:00
EM (em)
PERCENT (\%)
2017-01-06 17:41:10 -05:00
ASTERIX \*
CENTER "center"
NORTH "north"
SOUTH "south"
EAST "east"
WEST "west"
NONE "none"
BOLD "bold"
UNDERLINE "underline"
ITALIC "italic"
2017-01-04 16:27:27 -05:00
LS_DASH "dash"
LS_SOLID "solid"
INCLUDE "@import"
2017-03-29 13:54:13 -04:00
CONFIGURATION "configuration"
%x INCLUDE
%x PROPERTIES
%x NAMESTR
2017-03-13 05:49:33 -04:00
%x SECTION
2017-01-06 17:41:10 -05:00
%x DEFAULTS
2016-12-09 13:49:49 -05:00
%%
2016-12-12 10:55:31 -05:00
%{
YY_LLOC_START
%}
2016-12-17 10:16:28 -05:00
%{
if ( queue == NULL ){
queue = g_queue_new ( );
yylloc->filename = current->filename;
2017-03-28 03:19:04 -04:00
// unsure why todo this.
yylloc->first_line = yylloc->last_line = 1;
yylloc->first_column = yylloc->last_column = 1;
2016-12-17 10:16:28 -05:00
}
%}
2017-01-05 16:04:39 -05:00
2017-03-13 05:49:33 -04:00
/**
* General code for handling comments.
* Both C and C++ style comments, including nexting.
*/
2016-12-17 10:16:28 -05:00
<*>"//" {
int c = input();
while ( c != 0 && c != EOF){
2016-12-11 12:25:47 -05:00
if (c == '\n') {
2016-12-12 10:55:31 -05:00
yylloc->last_column = 1;
yylloc->last_line ++;
2016-12-11 12:25:47 -05:00
break;
}
2016-12-12 10:55:31 -05:00
yylloc->last_column++;
c = input();
2016-12-12 10:55:31 -05:00
}
YY_LLOC_START
2016-12-11 12:25:47 -05:00
}
2016-12-17 10:16:28 -05:00
<*>"/*" {
2016-12-11 12:25:47 -05:00
int c = 0, p;
int nesting_depth = 1;
while (nesting_depth) {
p = c;
c = input();
switch (c) {
2016-12-12 10:55:31 -05:00
case '*': yylloc->last_column++; if (p == '/') { c = 0; nesting_depth++; } break;
case '/': yylloc->last_column++; if (p == '*') { c = 0; nesting_depth--; } break;
case '\n': {
yylloc->last_column = 1;
yylloc->last_line ++;
break;
}
case 0: nesting_depth = 0; break;
case EOF: nesting_depth = 0; break;
2016-12-12 10:55:31 -05:00
default:
yylloc->last_column++;
;
2016-12-11 12:25:47 -05:00
}
}
2016-12-12 10:55:31 -05:00
YY_LLOC_START
2016-12-11 12:25:47 -05:00
}
/**
* HANDLE INCLUDES
*/
<INITIAL>{INCLUDE} {
g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) );
BEGIN(INCLUDE);
}
2017-03-13 05:49:33 -04:00
/** Skip all whitespace */
<INCLUDE>{WHITESPACE} {}
2017-03-13 05:49:33 -04:00
/** Parse path. Last element in this INCLUDE */
<INCLUDE>\"{STRING}\" {
yytext[yyleng-1] = '\0';
ParseObject *top = g_queue_peek_head ( file_queue );
g_assert ( top != NULL );
char *filename = rofi_theme_parse_prepare_file ( &yytext[1], top->filename );
if ( g_list_find_custom ( imported_files, filename, (GCompareFunc)g_strcmp0 ) != NULL ) {
g_log ( LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Skipping file: '%s' already parsed.", filename );
} else {
g_log ( LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Parsing file: '%s'", filename );
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 );
imported_files = g_list_append ( imported_files, po->filename );
yypush_buffer_state (yy_create_buffer ( 0, YY_BUF_SIZE ));
yylloc->first_line = yylloc->last_line = 1;
yylloc->first_column = yylloc->last_column = 1;
yylloc->filename = current->filename;
} 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 )));
}
2017-03-13 05:49:33 -04:00
/** Everythin not yet parsed is an error. */
<INCLUDE>. {
return T_ERROR_INCLUDE;
}
/**
* END INCLUDES
*/
2017-03-13 05:49:33 -04:00
/**
* Handle defaults: * { ... }
*/
<INITIAL>{CONFIGURATION} {
g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) );
BEGIN(DEFAULTS);
return CONFIGURATION;
}
2017-01-06 17:41:10 -05:00
<INITIAL>{ASTERIX} {
g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) );
BEGIN(DEFAULTS);
return PDEFAULTS;
}
2017-03-13 05:49:33 -04:00
/** Skip all whitespace */
2017-01-06 17:41:10 -05:00
<DEFAULTS>{WHITESPACE} {}
<DEFAULTS>"\{" {
g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) );
2017-03-13 05:49:33 -04:00
BEGIN(SECTION);
2017-01-06 17:41:10 -05:00
return BOPEN;
}
2017-03-13 05:49:33 -04:00
/** Everythin not yet parsed is an error. */
<DEFAULTS>. {
return T_ERROR_DEFAULTS;
}
2017-01-06 17:41:10 -05:00
2017-03-13 05:49:33 -04:00
<INITIAL>"#" { g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); BEGIN(NAMESTR);return NAME_PREFIX;}
/* Go into parsing an section*/
<NAMESTR>"\{" {
2016-12-17 10:16:28 -05:00
g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) );
2017-03-13 05:49:33 -04:00
BEGIN(SECTION);
2016-12-17 10:16:28 -05:00
return BOPEN;
}
2017-03-13 05:49:33 -04:00
/* Pop out of parsing an section. */
<SECTION>"\}" {
g_queue_pop_head ( queue );
2016-12-17 10:16:28 -05:00
BEGIN(GPOINTER_TO_INT(g_queue_pop_head ( queue )));
return BCLOSE;
}
<NAMESTR>\.|{WHITESPACE} { return NSEP; }
2017-03-13 05:49:33 -04:00
<SECTION>{WORD} { yylval->sval = g_strdup(yytext); return N_STRING;}
2016-12-17 10:16:28 -05:00
<NAMESTR>{WORD} { yylval->sval = g_strdup(yytext); return NAME_ELEMENT;}
2017-03-13 05:49:33 -04:00
/* After Namestr/Classstr we want to go to state str, then to { */
<INITIAL,SECTION>{WHITESPACE}+ ; // ignore all whitespace
<PROPERTIES>{WHITESPACE}+ ; // ignore all whitespace
2017-03-13 05:49:33 -04:00
<SECTION>":" { g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); BEGIN(PROPERTIES); return PSEP; }
2016-12-17 10:16:28 -05:00
<PROPERTIES>";" { BEGIN(GPOINTER_TO_INT ( g_queue_pop_head ( queue ))); return PCLOSE;}
<PROPERTIES>(true|false) { yylval->bval= g_strcmp0(yytext, "true") == 0; return T_BOOLEAN;}
2017-04-05 15:27:35 -04:00
<PROPERTIES>{PNNUMBER} { yylval->ival = (int)g_ascii_strtoll(yytext, NULL, 10); return T_INT;}
<PROPERTIES>{PNNUMBER}\.{NUMBER}+ { yylval->fval = g_ascii_strtod(yytext, NULL); return T_DOUBLE;}
<PROPERTIES>\"{STRING}\" { yytext[yyleng-1] = '\0'; yylval->sval = g_strdup(&yytext[1]); return T_STRING;}
2017-01-05 12:22:34 -05:00
<PROPERTIES>@{WORD} {
yylval->sval = g_strdup(yytext);
return T_LINK;
}
2016-12-31 17:27:17 -05:00
<PROPERTIES>{REAL}{EM} {
yylval->distance.distance = (double)g_ascii_strtod(yytext, NULL);
yylval->distance.type = PW_EM;
2017-01-04 16:27:27 -05:00
yylval->distance.style = SOLID;
2016-12-31 16:47:22 -05:00
return T_PIXEL;
}
2017-01-11 17:19:29 -05:00
<PROPERTIES>{PNNUMBER}{PX} {
2016-12-31 17:27:17 -05:00
yylval->distance.distance = (double)g_ascii_strtoll(yytext, NULL, 10);
yylval->distance.type = PW_PX;
2017-01-04 16:27:27 -05:00
yylval->distance.style = SOLID;
return T_PIXEL;
}
2017-04-05 15:27:35 -04:00
<PROPERTIES>{PNNUMBER}{PX}{WHITESPACE}{LS_DASH} {
2017-01-04 16:27:27 -05:00
yylval->distance.distance = (double)g_ascii_strtoll(yytext, NULL, 10);
yylval->distance.type = PW_PX;
yylval->distance.style = DASH;
return T_PIXEL;
}
2017-04-05 15:27:35 -04:00
<PROPERTIES>{REAL}{EM}{WHITESPACE}{LS_DASH} {
yylval->distance.distance = (double)g_ascii_strtod(yytext, NULL);
yylval->distance.type = PW_EM;
2017-01-04 16:27:27 -05:00
yylval->distance.style = DASH;
return T_PIXEL;
}
2017-04-05 15:27:35 -04:00
<PROPERTIES>{PNNUMBER}{PX}{WHITESPACE}{LS_SOLID} {
2017-01-04 16:27:27 -05:00
yylval->distance.distance = (double)g_ascii_strtoll(yytext, NULL, 10);
yylval->distance.type = PW_PX;
yylval->distance.style = SOLID;
return T_PIXEL;
}
2017-04-05 15:27:35 -04:00
<PROPERTIES>{REAL}{EM}{WHITESPACE}{LS_SOLID} {
yylval->distance.distance = (double)g_ascii_strtod(yytext, NULL);
yylval->distance.type = PW_EM;
2017-01-04 16:27:27 -05:00
yylval->distance.style = SOLID;
return T_PIXEL;
}
<PROPERTIES>{REAL}{PERCENT} {
yylval->distance.distance = (double)g_ascii_strtod(yytext, NULL);
yylval->distance.type = PW_PERCENT;
2017-01-04 16:27:27 -05:00
yylval->distance.style = SOLID;
return T_PIXEL;
}
<PROPERTIES>{REAL}{PERCENT}{WHITESPACE}{LS_SOLID} {
yylval->distance.distance = (double)g_ascii_strtod(yytext, NULL);
yylval->distance.type = PW_PERCENT;
yylval->distance.style = SOLID;
return T_PIXEL;
}
<PROPERTIES>{REAL}{PERCENT}{WHITESPACE}{LS_DASH} {
yylval->distance.distance = (double)g_ascii_strtod(yytext, NULL);
yylval->distance.type = PW_PERCENT;
yylval->distance.style = DASH;
return T_PIXEL;
}
<PROPERTIES>#{HEX}{8} {
2016-12-11 06:19:46 -05:00
union { unsigned int val; struct { unsigned char b,g,r,a;};} val;
2016-12-10 13:48:44 -05:00
val.val = (unsigned int)strtoull ( &yytext[1], NULL, 16);
2016-12-12 10:55:31 -05:00
yylval->colorval.alpha = val.a/255.0;
yylval->colorval.red = val.r/255.0;
yylval->colorval.green = val.g/255.0;
yylval->colorval.blue = val.b/255.0;
2016-12-11 06:19:46 -05:00
return T_COLOR;
}
<PROPERTIES>#{HEX}{6} {
2016-12-11 06:19:46 -05:00
union { unsigned int val; struct { unsigned char b,g,r,a;};} val;
val.val = (unsigned int)g_ascii_strtoull ( &yytext[1], NULL, 16);
2016-12-12 10:55:31 -05:00
yylval->colorval.alpha = 1.0;
yylval->colorval.red = val.r/255.0;
yylval->colorval.green = val.g/255.0;
yylval->colorval.blue = val.b/255.0;
2016-12-10 13:48:44 -05:00
return T_COLOR;
}
2017-04-02 06:47:53 -04:00
<PROPERTIES>#{HEX}{3} {
union { uint16_t val; struct { unsigned char b:4,g:4,r:4,a :4;};} val;
val.val = (uint16_t )g_ascii_strtoull ( &yytext[1], NULL, 16);
yylval->colorval.alpha = 1.0;
yylval->colorval.red = val.r/15.0;
yylval->colorval.green = val.g/15.0;
yylval->colorval.blue = val.b/15.0;
2017-04-02 06:47:53 -04:00
return T_COLOR;
}
<PROPERTIES>rgba\({WSO}{NUMBER}{1,3},{WSO}{NUMBER}{1,3},{WSO}{NUMBER}{1,3},{WSO}[01](\.{NUMBER}+)?\) {
char *endptr = &yytext[5];
2017-04-26 16:45:14 -04:00
yylval->colorval.red = g_ascii_strtoull ( endptr, &endptr, 10)/255.0;
yylval->colorval.green= g_ascii_strtoull ( endptr+1, &endptr, 10)/255.0;
yylval->colorval.blue= g_ascii_strtoull ( endptr+1, &endptr, 10)/255.0;
2016-12-12 10:55:31 -05:00
yylval->colorval.alpha= g_ascii_strtod ( endptr+1, NULL);
return T_COLOR;
}
<PROPERTIES>rgb\({WSO}{NUMBER}{1,3},{WSO}{NUMBER}{1,3},{WSO}{NUMBER}{1,3}\) {
char *endptr = &yytext[4];
2017-04-26 16:45:14 -04:00
yylval->colorval.red = g_ascii_strtoull ( endptr, &endptr, 10)/255.0;
yylval->colorval.green = g_ascii_strtoull ( endptr+1, &endptr, 10)/255.0;
yylval->colorval.blue = g_ascii_strtoull ( endptr+1, &endptr, 10)/255.0;
2016-12-12 10:55:31 -05:00
yylval->colorval.alpha = 1.0;
return T_COLOR;
2016-12-10 13:48:44 -05:00
}
<PROPERTIES>hsl\({WSO}{NUMBER}{1,3},{WSO}[1]?{NUMBER}{1,2}{PERCENT},{WSO}[1]?{NUMBER}{1,2}{PERCENT}\) {
char *endptr = &yytext[4];
gint64 hi= g_ascii_strtoll ( endptr, &endptr, 10);
gint64 si= g_ascii_strtoll ( endptr+1, &endptr, 10);
gint64 li= g_ascii_strtoll ( endptr+2, &endptr, 10);
gdouble h = IN_RANGE(hi, 0, 359);
gdouble s = IN_RANGE(si, 0, 100);
gdouble l = IN_RANGE(li, 0, 100);
yylval->colorval = hsl_to_rgb ( h/360.0, s/100.0, l/100.0 );
yylval->colorval.alpha = 1.0;
return T_COLOR;
}
<PROPERTIES>cmyk\({WHITESPACE}[1]?{NUMBER}{1,2}{PERCENT},{WHITESPACE}[1]?{NUMBER}{1,2}{PERCENT},{WHITESPACE}[1]?{NUMBER}{1,2}{PERCENT},{WHITESPACE}[1]?{NUMBER}{1,2}{PERCENT}\) {
char *endptr = &yytext[5];
gint64 ci = g_ascii_strtoll ( endptr, &endptr, 10);
gint64 mi = g_ascii_strtoll ( endptr+2, &endptr, 10);
gint64 my = g_ascii_strtoll ( endptr+2, &endptr, 10);
gint64 mk = g_ascii_strtoll ( endptr+2, &endptr, 10);
double c= IN_RANGE(ci, 0, 100)/100.0;
double m= IN_RANGE(mi, 0, 100)/100.0;
double y= IN_RANGE(my, 0, 100)/100.0;
double k= IN_RANGE(mk, 0, 100)/100.0;
yylval->colorval.red = (1.0-c)*(1.0-k);
yylval->colorval.green = (1.0-m)*(1.0-k);
yylval->colorval.blue = (1.0-y)*(1.0-k);
yylval->colorval.alpha = 1.0;
return T_COLOR;
}
<PROPERTIES>hwb\({WHITESPACE}{NUMBER}{1,3},{WHITESPACE}[1]?{NUMBER}{1,2}{PERCENT},{WHITESPACE}[1]?{NUMBER}{1,2}{PERCENT}\) {
char *endptr = &yytext[4];
gint64 hi = g_ascii_strtoll ( endptr, &endptr, 10);
gint64 hw = g_ascii_strtoll ( endptr+1, &endptr, 10);
gint64 hb = g_ascii_strtoll ( endptr+2, &endptr, 10);
double h= IN_RANGE(hi,0,360)/360.0;
double w= IN_RANGE(hw,0,100)/100.0;
double b= IN_RANGE(hb,0,100)/100.0;
yylval->colorval = hsl_to_rgb ( h, 1.0, 0.5);
yylval->colorval.red *= ( 1. - w - b );
yylval->colorval.red += w;
yylval->colorval.green *= ( 1. - w - b );
yylval->colorval.green += w;
yylval->colorval.blue *= ( 1. - w - b );
yylval->colorval.blue += w;
yylval->colorval.alpha = 1.0;
return T_COLOR;
}
<PROPERTIES>argb:{HEX}{1,8} {
union { unsigned int val; struct { unsigned char b,g,r,a;};} val;
val.val = (unsigned int)strtoull ( &yytext[5], NULL, 16);
yylval->colorval.alpha = val.a/255.0;
yylval->colorval.red = val.r/255.0;
yylval->colorval.green = val.g/255.0;
yylval->colorval.blue = val.b/255.0;
return T_COLOR;
}
<PROPERTIES>{CENTER} {
yylval->ival = WL_CENTER;
return T_POSITION;
}
<PROPERTIES>{EAST} {
yylval->ival = WL_EAST;
return T_POSITION;
}
<PROPERTIES>{WEST} {
yylval->ival = WL_WEST;
return T_POSITION;
}
<PROPERTIES>{SOUTH}{EAST} {
yylval->ival = WL_SOUTH_EAST;
return T_POSITION;
}
<PROPERTIES>{SOUTH}{WEST} {
yylval->ival = WL_SOUTH_WEST;
return T_POSITION;
}
<PROPERTIES>{SOUTH} {
yylval->ival = WL_SOUTH;
return T_POSITION;
}
<PROPERTIES>{NORTH}{EAST} {
yylval->ival = WL_NORTH_EAST;
return T_POSITION;
}
<PROPERTIES>{NORTH}{WEST} {
yylval->ival = WL_NORTH_WEST;
return T_POSITION;
}
<PROPERTIES>{NORTH} {
yylval->ival = WL_NORTH;
return T_POSITION;
}
<PROPERTIES>{NONE} {
yylval->ival = HL_NONE;
return T_HIGHLIGHT_STYLE;
}
<PROPERTIES>{BOLD} {
yylval->ival = HL_BOLD;
return T_HIGHLIGHT_STYLE;
}
<PROPERTIES>{ITALIC} {
yylval->ival = HL_ITALIC;
return T_HIGHLIGHT_STYLE;
}
<PROPERTIES>{UNDERLINE} {
yylval->ival = HL_UNDERLINE;
return T_HIGHLIGHT_STYLE;
}
2017-01-05 16:04:39 -05:00
<INITIAL><<EOF>> {
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;
*yylloc = current->location;
BEGIN(GPOINTER_TO_INT ( g_queue_pop_head ( queue )));
}
2017-01-05 16:04:39 -05:00
}
2017-01-05 16:04:39 -05:00
<*>\n {
2017-01-05 12:22:34 -05:00
yylloc->last_column = 1;
yylloc->last_line ++;
};
<*>(\r\n) {
2016-12-12 10:55:31 -05:00
yylloc->last_column = 1;
yylloc->last_line ++;
};
<INITIAL>. {
return T_ERROR;
}
2017-03-13 05:49:33 -04:00
<SECTION>. {
return T_ERROR_SECTION;
}
<PROPERTIES>. {
return T_ERROR_PROPERTY;
}
<NAMESTR>. {
return T_ERROR_NAMESTRING;
}
2016-12-09 13:49:49 -05:00
%%
static char * rofi_theme_parse_prepare_file ( const char *file, const char *parent_file )
{
char *filename = rofi_expand_path ( file );
// If no absolute path specified, expand it.
if ( parent_file != NULL && ! g_path_is_absolute ( filename ) ) {
char *basedir = g_path_get_dirname ( parent_file );
char *path = g_build_filename ( basedir, filename, NULL );
g_free ( filename);
filename = path;
g_free ( basedir );
}
GFile *gf = g_file_new_for_path ( filename );
g_free(filename);
filename = g_file_get_path ( gf );
g_object_unref ( gf );
return filename;
}
gboolean rofi_theme_parse_file ( const char *file )
{
char *file2 = helper_get_theme_path ( file );
char *filename = rofi_theme_parse_prepare_file ( file2, NULL );
g_free ( file2 );
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->filename = filename;
po->filein = yyin;
current = po;
imported_files = g_list_append ( imported_files, po->filename );
g_queue_push_head ( file_queue, po );
2017-03-13 05:49:33 -04:00
g_log ( LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Parsing top file: '%s'", filename );
int parser_retv = yyparse ( file );
yylex_destroy ();
yyin = NULL;
2017-04-06 03:12:03 -04:00
while ( (po = g_queue_pop_head ( file_queue ) )) {
if ( po ) {
if ( po->type == PT_FILE ){
fclose ( po->filein );
}
g_free ( po );
}
}
// Free up.
g_list_foreach ( imported_files, (GFunc)g_free, NULL);
g_list_free ( imported_files );
g_queue_free ( file_queue );
2017-04-04 02:31:25 -04:00
imported_files = NULL;
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 );
2017-03-13 05:49:33 -04:00
g_log ( LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Parsing string: '%s'", string );
int parser_retv = yyparse ( string );
yylex_destroy ();
2017-04-06 03:12:03 -04:00
while ( (po = g_queue_pop_head ( file_queue ) )) {
if ( po ) {
if ( po->type == PT_FILE ){
fclose ( po->filein );
}
g_free ( po );
}
}
// Free up.
g_list_foreach ( imported_files, (GFunc)g_free, NULL);
g_list_free ( imported_files );
2017-04-04 02:31:25 -04:00
imported_files = NULL;
g_queue_free ( file_queue );
file_queue = NULL;
if ( parser_retv != 0 ) {
return TRUE;
}
return FALSE;
}