Merge branch 'master' into progress_hint
This commit is contained in:
		
						commit
						eaf0bc8308
					
				
							
								
								
									
										6
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								Makefile
									
									
									
									
									
								
							| @ -3,7 +3,7 @@ | ||||
| 
 | ||||
| include config.mk | ||||
| 
 | ||||
| SRC = draw.c dunst.c list.c dunst_dbus.c ini.c utils.c | ||||
| SRC = draw.c dunst.c list.c dunst_dbus.c utils.c options.c | ||||
| OBJ = ${SRC:.c=.o} | ||||
| 
 | ||||
| all: doc options dunst service | ||||
| @ -24,9 +24,9 @@ config.h: | ||||
| 	@echo creating $@ from config.def.h | ||||
| 	@cp config.def.h $@ | ||||
| 
 | ||||
| dunst: draw.o dunst.o list.o dunst_dbus.o ini.o utils.o | ||||
| dunst: draw.o dunst.o list.o dunst_dbus.o utils.o options.o | ||||
| 	@echo CC -o $@ | ||||
| 	@${CC} ${CFLAGS} -o $@ dunst.o draw.o list.o dunst_dbus.o ini.o utils.o ${LDFLAGS} | ||||
| 	@${CC} ${CFLAGS} -o $@ dunst.o draw.o list.o dunst_dbus.o options.o utils.o ${LDFLAGS} | ||||
| 
 | ||||
| clean: | ||||
| 	@echo cleaning | ||||
|  | ||||
							
								
								
									
										380
									
								
								dunst.c
									
									
									
									
									
								
							
							
						
						
									
										380
									
								
								dunst.c
									
									
									
									
									
								
							| @ -27,9 +27,12 @@ | ||||
| #include "draw.h" | ||||
| #include "dunst_dbus.h" | ||||
| #include "list.h" | ||||
| #include "ini.h" | ||||
| #include "utils.h" | ||||
| 
 | ||||
| #ifndef STATIC_CONFIG | ||||
| #include "options.h" | ||||
| #endif | ||||
| 
 | ||||
| #define INRECT(x,y,rx,ry,rw,rh) ((x) >= (rx) && (x) < (rx)+(rw) && (y) >= (ry) && (y) < (ry)+(rh)) | ||||
| #define LENGTH(X)               (sizeof X / sizeof X[0]) | ||||
| #define MIN(a,b)                ((a) < (b) ? (a) : (b)) | ||||
| @ -185,12 +188,12 @@ void warn(const char *text, int urg) | ||||
|         if (n == NULL) | ||||
|                 die("Unable to allocate memory", EXIT_FAILURE); | ||||
| 
 | ||||
|         n->appname = "dunst"; | ||||
|         n->appname = strdup("dunst"); | ||||
|         n->summary = strdup(text); | ||||
|         if (n->summary == NULL) | ||||
|                 die("Unable to allocate memory", EXIT_FAILURE); | ||||
|         n->body = ""; | ||||
|         n->icon = ""; | ||||
|         n->body = strdup(""); | ||||
|         n->icon = strdup(""); | ||||
|         n->timeout = 0; | ||||
|         n->urgency = urg; | ||||
|         n->progress = 0; | ||||
| @ -339,7 +342,12 @@ void update_lists() | ||||
|                 } | ||||
| 
 | ||||
|                 to_move = most_important(notification_queue); | ||||
|                 if (!to_move) { | ||||
|                         return; | ||||
|                 } | ||||
|                 n = (notification *) to_move->data; | ||||
|                 if (!n) | ||||
|                         return; | ||||
|                 n->start = now; | ||||
| 
 | ||||
|                 /* TODO get notifications pushed back into
 | ||||
| @ -358,7 +366,7 @@ void update_lists() | ||||
| int do_word_wrap(char *source, int max_width) | ||||
| { | ||||
| 
 | ||||
|         strtrim_end(source); | ||||
|         rstrip(source); | ||||
| 
 | ||||
|         if (!source || strlen(source) == 0) | ||||
|                 return 0; | ||||
| @ -403,39 +411,30 @@ int do_word_wrap(char *source, int max_width) | ||||
| 
 | ||||
| void update_draw_txt_buf(notification * n, int max_width) | ||||
| { | ||||
|         strtrim_end(n->msg); | ||||
|         rstrip(n->msg); | ||||
|         char *msg = n->msg; | ||||
|         while(isspace(*msg)) | ||||
|                 msg++; | ||||
| 
 | ||||
|         if (!n->draw_txt_buf.txt) { | ||||
|                 int dup_len = strlen(" () ") + digit_count(INT_MAX); | ||||
|                 int msg_len = strlen(msg) + 2;       /* 2 == surrounding spaces */ | ||||
|                 int age_len = strlen(" ( h 60m 60s old ) ") | ||||
|                     + digit_count(INT_MAX);     /* could be INT_MAX hours */ | ||||
|                 int line_length = dup_len + msg_len + age_len; | ||||
|         if (n->draw_txt_buf.txt) | ||||
|                 free(n->draw_txt_buf.txt); | ||||
| 
 | ||||
|                 line_length += sizeof(" ( more ) ") + digit_count(INT_MAX); | ||||
| 
 | ||||
|                 n->draw_txt_buf.txt = calloc(line_length, sizeof(char)); | ||||
|                 n->draw_txt_buf.bufsize = line_length; | ||||
|         } | ||||
| 
 | ||||
|         char *buf = n->draw_txt_buf.txt; | ||||
|         int bufsize = n->draw_txt_buf.bufsize; | ||||
|         char *next = buf; | ||||
| 
 | ||||
|         memset(buf, '\0', bufsize); | ||||
|         char *buf; | ||||
| 
 | ||||
|         /* print dup_count */ | ||||
|         if (n->dup_count > 0) { | ||||
|                 snprintf(next, bufsize - strlen(buf), "(%d) ", n->dup_count); | ||||
|                 next = buf + strlen(buf); | ||||
|                 asprintf(&buf, "(%d)", n->dup_count); | ||||
|         } else { | ||||
|                 buf = strdup(""); | ||||
|         } | ||||
| 
 | ||||
