From 417c052803058c59379d69a77a1421319aea460f Mon Sep 17 00:00:00 2001 From: ernestoCruz05 Date: Sat, 11 Apr 2026 09:42:12 +0100 Subject: [PATCH] refactor(parse_config.h): replace the if else chain with a LUT loop approach --- src/config/parse_config.h | 489 ++++++++++++++++++-------------------- 1 file changed, 227 insertions(+), 262 deletions(-) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index e02b5017..dc954d0b 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -920,11 +920,108 @@ uint32_t parse_num_type(char *str) { } } +typedef enum { + ARG_NONE, + ARG_INT, + ARG_FLOAT, + ARG_UINT, + ARG_DIRECTION, + ARG_CIRCLE_DIR, + ARG_UINT_BIT, + ARG_STR_V, + ARG_MOUSE_ACTION, + ARG_INT_CLAMP, + ARG_SPECIAL_SETOPTION, + ARG_SPECIAL_VIEW, + ARG_SPECIAL_SPAWN, + ARG_SPECIAL_SPAWN_ON_EMPTY, + ARG_SPECIAL_TAG, + ARG_SPECIAL_FOCUSMON, + ARG_SPECIAL_TAGMON, + ARG_SPECIAL_CROSSMON, + ARG_SPECIAL_WINGEOM, + ARG_SPECIAL_TOGGLE_NAMED_SCRATCHPAD, +} ArgParseType; + +typedef struct { + const char *name; + FuncType func; + ArgParseType arg_type; +} CmdEntry; + +static const CmdEntry cmd_table[] = { + { "focusstack", focusstack, ARG_CIRCLE_DIR }, + { "focusdir", focusdir, ARG_DIRECTION }, + { "incnmaster", incnmaster, ARG_INT }, + { "setmfact", setmfact, ARG_FLOAT }, + { "zoom", zoom, ARG_NONE }, + { "exchange_client", exchange_client, ARG_DIRECTION }, + { "exchange_stack_client", exchange_stack_client, ARG_CIRCLE_DIR }, + { "toggleglobal", toggleglobal, ARG_NONE }, + { "toggleoverview", toggleoverview, ARG_INT }, + { "set_proportion", set_proportion, ARG_FLOAT }, + { "switch_proportion_preset", switch_proportion_preset, ARG_CIRCLE_DIR }, + { "viewtoleft", viewtoleft, ARG_INT }, + { "viewtoright", viewtoright, ARG_INT }, + { "tagsilent", tagsilent, ARG_UINT_BIT }, + { "tagtoleft", tagtoleft, ARG_INT }, + { "tagtoright", tagtoright, ARG_INT }, + { "killclient", killclient, ARG_NONE }, + { "centerwin", centerwin, ARG_NONE }, + { "focuslast", focuslast, ARG_NONE }, + { "toggle_trackpad_enable", toggle_trackpad_enable, ARG_NONE }, + { "setoption", setoption, ARG_SPECIAL_SETOPTION }, + { "setkeymode", setkeymode, ARG_STR_V }, + { "switch_keyboard_layout", switch_keyboard_layout, ARG_INT_CLAMP }, + { "setlayout", setlayout, ARG_STR_V }, + { "switch_layout", switch_layout, ARG_NONE }, + { "togglefloating", togglefloating, ARG_NONE }, + { "togglefullscreen", togglefullscreen, ARG_NONE }, + { "togglefakefullscreen", togglefakefullscreen, ARG_NONE }, + { "toggleoverlay", toggleoverlay, ARG_NONE }, + { "minimized", minimized, ARG_NONE }, + { "restore_minimized", restore_minimized, ARG_NONE }, + { "toggle_scratchpad", toggle_scratchpad, ARG_NONE }, + { "toggle_render_border", toggle_render_border, ARG_NONE }, + { "focusmon", focusmon, ARG_SPECIAL_FOCUSMON }, + { "tagmon", tagmon, ARG_SPECIAL_TAGMON }, + { "incgaps", incgaps, ARG_INT }, + { "togglegaps", togglegaps, ARG_NONE }, + { "chvt", chvt, ARG_UINT }, + { "spawn", spawn, ARG_SPECIAL_SPAWN }, + { "spawn_shell", spawn_shell, ARG_SPECIAL_SPAWN }, + { "spawn_on_empty", spawn_on_empty, ARG_SPECIAL_SPAWN_ON_EMPTY }, + { "quit", quit, ARG_NONE }, + { "create_virtual_output", create_virtual_output, ARG_NONE }, + { "destroy_all_virtual_output", destroy_all_virtual_output, ARG_NONE }, + { "moveresize", moveresize, ARG_MOUSE_ACTION }, + { "togglemaximizescreen", togglemaximizescreen, ARG_NONE }, + { "viewtoleft_have_client", viewtoleft_have_client, ARG_INT }, + { "viewtoright_have_client", viewtoright_have_client, ARG_INT }, + { "reload_config", reload_config, ARG_NONE }, + { "tag", tag, ARG_SPECIAL_TAG }, + { "view", bind_to_view, ARG_SPECIAL_VIEW }, + { "viewcrossmon", viewcrossmon, ARG_SPECIAL_CROSSMON }, + { "tagcrossmon", tagcrossmon, ARG_SPECIAL_CROSSMON }, + { "toggletag", toggletag, ARG_UINT_BIT }, + { "toggleview", toggleview, ARG_UINT_BIT }, + { "comboview", comboview, ARG_UINT_BIT }, + { "smartmovewin", smartmovewin, ARG_DIRECTION }, + { "smartresizewin", smartresizewin, ARG_DIRECTION }, + { "resizewin", resizewin, ARG_SPECIAL_WINGEOM }, + { "movewin", movewin, ARG_SPECIAL_WINGEOM }, + { "toggle_named_scratchpad", toggle_named_scratchpad, ARG_SPECIAL_TOGGLE_NAMED_SCRATCHPAD }, + { "disable_monitor", disable_monitor, ARG_STR_V }, + { "enable_monitor", enable_monitor, ARG_STR_V }, + { "toggle_monitor", toggle_monitor, ARG_STR_V }, + { "scroller_stack", scroller_stack, ARG_DIRECTION }, + { "toggle_all_floating", toggle_all_floating, ARG_NONE }, +}; + FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value, char *arg_value2, char *arg_value3, char *arg_value4, char *arg_value5) { - FuncType func = NULL; (*arg).i = 0; (*arg).i2 = 0; (*arg).f = 0.0f; @@ -935,279 +1032,147 @@ FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value, (*arg).v2 = NULL; (*arg).v3 = NULL; - if (strcmp(func_name, "focusstack") == 0) { - func = focusstack; - (*arg).i = parse_circle_direction(arg_value); - } else if (strcmp(func_name, "focusdir") == 0) { - func = focusdir; - (*arg).i = parse_direction(arg_value); - } else if (strcmp(func_name, "incnmaster") == 0) { - func = incnmaster; - (*arg).i = atoi(arg_value); - } else if (strcmp(func_name, "setmfact") == 0) { - func = setmfact; - (*arg).f = atof(arg_value); - } else if (strcmp(func_name, "zoom") == 0) { - func = zoom; - } else if (strcmp(func_name, "exchange_client") == 0) { - func = exchange_client; - (*arg).i = parse_direction(arg_value); - } else if (strcmp(func_name, "exchange_stack_client") == 0) { - func = exchange_stack_client; - (*arg).i = parse_circle_direction(arg_value); - } else if (strcmp(func_name, "toggleglobal") == 0) { - func = toggleglobal; - } else if (strcmp(func_name, "toggleoverview") == 0) { - func = toggleoverview; - (*arg).i = atoi(arg_value); - } else if (strcmp(func_name, "set_proportion") == 0) { - func = set_proportion; - (*arg).f = atof(arg_value); - } else if (strcmp(func_name, "switch_proportion_preset") == 0) { - func = switch_proportion_preset; - (*arg).i = parse_circle_direction(arg_value); - } else if (strcmp(func_name, "viewtoleft") == 0) { - func = viewtoleft; - (*arg).i = atoi(arg_value); - } else if (strcmp(func_name, "viewtoright") == 0) { - func = viewtoright; - (*arg).i = atoi(arg_value); - } else if (strcmp(func_name, "tagsilent") == 0) { - func = tagsilent; - (*arg).ui = 1 << (atoi(arg_value) - 1); - } else if (strcmp(func_name, "tagtoleft") == 0) { - func = tagtoleft; - (*arg).i = atoi(arg_value); - } else if (strcmp(func_name, "tagtoright") == 0) { - func = tagtoright; - (*arg).i = atoi(arg_value); - } else if (strcmp(func_name, "killclient") == 0) { - func = killclient; - } else if (strcmp(func_name, "centerwin") == 0) { - func = centerwin; - } else if (strcmp(func_name, "focuslast") == 0) { - func = focuslast; - } else if (strcmp(func_name, "toggle_trackpad_enable") == 0) { - func = toggle_trackpad_enable; - } else if (strcmp(func_name, "setoption") == 0) { - func = setoption; + const size_t table_len = sizeof(cmd_table) / sizeof(cmd_table[0]); - (*arg).v = strdup(arg_value); + for (size_t k = 0; k < table_len; k++) { + if (strcmp(func_name, cmd_table[k].name) != 0) + continue; - // 收集需要拼接的参数 - const char *non_empty_params[4] = {NULL}; - int32_t param_index = 0; + FuncType func = cmd_table[k].func; - if (arg_value2 && arg_value2[0] != '\0') - non_empty_params[param_index++] = arg_value2; - if (arg_value3 && arg_value3[0] != '\0') - non_empty_params[param_index++] = arg_value3; - if (arg_value4 && arg_value4[0] != '\0') - non_empty_params[param_index++] = arg_value4; - if (arg_value5 && arg_value5[0] != '\0') - non_empty_params[param_index++] = arg_value5; - - // 处理拼接 - if (param_index == 0) { - (*arg).v2 = strdup(""); - } else { - // 计算总长度 - size_t len = 0; - for (int32_t i = 0; i < param_index; i++) { - len += strlen(non_empty_params[i]); - } - len += (param_index - 1) + 1; // 逗号数 + null终止符 - - char *temp = malloc(len); - if (temp) { - char *cursor = temp; - for (int32_t i = 0; i < param_index; i++) { - if (i > 0) { - *cursor++ = ','; + switch (cmd_table[k].arg_type) { + case ARG_NONE: + break; + case ARG_INT: + (*arg).i = atoi(arg_value); + break; + case ARG_FLOAT: + (*arg).f = atof(arg_value); + break; + case ARG_UINT: + (*arg).ui = (uint32_t)atoi(arg_value); + break; + case ARG_DIRECTION: + (*arg).i = parse_direction(arg_value); + break; + case ARG_CIRCLE_DIR: + (*arg).i = parse_circle_direction(arg_value); + break; + case ARG_UINT_BIT: + (*arg).ui = 1 << (atoi(arg_value) - 1); + break; + case ARG_STR_V: + (*arg).v = strdup(arg_value); + break; + case ARG_MOUSE_ACTION: + (*arg).ui = parse_mouse_action(arg_value); + break; + case ARG_INT_CLAMP: + (*arg).i = CLAMP_INT(atoi(arg_value), 0, 100); + break; + case ARG_SPECIAL_SETOPTION: { + (*arg).v = strdup(arg_value); + const char *non_empty_params[4] = {NULL}; + int32_t param_index = 0; + if (arg_value2 && arg_value2[0] != '\0') + non_empty_params[param_index++] = arg_value2; + if (arg_value3 && arg_value3[0] != '\0') + non_empty_params[param_index++] = arg_value3; + if (arg_value4 && arg_value4[0] != '\0') + non_empty_params[param_index++] = arg_value4; + if (arg_value5 && arg_value5[0] != '\0') + non_empty_params[param_index++] = arg_value5; + if (param_index == 0) { + (*arg).v2 = strdup(""); + } else { + size_t len = 0; + for (int32_t j = 0; j < param_index; j++) + len += strlen(non_empty_params[j]); + len += (param_index - 1) + 1; + char *temp = malloc(len); + if (temp) { + char *cursor = temp; + for (int32_t j = 0; j < param_index; j++) { + if (j > 0) + *cursor++ = ','; + size_t param_len = strlen(non_empty_params[j]); + memcpy(cursor, non_empty_params[j], param_len); + cursor += param_len; } - size_t param_len = strlen(non_empty_params[i]); - memcpy(cursor, non_empty_params[i], param_len); - cursor += param_len; + *cursor = '\0'; + (*arg).v2 = temp; } - *cursor = '\0'; - (*arg).v2 = temp; } + break; } - } else if (strcmp(func_name, "setkeymode") == 0) { - func = setkeymode; - (*arg).v = strdup(arg_value); - } else if (strcmp(func_name, "switch_keyboard_layout") == 0) { - func = switch_keyboard_layout; - (*arg).i = CLAMP_INT(atoi(arg_value), 0, 100); - } else if (strcmp(func_name, "setlayout") == 0) { - func = setlayout; - (*arg).v = strdup(arg_value); - } else if (strcmp(func_name, "switch_layout") == 0) { - func = switch_layout; - } else if (strcmp(func_name, "togglefloating") == 0) { - func = togglefloating; - } else if (strcmp(func_name, "togglefullscreen") == 0) { - func = togglefullscreen; - } else if (strcmp(func_name, "togglefakefullscreen") == 0) { - func = togglefakefullscreen; - } else if (strcmp(func_name, "toggleoverlay") == 0) { - func = toggleoverlay; - } else if (strcmp(func_name, "minimized") == 0) { - func = minimized; - } else if (strcmp(func_name, "restore_minimized") == 0) { - func = restore_minimized; - } else if (strcmp(func_name, "toggle_scratchpad") == 0) { - func = toggle_scratchpad; - } else if (strcmp(func_name, "toggle_render_border") == 0) { - func = toggle_render_border; - } else if (strcmp(func_name, "focusmon") == 0) { - func = focusmon; - (*arg).i = parse_direction(arg_value); - if ((*arg).i == UNDIR) { - (*arg).v = strdup(arg_value); - } - } else if (strcmp(func_name, "tagmon") == 0) { - func = tagmon; - (*arg).i = parse_direction(arg_value); - (*arg).i2 = atoi(arg_value2); - if ((*arg).i == UNDIR) { - (*arg).v = strdup(arg_value); - }; - } else if (strcmp(func_name, "incgaps") == 0) { - func = incgaps; - (*arg).i = atoi(arg_value); - } else if (strcmp(func_name, "togglegaps") == 0) { - func = togglegaps; - } else if (strcmp(func_name, "chvt") == 0) { - func = chvt; - (*arg).ui = atoi(arg_value); - } else if (strcmp(func_name, "spawn") == 0) { - func = spawn; - char *values[] = {arg_value, arg_value2, arg_value3, arg_value4, - arg_value5}; - (*arg).v = combine_args_until_empty(values, 5); - } else if (strcmp(func_name, "spawn_shell") == 0) { - func = spawn_shell; - char *values[] = {arg_value, arg_value2, arg_value3, arg_value4, - arg_value5}; - (*arg).v = combine_args_until_empty(values, 5); - } else if (strcmp(func_name, "spawn_on_empty") == 0) { - func = spawn_on_empty; - (*arg).v = strdup(arg_value); // 注意:之后需要释放这个内存 - (*arg).ui = 1 << (atoi(arg_value2) - 1); - } else if (strcmp(func_name, "quit") == 0) { - func = quit; - } else if (strcmp(func_name, "create_virtual_output") == 0) { - func = create_virtual_output; - } else if (strcmp(func_name, "destroy_all_virtual_output") == 0) { - func = destroy_all_virtual_output; - } else if (strcmp(func_name, "moveresize") == 0) { - func = moveresize; - (*arg).ui = parse_mouse_action(arg_value); - } else if (strcmp(func_name, "togglemaximizescreen") == 0) { - func = togglemaximizescreen; - } else if (strcmp(func_name, "viewtoleft_have_client") == 0) { - func = viewtoleft_have_client; - (*arg).i = atoi(arg_value); - } else if (strcmp(func_name, "viewtoright_have_client") == 0) { - func = viewtoright_have_client; - (*arg).i = atoi(arg_value); - } else if (strcmp(func_name, "reload_config") == 0) { - func = reload_config; - } else if (strcmp(func_name, "tag") == 0) { - func = tag; - (*arg).ui = 1 << (atoi(arg_value) - 1); - (*arg).i = atoi(arg_value2); - } else if (strcmp(func_name, "view") == 0) { - func = bind_to_view; - - uint32_t mask = 0; - char *token; - char *arg_copy = strdup(arg_value); - - if (arg_copy != NULL) { - char *saveptr = NULL; - token = strtok_r(arg_copy, "|", &saveptr); - - while (token != NULL) { - int32_t num = atoi(token); - if (num > 0 && num <= LENGTH(tags)) { - mask |= (1 << (num - 1)); + case ARG_SPECIAL_VIEW: { + uint32_t mask = 0; + char *arg_copy = strdup(arg_value); + if (arg_copy != NULL) { + char *saveptr = NULL; + char *token = strtok_r(arg_copy, "|", &saveptr); + while (token != NULL) { + int32_t num = atoi(token); + if (num > 0 && num <= (int32_t)LENGTH(tags)) + mask |= (1 << (num - 1)); + token = strtok_r(NULL, "|", &saveptr); } - token = strtok_r(NULL, "|", &saveptr); + free(arg_copy); } - - free(arg_copy); + (*arg).ui = mask ? mask : (uint32_t)atoi(arg_value); + (*arg).i = atoi(arg_value2); + break; + } + case ARG_SPECIAL_SPAWN: { + char *values[] = {arg_value, arg_value2, arg_value3, arg_value4, + arg_value5}; + (*arg).v = combine_args_until_empty(values, 5); + break; + } + case ARG_SPECIAL_SPAWN_ON_EMPTY: + (*arg).v = strdup(arg_value); + (*arg).ui = 1 << (atoi(arg_value2) - 1); + break; + case ARG_SPECIAL_TAG: + (*arg).ui = 1 << (atoi(arg_value) - 1); + (*arg).i = atoi(arg_value2); + break; + case ARG_SPECIAL_FOCUSMON: + (*arg).i = parse_direction(arg_value); + if ((*arg).i == UNDIR) + (*arg).v = strdup(arg_value); + break; + case ARG_SPECIAL_TAGMON: + (*arg).i = parse_direction(arg_value); + (*arg).i2 = atoi(arg_value2); + if ((*arg).i == UNDIR) + (*arg).v = strdup(arg_value); + break; + case ARG_SPECIAL_CROSSMON: + (*arg).ui = 1 << (atoi(arg_value) - 1); + (*arg).v = strdup(arg_value2); + break; + case ARG_SPECIAL_WINGEOM: + (*arg).ui = parse_num_type(arg_value); + (*arg).ui2 = parse_num_type(arg_value2); + (*arg).i = (*arg).ui == NUM_TYPE_DEFAULT ? atoi(arg_value) + : atoi(arg_value + 1); + (*arg).i2 = (*arg).ui2 == NUM_TYPE_DEFAULT ? atoi(arg_value2) + : atoi(arg_value2 + 1); + break; + case ARG_SPECIAL_TOGGLE_NAMED_SCRATCHPAD: + (*arg).v = strdup(arg_value); + (*arg).v2 = strdup(arg_value2); + (*arg).v3 = strdup(arg_value3); + break; + default: + break; } - if (mask) { - (*arg).ui = mask; - } else { - (*arg).ui = atoi(arg_value); - } - (*arg).i = atoi(arg_value2); - } else if (strcmp(func_name, "viewcrossmon") == 0) { - func = viewcrossmon; - (*arg).ui = 1 << (atoi(arg_value) - 1); - (*arg).v = strdup(arg_value2); - } else if (strcmp(func_name, "tagcrossmon") == 0) { - func = tagcrossmon; - (*arg).ui = 1 << (atoi(arg_value) - 1); - (*arg).v = strdup(arg_value2); - } else if (strcmp(func_name, "toggletag") == 0) { - func = toggletag; - (*arg).ui = 1 << (atoi(arg_value) - 1); - } else if (strcmp(func_name, "toggleview") == 0) { - func = toggleview; - (*arg).ui = 1 << (atoi(arg_value) - 1); - } else if (strcmp(func_name, "comboview") == 0) { - func = comboview; - (*arg).ui = 1 << (atoi(arg_value) - 1); - } else if (strcmp(func_name, "smartmovewin") == 0) { - func = smartmovewin; - (*arg).i = parse_direction(arg_value); - } else if (strcmp(func_name, "smartresizewin") == 0) { - func = smartresizewin; - (*arg).i = parse_direction(arg_value); - } else if (strcmp(func_name, "resizewin") == 0) { - func = resizewin; - (*arg).ui = parse_num_type(arg_value); - (*arg).ui2 = parse_num_type(arg_value2); - (*arg).i = (*arg).ui == NUM_TYPE_DEFAULT ? atoi(arg_value) - : atoi(arg_value + 1); - (*arg).i2 = (*arg).ui2 == NUM_TYPE_DEFAULT ? atoi(arg_value2) - : atoi(arg_value2 + 1); - } else if (strcmp(func_name, "movewin") == 0) { - func = movewin; - (*arg).ui = parse_num_type(arg_value); - (*arg).ui2 = parse_num_type(arg_value2); - (*arg).i = (*arg).ui == NUM_TYPE_DEFAULT ? atoi(arg_value) - : atoi(arg_value + 1); - (*arg).i2 = (*arg).ui2 == NUM_TYPE_DEFAULT ? atoi(arg_value2) - : atoi(arg_value2 + 1); - } else if (strcmp(func_name, "toggle_named_scratchpad") == 0) { - func = toggle_named_scratchpad; - (*arg).v = strdup(arg_value); - (*arg).v2 = strdup(arg_value2); - (*arg).v3 = strdup(arg_value3); - } else if (strcmp(func_name, "disable_monitor") == 0) { - func = disable_monitor; - (*arg).v = strdup(arg_value); - } else if (strcmp(func_name, "enable_monitor") == 0) { - func = enable_monitor; - (*arg).v = strdup(arg_value); - } else if (strcmp(func_name, "toggle_monitor") == 0) { - func = toggle_monitor; - (*arg).v = strdup(arg_value); - } else if (strcmp(func_name, "scroller_stack") == 0) { - func = scroller_stack; - (*arg).i = parse_direction(arg_value); - } else if (strcmp(func_name, "toggle_all_floating") == 0) { - func = toggle_all_floating; - } else { - return NULL; + return func; } - return func; + + return NULL; } void set_env() {