1717/* Anyone with a 10M config file is doing something very wrong */
1818#define MAX_CONFIG_SIZE (10*1024*1024)
1919
20+ struct uint32_percent {
21+ uint32_t value ;
22+ bool percent ;
23+ };
24+
2025static char * strip (const char * str );
2126static bool parse_option (struct tofi * tofi , const char * filename , size_t lineno , const char * option , const char * value );
2227static char * get_config_path (void );
@@ -26,7 +31,7 @@ static bool parse_bool(const char *filename, size_t lineno, const char *str, boo
2631static struct color parse_color (const char * filename , size_t lineno , const char * str , bool * err );
2732static uint32_t parse_uint32 (const char * filename , size_t lineno , const char * str , bool * err );
2833static int32_t parse_int32 (const char * filename , size_t lineno , const char * str , bool * err );
29- static uint32_t parse_uint32_percent (const char * filename , size_t lineno , const char * str , bool * err , uint32_t max );
34+ static struct uint32_percent parse_uint32_percent (const char * filename , size_t lineno , const char * str , bool * err );
3035
3136/*
3237 * Function-like macro. Yuck.
@@ -231,6 +236,7 @@ char *strip(const char *str)
231236bool parse_option (struct tofi * tofi , const char * filename , size_t lineno , const char * option , const char * value )
232237{
233238 bool err = false;
239+ struct uint32_percent percent ;
234240 if (strcasecmp (option , "anchor" ) == 0 ) {
235241 tofi -> anchor = parse_anchor (filename , lineno , value , & err );
236242 } else if (strcasecmp (option , "background-color" ) == 0 ) {
@@ -270,25 +276,45 @@ bool parse_option(struct tofi *tofi, const char *filename, size_t lineno, const
270276 } else if (strcasecmp (option , "selection-background" ) == 0 ) {
271277 tofi -> window .entry .selection_background_color = parse_color (filename , lineno , value , & err );
272278 } else if (strcasecmp (option , "width" ) == 0 ) {
273- tofi -> window .width = parse_uint32_percent (filename , lineno , value , & err , tofi -> output_width );
279+ percent = parse_uint32_percent (filename , lineno , value , & err );
280+ tofi -> window .width = percent .value ;
281+ tofi -> window .width_is_percent = percent .percent ;
274282 } else if (strcasecmp (option , "height" ) == 0 ) {
275- tofi -> window .height = parse_uint32_percent (filename , lineno , value , & err , tofi -> output_height );
283+ percent = parse_uint32_percent (filename , lineno , value , & err );
284+ tofi -> window .height = percent .value ;
285+ tofi -> window .height_is_percent = percent .percent ;
276286 } else if (strcasecmp (option , "margin-top" ) == 0 ) {
277- tofi -> window .margin_top = parse_uint32_percent (filename , lineno , value , & err , tofi -> output_height );
287+ percent = parse_uint32_percent (filename , lineno , value , & err );
288+ tofi -> window .margin_top = percent .value ;
289+ tofi -> window .margin_top_is_percent = percent .percent ;
278290 } else if (strcasecmp (option , "margin-bottom" ) == 0 ) {
279- tofi -> window .margin_bottom = parse_uint32_percent (filename , lineno , value , & err , tofi -> output_height );
291+ percent = parse_uint32_percent (filename , lineno , value , & err );
292+ tofi -> window .margin_bottom = percent .value ;
293+ tofi -> window .margin_bottom_is_percent = percent .percent ;
280294 } else if (strcasecmp (option , "margin-left" ) == 0 ) {
281- tofi -> window .margin_left = parse_uint32_percent (filename , lineno , value , & err , tofi -> output_width );
295+ percent = parse_uint32_percent (filename , lineno , value , & err );
296+ tofi -> window .margin_left = percent .value ;
297+ tofi -> window .margin_left_is_percent = percent .percent ;
282298 } else if (strcasecmp (option , "margin-right" ) == 0 ) {
283- tofi -> window .margin_right = parse_uint32_percent (filename , lineno , value , & err , tofi -> output_width );
299+ percent = parse_uint32_percent (filename , lineno , value , & err );
300+ tofi -> window .margin_right = percent .value ;
301+ tofi -> window .margin_right_is_percent = percent .percent ;
284302 } else if (strcasecmp (option , "padding-top" ) == 0 ) {
285- tofi -> window .entry .padding_top = parse_uint32_percent (filename , lineno , value , & err , tofi -> output_height );
303+ percent = parse_uint32_percent (filename , lineno , value , & err );
304+ tofi -> window .entry .padding_top = percent .value ;
305+ tofi -> window .entry .padding_top_is_percent = percent .percent ;
286306 } else if (strcasecmp (option , "padding-bottom" ) == 0 ) {
287- tofi -> window .entry .padding_bottom = parse_uint32_percent (filename , lineno , value , & err , tofi -> output_height );
307+ percent = parse_uint32_percent (filename , lineno , value , & err );
308+ tofi -> window .entry .padding_bottom = percent .value ;
309+ tofi -> window .entry .padding_bottom_is_percent = percent .percent ;
288310 } else if (strcasecmp (option , "padding-left" ) == 0 ) {
289- tofi -> window .entry .padding_left = parse_uint32_percent (filename , lineno , value , & err , tofi -> output_width );
311+ percent = parse_uint32_percent (filename , lineno , value , & err );
312+ tofi -> window .entry .padding_left = percent .value ;
313+ tofi -> window .entry .padding_left_is_percent = percent .percent ;
290314 } else if (strcasecmp (option , "padding-right" ) == 0 ) {
291- tofi -> window .entry .padding_right = parse_uint32_percent (filename , lineno , value , & err , tofi -> output_width );
315+ percent = parse_uint32_percent (filename , lineno , value , & err );
316+ tofi -> window .entry .padding_right = percent .value ;
317+ tofi -> window .entry .padding_right_is_percent = percent .percent ;
292318 } else if (strcasecmp (option , "horizontal" ) == 0 ) {
293319 tofi -> window .entry .horizontal = parse_bool (filename , lineno , value , & err );
294320 } else if (strcasecmp (option , "hide-cursor" ) == 0 ) {
@@ -304,20 +330,56 @@ bool parse_option(struct tofi *tofi, const char *filename, size_t lineno, const
304330 tofi -> window .entry .harfbuzz .disable_hinting = !parse_bool (filename , lineno , value , & err );
305331 } else if (strcasecmp (option , "late-keyboard-init" ) == 0 ) {
306332 tofi -> late_keyboard_init = parse_bool (filename , lineno , value , & err );
333+ } else if (strcasecmp (option , "output" ) == 0 ) {
334+ snprintf (tofi -> target_output_name , N_ELEM (tofi -> target_output_name ), "%s" , value );
307335 } else {
308336 PARSE_ERROR (filename , lineno , "Unknown option \"%s\"\n" , option );
309337 err = true;
310338 }
311339 return !err ;
312340}
313341
314- void apply_option (struct tofi * tofi , const char * option , const char * value )
342+ void config_apply (struct tofi * tofi , const char * option , const char * value )
315343{
316344 if (!parse_option (tofi , "" , 0 , option , value )) {
317345 exit (EXIT_FAILURE );
318346 };
319347}
320348
349+ void config_fix_percentages (struct tofi * tofi )
350+ {
351+ if (tofi -> window .width_is_percent ) {
352+ tofi -> window .width = tofi -> window .width * tofi -> output_width / 100 ;
353+ }
354+ if (tofi -> window .height_is_percent ) {
355+ tofi -> window .height = tofi -> window .height * tofi -> output_height / 100 ;
356+ }
357+ if (tofi -> window .margin_top_is_percent ) {
358+ tofi -> window .margin_top = tofi -> window .margin_top * tofi -> output_height / 100 ;
359+ }
360+ if (tofi -> window .margin_bottom_is_percent ) {
361+ tofi -> window .margin_bottom = tofi -> window .margin_bottom * tofi -> output_height / 100 ;
362+ }
363+ if (tofi -> window .margin_left_is_percent ) {
364+ tofi -> window .margin_left = tofi -> window .margin_left * tofi -> output_width / 100 ;
365+ }
366+ if (tofi -> window .margin_right_is_percent ) {
367+ tofi -> window .margin_right = tofi -> window .margin_right * tofi -> output_width / 100 ;
368+ }
369+ if (tofi -> window .entry .padding_top_is_percent ) {
370+ tofi -> window .entry .padding_top = tofi -> window .entry .padding_top * tofi -> output_height / 100 ;
371+ }
372+ if (tofi -> window .entry .padding_bottom_is_percent ) {
373+ tofi -> window .entry .padding_bottom = tofi -> window .entry .padding_bottom * tofi -> output_height / 100 ;
374+ }
375+ if (tofi -> window .entry .padding_left_is_percent ) {
376+ tofi -> window .entry .padding_left = tofi -> window .entry .padding_left * tofi -> output_width / 100 ;
377+ }
378+ if (tofi -> window .entry .padding_right_is_percent ) {
379+ tofi -> window .entry .padding_right = tofi -> window .entry .padding_right * tofi -> output_width / 100 ;
380+ }
381+ }
382+
321383char * get_config_path ()
322384{
323385 char * base_dir = getenv ("XDG_CONFIG_HOME" );
@@ -450,26 +512,27 @@ int32_t parse_int32(const char *filename, size_t lineno, const char *str, bool *
450512 return ret ;
451513}
452514
453- uint32_t parse_uint32_percent (const char * filename , size_t lineno , const char * str , bool * err , uint32_t max )
515+ struct uint32_percent parse_uint32_percent (const char * filename , size_t lineno , const char * str , bool * err )
454516{
455517 errno = 0 ;
456518 char * endptr ;
457- int32_t ret = strtoul (str , & endptr , 0 );
519+ int32_t val = strtoul (str , & endptr , 0 );
520+ bool percent = false;
458521 if (endptr == str ) {
459522 PARSE_ERROR (filename , lineno , "Failed to parse \"%s\" as unsigned int.\n" , str );
460523 if (err ) {
461524 * err = true;
462525 }
463- } else if (errno || ret < 0 ) {
526+ } else if (errno || val < 0 ) {
464527 PARSE_ERROR (filename , lineno , "Unsigned int value \"%s\" out of range.\n" , str );
465528 if (err ) {
466529 * err = true;
467530 }
468531 }
469532 if (!err || !* err ) {
470533 if (* endptr == '%' ) {
471- ret = max * ret / 100 ;
534+ percent = true ;
472535 }
473536 }
474- return ret ;
537+ return ( struct uint32_percent ){ val , percent } ;
475538}
0 commit comments