|         /* print msg */ | ||||
|         strncat(buf, msg, bufsize - strlen(buf)); | ||||
|         next = buf + strlen(buf); | ||||
|         { | ||||
|                 char *new_buf; | ||||
|                 asprintf(&new_buf, "%s %s", buf, msg); | ||||
|                 free(buf); | ||||
|                 buf = new_buf; | ||||
|         } | ||||
| 
 | ||||
|         /* print age */ | ||||
|         int hours, minutes, seconds; | ||||
| @ -446,20 +445,22 @@ void update_draw_txt_buf(notification * n, int max_width) | ||||
|                 minutes = t_delta / 60 % 60; | ||||
|                 seconds = t_delta % 60; | ||||
| 
 | ||||
|                 char *new_buf; | ||||
|                 if (hours > 0) { | ||||
|                         snprintf(next, bufsize - strlen(buf), | ||||
|                                  " (%dh %dm %ds old)", hours, minutes, seconds); | ||||
|                 } else if (minutes > 0) { | ||||
|                         snprintf(next, bufsize - strlen(buf), " (%dm %ds old)", | ||||
|                         asprintf(&new_buf, "%s (%dh %dm %ds old)", buf, hours, | ||||
|                                         minutes, seconds); | ||||
|                 } else if (minutes > 0) { | ||||
|                         asprintf(&new_buf, "%s (%dm %ds old)", buf, minutes, seconds); | ||||
|                 } else { | ||||
|                         snprintf(next, bufsize - strlen(buf), " (%ds old)", | ||||
|                                  seconds); | ||||
|                 } | ||||
|                         asprintf(&new_buf, "%s (%ds old)", buf, seconds); | ||||
|                 } | ||||
| 
 | ||||
|         n->draw_txt_buf.line_count = | ||||
|             do_word_wrap(n->draw_txt_buf.txt, max_width); | ||||
|                 free(buf); | ||||
|                 buf = new_buf; | ||||
|         } | ||||
| 
 | ||||
|         n->draw_txt_buf.line_count = do_word_wrap(buf, max_width); | ||||
|         n->draw_txt_buf.txt = buf; | ||||
| } | ||||
| 
 | ||||
| char *draw_txt_get_line(draw_txt * dt, int line) | ||||
| @ -1076,10 +1077,10 @@ void init_shortcut(keyboard_shortcut * ks) | ||||
|                         str++; | ||||
|                 *str = '\0'; | ||||
|                 str++; | ||||
|                 strtrim_end(mod); | ||||
|                 rstrip(mod); | ||||
|                 ks->mask = ks->mask | string_to_mask(mod); | ||||
|         } | ||||
|         strtrim_end(str); | ||||
|         rstrip(str); | ||||
| 
 | ||||
|         ks->sym = XStringToKeysym(str); | ||||
|         /* find matching keycode for ks->sym */ | ||||
| @ -1204,6 +1205,7 @@ int select_screen(XineramaScreenInfo * info, int info_len) | ||||
| 
 | ||||
