From 41ce7cce4a7335c9f0619c4f7b218c70ead98133 Mon Sep 17 00:00:00 2001 From: Benedikt Heine Date: Tue, 18 Dec 2018 13:43:35 +0100 Subject: [PATCH] Add string_parse_* functions Changes all string parsers to have a the almost same interface while also having a proper return value, which indicates success of the parsing process. --- config.h | 3 +- src/draw.c | 6 +- src/option_parser.c | 134 +++++++++++++++++++++++++++---- src/option_parser.h | 23 +++--- src/settings.c | 188 +++++++++++++------------------------------- src/settings.h | 9 ++- 6 files changed, 191 insertions(+), 172 deletions(-) diff --git a/config.h b/config.h index 25f35b8..1a996c3 100644 --- a/config.h +++ b/config.h @@ -46,8 +46,7 @@ struct settings defaults = { .separator_height = 2, /* height of the separator line between two notifications */ .padding = 0, .h_padding = 0, /* horizontal padding */ -.sep_color = SEP_AUTO, /* SEP_AUTO, SEP_FOREGROUND, SEP_FRAME, SEP_CUSTOM */ -.sep_custom_color_str = NULL,/* custom color if sep_color is set to CUSTOM */ +.sep_color = {SEP_AUTO}, /* SEP_AUTO, SEP_FOREGROUND, SEP_FRAME, SEP_CUSTOM */ .frame_width = 0, .frame_color = "#888888", diff --git a/src/draw.c b/src/draw.c index 5e50e0b..bae6a30 100644 --- a/src/draw.c +++ b/src/draw.c @@ -93,14 +93,14 @@ static struct color calculate_foreground_color(struct color bg) static struct color layout_get_sepcolor(struct colored_layout *cl, struct colored_layout *cl_next) { - switch (settings.sep_color) { + switch (settings.sep_color.type) { case SEP_FRAME: if (cl_next->n->urgency > cl->n->urgency) return cl_next->frame; else return cl->frame; case SEP_CUSTOM: - return string_to_color(settings.sep_custom_color_str); + return string_to_color(settings.sep_color.sep_color); case SEP_FOREGROUND: return cl->fg; case SEP_AUTO: @@ -486,7 +486,7 @@ static cairo_surface_t *render_background(cairo_surface_t *srf, draw_rounded_rect(c, x, y, width, height, corner_radius, first, last); cairo_fill(c); - if ( settings.sep_color != SEP_FRAME + if ( settings.sep_color.type != SEP_FRAME && settings.separator_height > 0 && !last) { struct color sep_color = layout_get_sepcolor(cl, cl_next); diff --git a/src/option_parser.c b/src/option_parser.c index 85e780f..9dbca54 100644 --- a/src/option_parser.c +++ b/src/option_parser.c @@ -11,6 +11,7 @@ #include "dunst.h" #include "log.h" #include "utils.h" +#include "settings.h" struct entry { char *key; @@ -39,6 +40,122 @@ static void cmdline_usage_append(const char *key, const char *type, const char * static int cmdline_find_option(const char *key); +#define STRING_PARSE_RET(string, value) if (STR_EQ(s, string)) { *ret = value; return true; } + +bool string_parse_alignment(const char *s, enum alignment *ret) +{ + ASSERT_OR_RET(s, false); + ASSERT_OR_RET(ret, false); + + STRING_PARSE_RET("left", ALIGN_LEFT); + STRING_PARSE_RET("center", ALIGN_CENTER); + STRING_PARSE_RET("right", ALIGN_RIGHT); + + return false; +} + +bool string_parse_ellipsize(const char *s, enum ellipsize *ret) +{ + ASSERT_OR_RET(s, false); + ASSERT_OR_RET(ret, false); + + STRING_PARSE_RET("start", ELLIPSE_START); + STRING_PARSE_RET("middle", ELLIPSE_MIDDLE); + STRING_PARSE_RET("end", ELLIPSE_END); + + return false; +} + +bool string_parse_follow_mode(const char *s, enum follow_mode *ret) +{ + ASSERT_OR_RET(s, false); + ASSERT_OR_RET(ret, false); + + STRING_PARSE_RET("mouse", FOLLOW_MOUSE); + STRING_PARSE_RET("keyboard", FOLLOW_KEYBOARD); + STRING_PARSE_RET("none", FOLLOW_NONE); + + return false; +} + + +bool string_parse_fullscreen(const char *s, enum behavior_fullscreen *ret) +{ + ASSERT_OR_RET(s, false); + ASSERT_OR_RET(ret, false); + + STRING_PARSE_RET("show", FS_SHOW); + STRING_PARSE_RET("delay", FS_DELAY); + STRING_PARSE_RET("pushback", FS_PUSHBACK); + + return false; +} + +bool string_parse_icon_position(const char *s, enum icon_position *ret) +{ + ASSERT_OR_RET(s, false); + ASSERT_OR_RET(ret, false); + + STRING_PARSE_RET("left", ICON_LEFT); + STRING_PARSE_RET("right", ICON_RIGHT); + STRING_PARSE_RET("off", ICON_OFF); + + return false; +} + +bool string_parse_markup_mode(const char *s, enum markup_mode *ret) +{ + ASSERT_OR_RET(s, false); + ASSERT_OR_RET(ret, false); + + STRING_PARSE_RET("strip", MARKUP_STRIP); + STRING_PARSE_RET("no", MARKUP_NO); + STRING_PARSE_RET("full", MARKUP_FULL); + STRING_PARSE_RET("yes", MARKUP_FULL); + + return false; +} + +bool string_parse_mouse_action(const char *s, enum mouse_action *ret) +{ + ASSERT_OR_RET(s, false); + ASSERT_OR_RET(ret, false); + + STRING_PARSE_RET("none", MOUSE_NONE); + STRING_PARSE_RET("do_action", MOUSE_DO_ACTION); + STRING_PARSE_RET("close_current", MOUSE_CLOSE_CURRENT); + STRING_PARSE_RET("close_all", MOUSE_CLOSE_ALL); + + return false; +} + +bool string_parse_sepcolor(const char *s, struct separator_color_data *ret) +{ + ASSERT_OR_RET(s, false); + ASSERT_OR_RET(ret, false); + + STRING_PARSE_RET("auto", (struct separator_color_data){.type = SEP_AUTO}); + STRING_PARSE_RET("foreground", (struct separator_color_data){.type = SEP_FOREGROUND}); + STRING_PARSE_RET("frame", (struct separator_color_data){.type = SEP_FRAME}); + + ret->type = SEP_CUSTOM; + ret->sep_color = g_strdup(s); + + return true; +} + +bool string_parse_urgency(const char *s, enum urgency *ret) +{ + ASSERT_OR_RET(s, false); + ASSERT_OR_RET(ret, false); + + STRING_PARSE_RET("low", URG_LOW); + STRING_PARSE_RET("normal", URG_NORM); + STRING_PARSE_RET("critical", URG_CRIT); + + return false; +} + struct section *new_section(const char *name) { for (int i = 0; i < section_count; i++) { @@ -525,21 +642,4 @@ const char *cmdline_create_usage(void) return usage_str; } -/* see option_parser.h */ -enum behavior_fullscreen parse_enum_fullscreen(const char *string, enum behavior_fullscreen def) -{ - ASSERT_OR_RET(string, def); - - if (STR_EQ(string, "show")) - return FS_SHOW; - else if (STR_EQ(string, "delay")) - return FS_DELAY; - else if (STR_EQ(string, "pushback")) - return FS_PUSHBACK; - else { - LOG_W("Unknown fullscreen value: '%s'\n", string); - return def; - } -} - /* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */ diff --git a/src/option_parser.h b/src/option_parser.h index d712fa8..8d98618 100644 --- a/src/option_parser.h +++ b/src/option_parser.h @@ -7,6 +7,17 @@ #include #include "dunst.h" +#include "settings.h" + +bool string_parse_alignment(const char *s, enum alignment *ret); +bool string_parse_ellipsize(const char *s, enum ellipsize *ret); +bool string_parse_follow_mode(const char *s, enum follow_mode *ret); +bool string_parse_fullscreen(const char *s, enum behavior_fullscreen *ret); +bool string_parse_icon_position(const char *s, enum icon_position *ret); +bool string_parse_markup_mode(const char *s, enum markup_mode *ret); +bool string_parse_mouse_action(const char *s, enum mouse_action *ret); +bool string_parse_sepcolor(const char *s, struct separator_color_data *ret); +bool string_parse_urgency(const char *s, enum urgency *ret); int load_ini_file(FILE *); char *ini_get_path(const char *section, const char *key, const char *def); @@ -65,17 +76,5 @@ int option_get_bool(const char *ini_section, */ const char *next_section(const char *section); -/** - * Parse the fullscreen behavior value of the given string - * - * @param string the string representation of #behavior_fullscreen. - * The string must not contain any waste characters. - * @param def value to return in case of errors - * - * @return the #behavior_fullscreen representation of `string` - * @return `def` if `string` is invalid or `NULL` - */ -enum behavior_fullscreen parse_enum_fullscreen(const char *string, enum behavior_fullscreen def); - #endif /* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */ diff --git a/src/settings.c b/src/settings.c index 0e6104c..d4bcba2 100644 --- a/src/settings.c +++ b/src/settings.c @@ -18,79 +18,18 @@ struct settings settings; -static const char *follow_mode_to_string(enum follow_mode f_mode) +static enum urgency ini_get_urgency(const char *section, const char *key, const enum urgency def) { - switch(f_mode) { - case FOLLOW_NONE: return "none"; - case FOLLOW_MOUSE: return "mouse"; - case FOLLOW_KEYBOARD: return "keyboard"; - default: return ""; + enum urgency ret; + char *c = ini_get_string(section, key, NULL); + + if (!string_parse_urgency(c, &ret)) { + if (c) + LOG_W("Unknown urgency: '%s'", c); + ret = def; } -} -static enum follow_mode parse_follow_mode(const char *mode) -{ - ASSERT_OR_RET(mode, FOLLOW_NONE); - - if (STR_EQ(mode, "mouse")) - return FOLLOW_MOUSE; - else if (STR_EQ(mode, "keyboard")) - return FOLLOW_KEYBOARD; - else if (STR_EQ(mode, "none")) - return FOLLOW_NONE; - else { - LOG_W("Unknown follow mode: '%s'", mode); - return FOLLOW_NONE; - } -} - -static enum markup_mode parse_markup_mode(const char *mode) -{ - if (STR_EQ(mode, "strip")) { - return MARKUP_STRIP; - } else if (STR_EQ(mode, "no")) { - return MARKUP_NO; - } else if (STR_EQ(mode, "full") || STR_EQ(mode, "yes")) { - return MARKUP_FULL; - } else { - LOG_W("Unknown markup mode: '%s'", mode); - return MARKUP_NO; - } -} - -static enum mouse_action parse_mouse_action(const char *action) -{ - if (STR_EQ(action, "none")) - return MOUSE_NONE; - else if (STR_EQ(action, "do_action")) - return MOUSE_DO_ACTION; - else if (STR_EQ(action, "close_current")) - return MOUSE_CLOSE_CURRENT; - else if (STR_EQ(action, "close_all")) - return MOUSE_CLOSE_ALL; - else { - LOG_W("Unknown mouse action: '%s'", action); - return MOUSE_NONE; - } -} - - -static enum urgency ini_get_urgency(const char *section, const char *key, const int def) -{ - int ret = def; - char *urg = ini_get_string(section, key, ""); - - if (STR_FULL(urg)) { - if (STR_EQ(urg, "low")) - ret = URG_LOW; - else if (STR_EQ(urg, "normal")) - ret = URG_NORM; - else if (STR_EQ(urg, "critical")) - ret = URG_CRIT; - else - LOG_W("Unknown urgency: '%s'", urg); - } - g_free(urg); + g_free(c); return ret; } @@ -205,13 +144,11 @@ void load_settings(char *cmdline_config_path) "Specify how markup should be handled" ); - //Use markup if set - //Use default if settings.markup not set yet - // (=>c empty&&!allow_markup) - if (c) { - settings.markup = parse_markup_mode(c); - } else if (!settings.markup) { - settings.markup = defaults.markup; + if (!string_parse_markup_mode(c, &settings.markup)) { + if (c) + LOG_W("Cannot parse markup mode value: '%s'", c); + if (!settings.markup) + settings.markup = defaults.markup; } g_free(c); } @@ -243,20 +180,13 @@ void load_settings(char *cmdline_config_path) { char *c = option_get_string( "global", - "ellipsize", "-ellipsize", "", + "ellipsize", "-ellipsize", NULL, "Ellipsize truncated lines on the start/middle/end" ); - if (STR_EMPTY(c)) { - settings.ellipsize = defaults.ellipsize; - } else if (STR_EQ(c, "start")) { - settings.ellipsize = ELLIPSE_START; - } else if (STR_EQ(c, "middle")) { - settings.ellipsize = ELLIPSE_MIDDLE; - } else if (STR_EQ(c, "end")) { - settings.ellipsize = ELLIPSE_END; - } else { - LOG_W("Unknown ellipsize value: '%s'", c); + if (!string_parse_ellipsize(c, &settings.ellipsize)) { + if (c) + LOG_W("Unknown ellipsize value: '%s'", c); settings.ellipsize = defaults.ellipsize; } g_free(c); @@ -283,11 +213,15 @@ void load_settings(char *cmdline_config_path) { char *c = option_get_string( "global", - "follow", "-follow", follow_mode_to_string(defaults.f_mode), + "follow", "-follow", NULL, "Follow mouse, keyboard or none?" ); - settings.f_mode = parse_follow_mode(c); + if (!string_parse_follow_mode(c, &settings.f_mode)) { + if (c) + LOG_W("Cannot parse follow mode: %s", c); + settings.f_mode = defaults.f_mode; + } g_free(c); } @@ -346,17 +280,14 @@ void load_settings(char *cmdline_config_path) "alignment", "-align/-alignment", "", "Text alignment left/center/right" ); - if (STR_FULL(c)) { - if (STR_EQ(c, "left")) - settings.align = ALIGN_LEFT; - else if (STR_EQ(c, "center")) - settings.align = ALIGN_CENTER; - else if (STR_EQ(c, "right")) - settings.align = ALIGN_RIGHT; - else + + if (!string_parse_alignment(c, &settings.align)) { + if (c) LOG_W("Unknown alignment value: '%s'", c); - g_free(c); + settings.align = defaults.align; } + + g_free(c); } settings.show_age_threshold = option_get_time( @@ -426,17 +357,8 @@ void load_settings(char *cmdline_config_path) "Color of the separator line (or 'auto')" ); - if (STR_FULL(c)) { - if (STR_EQ(c, "auto")) - settings.sep_color = SEP_AUTO; - else if (STR_EQ(c, "foreground")) - settings.sep_color = SEP_FOREGROUND; - else if (STR_EQ(c, "frame")) - settings.sep_color = SEP_FRAME; - else { - settings.sep_color = SEP_CUSTOM; - settings.sep_custom_color_str = g_strdup(c); - } + if (!string_parse_sepcolor(c, &settings.sep_color)) { + settings.sep_color = defaults.sep_color; } g_free(c); } @@ -493,17 +415,12 @@ void load_settings(char *cmdline_config_path) "Align icons left/right/off" ); - if (STR_FULL(c)) { - if (STR_EQ(c, "left")) - settings.icon_position = ICON_LEFT; - else if (STR_EQ(c, "right")) - settings.icon_position = ICON_RIGHT; - else if (STR_EQ(c, "off")) - settings.icon_position = ICON_OFF; - else + if (!string_parse_icon_position(c, &settings.icon_position)) { + if (c) LOG_W("Unknown icon position: '%s'", c); - g_free(c); + settings.icon_position = defaults.icon_position; } + g_free(c); } settings.max_icon_size = option_get_int( @@ -579,12 +496,11 @@ void load_settings(char *cmdline_config_path) "Action of Left click event" ); - if (c) { - settings.mouse_left_click = parse_mouse_action(c); - } else { + if (!string_parse_mouse_action(c, &settings.mouse_left_click)) { + if (c) + LOG_W("Unknown mouse action value: '%s'", c); settings.mouse_left_click = defaults.mouse_left_click; } - g_free(c); } @@ -595,12 +511,11 @@ void load_settings(char *cmdline_config_path) "Action of middle click event" ); - if (c) { - settings.mouse_middle_click = parse_mouse_action(c); - } else { + if (!string_parse_mouse_action(c, &settings.mouse_middle_click)) { + if (c) + LOG_W("Unknown mouse action value: '%s'", c); settings.mouse_middle_click = defaults.mouse_middle_click; } - g_free(c); } @@ -611,12 +526,11 @@ void load_settings(char *cmdline_config_path) "Action of right click event" ); - if (c) { - settings.mouse_right_click = parse_mouse_action(c); - } else { + if (!string_parse_mouse_action(c, &settings.mouse_right_click)) { + if (c) + LOG_W("Unknown mouse action value: '%s'", c); settings.mouse_right_click = defaults.mouse_right_click; } - g_free(c); } @@ -794,10 +708,11 @@ void load_settings(char *cmdline_config_path) "markup", NULL ); - if (c) { - r->markup = parse_markup_mode(c); - g_free(c); + if (!string_parse_markup_mode(c, &r->markup)) { + if (c) + LOG_W("Invalid markup mode value: %s", c); } + g_free(c); } r->urgency = ini_get_urgency(cur_section, "urgency", r->urgency); @@ -816,7 +731,10 @@ void load_settings(char *cmdline_config_path) "fullscreen", NULL ); - r->fullscreen = parse_enum_fullscreen(c, r->fullscreen); + if (!string_parse_fullscreen(c, &r->fullscreen)) { + if (c) + LOG_W("Invalid fullscreen value: %s", c); + } g_free(c); } r->script = ini_get_path(cur_section, "script", NULL); diff --git a/src/settings.h b/src/settings.h index 8e64507..6bcf6b8 100644 --- a/src/settings.h +++ b/src/settings.h @@ -15,6 +15,11 @@ enum separator_color { SEP_FOREGROUND, SEP_AUTO, SEP_FRAME, SEP_CUSTOM }; enum follow_mode { FOLLOW_NONE, FOLLOW_MOUSE, FOLLOW_KEYBOARD }; enum mouse_action { MOUSE_NONE, MOUSE_DO_ACTION, MOUSE_CLOSE_CURRENT, MOUSE_CLOSE_ALL }; +struct separator_color_data { + enum separator_color type; + char *sep_color; +}; + struct geometry { int x; int y; @@ -24,7 +29,6 @@ struct geometry { bool negative_y; bool negative_width; bool width_set; - }; struct settings { @@ -61,8 +65,7 @@ struct settings { int separator_height; int padding; int h_padding; - enum separator_color sep_color; - char *sep_custom_color_str; + struct separator_color_data sep_color; int frame_width; char *frame_color; int startup_notification;