diff --git a/CMakeLists.txt b/CMakeLists.txt index c5159c1..65eedcb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,8 +24,7 @@ project(${PROJECT_NAME} C) # Definition of the wmfs source set(wmfs_src - src/confparse/util.c - src/confparse/confparse.c + src/parse/parse.c src/barwin.c src/client.c src/config.c diff --git a/src/config.c b/src/config.c index 3b0293e..905ca08 100644 --- a/src/config.c +++ b/src/config.c @@ -32,9 +32,6 @@ #include "wmfs.h" -/* local function definition */ -static void conf_section(void (*)(char*), char *, char *); - func_name_list_t tmp_func_list[] = { {"spawn", uicb_spawn }, @@ -115,46 +112,38 @@ name_to_uint_t mouse_button_list[] = }; void -mouse_section(MouseBinding mb[], char *src, int ns) +mouse_section(MouseBinding mb[], int ns, struct conf_sec **sec) { - int i; - char *tmp; + int n; - for(i = 0; i < ns; ++i) + for (n = 0; sec[n]; n++) { - tmp = get_nsec(src, "mouse", i); - - cfg_set_sauv(tmp); - - mb[i].tag = get_opt(tmp, "-1", "tag").num; - mb[i].screen = get_opt(tmp, "-1", "screen").num; - mb[i].button = char_to_button(get_opt(tmp, "1", "button").str, mouse_button_list); - mb[i].func = name_to_func(get_opt(tmp, "", "func").str, func_list); - mb[i].cmd = get_opt(tmp, "", "cmd").str; - - cfg_set_sauv(src); + mb[n].tag = fetch_opt(sec[n], "-1", "tag")[0].num; + mb[n].screen = fetch_opt(sec[n], "-1", "screen")[0].num; + mb[n].button = char_to_button(fetch_opt(sec[n], "1", "button")[0].str, mouse_button_list); + mb[n].func = name_to_func(fetch_opt(sec[n], "", "func")[0].str, func_list); + mb[n].cmd = fetch_opt(sec[n], "", "cmd")[0].str; } - - return; } void -conf_misc_section(char *src) +conf_misc_section(void) { int pad = 12; + struct conf_sec **sec; - cfg_set_sauv(src); + sec = fetch_section(NULL, "misc"); - conf.font = get_opt(src, "sans-9", "font").str; - conf.raisefocus = get_opt(src, "false", "raisefocus").bool; - conf.raiseswitch = get_opt(src, "false", "raiseswitch").bool; - conf.focus_fmouse = get_opt(src, "true", "focus_follow_mouse").bool; - conf.focus_pclick = get_opt(src, "true", "focus_pointer_click").bool; - conf.status_timing = get_opt(src, "1", "status_timing").num; - conf.status_path = get_opt(src, "", "status_path").str; - conf.autostart_path = get_opt(src, "", "autostart_path").str; - conf.autostart_command = get_opt(src, "", "autostart_command").str; - pad = get_opt(src, "12", "pad").num; + conf.font = fetch_opt(sec[0], "sans-9", "font")[0].str; + conf.raisefocus = fetch_opt(sec[0], "false", "raisefocus")[0].bool; + conf.raiseswitch = fetch_opt(sec[0], "false", "raiseswitch")[0].bool; + conf.focus_fmouse = fetch_opt(sec[0], "true", "focus_follow_mouse")[0].bool; + conf.focus_pclick = fetch_opt(sec[0], "true", "focus_pointer_click")[0].bool; + conf.status_timing = fetch_opt(sec[0], "1", "status_timing")[0].num; + conf.status_path = fetch_opt(sec[0], "", "status_path")[0].str; + conf.autostart_path = fetch_opt(sec[0], "", "autostart_path")[0].str; + conf.autostart_command = fetch_opt(sec[0], "", "autostart_command")[0].str; + pad = fetch_opt(sec[0], "12", "pad")[0].num; if(pad > 24 || pad < 1) { @@ -171,159 +160,203 @@ conf_misc_section(char *src) conf.status_timing = 1; } + free(sec); + return; } void -conf_bar_section(char *src) +conf_bar_section(void) { - cfg_set_sauv(src); + struct conf_sec **sec, **mouse; + int n; - conf.border.bar = get_opt(src, "false", "border").bool; - conf.bars.height = get_opt(src, "-1", "height").num; - conf.colors.bar = getcolor(get_opt(src, "#000000", "bg").str); - conf.colors.text = get_opt(src, "#ffffff", "fg").str; - conf.bars.selbar = get_opt(src, "false", "selbar").bool; + sec = fetch_section(NULL, "bar"); - if((conf.bars.nmouse = get_size_sec(src, "mouse"))) + conf.border.bar = fetch_opt(sec[0], "false", "border")[0].bool; + conf.bars.height = fetch_opt(sec[0], "-1", "height")[0].num; + conf.colors.bar = getcolor(fetch_opt(sec[0], "#000000", "bg")[0].str); + conf.colors.text = fetch_opt(sec[0], "#ffffff", "fg")[0].str; + conf.bars.selbar = fetch_opt(sec[0], "false", "selbar")[0].bool; + + mouse = fetch_section(sec[0], "mouse"); + + if (!mouse) + return; + + for (n = 0; mouse[n] ; n++); + + conf.bars.nmouse = n; + + if (n > 0) { - conf.bars.mouse = emalloc(conf.bars.nmouse, sizeof(MouseBinding)); - mouse_section(conf.bars.mouse, src, conf.bars.nmouse); + conf.bars.mouse = emalloc(n, sizeof(MouseBinding)); + mouse_section(conf.bars.mouse, n, mouse); } + free(sec); + free(mouse); + return; } void -conf_root_section(char *src) +conf_root_section(void) { - cfg_set_sauv(src); + struct conf_sec **sec, **mouse; + int n; - conf.root.background_command = get_opt(src, "", "background_command").str; + sec = fetch_section(NULL, "root"); - if((conf.root.nmouse = get_size_sec(src, "mouse"))) + conf.root.background_command = fetch_opt(sec[0], "", "background_command")[0].str; + + mouse = fetch_section(sec[0], "mouse"); + + if (mouse) { - conf.root.mouse = emalloc(conf.root.nmouse, sizeof(MouseBinding)); - mouse_section(conf.root.mouse, src, conf.root.nmouse); + for(n = 0; mouse[n]; n++); + if ((conf.root.nmouse = n) > 0) { + conf.root.mouse = emalloc(n, sizeof(MouseBinding)); + mouse_section(conf.root.mouse, n, mouse); + } + free(mouse); } + free(sec); return; } void -conf_client_section(char *src) +conf_client_section(void) { - int i, j, d; - char *tmp, *tmp2, *tmp3, *p; - opt_type *buf; + int i, j, n; + char *flags, *p; + struct conf_sec **sec, **mouse, **titlebar, **button, **line; + struct opt_type *opt; - /* Client misc */ - cfg_set_sauv(src); + sec = fetch_section(NULL, "client"); - conf.client_round = get_opt(src, "true", "client_round").bool; - conf.client.borderheight = (get_opt(src, "1", "border_height").num < 1 ? 1 : get_opt(src, "1", "border_height").num); - conf.client.border_shadow = get_opt(src, "false", "border_shadow").bool; - conf.client.place_at_mouse = get_opt(src, "false", "place_at_mouse").bool; - conf.client.bordernormal = getcolor(get_opt(src, "#000000", "border_normal").str); - conf.client.borderfocus = getcolor(get_opt(src, "#ffffff", "border_focus").str); - conf.client.resizecorner_normal = getcolor(get_opt(src, "#222222", "resize_corner_normal").str); - conf.client.resizecorner_focus = getcolor(get_opt(src, "#DDDDDD", "resize_corner_focus").str); - conf.client.mod |= char_to_modkey(get_opt(src, "Alt", "modifier").str, key_list); - conf.client.set_new_win_master = get_opt(src, "true", "set_new_win_master").bool; + conf.client_round = fetch_opt(sec[0], "true", "client_round")[0].bool; - if((conf.client.nmouse = get_size_sec(src, "mouse"))) + if ((conf.client.borderheight = fetch_opt(sec[0], "1", "border_height")[0].num) < 1) + conf.client.borderheight = 1; + + conf.client.border_shadow = fetch_opt(sec[0], "false", "border_shadow")[0].bool; + conf.client.place_at_mouse = fetch_opt(sec[0], "false", "place_at_mouse")[0].bool; + conf.client.bordernormal = getcolor(fetch_opt(sec[0], "#000000", "border_normal")[0].str); + conf.client.borderfocus = getcolor(fetch_opt(sec[0], "#ffffff", "border_focus")[0].str); + conf.client.resizecorner_normal = getcolor(fetch_opt(sec[0], "#222222", "resize_corner_normal")[0].str); + conf.client.resizecorner_focus = getcolor(fetch_opt(sec[0], "#DDDDDD", "resize_corner_focus")[0].str); + conf.client.mod |= char_to_modkey(fetch_opt(sec[0], "Alt", "modifier")[0].str, key_list); + conf.client.set_new_win_master = fetch_opt(sec[0], "true", "set_new_win_master")[0].bool; + + mouse = fetch_section(sec[0], "mouse"); + + for(n = 0; mouse[n]; n++); + + if((conf.client.nmouse = n) > 0) { conf.client.mouse = emalloc(conf.client.nmouse, sizeof(MouseBinding)); - mouse_section(conf.client.mouse, src, conf.client.nmouse); + mouse_section(conf.client.mouse, n, mouse); } + free(mouse); - /* Titlebar part {{ */ - tmp = get_sec(src, "titlebar"); - cfg_set_sauv(tmp); + titlebar = fetch_section(sec[0], "titlebar"); - conf.titlebar.height = get_opt(tmp, "0", "height").num; - conf.titlebar.fg_normal = get_opt(tmp, "#ffffff", "fg_normal").str; - conf.titlebar.fg_focus = get_opt(tmp, "#000000", "fg_focus").str; + conf.titlebar.height = fetch_opt(titlebar[0], "0", "height")[0].num; + conf.titlebar.fg_normal = fetch_opt(titlebar[0], "#ffffff", "fg_normal")[0].str; + conf.titlebar.fg_focus = fetch_opt(titlebar[0], "#000000", "fg_focus")[0].str; - /* Stipple */ - conf.titlebar.stipple.active = get_opt(tmp, "false", "stipple").bool; + conf.titlebar.stipple.active = fetch_opt(titlebar[0], "false", "stipple")[0].bool; - if(!strcmp((p = get_opt(tmp, "-1", "stipple_normal").str), "-1")) + if(!strcmp((p = fetch_opt(titlebar[0], "-1", "stipple_normal")[0].str), "-1")) conf.titlebar.stipple.colors.normal = getcolor(conf.titlebar.fg_normal); else conf.titlebar.stipple.colors.normal = getcolor(p); - if(!strcmp((p = get_opt(tmp, "-1", "stipple_focus").str), "-1")) + if(!strcmp((p = fetch_opt(titlebar[0], "-1", "stipple_focus")[0].str), "-1")) conf.titlebar.stipple.colors.focus = getcolor(conf.titlebar.fg_focus); else conf.titlebar.stipple.colors.focus = getcolor(p); - if((conf.titlebar.nmouse = get_size_sec(tmp, "mouse"))) + mouse = fetch_section(titlebar[0], "mouse"); + + for(n = 0; sec[n]; n++); + + if((conf.titlebar.nmouse = n) > 0) { conf.titlebar.mouse = emalloc(conf.titlebar.nmouse, sizeof(MouseBinding)); - mouse_section(conf.titlebar.mouse, tmp, conf.titlebar.nmouse); + mouse_section(conf.titlebar.mouse, n, mouse); } + free(mouse); /* Multi button part */ - if((conf.titlebar.nbutton = get_size_sec(tmp, "button"))) + button = fetch_section(sec[0], "button"); + + for(n = 0; button[n]; n++); + + if((conf.titlebar.nbutton = n) > 0) { conf.titlebar.button = emalloc(conf.titlebar.nbutton, sizeof(Button)); for(i = 0; i < conf.titlebar.nbutton; ++i) { - tmp2 = get_nsec(tmp, "button", i); + flags = fetch_opt(button[n], "none", "flags")[0].str; - cfg_set_sauv(tmp2); - - tmp3 = get_opt(tmp2, "none", "flags").str; conf.titlebar.button[i].flags = 0; - if(strstr(tmp3, "free")) + if(strstr(flags, "free")) conf.titlebar.button[i].flags |= FreeFlag; - if(strstr(tmp3, "max")) + if(strstr(flags, "max")) conf.titlebar.button[i].flags |= MaxFlag; - if(strstr(tmp3, "tile")) + if(strstr(flags, "tile")) conf.titlebar.button[i].flags |= TileFlag; /* Multi mouse section */ - if((conf.titlebar.button[i].nmouse = get_size_sec(tmp2, "mouse"))) + mouse = fetch_section(button[n], "mouse"); + + for(n = 0; mouse[n]; n++); + + if((conf.titlebar.button[i].nmouse = n) > 0) { conf.titlebar.button[i].mouse = emalloc(conf.titlebar.button[i].nmouse, sizeof(MouseBinding)); - mouse_section(conf.titlebar.button[i].mouse, tmp2, conf.titlebar.button[i].nmouse); + mouse_section(conf.titlebar.button[i].mouse, n, mouse); } + free(mouse); /* Multi line section */ - if((conf.titlebar.button[i].nlines = get_size_sec(tmp2, "line"))) + line = fetch_section(button[n], "line"); + + for (n = 0; line[n]; n++); + + if((conf.titlebar.button[i].nlines = n) > 0) { conf.titlebar.button[i].linecoord = emalloc(conf.titlebar.button[i].nlines, sizeof(XSegment)); - for(j = 0; j < conf.titlebar.button[i].nlines; ++j) + for(j = 0; j < n; ++j) { - tmp3 = get_nsec(tmp2, "line", j); - cfg_set_sauv(tmp3); - - buf = get_list_opt(tmp3, "{0, 0, 0, 0}", "coord", &d); - - conf.titlebar.button[i].linecoord[j].x1 = buf[0].num; - conf.titlebar.button[i].linecoord[j].y1 = buf[1].num; - conf.titlebar.button[i].linecoord[j].x2 = buf[2].num; - conf.titlebar.button[i].linecoord[j].y2 = buf[3].num; - - cfg_set_sauv(tmp2); + opt = fetch_opt(line[j], "0", "coord"); + conf.titlebar.button[i].linecoord[j].x1 = opt[0].num; + conf.titlebar.button[i].linecoord[j].y1 = opt[1].num; + conf.titlebar.button[i].linecoord[j].x2 = opt[2].num; + conf.titlebar.button[i].linecoord[j].y2 = opt[3].num; } } - - cfg_set_sauv(tmp); + free(line); } } - /* }} */ + free(button); + free(titlebar); + free(sec); return; } void -conf_layout_section(char *src) +conf_layout_section(void) { int i; char *tmp = NULL, *p; + struct conf_sec **layouts, **layout; + int n; /* Set conf.layout NULL for conf reload */ for(i = 0; i < NUM_OF_LAYOUT; ++i) @@ -332,20 +365,24 @@ conf_layout_section(char *src) conf.layout[i].func = NULL; } - cfg_set_sauv(src); + layouts = fetch_section(NULL, "layouts"); - conf.border.layout = get_opt(src, "false", "border").bool; - conf.colors.layout_fg = get_opt(src, "#ffffff", "fg").str; - conf.colors.layout_bg = getcolor((get_opt(src, "#000000", "bg").str)); + conf.border.layout = fetch_opt(layouts[0], "false", "border")[0].bool; + conf.colors.layout_fg = fetch_opt(layouts[0], "#ffffff", "fg")[0].str; + conf.colors.layout_bg = getcolor((fetch_opt(layouts[0], "#000000", "bg")[0].str)); - if((tmp = get_opt(src, "menu", "system").str) && !strcmp(tmp, "menu")) + if((tmp = fetch_opt(layouts[0], "menu", "system")[0].str) && !strcmp(tmp, "menu")) conf.layout_system = True; - if((tmp = get_opt(src, "right", "placement").str) && !strcmp(tmp, "left")) + if((tmp = fetch_opt(layouts[0], "right", "placement")[0].str) && !strcmp(tmp, "left")) conf.layout_placement = True; - conf.nlayout = get_size_sec(src, "layout"); + layout = fetch_section(layouts[0], "layout"); + + for (n = 0; layout[n]; n++); + + conf.nlayout = n; if(conf.nlayout > NUM_OF_LAYOUT || !(conf.nlayout)) { @@ -370,40 +407,37 @@ conf_layout_section(char *src) { for(i = 0; i < conf.nlayout; ++i) { - tmp = get_nsec(src, "layout", i); - - cfg_set_sauv(tmp); - - if(!name_to_func((p = get_opt(tmp, "tile", "type").str), layout_list)) + if(!name_to_func((p = fetch_opt(layout[i], "tile", "type")[0].str), layout_list)) warnx("configuration : Unknown Layout type : \"%s\".", p); else { if(conf.layout_system && conf.nlayout > 1) { - menu_new_item(&menulayout.item[i], get_opt(tmp, "", "symbol").str, + menu_new_item(&menulayout.item[i], fetch_opt(layout[i], "", "symbol")[0].str, uicb_set_layout, p); menulayout.item[i].check = name_to_func("check_layout", func_list); } - conf.layout[i].symbol = get_opt(tmp, "TILE (default)", "symbol").str; + conf.layout[i].symbol = fetch_opt(layout[i], "TILE (default)", "symbol")[0].str; conf.layout[i].func = name_to_func(p, layout_list); conf.layout[i].type = p; } - - cfg_set_sauv(src); } } + free(layout); + free(layouts); return; } void -conf_tag_section(char *src) +conf_tag_section(void) { - int i, j, k, l = 0, m, n, sc; - char *cfgtmp, *tmp; - opt_type *buf; + int i, j, k, l = 0, m, n, sc, count; + char *tmp; + struct conf_sec **sec, **tag, **mouse; + struct opt_type *opt; /* If there is no tag in the conf or more than * MAXTAG (32) print an error and create only one. @@ -413,27 +447,27 @@ conf_tag_section(char *src) layout_name_to_struct(conf.layout, "tile_right", conf.nlayout, layout_list), 0, NULL, 0 }; - cfg_set_sauv(src); + sec = fetch_section(NULL, "tags"); - conf.tag_round = get_opt(src, "false", "tag_round").bool; - conf.colors.tagselfg = get_opt(src, "#ffffff", "sel_fg").str; - conf.colors.tagselbg = getcolor(get_opt(src, "#000000", "sel_bg").str); - conf.colors.tagurfg = get_opt(src, "#000000", "urgent_fg").str; - conf.colors.tagurbg = getcolor(get_opt(src, "#DD1111", "urgent_bg").str); - conf.colors.tag_occupied_bg = getcolor(get_opt(src, "#222222", "occupied_bg").str); - conf.border.tag = get_opt(src, "false", "border").bool; + conf.tag_round = fetch_opt(sec[0], "false", "tag_round")[0].bool; + conf.colors.tagselfg = fetch_opt(sec[0], "#ffffff", "sel_fg")[0].str; + conf.colors.tagselbg = getcolor(fetch_opt(sec[0], "#000000", "sel_bg")[0].str); + conf.colors.tagurfg = fetch_opt(sec[0], "#000000", "urgent_fg")[0].str; + conf.colors.tagurbg = getcolor(fetch_opt(sec[0], "#DD1111", "urgent_bg")[0].str); + conf.colors.tag_occupied_bg = getcolor(fetch_opt(sec[0], "#222222", "occupied_bg")[0].str); + conf.border.tag = fetch_opt(sec[0], "false", "border")[0].bool; /* Mouse button action on tag */ conf.mouse_tag_action[TagSel] = - char_to_button(get_opt(src, "1", "mouse_button_tag_sel").str, mouse_button_list); + char_to_button(fetch_opt(sec[0], "1", "mouse_button_tag_sel")[0].str, mouse_button_list); conf.mouse_tag_action[TagTransfert] = - char_to_button(get_opt(src, "2", "mouse_button_tag_transfert").str, mouse_button_list); + char_to_button(fetch_opt(sec[0], "2", "mouse_button_tag_transfert")[0].str, mouse_button_list); conf.mouse_tag_action[TagAdd] = - char_to_button(get_opt(src, "3", "mouse_button_tag_add").str, mouse_button_list); + char_to_button(fetch_opt(sec[0], "3", "mouse_button_tag_add")[0].str, mouse_button_list); conf.mouse_tag_action[TagNext] = - char_to_button(get_opt(src, "4", "mouse_button_tag_next").str, mouse_button_list); + char_to_button(fetch_opt(sec[0], "4", "mouse_button_tag_next")[0].str, mouse_button_list); conf.mouse_tag_action[TagPrev] = - char_to_button(get_opt(src, "5", "mouse_button_tag_prev").str, mouse_button_list); + char_to_button(fetch_opt(sec[0], "5", "mouse_button_tag_prev")[0].str, mouse_button_list); sc = screen_count(); @@ -446,16 +480,16 @@ conf_tag_section(char *src) for(i = 0; i < sc; ++i) seltag[i] = 1; + tag = fetch_section(sec[0], "tag"); + + for(n = 0; tag[n]; n++); + for(i = 0; i < sc; ++i) - tags[i] = emalloc(get_size_sec(src, "tag") + 2, sizeof(Tag)); + tags[i] = emalloc(n + 2, sizeof(Tag)); - for(i = 0; i < get_size_sec(src, "tag"); ++i) + for(i = (n-1); i >= 0; i--) { - /* printf("%d -> %s\n", i, (cfgtmp = get_nsec(src, "tag", i)));*/ - cfgtmp = get_nsec(src, "tag", i); - cfg_set_sauv(cfgtmp); - - j = get_opt(cfgtmp, "-1", "screen").num; + j = fetch_opt(tag[i], "-1", "screen")[0].num; if(j < 0 || j > sc - 1) j = -1; @@ -465,14 +499,14 @@ conf_tag_section(char *src) ((j == -1) ? ++k : --l)) { ++conf.ntag[k]; - tags[k][conf.ntag[k]].name = get_opt(cfgtmp, "", "name").str; - tags[k][conf.ntag[k]].mwfact = get_opt(cfgtmp, "0.65", "mwfact").fnum; - tags[k][conf.ntag[k]].nmaster = get_opt(cfgtmp, "1", "nmaster").num; - tags[k][conf.ntag[k]].resizehint = get_opt(cfgtmp, "false", "resizehint").bool; - tags[k][conf.ntag[k]].abovefc = get_opt(cfgtmp, "false", "abovefc").bool; + tags[k][conf.ntag[k]].name = fetch_opt(tag[i], "", "name")[0].str; + tags[k][conf.ntag[k]].mwfact = fetch_opt(tag[i], "0.65", "mwfact")[0].fnum; + tags[k][conf.ntag[k]].nmaster = fetch_opt(tag[i], "1", "nmaster")[0].num; + tags[k][conf.ntag[k]].resizehint = fetch_opt(tag[i], "false", "resizehint")[0].bool; + tags[k][conf.ntag[k]].abovefc = fetch_opt(tag[i], "false", "abovefc")[0].bool; tags[k][conf.ntag[k]].layers = 1; - tmp = _strdup(get_opt(cfgtmp, "top", "infobar_position").str); + tmp = fetch_opt(tag[i], "top", "infobar_position")[0].str; if(!strcmp(tmp ,"none") || !strcmp(tmp, "hide") || !strcmp(tmp, "hidden")) tags[k][conf.ntag[k]].barpos = IB_Hide; @@ -482,30 +516,36 @@ conf_tag_section(char *src) tags[k][conf.ntag[k]].barpos = IB_Top; tags[k][conf.ntag[k]].layout = layout_name_to_struct(conf.layout, - get_opt(cfgtmp, "tile_right", "layout").str, + fetch_opt(tag[i], "tile_right", "layout")[0].str, conf.nlayout, layout_list); /* Clients list */ - buf = get_list_opt(cfgtmp, "", "clients", &n); - if(n) + opt = fetch_opt(tag[i], "", "clients"); + + for (count = 0; opt[count].str; count++); + + if(count) { - tags[k][conf.ntag[k]].nclients = n; - tags[k][conf.ntag[k]].clients = emalloc(n, sizeof(char *)); - for(m = 0; m < n; ++m) - tags[k][conf.ntag[k]].clients[m] = (buf[m].str) ? buf[m].str : NULL; + tags[k][conf.ntag[k]].nclients = count; + tags[k][conf.ntag[k]].clients = emalloc(count, sizeof(char *)); + for(m = 0; m < count; ++m) + tags[k][conf.ntag[k]].clients[m] = opt[m].str; } /* Multi mouse sections */ - if((tags[k][conf.ntag[k]].nmouse = get_size_sec(cfgtmp, "mouse"))) + mouse = fetch_section(tag[i], "mouse"); + + for (count = 0; mouse[count]; count++); + + if((tags[k][conf.ntag[k]].nmouse = count)) { tags[k][conf.ntag[k]].mouse = emalloc(tags[k][conf.ntag[k]].nmouse, sizeof(MouseBinding)); - mouse_section(tags[k][conf.ntag[k]].mouse, cfgtmp, tags[k][conf.ntag[k]].nmouse); + mouse_section(tags[k][conf.ntag[k]].mouse, count, mouse); } - + free(mouse); } l = 0; - cfg_set_sauv(src); } for(i = 0; i < sc; ++i) @@ -516,35 +556,41 @@ conf_tag_section(char *src) tags[i][1] = default_tag; } + free(tag); + free(sec); + return; } void -conf_menu_section(char *src) +conf_menu_section(void) { - char *tmp, *tmp2; - int i, j; + char *tmp2; + int i, j, n; + struct conf_sec **menu, **set_menu, **item; - cfg_set_sauv(src); + menu = fetch_section(NULL, "menu"); + set_menu = fetch_section(menu[0], "set_menu"); - CHECK((conf.nmenu = get_size_sec(src, "set_menu"))); + for (n = 0; set_menu[n]; n++); + + + CHECK((conf.nmenu = n)); conf.menu = calloc(conf.nmenu, sizeof(Menu)); for(i = 0; i < conf.nmenu; ++i) { - tmp = get_nsec(src, "set_menu", i); - cfg_set_sauv(tmp); - conf.menu[i].name = get_opt(tmp, "menu_wname", "name").str; + conf.menu[i].name = fetch_opt(set_menu[i], "menu_wname", "name")[0].str; - if(!(conf.menu[i].place_at_mouse = get_opt(tmp, "true", "place_at_mouse").bool)) + if(!(conf.menu[i].place_at_mouse = fetch_opt(set_menu[i], "true", "place_at_mouse")[0].bool)) { - conf.menu[i].x = get_opt(tmp, "0", "x").num; - conf.menu[i].y = get_opt(tmp, "0", "y").num; + conf.menu[i].x = fetch_opt(set_menu[i], "0", "x")[0].num; + conf.menu[i].y = fetch_opt(set_menu[i], "0", "y")[0].num; } - tmp2 = _strdup(get_opt(tmp, "center", "align").str); + tmp2 = fetch_opt(set_menu[i], "center", "align")[0].str; if(!strcmp(tmp2 ,"left")) conf.menu[i].align = MA_Left; @@ -553,99 +599,98 @@ conf_menu_section(char *src) else conf.menu[i].align = MA_Center; - conf.menu[i].colors.focus.bg = getcolor(get_opt(tmp, "#000000", "bg_focus").str); - conf.menu[i].colors.focus.fg = get_opt(tmp, "#ffffff", "fg_focus").str; - conf.menu[i].colors.normal.bg = getcolor(get_opt(tmp, "#000000", "bg_normal").str); - conf.menu[i].colors.normal.fg = get_opt(tmp, "#ffffff", "fg_normal").str; + conf.menu[i].colors.focus.bg = getcolor(fetch_opt(set_menu[i], "#000000", "bg_focus")[0].str); + conf.menu[i].colors.focus.fg = fetch_opt(set_menu[i], "#ffffff", "fg_focus")[0].str; + conf.menu[i].colors.normal.bg = getcolor(fetch_opt(set_menu[i], "#000000", "bg_normal")[0].str); + conf.menu[i].colors.normal.fg = fetch_opt(set_menu[i], "#ffffff", "fg_normal")[0].str; - if((conf.menu[i].nitem = get_size_sec(tmp, "item"))) + item = fetch_section(set_menu[i], "item"); + + for (n = 0; item[n]; n++); + + if((conf.menu[i].nitem = n)) { conf.menu[i].item = emalloc(conf.menu[i].nitem, sizeof(MenuItem)); - for(j = 0; j < get_size_sec(tmp, "item"); ++j) + for(j = 0; j < conf.menu[i].nitem; ++j) { - tmp2 = get_nsec(tmp, "item", j); - cfg_set_sauv(tmp2); - - conf.menu[i].item[j].name = get_opt(tmp2, "item_wname", "name").str; - conf.menu[i].item[j].func = name_to_func(get_opt(tmp2, "", "func").str, func_list); - conf.menu[i].item[j].cmd = (!get_opt(tmp2, "", "cmd").str) ? NULL : get_opt(tmp2, "", "cmd").str; - conf.menu[i].item[j].check = name_to_func(get_opt(tmp2, "", "check").str, func_list); - conf.menu[i].item[j].submenu = get_opt(tmp2, "", "submenu").str; - - cfg_set_sauv(tmp); + conf.menu[i].item[j].name = fetch_opt(item[j], "item_wname", "name")[0].str; + conf.menu[i].item[j].func = name_to_func(fetch_opt(item[j], "", "func")[0].str, func_list); + conf.menu[i].item[j].cmd = fetch_opt(item[j], "", "cmd")[0].str; + conf.menu[i].item[j].check = name_to_func(fetch_opt(item[j], "", "check")[0].str, func_list); + conf.menu[i].item[j].submenu = fetch_opt(item[j], "", "submenu")[0].str; } } - - cfg_set_sauv(src); + free(item); } + free(set_menu); + free(menu); return; } void -conf_launcher_section(char *src) +conf_launcher_section(void) { - int i; - char *tmp; + int i, n; + struct conf_sec **launcher, **set_launcher; - cfg_set_sauv(src); + launcher = fetch_section(NULL, "launcher"); + set_launcher = fetch_section(launcher[0], "set_launcher"); - CHECK((conf.nlauncher = get_size_sec(src, "set_launcher"))); + for (n = 0; set_launcher[n]; n++); + + CHECK((conf.nlauncher = n)); conf.launcher = emalloc(conf.nlauncher, sizeof(Launcher)); for(i = 0; i < conf.nlauncher; ++i) { - tmp = get_nsec(src, "set_launcher", i); - cfg_set_sauv(tmp); - - conf.launcher[i].name = get_opt(tmp, "launcher", "name").str; - conf.launcher[i].prompt = get_opt(tmp, "Exec:", "prompt").str; - conf.launcher[i].command = get_opt(tmp, "exec", "command").str; + conf.launcher[i].name = fetch_opt(set_launcher[i], "launcher", "name")[0].str; + conf.launcher[i].prompt = fetch_opt(set_launcher[i], "Exec:", "prompt")[0].str; + conf.launcher[i].command = fetch_opt(set_launcher[i], "exec", "command")[0].str; conf.launcher[i].nhisto = 1; - - cfg_set_sauv(src); } + free(set_launcher); + free(launcher); return; } void -conf_keybind_section(char *src) +conf_keybind_section(void) { int i, j, n = 0; - char *tmp; - opt_type *buf; + struct conf_sec **sec, **ks; + struct opt_type *opt; - cfg_set_sauv(src); + sec = fetch_section(NULL, "keys"); + ks = fetch_section(sec[0], "key"); - conf.nkeybind = get_size_sec(src, "key"); + for (n = 0; ks[n]; n++); + + conf.nkeybind = n; keys = emalloc(conf.nkeybind, sizeof(Key)); for(i = 0; i < conf.nkeybind; ++i) { - tmp = get_nsec(src, "key", i); + opt = fetch_opt(ks[i], "", "mod"); - cfg_set_sauv(tmp); - - buf = get_list_opt(tmp, "", "mod", &n); + for (n = 0; opt[n].str; n++); for(j = 0; j < n; ++j) - keys[i].mod |= char_to_modkey(buf[j].str, key_list); + keys[i].mod |= char_to_modkey(opt[j].str, key_list); - keys[i].keysym = XStringToKeysym(get_opt(tmp, "None", "key").str); + keys[i].keysym = XStringToKeysym(fetch_opt(ks[i], "None", "key")[0].str); - keys[i].func = name_to_func(get_opt(tmp, "", "func").str, func_list); + keys[i].func = name_to_func(fetch_opt(ks[i], "", "func")[0].str, func_list); if(keys[i].func == NULL) { - warnx("configuration : Unknown Function \"%s\".", get_opt(tmp, "", "func").str); + warnx("configuration : Unknown Function \"%s\".", fetch_opt(ks[i], "", "func")[0].str); keys[i].func = uicb_spawn; } - keys[i].cmd = (!get_opt(tmp, "", "cmd").str) ? NULL : get_opt(tmp, "", "cmd").str; - - cfg_set_sauv(src); + keys[i].cmd = fetch_opt(ks[i], "", "cmd")[0].str; } return; @@ -656,46 +701,29 @@ conf_keybind_section(char *src) void init_conf(void) { - char *file; - - if(!(file = file_to_str(conf.confpath))) + if (get_conf(conf.confpath) == -1) { warnx("parsing configuration file (%s) failed.", conf.confpath); sprintf(conf.confpath, "%s/wmfs/wmfsrc", XDG_CONFIG_DIR); warnx("Use the default configuration (%s).", conf.confpath); - file = file_to_str(conf.confpath); + if (get_conf(conf.confpath) == -1) + errx(1, "parsing configuration file (%s) failed.", conf.confpath); + } /* Set func_list */ func_list = emalloc(LEN(tmp_func_list), sizeof(func_name_list_t)); memcpy(func_list, tmp_func_list, LEN(tmp_func_list) * sizeof(func_name_list_t)); - conf_section(conf_misc_section, file, "misc"); - conf_section(conf_bar_section, file, "bar"); - conf_section(conf_root_section, file, "root"); - conf_section(conf_client_section, file, "client"); - conf_section(conf_layout_section, file, "layouts"); - conf_section(conf_tag_section, file, "tags"); - conf_section(conf_menu_section, file, "menu"); - conf_section(conf_launcher_section, file, "launcher"); - conf_section(conf_keybind_section, file, "keys"); - - free(file); - - return; -} - - -/** Simple wrapper for calling functions and free pointer - */ -static void -conf_section(void (*func)(char*), char *src, char *name) -{ - char *sec; - - sec = get_sec(src, name); - func(sec); - IFREE(sec); + conf_misc_section(); + conf_bar_section(); + conf_root_section(); + conf_client_section(); + conf_layout_section(); + conf_tag_section(); + conf_menu_section(); + conf_launcher_section(); + conf_keybind_section(); return; } diff --git a/src/confparse/confparse.c b/src/confparse/confparse.c deleted file mode 100644 index 39463e3..0000000 --- a/src/confparse/confparse.c +++ /dev/null @@ -1,287 +0,0 @@ -/* -* confparse.c -* Copyright © 2008, 2009 Martin Duquesnoy -* 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 the 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "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 THE COPYRIGHT -* OWNER OR CONTRIBUTORS 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. -*/ - -#include "confparse.h" - -char* -file_to_str(char *path) -{ - char *buf, *ret, *p, *c; - int fd, i; - struct stat st; - Bool is_char = False; - - if (!path) - return NULL; - - if (!(fd = open(path, O_RDONLY))) - { - warn("%s", path); - return NULL; - } - - /* Get the file size */ - stat(path, &st); - - /* Bufferize file */ - if((buf = (char*)mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, SEEK_SET)) == (char*) MAP_FAILED) - return NULL; - - /* Copy buffer without comments in return value */ - ret = emalloc(strlen(buf) + 1, sizeof(char)); - - for(p = buf, i = 0; *p != '\0'; p++) - { - if(!is_char && (c = strchr("\"'", *p))) - is_char = !is_char; - else if (is_char && *p == *c) - is_char = !is_char; - - if(*p == COMMENT_CHAR && !is_char) - { - if(!(p = strchr(p, '\n'))) - break; - ret[i++] = '\n'; - } - else - ret[i++] = *p; - } - ret[i++] = '\0'; - - /* Unmap buffer, thanks linkdd. */ - munmap(buf, st.st_size); - close(fd); - - warnx("%s read.", path); - - return ret; -} - -char* -get_sec(char *src, char *name) -{ - char *ret = NULL, *start, *end, *p; - char **sec; - size_t len; - - if(!src) - return NULL; - - if(!name) - return src; - - sec = secname(name); - len = strlen(sec[SecStart]); - - /* Find start section pointer */ - for(start = src; *start != '\0'; start++) - { - if( (p = strchr("\"'", *start)) ) - while (*(++start) && *start != *p); - - if(!strncmp(start, sec[SecStart], len)) - break; - } - - if(*start != '\0') - { - /* Here is_char == False */ - start += len; - /* Find end section pointer */ - for(end = start; *end != '\0'; end++) - { - if( (p = strchr("\"'", *start)) ) - while (*(++start) && *start != *p); - - if(!strncmp(end, sec[SecEnd], len+1)) - break; - } - - /* Allocate and set ret */ - if(end != '\0') - { - len = end - start; - ret = emalloc(len + 1, sizeof(char)); - memcpy(ret, start, len); - ret[len] = '\0'; - } - } - - free_secname(sec); - - return ret; -} - -char* -get_nsec(char *src, char *name, int n) -{ - int i; - char *ret, *buf, **sec; - - if(!src || !strlen(src)) - return NULL; - - if(!name) - return src; - - if(!n) - return get_sec(src, name); - - sec = secname(name); - - for(i = 0, buf = sauv_delimc; i < n && (buf = strstr(buf, sec[SecStart])); ++i, buf += strlen(sec[SecStart])); - - ret = get_sec(src + strlen(src) - strlen(buf), name); - - free_secname(sec); - - return ret; -} - -int -get_size_sec(char *src, char *name) -{ - int ret; - char **sec, *buf; - - if(!src || !name) - return 0; - - sec = secname(name); - - for(ret = 0, buf = sauv_secc; (buf = strstr(buf, sec[SecStart])); ++ret, buf += strlen(sec[SecStart])); - - free_secname(sec); - - return ret; -} - -opt_type -get_opt(char *src, char *def, char *name) -{ - int i; - char *p = NULL, *p2 = NULL; - opt_type ret = null_opt_type; - - if(!src || !name) - return (def) ? str_to_opt(def) : ret; - - if((p = opt_srch(sauv_secc, name))) - { - for(i = 0; p[i] && p[i] != '\n'; ++i); - p[i] = '\0'; - - p2 = _strdup(p + strlen(name)); - - if((p = strchr(p, '=')) && !is_in_delimiter(p, 0)) - { - for(i = 0; p2[i] && p2[i] != '='; ++i); - p2[i] = '\0'; - - /* Check if there is anything else that spaces - * between option name and '=' */ - for(i = 0; i < strlen(p2); ++i) - if(p2[i] != ' ') - { - warnx("Configuration warning: Missing '=' after option: '%s'" - " and before expression: '%s'\n", name, p2); - return str_to_opt(def); - } - - ret = str_to_opt(clean_value(++p)); - } - free(p2); - } - - if(!ret.str) - ret = str_to_opt(def); - - return ret; -} - -/* option = {val1, val2, val3} */ -opt_type* -get_list_opt(char *src, char *def, char *name, int *n) -{ - int i, j; - char *p, *p2, *p2_orig; - opt_type *ret; - - if(!src || !name) - return NULL; - - *n = 0; - - if(!(p = get_opt(src, def, name).str)) - return NULL; - - for(i = 0; p[i] && (p[i] != LIST_DEL_E || is_in_delimiter(p, i)); ++i); - p[i + 1] = '\0'; - - /* Syntax of list {val1, val2, ..., valx} */ - if(*p != LIST_DEL_S || *(p + strlen(p) - 1) != LIST_DEL_E) - return NULL; - - /* Erase ( ) */ - ++p; - *(p + strlen(p) - 1) = '\0'; - - /* > 1 value in list */ - if(strchr(p, ',')) - { - /* Count ',' */ - for(i = 0, *n = 1; i < strlen(p); ++i) - if(p[i] == ',' && !is_in_delimiter(p, i)) - ++(*n); - - ret = emalloc(*n, sizeof(opt_type)); - - p2_orig = p2 = _strdup(p); - - /* Set all value in return array */ - for(i = j = 0; i < *n; ++i, p2 += ++j) - { - for(j = 0; j < strlen(p2) && (p2[j] != ',' || is_in_delimiter(p2, j)); ++j); - p2[j] = '\0'; - - ret[i] = str_to_opt(clean_value(p2)); - } - free(p2_orig); - } - else - { - ret = emalloc((*n = 1), sizeof(opt_type)); - *ret = str_to_opt(clean_value(p)); - } - - return ret; -} diff --git a/src/confparse/confparse.h b/src/confparse/confparse.h deleted file mode 100644 index 2645b20..0000000 --- a/src/confparse/confparse.h +++ /dev/null @@ -1,87 +0,0 @@ -/* -* confparse.h -* Copyright © 2008, 2009 Martin Duquesnoy -* 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 the 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "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 THE COPYRIGHT -* OWNER OR CONTRIBUTORS 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. -*/ - -#ifndef CONFPARSE_H -#define CONFPARSE_H - -#include -#include -#include - -#include "../wmfs.h" - -/* Section delimiter */ -#define SEC_DEL_S '[' -#define SEC_DEL_E ']' - -/* List delimiter */ -#define LIST_DEL_S '{' -#define LIST_DEL_E '}' - -/* Comment character */ -#define COMMENT_CHAR '#' - -enum { SecStart, SecEnd, SecLast }; - -typedef struct -{ - long int num; - float fnum; - Bool bool; - char *str; -} opt_type; - -/* util.c */ -char *erase_delim_content(char *buf); -Bool is_in_delimiter(char *buf, int p); -char *erase_sec_content(char *buf); -char *opt_srch(char *buf, char *opt); -opt_type str_to_opt(char *str); -char *clean_value(char *str); -void cfg_set_sauv(char *str); -char **secname(char *name); -void free_secname(char **secname); - -/* confparse.c */ -char *file_to_str(char *path); -char *get_sec(char *src, char *name); -char *get_nsec(char *src, char *name, int n); -int get_size_sec(char *src, char *name); -opt_type get_opt(char *src, char *def, char *name); -opt_type *get_list_opt(char *src, char *def, char *name, int *n); - -static const opt_type null_opt_type = {0, 0, 0, NULL}; - -char *sauv_delimc; -char *sauv_secc; - -#endif /* CONFPARSE_H */ diff --git a/src/confparse/util.c b/src/confparse/util.c deleted file mode 100644 index 5637675..0000000 --- a/src/confparse/util.c +++ /dev/null @@ -1,220 +0,0 @@ -/* -* confparse/util.c -* Copyright © 2008, 2009 Martin Duquesnoy -* 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 the 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "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 THE COPYRIGHT -* OWNER OR CONTRIBUTORS 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. -*/ - -#include "confparse.h" - -char* -erase_delim_content(char *buf) -{ - int i, j; - char *str, c; - - if(!buf || !(str = _strdup(buf))) - return NULL; - - for(i = 0; i < strlen(str); ++i) - if(strchr("\"'", (c = str[i]))) - { - for(*(str + (j = i)) = ' '; str[j] && str[j] != c; str[j++] = ' '); - str[j] = ' '; - } - - return str; -} - -/* Erase all content of all delimiters, put it - * int str, and check if buf[p] is in an delimiter. */ -Bool -is_in_delimiter(char *buf, int p) -{ - if(*(erase_delim_content(buf) + p) != buf[p]) - return True; - - return False; -} - -char* -erase_sec_content(char *buf) -{ - int i, j; - char *p, *str, *name, *ret; - char **sec; - - if(!buf || !(str = _strdup(sauv_delimc))) - return NULL; - - ret = _strdup(buf); - - for(i = 1, name = _strdup(str + i); strchr(str + i, SEC_DEL_S); ++i, name = _strdup(str + i)) - { - for(; str[i] && str[i] != SEC_DEL_S; ++i); - for(j = 0; str[i] && str[i] != SEC_DEL_E; name[j++] = str[i++]); - ++name; - name[j - 1] = '\0'; - - if(*name == '/') - continue; - - sec = secname(name); - - if((p = strstr(str + i, sec[SecEnd]))) - for(++i; i < strlen(ret) - strlen(p); ret[i++] = ' '); - else - break; - } - - free_secname(sec); - - return ret; -} - -/* To get the RIGHT name of an option; if option needed is - * pwet and there is tagadapwettagada in the configuration, - * with strstr(), the name will matchs */ -char* -opt_srch(char *buf, char *opt) -{ - char *p; - - if(!buf || !opt) - return NULL; - - if((p = strstr(sauv_delimc /*erase_delim_content(buf)*/, opt))) - if((*(p + strlen(opt)) == ' ' || *(p + strlen(opt)) == '=') - && (*(p - 1) == ' ' || *(p - 1) == '\n' || *(p - 1) == '\t' || !(*(p - 1)))) - return _strdup(buf + (strlen(buf) - strlen(p))); - - return NULL; -} - -opt_type -str_to_opt(char *str) -{ - opt_type ret = null_opt_type; - - if(!strlen(str)) - return ret; - - /* Integer */ - ret.num = atoi(str); - - /* Float */ - sscanf(str, "%f", &ret.fnum); - - /* Boolean */ - if(strstr(str, "true") || strstr(str, "True") - || strstr(str, "TRUE") || strstr(str, "1")) - ret.bool = True; - - /* String */ - ret.str = _strdup(str); - - return ret; -} - -char* -clean_value(char *str) -{ - int i; - char c, *p; - - if(!str || !(p = _strdup(str))) - return NULL; - - /* Remove useless spaces */ - for(; *p == ' '; ++p); - for(; *(p + strlen(p) - 1) == ' '; *(p + strlen(p) - 1) = '\0'); - - /* For string delimiter (" or ') */ - if(((c = *p) == '"' || (c = *p) == '\'') && strchr(p + 1, c)) - { - for(++p, i = 0; p[i] && p[i] != c; ++i); - p[i] = '\0'; - } - - return p; -} - -void -cfg_set_sauv(char *str) -{ - if(!str) - { - sauv_delimc = NULL; - sauv_secc = NULL; - - return; - } - - sauv_delimc = erase_delim_content(str); - sauv_secc = erase_sec_content(str); - - return; -} - -char** -secname(char *name) -{ - char **ret = NULL; - - if(!name) - return NULL; - - ret = emalloc(SecLast, sizeof(char*)); - - /* Len of name + '[' + ']' + '\0' */ - ret[SecStart] = emalloc(strlen(name) + 3, sizeof(char)); - - /* Len of name + '[' + '/' + ']' + '\0' */ - ret[SecEnd] = emalloc(strlen(name) + 4, sizeof(char)); - - sprintf(ret[SecStart], "%c%s%c", SEC_DEL_S, name, SEC_DEL_E); - sprintf(ret[SecEnd], "%c/%s%c", SEC_DEL_S, name, SEC_DEL_E); - - return ret; -} - -void -free_secname(char **secname) -{ - if(!secname || LEN(secname) != SecLast) - return; - - if(secname[SecStart]) - free(secname[SecStart]); - if(secname[SecEnd]) - free(secname[SecEnd]); - - free(secname); - - return; -} diff --git a/src/parse/parse.c b/src/parse/parse.c new file mode 100644 index 0000000..5695293 --- /dev/null +++ b/src/parse/parse.c @@ -0,0 +1,439 @@ +/* + * Copyright (c) 2010 Philippe Pepiot + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#define _BSD_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../wmfs.h" + + +static void get_keyword(const char *buf, size_t n); +static void pop_keyword(void); +static void pop_stack(void); +static struct conf_sec *get_section(void); +static struct conf_opt *get_option(void); +static struct opt_type string_to_opt(char *); +#ifdef DEBUG +static void print_kw_tree(void); +static char * get_kw_name(enum conf_type); +#endif + +static TAILQ_HEAD(, conf_keyword) keywords; +static TAILQ_HEAD(, conf_stack) stack; +static SLIST_HEAD(, conf_sec) config; +static struct conf_keyword *curk; /* current keyword */ +static struct conf_stack *curw; /* current word */ +static const struct opt_type opt_type_null = { 0, 0, False, NULL }; + +static struct { + const char *name; + size_t line; +} file = { NULL, 1 }; + +static void +get_keyword(const char *buf, size_t n) +{ + struct conf_keyword *kw; + size_t j, i; + struct conf_state s = { False, False, '\0' }; + struct conf_stack *e; + + TAILQ_INIT(&stack); + TAILQ_INIT(&keywords); + kw = emalloc(1, sizeof(*kw)); + e = emalloc(1, sizeof(*e)); + + for(i = 0, j = 0; i < n; i++) + { + if (buf[i] == '\n' && s.comment == True) { + s.comment = False; + continue; + } + + if (buf[i] == '#' && s.quote == False) { + s.comment = True; + continue; + } + + if (s.comment == True) + continue; + + if (buf[i] == s.quote_char && s.quote == True) { + NEW_WORD(); + s.quote = False; + continue; + } + + if ((buf[i] == '"' || buf[i] == '\'') && + s.quote == False) + { + s.quote_char = buf[i]; + s.quote = True; + continue; + } + + if (buf[i] == '[' && s.quote == False) { + NEW_WORD(); + TOKEN((buf[i+1] == '/') ? SEC_END : SEC_START); + if (buf[i+1] == '/') + i++; + continue; + } + + if (buf[i] == ']' && s.quote == False) { + NEW_WORD(); + continue; + } + + if (buf[i] == '{' && s.quote == False) { + NEW_WORD(); + TOKEN(LIST_START); + continue; + } + + if (buf[i] == '}' && s.quote == False) { + NEW_WORD(); + TOKEN(LIST_END); + continue; + } + + if (buf[i] == ',' && s.quote == False) { + NEW_WORD(); + continue; + } + + if (buf[i] == '=' && s.quote == False) { + NEW_WORD(); + TOKEN(EQUAL); + continue; + } + + if (strchr("\t\n ", buf[i]) && s.quote == False) { + if (buf[i] == '\n') + file.line++; + NEW_WORD(); + continue; + } + + e->name[j++] = buf[i]; + } +} + +#ifdef DEBUG +static void +print_kw_tree(void) +{ + struct conf_keyword *k; + struct conf_stack *s; + + s = TAILQ_FIRST(&stack); + + TAILQ_FOREACH(k, &keywords, entry) + printf("%s ", get_kw_name(k->type)); + printf("\n"); +} + +static char * +get_kw_name(enum conf_type type) +{ + switch (type) { + case SEC_START: + return ("SEC_START"); + break; + case SEC_END: + return ("SEC_END"); + break; + case WORD: + return ("WORD"); + break; + case LIST_START: + return ("LIST_START "); + break; + case LIST_END: + return ("LIST_END "); + break; + case EQUAL: + return ("EQUAL "); + break; + default: + return ("NONE "); + break; + } +} +#endif + +int +get_conf(const char *name) +{ + int fd; + struct stat st; + char *buf; + struct conf_sec *s; + + if (!name) + return (-1); + + if ((fd = open(name, O_RDONLY)) == -1 || + stat(name, &st) == -1) + { + warn("%s", name); + return (-1); + } + + buf = (char*)mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, SEEK_SET); + + if (buf == (char*) MAP_FAILED) + return -1; + + get_keyword(buf, st.st_size); + + munmap(buf, st.st_size); + close(fd); + warnx("%s read", name); + + file.name = name; + + curk = TAILQ_FIRST(&keywords); + curw = TAILQ_FIRST(&stack); + + SLIST_INIT(&config); + + while (!TAILQ_EMPTY(&keywords)) { + switch (curk->type) { + case SEC_START: + s = get_section(); + SLIST_INSERT_HEAD(&config, s, entry); + break; + default: + errx(1, "%s:%d: near '%s', config out of any section", + file.name, curk->line, curw->name); + break; + } + } + return 0; +} + +static struct conf_sec * +get_section(void) +{ + struct conf_sec *s; + struct conf_opt *o; + struct conf_sec *sub; + + s = emalloc(1, sizeof(*s)); + s->name = strdup(curw->name); + pop_stack(); + pop_keyword(); + + if (curk->type != WORD) + errx(1, "%s:%d: near '%s', missing section name", + file.name, curk->line, curw->name); + pop_keyword(); + + while (curk->type != SEC_END) { + switch (curk->type) { + case WORD: + o = get_option(); + SLIST_INSERT_HEAD(&s->optlist, o, entry); + s->nopt++; + break; + case SEC_START: + sub = get_section(); + SLIST_INSERT_HEAD(&s->sub, sub, entry); + s->nsub++; + case SEC_END: + break; + default: + errx(1, "%s:%d: near '%s', syntax error", + file.name, curk->line, curw->name); + break; + } + } + pop_keyword(); + + if (curk->type != WORD) + errx(1, "%s:%d: near '%s', missing end-section name", + file.name, curk->line, curw->name); + + if (strcmp(curw->name, s->name)) + errx(1, "%s:%d: near '%s', non-closed section '%s'", + file.name, curk->line, curw->name, s->name); + + pop_stack(); + pop_keyword(); + return s; +} + + +static struct conf_opt * +get_option(void) +{ + struct conf_opt *o; + size_t j = 0; + + o = emalloc(1, sizeof(*o)); + o->name = strdup(curw->name); + pop_stack(); + pop_keyword(); + + if (curk->type != EQUAL) + errx(1, "%s:%d: near '%s', missing '=' here", + file.name, curk->line, curw->name); + + pop_keyword(); + + switch (curk->type) { + case WORD: + o->val[0] = strdup(curw->name); + o->val[1] = NULL; + pop_stack(); + break; + case LIST_START: + pop_keyword(); + while (curk->type != LIST_END) { + if (curk->type != WORD) + errx(1, "%s:%d: near '%s', declaration into a list", + file.name, curk->line, curw->name); + o->val[j++] = strdup(curw->name); + pop_stack(); + pop_keyword(); + } + o->val[j] = NULL; + break; + default: + errx(1, "%s:%d: near '%s', syntax error", + file.name, curk->line, curw->name); + break; + } + pop_keyword(); + return o; +} + + +static void +pop_keyword(void) +{ + TAILQ_REMOVE(&keywords, curk, entry); +#ifdef DEBUG + warnx("%s", get_kw_name(curk->type)); +#endif + free(curk); + + curk = TAILQ_FIRST(&keywords); +} + +static void +pop_stack(void) +{ + TAILQ_REMOVE(&stack, curw, entry); +#ifdef DEBUG + warnx("%s", curw->name); +#endif + free(curw); + + curw = TAILQ_FIRST(&stack); +} + + +struct conf_sec ** +fetch_section(struct conf_sec *s, char *name) +{ + struct conf_sec **ret; + struct conf_sec *sec; + size_t i = 0; + + if (!name) + return NULL; + + if (!s) { + ret = emalloc(2, sizeof(struct conf_sec *)); + SLIST_FOREACH(sec, &config, entry) + if (!strcmp(sec->name, name)) { + ret[0] = sec; + ret[1] = NULL; + break; + } + } + else { + ret = emalloc(s->nsub+1, sizeof(struct conf_sec *)); + SLIST_FOREACH(sec, &s->sub, entry) { + if (!strcmp(sec->name, name) && i < s->nsub) + ret[i++] = sec; + } + ret[i] = NULL; + } + return ret; +} + +struct opt_type * +fetch_opt(struct conf_sec *s, char *dfl, char *name) +{ + struct conf_opt *o; + struct opt_type *ret; + size_t i = 0; + + if (!name) + return NULL; + + ret = emalloc(10, sizeof(struct opt_type)); + + if (s) { + SLIST_FOREACH(o, &s->optlist, entry) + if (!strcmp(o->name, name)) { + while (o->val[i]) { + ret[i] = string_to_opt(o->val[i]); + i++; + } + ret[i] = opt_type_null; + return ret; + } + } + + ret[0] = string_to_opt(dfl); + ret[1] = opt_type_null; + + return ret; +} + +static struct opt_type +string_to_opt(char *s) +{ + struct opt_type ret = opt_type_null; + + if (!s || !strlen(s)) + return ret; + + ret.num = atoi(s); + sscanf(s, "%f", &ret.fnum); + + if (!strcmp(s, "true") || !strcmp(s, "True") || + !strcmp(s, "TRUE") || !strcmp(s, "1")) + ret.bool = True; + else + ret.bool = False; + + ret.str = s; + + return ret; +} + diff --git a/src/parse/parse.h b/src/parse/parse.h new file mode 100644 index 0000000..866716f --- /dev/null +++ b/src/parse/parse.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2010 Philippe Pepiot + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef PARSE_H +#define PARSE_H + +#include + +#if !defined(WMFS_H) +typedef enum { False, True } Bool; +#endif + +enum conf_type { SEC_START, SEC_END, WORD, EQUAL, LIST_START, LIST_END, NONE }; + +#define TOKEN(t) \ + do { \ + kw->type = (t); \ + kw->line = file.line; \ + TAILQ_INSERT_TAIL(&keywords, kw, entry); \ + kw = malloc(sizeof(*kw)); \ + } while (0) + +#define NEW_WORD() \ + do { \ + if (j > 0) { \ + e->name[j] = '\0'; \ + TAILQ_INSERT_TAIL(&stack, e, entry); \ + e = malloc(sizeof(*e)); \ + j = 0; \ + TOKEN(WORD); \ + } \ + } while (0) + +struct conf_keyword { + enum conf_type type; + size_t line; + TAILQ_ENTRY(conf_keyword) entry; +}; + +struct conf_stack { + char name[BUFSIZ]; + TAILQ_ENTRY(conf_stack) entry; +}; + +struct conf_state { + Bool quote; + Bool comment; + char quote_char; +}; + +struct conf_opt { + char *name; + char *val[10]; + SLIST_ENTRY(conf_opt) entry; + size_t nval; +}; + +struct conf_sec { + char *name; + SLIST_HEAD(, conf_opt) optlist; + SLIST_HEAD(, conf_sec) sub; + SLIST_ENTRY(conf_sec) entry; + size_t nopt; + size_t nsub; +}; + +struct opt_type { + long int num; + float fnum; + Bool bool; + char *str; +}; + +int get_conf(const char *); +struct conf_sec **fetch_section(struct conf_sec *, char *); +struct opt_type *fetch_opt(struct conf_sec *, char *, char *); + +#endif /* PARSE_H */ diff --git a/src/util.c b/src/util.c index 6e2961a..d50d934 100644 --- a/src/util.c +++ b/src/util.c @@ -292,3 +292,26 @@ parse_image_block(ImageAttr *im, char *str) } #endif /* HAVE_IMLIB */ +char* +clean_value(char *str) +{ + int i; + char c, *p; + + if(!str || !(p = _strdup(str))) + return NULL; + + /* Remove useless spaces */ + for(; *p == ' '; ++p); + for(; *(p + strlen(p) - 1) == ' '; *(p + strlen(p) - 1) = '\0'); + + /* For string delimiter (" or ') */ + if(((c = *p) == '"' || (c = *p) == '\'') && strchr(p + 1, c)) + { + for(++p, i = 0; p[i] && p[i] != c; ++i); + p[i] = '\0'; + } + + return p; +} + diff --git a/src/wmfs.c b/src/wmfs.c index 7140a31..3527bd5 100644 --- a/src/wmfs.c +++ b/src/wmfs.c @@ -116,13 +116,6 @@ quit(void) } IFREE(conf.launcher); - IFREE(conf.ntag); - IFREE(conf.titlebar.mouse); - for(i = 0; i < conf.titlebar.nbutton; ++i) - { - IFREE(conf.titlebar.button[i].mouse); - IFREE(conf.titlebar.button[i].linecoord); - } IFREE(conf.bars.mouse); IFREE(conf.titlebar.button); diff --git a/src/wmfs.h b/src/wmfs.h index 2124235..effdddb 100644 --- a/src/wmfs.h +++ b/src/wmfs.h @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -55,7 +56,7 @@ #include /* Local headers */ -#include "confparse/confparse.h" +#include "parse/parse.h" #include "config.h" #include "structs.h" @@ -273,6 +274,7 @@ char *char_to_str(const char c); void spawn(const char *str, ...); void swap_ptr(void **x, void **y); void uicb_spawn(uicb_t); +char *clean_value(char *str); #ifdef HAVE_IMLIB int parse_image_block(ImageAttr *im, char *str);