|         } else { | ||||
|                 int x, y; | ||||
|                 assert(f_mode == FOLLOW_MOUSE || f_mode == FOLLOW_KEYBOARD); | ||||
|                 Window root = RootWindow(dc->dpy, DefaultScreen(dc->dpy)); | ||||
| 
 | ||||
|                 if (f_mode == FOLLOW_MOUSE) { | ||||
| @ -1248,10 +1250,9 @@ void update_screen_info() | ||||
| { | ||||
| #ifdef XINERAMA | ||||
|         int n; | ||||
|         int screen = scr.scr; | ||||
|         XineramaScreenInfo *info; | ||||
|         if ((info = XineramaQueryScreens(dc->dpy, &n))) { | ||||
|                 screen = select_screen(info, n); | ||||
|                 int screen = select_screen(info, n); | ||||
|                 if (screen >= n) { | ||||
|                         /* invalid monitor, fallback to default */ | ||||
|                         screen = 0; | ||||
| @ -1486,26 +1487,6 @@ void parse_cmdline(int argc, char *argv[]) | ||||
| } | ||||
| 
 | ||||
| #ifndef STATIC_CONFIG | ||||
| static int dunst_ini_get_boolean(const char *value) | ||||
| { | ||||
|         switch (value[0]) { | ||||
|         case 'y': | ||||
|         case 'Y': | ||||
|         case 't': | ||||
|         case 'T': | ||||
|         case '1': | ||||
|                 return True; | ||||
|         case 'n': | ||||
|         case 'N': | ||||
|         case 'f': | ||||
|         case 'F': | ||||
|         case '0': | ||||
|                 return False; | ||||
|         default: | ||||
|                 return False; | ||||
|         } | ||||
| } | ||||
| 
 | ||||
| static rule_t *dunst_rules_find_or_create(const char *section) | ||||
| { | ||||
|         l_node *iter; | ||||
| @ -1527,158 +1508,6 @@ static rule_t *dunst_rules_find_or_create(const char *section) | ||||
|         return rule; | ||||
| } | ||||
| 
 | ||||
| static char *dunst_ini_get_string(const char *value) | ||||
| { | ||||
|         char *s; | ||||
| 
 | ||||
|         if (value[0] == '"') | ||||
|                 s = strdup(value + 1); | ||||
|         else | ||||
|                 s = strdup(value); | ||||
| 
 | ||||
|         if (s[strlen(s) - 1] == '"') | ||||
|                 s[strlen(s) - 1] = '\0'; | ||||
| 
 | ||||
|         return s; | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| dunst_ini_handle(void *user_data, const char *section, | ||||
|                  const char *name, const char *value) | ||||
| { | ||||
|         if (strcmp(section, "global") == 0) { | ||||
|                 if (strcmp(name, "font") == 0) | ||||
|                         font = dunst_ini_get_string(value); | ||||
|                 else if (strcmp(name, "format") == 0) | ||||
|                         format = dunst_ini_get_string(value); | ||||
|                 else if (strcmp(name, "sort") == 0) | ||||
|                         sort = dunst_ini_get_boolean(value); | ||||
|                 else if (strcmp(name, "indicate_hidden") == 0) | ||||
|                         indicate_hidden = dunst_ini_get_boolean(value); | ||||
|                 else if (strcmp(name, "word_wrap") == 0) | ||||
|                         word_wrap = dunst_ini_get_boolean(value); | ||||
|                 else if (strcmp(name, "idle_threshold") == 0) | ||||
|                         idle_threshold = atoi(value); | ||||
|                 else if (strcmp(name, "monitor") == 0) | ||||
|                         scr.scr = atoi(value); | ||||
|                 else if (strcmp(name, "follow") == 0) { | ||||
|                         char *c = dunst_ini_get_string(value); | ||||
|                         parse_follow_mode(c); | ||||
|                         free(c); | ||||
|                 } else if (strcmp(name, "geometry") == 0) | ||||
|                         geom = dunst_ini_get_string(value); | ||||
|                 else if (strcmp(name, "line_height") == 0) | ||||
|                         line_height = atoi(value); | ||||
|                 else if (strcmp(name, "modifier") == 0) { | ||||
|                         deprecated_dunstrc_shortcuts = True; | ||||
|                         char *c = dunst_ini_get_string(value); | ||||
|                         KeySym mod = string_to_mask(c); | ||||
|                         free(c); | ||||
|                         close_ks.mask = mod; | ||||
|                         close_all_ks.mask = mod; | ||||
|                         history_ks.mask = mod; | ||||
|                 } else if (strcmp(name, "key") == 0) { | ||||
|                         close_ks.str = dunst_ini_get_string(value); | ||||
|                 } else if (strcmp(name, "all_key") == 0) { | ||||
|                         close_all_ks.str = dunst_ini_get_string(value); | ||||
|                 } else if (strcmp(name, "history_key") == 0) { | ||||
|                         history_ks.str = dunst_ini_get_string(value); | ||||
|                 } else if (strcmp(name, "bounce_freq") == 0) { | ||||
|                         bounce_freq = atof(value); | ||||
|                 } else if (strcmp(name, "alignment") == 0) { | ||||
|                         if (strcmp(value, "left") == 0) | ||||
|                                 align = left; | ||||
|                         else if (strcmp(value, "center") == 0) | ||||
|                                 align = center; | ||||
|                         else if (strcmp(value, "right") == 0) | ||||
|                                 align = right; | ||||
|                         /* FIXME warning on unknown alignment */ | ||||
|                 } else if (strcmp(name, "show_age_threshold") == 0) | ||||
|                         show_age_threshold = atoi(value); | ||||
|                 else if (strcmp(name, "sticky_history") == 0) | ||||
|                         sticky_history = dunst_ini_get_boolean(value); | ||||
|                 else if (strcmp(name, "separator_height") == 0) | ||||
|                         separator_height = atoi(value); | ||||
|                 else if (strcmp(name, "transparency") == 0) | ||||
|                         transparency = atoi(value); | ||||
|                 if (strcmp(name, "separator_color") == 0) { | ||||
|                         char *str = dunst_ini_get_string(value); | ||||
|                         if (strcmp(str, "auto") == 0) | ||||
|                                 sep_color = AUTO; | ||||
|                         else if (strcmp(str, "foreground") == 0) | ||||
|                                 sep_color = FOREGROUND; | ||||
|                         else | ||||
|                                 fprintf(stderr, "Warning: Unknown separator color\n"); | ||||
|                         free(str); | ||||
|                 } | ||||
|         } else if (strcmp(section, "urgency_low") == 0) { | ||||
|                 if (strcmp(name, "background") == 0) | ||||
|                         lowbgcolor = dunst_ini_get_string(value); | ||||
|                 else if (strcmp(name, "foreground") == 0) | ||||
|                         lowfgcolor = dunst_ini_get_string(value); | ||||
|                 else if (strcmp(name, "timeout") == 0) | ||||
|                         timeouts[LOW] = atoi(value); | ||||
| 
 | ||||
|         } else if (strcmp(section, "urgency_normal") == 0) { | ||||
|                 if (strcmp(name, "background") == 0) | ||||
|                         normbgcolor = dunst_ini_get_string(value); | ||||
|                 else if (strcmp(name, "foreground") == 0) | ||||
|                         normfgcolor = dunst_ini_get_string(value); | ||||
|                 else if (strcmp(name, "timeout") == 0) | ||||
|                         timeouts[NORM] = atoi(value); | ||||
| 
 | ||||
|         } else if (strcmp(section, "urgency_critical") == 0) { | ||||
|                 if (strcmp(name, "background") == 0) | ||||
|                         critbgcolor = dunst_ini_get_string(value); | ||||
|                 else if (strcmp(name, "foreground") == 0) | ||||
|                         critfgcolor = dunst_ini_get_string(value); | ||||
|                 else if (strcmp(name, "timeout") == 0) | ||||
|                         timeouts[CRIT] = atoi(value); | ||||
| 
 | ||||
|         } else if (strcmp(section, "shortcuts") == 0) { | ||||
|                 if (strcmp(name, "close") == 0) | ||||
|                         close_ks.str = dunst_ini_get_string(value); | ||||
|                 else if (strcmp(name, "close_all") == 0) | ||||
|                         close_all_ks.str = dunst_ini_get_string(value); | ||||
|                 else if (strcmp(name, "history") == 0) | ||||
|                         history_ks.str = dunst_ini_get_string(value); | ||||
|         } else { | ||||
| 
 | ||||
|                 rule_t *current_rule = dunst_rules_find_or_create(section); | ||||
| 
 | ||||
|                 if (strcmp(name, "appname") == 0) | ||||
|                         current_rule->appname = dunst_ini_get_string(value); | ||||
|                 else if (strcmp(name, "summary") == 0) | ||||
|                         current_rule->summary = dunst_ini_get_string(value); | ||||
|                 else if (strcmp(name, "body") == 0) | ||||
|                         current_rule->body = dunst_ini_get_string(value); | ||||
|                 else if (strcmp(name, "icon") == 0) | ||||
|                         current_rule->icon = dunst_ini_get_string(value); | ||||
|                 else if (strcmp(name, "timeout") == 0) | ||||
|                         current_rule->timeout = atoi(value); | ||||
|                 else if (strcmp(name, "urgency") == 0) { | ||||
|                         const char *urg = value; | ||||
| 
 | ||||
|                         if (strcmp(urg, "low") == 0) | ||||
|                                 current_rule->urgency = LOW; | ||||
|                         else if (strcmp(urg, "normal") == 0) | ||||
|                                 current_rule->urgency = NORM; | ||||
|                         else if (strcmp(urg, "critical") == 0) | ||||
|                                 current_rule->urgency = CRIT; | ||||
|                         else | ||||
|                                 fprintf(stderr, | ||||
|                                         "unknown urgency: %s, ignoring\n", urg); | ||||
|                 } else if (strcmp(name, "foreground") == 0) | ||||
|                         current_rule->fg = dunst_ini_get_string(value); | ||||
|                 else if (strcmp(name, "background") == 0) | ||||
|                         current_rule->bg = dunst_ini_get_string(value); | ||||
|                 else if (strcmp(name, "format") == 0) | ||||
|                         current_rule->format = dunst_ini_get_string(value); | ||||
|         } | ||||
| 
 | ||||
|         return 1; | ||||
| } | ||||
| 
 | ||||
| void parse_dunstrc(char *cmdline_config_path) | ||||
| { | ||||
| 
 | ||||
| @ -1704,15 +1533,133 @@ void parse_dunstrc(char *cmdline_config_path) | ||||
|                 } | ||||
|         } | ||||
| 
 | ||||
|         if (ini_parse_file(config_file, dunst_ini_handle, NULL) < 0) { | ||||
|                 puts("dunstrc could not be parsed -> skipping\n"); | ||||
|         load_ini_file(config_file); | ||||
| 
 | ||||
|         font = ini_get_string("global", "font", font); | ||||
|         format = ini_get_string("global", "format", format); | ||||
|         sort = ini_get_bool("global", "sort", sort); | ||||
|         indicate_hidden = ini_get_bool("global", "indicate_hidden", indicate_hidden); | ||||
|         word_wrap = ini_get_bool("global", "word_wrap", word_wrap); | ||||
|         idle_threshold = ini_get_int("global", "idle_threshold", idle_threshold); | ||||
|         monitor = ini_get_int("global", "monitor", monitor); | ||||
|         { | ||||
|                 char *c = ini_get_string("global", "follow", ""); | ||||
|                 if (strlen(c) > 0) { | ||||
|                         parse_follow_mode(c); | ||||
|                         free(c); | ||||
|                 } | ||||
|         } | ||||
|         geom = ini_get_string("global", "geometry", geom); | ||||
|         line_height = ini_get_int("global", "line_height", line_height); | ||||
|         { | ||||
|                 char *c = ini_get_string("global", "modifier", ""); | ||||
|                 if (strlen(c) > 0) { | ||||
|                         deprecated_dunstrc_shortcuts = True; | ||||
|                         KeySym mod = string_to_mask(c); | ||||
|                         close_ks.mask = mod; | ||||
|                         close_all_ks.mask = mod; | ||||
|                         close_all_ks.mask = mod; | ||||
|                         free(c); | ||||
|                 } | ||||
|         } | ||||
|         close_ks.str = ini_get_string("global", "key", close_ks.str); | ||||
|         close_all_ks.str = ini_get_string("global", "key", close_all_ks.str); | ||||
|         history_ks.str = ini_get_string("global", "key", history_ks.str); | ||||
|         bounce_freq = ini_get_double("global", "bounce_freq", bounce_freq); | ||||
|         { | ||||
|                 char *c = ini_get_string("global", "alignment", ""); | ||||
|                 if (strlen(c) > 0) { | ||||
|                         if (strcmp(c, "left") == 0) | ||||
|                                 align = left; | ||||
|                         else if (strcmp(c, "center") == 0) | ||||
|                                 align = center; | ||||
|                         else if (strcmp(c, "right") == 0) | ||||
|                                 align = right; | ||||
|                         else | ||||
|                                 fprintf(stderr, "Warning: unknown allignment\n"); | ||||
|                         free(c); | ||||
|                 } | ||||
|         } | ||||
|         show_age_threshold = ini_get_int("global", "show_age_threshold", show_age_threshold); | ||||
|         sticky_history = ini_get_bool("global", "sticky_history", sticky_history); | ||||
|         separator_height = ini_get_int("global", "separator_height", separator_height); | ||||
|         transparency = ini_get_int("global", "transparency", transparency); | ||||
|         { | ||||
|                 char *c = ini_get_string("global", "separator_color", ""); | ||||
|                 if (strlen(c) > 0) { | ||||
|                         if (strcmp(c, "auto") == 0) | ||||
|                                 sep_color = AUTO; | ||||
|                         else if (strcmp(c, "foreground") == 0) | ||||
|                                 sep_color = FOREGROUND; | ||||
|                         else | ||||
|                                 fprintf(stderr, "Warning: Unknown separator color\n"); | ||||
|                         free(c); | ||||
|                 } | ||||
|         } | ||||
| 
 | ||||
|         lowbgcolor = ini_get_string("urgency_low", "background", lowbgcolor); | ||||
|         lowfgcolor = ini_get_string("urgency_low", "foreground", lowfgcolor); | ||||
|         timeouts[LOW] = ini_get_int("urgency_low", "timeout", timeouts[LOW]); | ||||
|         normbgcolor = ini_get_string("urgency_normal", "background", normbgcolor); | ||||
|         normfgcolor = ini_get_string("urgency_normal", "foreground", normfgcolor); | ||||
|         timeouts[NORM] = ini_get_int("urgency_normal", "timeout", timeouts[NORM]); | ||||
|         critbgcolor = ini_get_string("urgency_critical", "background", critbgcolor); | ||||
|         critfgcolor = ini_get_string("urgency_critical", "foreground", critfgcolor); | ||||
|         timeouts[CRIT] = ini_get_int("urgency_critical", "timeout", timeouts[CRIT]); | ||||
| 
 | ||||
|         close_ks.str = ini_get_string("shortcuts", "close", close_ks.str); | ||||
|         close_all_ks.str = ini_get_string("shortcuts", "close_all", close_all_ks.str); | ||||
|         history_ks.str = ini_get_string("shortcuts", "history", history_ks.str); | ||||
| 
 | ||||
| 
 | ||||
|         char *cur_section = NULL; | ||||
|         for (; cur_section; cur_section = next_section(cur_section)) { | ||||
|                 if (strcmp(cur_section, "global") == 0 | ||||
|                  || strcmp(cur_section, "shortcuts") == 0 | ||||
|                  || strcmp(cur_section, "urgency_low") == 0 | ||||
|                  || strcmp(cur_section, "urgency_normal") == 0 | ||||
|                  || strcmp(cur_section, "urgency_critical") == 0) | ||||
|                         continue; | ||||
| 
 | ||||
|                 rule_t *current_rule = dunst_rules_find_or_create(cur_section); | ||||
|                 current_rule->appname = ini_get_string( | ||||
|                                 cur_section, "appname", current_rule->appname); | ||||
|                 current_rule->summary = ini_get_string( | ||||
|                                 cur_section, "summary", current_rule->summary); | ||||
|                 current_rule->body = ini_get_string( | ||||
|                                 cur_section, "body", current_rule->body); | ||||
|                 current_rule->icon = ini_get_string( | ||||
|                                 cur_section, "icon", current_rule->icon); | ||||
|                 current_rule->timeout = ini_get_int( | ||||
|                                 cur_section, "timeout", current_rule->timeout); | ||||
|                 { | ||||
|                         char *urg = ini_get_string(cur_section, "urgency", ""); | ||||
|                         if (strlen(urg) > 0) { | ||||
|                                 if (strcmp(urg, "low") == 0) | ||||
|                                         current_rule->urgency = LOW; | ||||
|                                 else if (strcmp(urg, "normal") == 0) | ||||
|                                         current_rule->urgency = NORM; | ||||
|                                 else if (strcmp(urg, "critical") == 0) | ||||
|                                         current_rule->urgency = CRIT; | ||||
|                                 else | ||||
|                                         fprintf(stderr, | ||||
|                                                 "unknown urgency: %s, ignoring\n", urg); | ||||
|                                 free(urg); | ||||
|                         } | ||||
|                 } | ||||
|                 current_rule->fg = ini_get_string( | ||||
|                                 cur_section, "foreground", current_rule->fg); | ||||
|                 current_rule->bg = ini_get_string( | ||||
|                                 cur_section, "background", current_rule->bg); | ||||
|                 current_rule->format = ini_get_string( | ||||
|                                 cur_section, "format", current_rule->format); | ||||
|         } | ||||
| 
 | ||||
|         fclose(config_file); | ||||
|         free_ini(); | ||||
|         xdgWipeHandle(&xdg); | ||||
| 
 | ||||
| } | ||||
| #endif                          /* STATIC_CONFIG */ | ||||
| 
 | ||||
| 
 | ||||
| char *parse_cmdline_for_config_file(int argc, char *argv[]) | ||||
| { | ||||
| @ -1727,6 +1674,7 @@ char *parse_cmdline_for_config_file(int argc, char *argv[]) | ||||
|         } | ||||
|         return NULL; | ||||
| } | ||||
| #endif                          /* STATIC_CONFIG */ | ||||
| 
 | ||||
| int main(int argc, char *argv[]) | ||||
| { | ||||
|  | ||||
							
								
								
									
										1
									
								
								dunst.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								dunst.h
									
									
									
									
									
								
							| @ -33,7 +33,6 @@ typedef struct _screen_info { | ||||
| typedef struct _draw_txt { | ||||
|         char *txt; | ||||
|         int line_count; | ||||
|         int bufsize; | ||||
| } draw_txt; | ||||
| 
 | ||||
| typedef struct _notification { | ||||
|  | ||||
							
								
								
									
										176
									
								
								ini.c
									
									
									
									
									
								
							
							
						
						
									
										176
									
								
								ini.c
									
									
									
									
									
								
							| @ -1,176 +0,0 @@ | ||||
| /* inih -- simple .INI file parser
 | ||||
| 
 | ||||
| inih is released under the New BSD license. Go to the project | ||||
| home page for more info: | ||||
| 
 | ||||
| The "inih" library is distributed under the New BSD license: | ||||
| 
 | ||||
| Copyright (c) 2009, Brush Technology | ||||
| All rights reserved. | ||||
| 
 | ||||
| Redistribution and use in source and binary forms, with or without | ||||
| modification, are permitted provided that the following conditions are met: | ||||
|     * Redistributions of source code must retain the above copyright | ||||
|       notice, this list of conditions and the following disclaimer. | ||||
|     * Redistributions in binary form must reproduce the above copyright | ||||
|       notice, this list of conditions and the following disclaimer in the | ||||
|       documentation and/or other materials provided with the distribution. | ||||
|     * Neither the name of Brush Technology nor the names of its contributors | ||||
|       may be used to endorse or promote products derived from this software | ||||
|       without specific prior written permission. | ||||
| 
 | ||||
| THIS SOFTWARE IS PROVIDED BY BRUSH TECHNOLOGY ''AS IS'' AND ANY | ||||
| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||||
| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||||
| DISCLAIMED. IN NO EVENT SHALL BRUSH TECHNOLOGY BE LIABLE FOR ANY | ||||
| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||||
| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||||
| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||||
| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||||
| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
| 
 | ||||
| http://code.google.com/p/inih/
 | ||||
| 
 | ||||
| */ | ||||
| 
 | ||||
| #include <stdio.h> | ||||
| #include <ctype.h> | ||||
| #include <string.h> | ||||
| 
 | ||||
| #include "ini.h" | ||||
| 
 | ||||
| #define MAX_LINE 200 | ||||
| #define MAX_SECTION 50 | ||||
| #define MAX_NAME 50 | ||||
| 
 | ||||
| /* Strip whitespace chars off end of given string, in place. Return s. */ | ||||
| static char* rstrip(char* s) | ||||
| { | ||||
|     char* p = s + strlen(s); | ||||
|     while (p > s && isspace(*--p)) | ||||
|         *p = '\0'; | ||||
|     return s; | ||||
| } | ||||
| 
 | ||||
| /* Return pointer to first non-whitespace char in given string. */ | ||||
| static char* lskip(const char* s) | ||||
| { | ||||
|     while (*s && isspace(*s)) | ||||
|         s++; | ||||
|     return (char*)s; | ||||
| } | ||||
| 
 | ||||
| /* Return pointer to first char c or ';' comment in given string, or pointer to
 | ||||
|    null at end of string if neither found. ';' must be prefixed by a whitespace | ||||
|    character to register as a comment. */ | ||||
| static char* find_char_or_comment(const char* s, char c) | ||||
| { | ||||
|     int was_whitespace = 0; | ||||
|     while (*s && *s != c && !(was_whitespace && *s == ';')) { | ||||
|         was_whitespace = isspace(*s); | ||||
|         s++; | ||||
|     } | ||||
|     return (char*)s; | ||||
| } | ||||
| 
 | ||||
| /* Version of strncpy that ensures dest (size bytes) is null-terminated. */ | ||||
| static char* strncpy0(char* dest, const char* src, size_t size) | ||||
| { | ||||
|     strncpy(dest, src, size); | ||||
|     dest[size - 1] = '\0'; | ||||
|     return dest; | ||||
| } | ||||
| 
 | ||||
| /* See documentation in header file. */ | ||||
| int ini_parse_file(FILE* file, | ||||
|                    int (*handler)(void*, const char*, const char*, | ||||
|                                   const char*), | ||||
|                    void* user) | ||||
| { | ||||
|     /* Uses a fair bit of stack (use heap instead if you need to) */ | ||||
|     char line[MAX_LINE]; | ||||
|     char section[MAX_SECTION] = ""; | ||||
|     char prev_name[MAX_NAME] = ""; | ||||
| 
 | ||||
|     char* start; | ||||
|     char* end; | ||||
|     char* name; | ||||
|     char* value; | ||||
|     int lineno = 0; | ||||
|     int error = 0; | ||||
| 
 | ||||
|     /* Scan through file line by line */ | ||||
|     while (fgets(line, sizeof(line), file) != NULL) { | ||||
|         lineno++; | ||||
|         start = lskip(rstrip(line)); | ||||
| 
 | ||||
|         if (*start == ';' || *start == '#') { | ||||
|             /* Per Python ConfigParser, allow '#' comments at start of line */ | ||||
|         } | ||||
| #if INI_ALLOW_MULTILINE | ||||
|         else if (*prev_name && *start && start > line) { | ||||
|             /* Non-black line with leading whitespace, treat as continuation
 | ||||
|                of previous name's value (as per Python ConfigParser). */ | ||||
|             if (!handler(user, section, prev_name, start) && !error) | ||||
|                 error = lineno; | ||||
|         } | ||||
| #endif | ||||
|         else if (*start == '[') { | ||||
|             /* A "[section]" line */ | ||||
|             end = find_char_or_comment(start + 1, ']'); | ||||
|             if (*end == ']') { | ||||
|                 *end = '\0'; | ||||
|                 strncpy0(section, start + 1, sizeof(section)); | ||||
|                 *prev_name = '\0'; | ||||
|             } | ||||
|             else if (!error) { | ||||
|                 /* No ']' found on section line */ | ||||
|                 error = lineno; | ||||
|             } | ||||
|         } | ||||
|         else if (*start && *start != ';') { | ||||
|             /* Not a comment, must be a name[=:]value pair */ | ||||
|             end = find_char_or_comment(start, '='); | ||||
|             if (*end != '=') { | ||||
|                 end = find_char_or_comment(start, ':'); | ||||
|             } | ||||
|             if (*end == '=' || *end == ':') { | ||||
|                 *end = '\0'; | ||||
|                 name = rstrip(start); | ||||
|                 value = lskip(end + 1); | ||||
|                 end = find_char_or_comment(value, '\0'); | ||||
|                 if (*end == ';') | ||||
|                     *end = '\0'; | ||||
|                 rstrip(value); | ||||
| 
 | ||||
|                 /* Valid name[=:]value pair found, call handler */ | ||||
|                 strncpy0(prev_name, name, sizeof(prev_name)); | ||||
|                 if (!handler(user, section, name, value) && !error) | ||||
|                     error = lineno; | ||||
|             } | ||||
|             else if (!error) { | ||||
|                 /* No '=' or ':' found on name[=:]value line */ | ||||
|                 error = lineno; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return error; | ||||
| } | ||||
| 
 | ||||
| /* See documentation in header file. */ | ||||
| int ini_parse(const char* filename, | ||||
|               int (*handler)(void*, const char*, const char*, const char*), | ||||
|               void* user) | ||||
| { | ||||
|     FILE* file; | ||||
|     int error; | ||||
| 
 | ||||
|     file = fopen(filename, "r"); | ||||
|     if (!file) | ||||
|         return -1; | ||||
|     error = ini_parse_file(file, handler, user); | ||||
|     fclose(file); | ||||
|     return error; | ||||
| } | ||||
							
								
								
									
										83
									
								
								ini.h
									
									
									
									
									
								
							
							
						
						
									
										83
									
								
								ini.h
									
									
									
									
									
								
							| @ -1,83 +0,0 @@ | ||||
| /* inih -- simple .INI file parser
 | ||||
| 
 | ||||
| inih is released under the New BSD license. Go to the project | ||||
| home page for more info: | ||||
| 
 | ||||
| The "inih" library is distributed under the New BSD license: | ||||
| 
 | ||||
| Copyright (c) 2009, Brush Technology | ||||
| All rights reserved. | ||||
| 
 | ||||
| Redistribution and use in source and binary forms, with or without | ||||
| modification, are permitted provided that the following conditions are met: | ||||
|     * Redistributions of source code must retain the above copyright | ||||
|       notice, this list of conditions and the following disclaimer. | ||||
|     * Redistributions in binary form must reproduce the above copyright | ||||
|       notice, this list of conditions and the following disclaimer in the | ||||
|       documentation and/or other materials provided with the distribution. | ||||
|     * Neither the name of Brush Technology nor the names of its contributors | ||||
|       may be used to endorse or promote products derived from this software | ||||
|       without specific prior written permission. | ||||
| 
 | ||||
| THIS SOFTWARE IS PROVIDED BY BRUSH TECHNOLOGY ''AS IS'' AND ANY | ||||
| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||||
| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||||
| DISCLAIMED. IN NO EVENT SHALL BRUSH TECHNOLOGY BE LIABLE FOR ANY | ||||
| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||||
| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||||
| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||||
| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||||
| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
| 
 | ||||
| 
 | ||||
| http://code.google.com/p/inih/
 | ||||
| 
 | ||||
| */ | ||||
| 
 | ||||
| #ifndef __INI_H__ | ||||
| #define __INI_H__ | ||||
| 
 | ||||
| /* Make this header file easier to include in C++ code */ | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
| 
 | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| /* Parse given INI-style file. May have [section]s, name=value pairs
 | ||||
|    (whitespace stripped), and comments starting with ';' (semicolon). Section | ||||
|    is "" if name=value pair parsed before any section heading. name:value | ||||
|    pairs are also supported as a concession to Python's ConfigParser. | ||||
| 
 | ||||
|    For each name=value pair parsed, call handler function with given user | ||||
|    pointer as well as section, name, and value (data only valid for duration | ||||
|    of handler call). Handler should return nonzero on success, zero on error. | ||||
| 
 | ||||
|    Returns 0 on success, line number of first error on parse error (doesn't | ||||
|    stop on first error), or -1 on file open error. | ||||
| */ | ||||
| int ini_parse(const char* filename, | ||||
|               int (*handler)(void* user, const char* section, | ||||
|                              const char* name, const char* value), | ||||
|               void* user); | ||||
| 
 | ||||
| /* Same as ini_parse(), but takes a FILE* instead of filename. This doesn't
 | ||||
|    close the file when it's finished -- the caller must do that. */ | ||||
| int ini_parse_file(FILE* file, | ||||
|                    int (*handler)(void* user, const char* section, | ||||
|                                   const char* name, const char* value), | ||||
|                    void* user); | ||||
| 
 | ||||
| /* Nonzero to allow multi-line value parsing, in the style of Python's
 | ||||
|    ConfigParser. If allowed, ini_parse() will call the handler with the same | ||||
|    name for each subsequent line parsed. */ | ||||
| #ifndef INI_ALLOW_MULTILINE | ||||
| #define INI_ALLOW_MULTILINE 1 | ||||
| #endif | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| #endif /* __INI_H__ */ | ||||
							
								
								
									
										254
									
								
								options.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										254
									
								
								options.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,254 @@ | ||||
| /* copyright 2012 Sascha Kruse and contributors (see LICENSE for licensing information) */ | ||||
| #include <string.h> | ||||
| #include <stdlib.h> | ||||
| #include <unistd.h> | ||||
| #include <stdbool.h> | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| #include "options.h" | ||||
| #include "utils.h" | ||||
| 
 | ||||
| typedef struct _entry_t { | ||||
|     char *key; | ||||
|     char *value; | ||||
| } entry_t; | ||||
| 
 | ||||
| typedef struct _section_t { | ||||
|     char *name; | ||||
|     int entry_count; | ||||
|     entry_t *entries; | ||||
| } section_t; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| static int section_count; | ||||
| static section_t *sections; | ||||
| 
 | ||||
| static section_t *new_section(char *name); | ||||
| static section_t *get_section(char *name); | ||||
| static void add_entry(char *section_name, char *key, char *value); | ||||
| static char *get_value(char *section, char *key); | ||||
| static char *clean_value(char *value); | ||||
| 
 | ||||
| section_t *new_section(char *name) | ||||
| { | ||||
|         section_count++; | ||||
|         sections = realloc(sections, sizeof(section_t) *section_count); | ||||
|         sections[section_count - 1].name = strdup(name); | ||||
|         sections[section_count - 1].entries = NULL; | ||||
|         sections[section_count - 1].entry_count = 0; | ||||
|         return §ions[section_count -1]; | ||||
| } | ||||
| 
 | ||||
| void free_ini(void) | ||||
| { | ||||
|         for(int i = 0; i < section_count; i++) { | ||||
|                 for (int j = 0; j < sections[i].entry_count; j++) { | ||||
|                         free(sections[i].entries[j].key); | ||||
|                         free(sections[i].entries[j].value); | ||||
|                 } | ||||
|                 free(sections[i].entries); | ||||
|                 free(sections[i].name); | ||||
|         } | ||||
|         free(sections); | ||||
| } | ||||
| 
 | ||||
| section_t *get_section(char *name) | ||||
| { | ||||
|         for (int i = 0; i < section_count; i++) { | ||||
|                 if (strcmp(sections[i].name, name) == 0) | ||||
|                         return §ions[i]; | ||||
|         } | ||||
| 
 | ||||
|         return NULL; | ||||
| } | ||||
| 
 | ||||
| void add_entry(char *section_name, char *key, char *value) | ||||
| { | ||||
|         section_t *s = get_section(section_name); | ||||
|         if (s == NULL) { | ||||
|                 s = new_section(section_name); | ||||
|         } | ||||
| 
 | ||||
|         s->entry_count++; | ||||
|         int len = s->entry_count; | ||||
|         s->entries = realloc(s->entries, sizeof(entry_t) * len); | ||||
|         s->entries[s->entry_count - 1].key = strdup(key); | ||||
|         s->entries[s->entry_count - 1].value = clean_value(value); | ||||
| } | ||||
| 
 | ||||
| char *get_value(char *section, char *key) | ||||
| { | ||||
|         section_t *s = get_section(section); | ||||
|         if (!s) { | ||||
|                 return NULL; | ||||
|         } | ||||
| 
 | ||||
|         for (int i = 0; i < s->entry_count; i++) { | ||||
|                 if (strcmp(s->entries[i].key, key) == 0) { | ||||
|                         return s->entries[i].value; | ||||
|                 } | ||||
|         } | ||||
|         return NULL; | ||||
| } | ||||
| 
 | ||||
| char *ini_get_string(char *section, char *key, const char *def) | ||||
| { | ||||
|         char *value = get_value(section, key); | ||||
|         if (value == NULL) | ||||
|                 return def; | ||||
|         else | ||||
|                 return strdup(value); | ||||
| } | ||||
| 
 | ||||
| int ini_get_int(char *section, char *key, int def) | ||||
| { | ||||
|         char *value = get_value(section, key); | ||||
|         if (value == NULL) | ||||
|                 return def; | ||||
|         else | ||||
|                 return atoi(value); | ||||
| } | ||||
| 
 | ||||
| double ini_get_double(char *section, char *key, int def) | ||||
| { | ||||
|         char *value = get_value(section, key); | ||||
|         if (value == NULL) | ||||
|                 return def; | ||||
|         else | ||||
|                 return atof(value); | ||||
| } | ||||
| 
 | ||||
| char *next_section(char *section) | ||||
| { | ||||
|         if (section_count == 0) | ||||
|                 return NULL; | ||||
| 
 | ||||
|         for (int i = 0; i < section_count; i++) { | ||||
|                 if (strcmp(section, sections[i].name) == 0) { | ||||
|                         if (i + 1 >= section_count) | ||||
|                                 return NULL; | ||||
|                         else | ||||
|                                 return sections[i+1].name; | ||||
|                 } | ||||
|         } | ||||
|         return NULL; | ||||
| } | ||||
| 
 | ||||
| int ini_get_bool(char *section, char *key, int def) | ||||
| { | ||||
|         char *value = get_value(section, key); | ||||
|         if (value == NULL) | ||||
|                 return def; | ||||
|         else { | ||||
|                 switch (value[0]) { | ||||
|                 case 'y': | ||||
|                 case 'Y': | ||||
|                 case 't': | ||||
|                 case 'T': | ||||
|                 case '1': | ||||
|                         return true; | ||||
|                 case 'n': | ||||
|                 case 'N': | ||||
|                 case 'f': | ||||
|                 case 'F': | ||||
|                 case '0': | ||||
|                         return false; | ||||
|                 default: | ||||
|                         return false; | ||||
|                 } | ||||
|         } | ||||
| } | ||||
| 
 | ||||
| char *clean_value(char *value) | ||||
| { | ||||
|         char *s; | ||||
| 
 | ||||
|         if (value[0] == '"') | ||||
|                 s = strdup(value + 1); | ||||
|         else | ||||
|                 s = strdup(value); | ||||
| 
 | ||||
|         if (s[strlen(s) - 1] == '"') | ||||
|                 s[strlen(s) - 1] = '\0'; | ||||
| 
 | ||||
|         return s; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| int load_ini_file(FILE *fp) | ||||
| { | ||||
|         char line[BUFSIZ]; | ||||
| 
 | ||||
|         int line_num = 0; | ||||
|         char *current_section = NULL; | ||||
|         while (fgets(line, sizeof(line), fp) != NULL) { | ||||
|                 line_num++; | ||||
| 
 | ||||
|                 char *start = lskip(rstrip(line)); | ||||
| 
 | ||||
|                 if (*start == ';' || *start == '#' || strlen(start) == 0) | ||||
|                         continue; | ||||
| 
 | ||||
|                 if (*start == '[') { | ||||
|                         char *end = strstr(start + 1, "]"); | ||||
|                         if (!end) { | ||||
|                                 printf("Warning: invalid config file at line %d\n", line_num); | ||||
|                                 printf("Missing ']'\n"); | ||||
|                                 continue; | ||||
|                         } | ||||
| 
 | ||||
|                         *end = '\0'; | ||||
| 
 | ||||
|                         if (current_section) | ||||
|                                 free(current_section); | ||||
|                         current_section = (strdup(start+1)); | ||||
|                         new_section(current_section); | ||||
|                         continue; | ||||
|                 } | ||||
| 
 | ||||
|                 char *equal = strstr(start + 1, "="); | ||||
|                 if (!equal) { | ||||
|                         printf("Warning: invalid config file at line %d\n", line_num); | ||||
|                         printf("Missing '='\n"); | ||||
|                         continue; | ||||
|                 } | ||||
| 
 | ||||
|                 *equal = '\0'; | ||||
|                 char *key = rstrip(start); | ||||
|                 char *value = lskip(equal+1); | ||||
| 
 | ||||
|                 char *quote = strstr(value, "\""); | ||||
|                 if (quote) { | ||||
|                         char *closing_quote = strstr(quote + 1, "\""); | ||||
|                         if (!closing_quote) { | ||||
|                                 printf("Warning: invalid config file at line %d\n", line_num); | ||||
|                                 printf("Missing '\"'\n"); | ||||
|                                 continue; | ||||
|                         } | ||||
| 
 | ||||
|                         closing_quote = '\0'; | ||||
|                 } else { | ||||
|                         char *comment = strstr(value, "#"); | ||||
|                         if (!comment) | ||||
|                                 comment = strstr(value, ";"); | ||||
|                         if (comment) | ||||
|                                 comment = '\0'; | ||||
|                 } | ||||
|                 value = rstrip(value); | ||||
| 
 | ||||
|                 if (!current_section) { | ||||
|                         printf("Warning: invalid config file at line: %d\n", line_num); | ||||
|                         printf("Key value pair without a section\n"); | ||||
|                         continue; | ||||
|                 } | ||||
| 
 | ||||
|                 add_entry(current_section, key, value); | ||||
|         } | ||||
|         if (current_section) | ||||
|                 free(current_section); | ||||
|         return 0; | ||||
| } | ||||
| /* vim: set ts=8 sw=8 tw=0: */ | ||||
							
								
								
									
										20
									
								
								options.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								options.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
| /* copyright 2012 Sascha Kruse and contributors (see LICENSE for licensing information) */ | ||||
| #pragma once | ||||
| 
 | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| 
 | ||||
| int load_ini_file(FILE *); | ||||
| char *ini_get_string(char *section, char *key, const char *def); | ||||
| int ini_get_int(char *section, char *key, int def); | ||||
| double ini_get_double(char *section, char *key, int def); | ||||
| int ini_get_bool(char *section, char *key, int def); | ||||
| void free_ini(void); | ||||
| 
 | ||||
| /* returns the next known section.
 | ||||
|  * if section == NULL returns first section. | ||||
|  * returns NULL if no more sections are available | ||||
|  */ | ||||
| char *next_section(char *section); | ||||
| 
 | ||||
| /* vim: set ts=8 sw=8 tw=0: */ | ||||
							
								
								
									
										9
									
								
								utils.c
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								utils.c
									
									
									
									
									
								
							| @ -7,7 +7,7 @@ | ||||
| #include "dunst.h" | ||||
| 
 | ||||
| 
 | ||||
| void strtrim_end(char *str) | ||||
| char *rstrip(char *str) | ||||
| { | ||||
|         char *end; | ||||
|         end = str + strlen(str) - 1; | ||||
| @ -15,6 +15,13 @@ void strtrim_end(char *str) | ||||
|                 *end = '\0'; | ||||
|                 end--; | ||||
|         } | ||||
|         return str; | ||||
| } | ||||
| 
 | ||||
| char *lskip(char *s) | ||||
| { | ||||
|         for(; *s && isspace(*s); s++); | ||||
|         return s; | ||||
| } | ||||
| 
 | ||||
| char *string_replace(const char *needle, const char *replacement, | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Sascha Kruse
						Sascha Kruse