mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2025-11-02 09:01:43 -05:00
feat: Spaces are allowed before and after the fields in config
This commit is contained in:
parent
0a79024da8
commit
bc4f598259
1 changed files with 151 additions and 44 deletions
|
|
@ -212,6 +212,54 @@ typedef struct {
|
|||
typedef void (*FuncType)(const Arg *);
|
||||
Config config;
|
||||
|
||||
// Helper function to trim whitespace from start and end of a string
|
||||
void trim_whitespace(char *str) {
|
||||
if (str == NULL || *str == '\0') return;
|
||||
|
||||
// Trim leading space
|
||||
char *start = str;
|
||||
while (isspace((unsigned char)*start)) {
|
||||
start++;
|
||||
}
|
||||
|
||||
// Trim trailing space
|
||||
char *end = str + strlen(str) - 1;
|
||||
while (end > start && isspace((unsigned char)*end)) {
|
||||
end--;
|
||||
}
|
||||
|
||||
// Null-terminate the trimmed string
|
||||
*(end + 1) = '\0';
|
||||
|
||||
// Move the trimmed part to the beginning if needed
|
||||
if (start != str) {
|
||||
memmove(str, start, end - start + 2); // +2 to include null terminator
|
||||
}
|
||||
}
|
||||
|
||||
int parse_double_array(const char *input, double *output, int max_count) {
|
||||
char *dup = strdup(input); // 复制一份用于修改
|
||||
char *token;
|
||||
int count = 0;
|
||||
|
||||
token = strtok(dup, ",");
|
||||
while (token != NULL && count < max_count) {
|
||||
trim_whitespace(token); // 对每一个分割后的 token 去除前后空格
|
||||
char *endptr;
|
||||
double val = strtod(token, &endptr);
|
||||
if (endptr == token || *endptr != '\0') {
|
||||
fprintf(stderr, "Error: Invalid number in array: %s\n", token);
|
||||
free(dup);
|
||||
return -1; // 解析失败
|
||||
}
|
||||
output[count++] = val;
|
||||
token = strtok(NULL, ",");
|
||||
}
|
||||
|
||||
free(dup);
|
||||
return count;
|
||||
}
|
||||
|
||||
// 清理字符串中的不可见字符(包括 \r, \n, 空格等)
|
||||
char *sanitize_string(char *str) {
|
||||
// 去除首部不可见字符
|
||||
|
|
@ -611,6 +659,10 @@ void parse_config_line(Config *config, const char *line) {
|
|||
return;
|
||||
}
|
||||
|
||||
// Then trim each part separately
|
||||
trim_whitespace(key);
|
||||
trim_whitespace(value);
|
||||
|
||||
if (strcmp(key, "animations") == 0) {
|
||||
config->animations = atoi(value);
|
||||
} else if (strcmp(key, "animation_type_open") == 0) {
|
||||
|
|
@ -638,34 +690,24 @@ void parse_config_line(Config *config, const char *line) {
|
|||
} else if (strcmp(key, "animation_duration_close") == 0) {
|
||||
config->animation_duration_close = atoi(value);
|
||||
} else if (strcmp(key, "animation_curve_move") == 0) {
|
||||
if (sscanf(value, "%lf,%lf,%lf,%lf", &config->animation_curve_move[0],
|
||||
&config->animation_curve_move[1],
|
||||
&config->animation_curve_move[2],
|
||||
&config->animation_curve_move[3]) != 4) {
|
||||
fprintf(stderr, "Error: Invalid animation_curve_move format: %s\n",
|
||||
value);
|
||||
int num = parse_double_array(value, config->animation_curve_move, 4);
|
||||
if (num != 4) {
|
||||
fprintf(stderr, "Error: Failed to parse animation_curve_move: %s\n", value);
|
||||
}
|
||||
} else if (strcmp(key, "animation_curve_open") == 0) {
|
||||
if (sscanf(value, "%lf,%lf,%lf,%lf", &config->animation_curve_open[0],
|
||||
&config->animation_curve_open[1],
|
||||
&config->animation_curve_open[2],
|
||||
&config->animation_curve_open[3]) != 4) {
|
||||
fprintf(stderr, "Error: Invalid animation_curve_open format: %s\n",
|
||||
value);
|
||||
int num = parse_double_array(value, config->animation_curve_open, 4);
|
||||
if (num != 4) {
|
||||
fprintf(stderr, "Error: Failed to parse animation_curve_open: %s\n", value);
|
||||
}
|
||||
} else if (strcmp(key, "animation_curve_tag") == 0) {
|
||||
if (sscanf(value, "%lf,%lf,%lf,%lf", &config->animation_curve_tag[0],
|
||||
&config->animation_curve_tag[1], &config->animation_curve_tag[2],
|
||||
&config->animation_curve_tag[3]) != 4) {
|
||||
fprintf(stderr, "Error: Invalid animation_curve_tag format: %s\n", value);
|
||||
int num = parse_double_array(value, config->animation_curve_tag, 4);
|
||||
if (num != 4) {
|
||||
fprintf(stderr, "Error: Failed to parse animation_curve_tag: %s\n", value);
|
||||
}
|
||||
} else if (strcmp(key, "animation_curve_close") == 0) {
|
||||
if (sscanf(value, "%lf,%lf,%lf,%lf", &config->animation_curve_close[0],
|
||||
&config->animation_curve_close[1],
|
||||
&config->animation_curve_close[2],
|
||||
&config->animation_curve_close[3]) != 4) {
|
||||
fprintf(stderr, "Error: Invalid animation_curve_close format: %s\n",
|
||||
value);
|
||||
int num = parse_double_array(value, config->animation_curve_close, 4);
|
||||
if (num != 4) {
|
||||
fprintf(stderr, "Error: Failed to parse animation_curve_close: %s\n", value);
|
||||
}
|
||||
} else if (strcmp(key, "scroller_structs") == 0) {
|
||||
config->scroller_structs = atoi(value);
|
||||
|
|
@ -925,6 +967,9 @@ void parse_config_line(Config *config, const char *line) {
|
|||
config->autostart[1], config->autostart[2]) != 3) {
|
||||
fprintf(stderr, "Error: Invalid autostart format: %s\n", value);
|
||||
}
|
||||
trim_whitespace(config->autostart[0]);
|
||||
trim_whitespace(config->autostart[1]);
|
||||
trim_whitespace(config->autostart[2]);
|
||||
} else if (strcmp(key, "tags") == 0) {
|
||||
config->tag_rules =
|
||||
realloc(config->tag_rules,
|
||||
|
|
@ -949,6 +994,9 @@ void parse_config_line(Config *config, const char *line) {
|
|||
char *key = token;
|
||||
char *val = colon + 1;
|
||||
|
||||
trim_whitespace(key);
|
||||
trim_whitespace(val);
|
||||
|
||||
if (strcmp(key, "id") == 0) {
|
||||
rule->id = atoi(val);
|
||||
} else if (strcmp(key, "layout_name") == 0) {
|
||||
|
|
@ -1002,6 +1050,9 @@ void parse_config_line(Config *config, const char *line) {
|
|||
char *key = token;
|
||||
char *val = colon + 1;
|
||||
|
||||
trim_whitespace(key);
|
||||
trim_whitespace(val);
|
||||
|
||||
if (strcmp(key, "isfloating") == 0) {
|
||||
rule->isfloating = atoi(val);
|
||||
} else if (strcmp(key, "title") == 0) {
|
||||
|
|
@ -1043,6 +1094,8 @@ void parse_config_line(Config *config, const char *line) {
|
|||
} else if (strcmp(key, "globalkeybinding") == 0) {
|
||||
char mod_str[256], keysym_str[256];
|
||||
sscanf(val, "%[^-]-%[a-zA-Z]", mod_str, keysym_str);
|
||||
trim_whitespace(mod_str);
|
||||
trim_whitespace(keysym_str);
|
||||
rule->globalkeybinding.mod = parse_mod(mod_str);
|
||||
rule->globalkeybinding.keysym = parse_keysym(keysym_str);
|
||||
}
|
||||
|
|
@ -1051,26 +1104,47 @@ void parse_config_line(Config *config, const char *line) {
|
|||
}
|
||||
config->window_rules_count++;
|
||||
} else if (strcmp(key, "monitorrule") == 0) {
|
||||
config->monitor_rules =
|
||||
config->monitor_rules =
|
||||
realloc(config->monitor_rules,
|
||||
(config->monitor_rules_count + 1) * sizeof(ConfigMonitorRule));
|
||||
if (!config->monitor_rules) {
|
||||
if (!config->monitor_rules) {
|
||||
fprintf(stderr, "Error: Failed to allocate memory for monitor rules\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ConfigMonitorRule *rule =
|
||||
&config->monitor_rules[config->monitor_rules_count];
|
||||
memset(rule, 0, sizeof(ConfigMonitorRule));
|
||||
ConfigMonitorRule *rule = &config->monitor_rules[config->monitor_rules_count];
|
||||
memset(rule, 0, sizeof(ConfigMonitorRule));
|
||||
|
||||
char layout[256], name[256];
|
||||
int parsed = sscanf(value, "%255[^,],%f,%d,%255[^,],%d,%f,%d,%d", name,
|
||||
&rule->mfact, &rule->nmaster, layout, &rule->rr,
|
||||
&rule->scale, &rule->x, &rule->y);
|
||||
// 临时存储每个字段的原始字符串
|
||||
char raw_name[256], raw_layout[256];
|
||||
char raw_mfact[256], raw_nmaster[256], raw_rr[256];
|
||||
char raw_scale[256], raw_x[256], raw_y[256];
|
||||
|
||||
if (parsed == 8) {
|
||||
rule->name = strdup(name);
|
||||
rule->layout = strdup(layout);
|
||||
// 先读取所有字段为字符串
|
||||
int parsed = sscanf(value, "%255[^,],%255[^,],%255[^,],%255[^,],%255[^,],%255[^,],%255[^,],%255s",
|
||||
raw_name, raw_mfact, raw_nmaster, raw_layout,
|
||||
raw_rr, raw_scale, raw_x, raw_y);
|
||||
|
||||
if (parsed == 8) {
|
||||
// 修剪每个字段的空格
|
||||
trim_whitespace(raw_name);
|
||||
trim_whitespace(raw_mfact);
|
||||
trim_whitespace(raw_nmaster);
|
||||
trim_whitespace(raw_layout);
|
||||
trim_whitespace(raw_rr);
|
||||
trim_whitespace(raw_scale);
|
||||
trim_whitespace(raw_x);
|
||||
trim_whitespace(raw_y);
|
||||
|
||||
// 转换修剪后的字符串为特定类型
|
||||
rule->name = strdup(raw_name);
|
||||
rule->layout = strdup(raw_layout);
|
||||
rule->mfact = atof(raw_mfact);
|
||||
rule->nmaster = atoi(raw_nmaster);
|
||||
rule->rr = atoi(raw_rr);
|
||||
rule->scale = atof(raw_scale);
|
||||
rule->x = atoi(raw_x);
|
||||
rule->y = atoi(raw_y);
|
||||
|
||||
if (!rule->name || !rule->layout) {
|
||||
if (rule->name)
|
||||
|
|
@ -1092,6 +1166,8 @@ void parse_config_line(Config *config, const char *line) {
|
|||
fprintf(stderr, "Error: Invalid bind format: %s\n", value);
|
||||
return;
|
||||
}
|
||||
trim_whitespace(env_type);
|
||||
trim_whitespace(env_value);
|
||||
setenv(env_type, env_value, 1);
|
||||
|
||||
} else if (strncmp(key, "exec", 9) == 0) {
|
||||
|
|
@ -1150,6 +1226,13 @@ void parse_config_line(Config *config, const char *line) {
|
|||
fprintf(stderr, "Error: Invalid bind format: %s\n", value);
|
||||
return;
|
||||
}
|
||||
trim_whitespace(mod_str);
|
||||
trim_whitespace(keysym_str);
|
||||
trim_whitespace(func_name);
|
||||
trim_whitespace(arg_value);
|
||||
trim_whitespace(arg_value2);
|
||||
trim_whitespace(arg_value3);
|
||||
trim_whitespace(arg_value4);
|
||||
|
||||
binding->mod = parse_mod(mod_str);
|
||||
binding->keysym = parse_keysym(keysym_str);
|
||||
|
|
@ -1193,6 +1276,13 @@ void parse_config_line(Config *config, const char *line) {
|
|||
fprintf(stderr, "Error: Invalid mousebind format: %s\n", value);
|
||||
return;
|
||||
}
|
||||
trim_whitespace(mod_str);
|
||||
trim_whitespace(button_str);
|
||||
trim_whitespace(func_name);
|
||||
trim_whitespace(arg_value);
|
||||
trim_whitespace(arg_value2);
|
||||
trim_whitespace(arg_value3);
|
||||
trim_whitespace(arg_value4);
|
||||
|
||||
binding->mod = parse_mod(mod_str);
|
||||
binding->button = parse_button(button_str);
|
||||
|
|
@ -1235,6 +1325,14 @@ void parse_config_line(Config *config, const char *line) {
|
|||
return;
|
||||
}
|
||||
|
||||
trim_whitespace(mod_str);
|
||||
trim_whitespace(dir_str);
|
||||
trim_whitespace(func_name);
|
||||
trim_whitespace(arg_value);
|
||||
trim_whitespace(arg_value2);
|
||||
trim_whitespace(arg_value3);
|
||||
trim_whitespace(arg_value4);
|
||||
|
||||
binding->mod = parse_mod(mod_str);
|
||||
binding->dir = parse_direction(dir_str);
|
||||
binding->arg.v = NULL;
|
||||
|
|
@ -1280,6 +1378,15 @@ void parse_config_line(Config *config, const char *line) {
|
|||
return;
|
||||
}
|
||||
|
||||
trim_whitespace(mod_str);
|
||||
trim_whitespace(motion_str);
|
||||
trim_whitespace(fingers_count_str);
|
||||
trim_whitespace(func_name);
|
||||
trim_whitespace(arg_value);
|
||||
trim_whitespace(arg_value2);
|
||||
trim_whitespace(arg_value3);
|
||||
trim_whitespace(arg_value4);
|
||||
|
||||
binding->mod = parse_mod(mod_str);
|
||||
binding->motion = parse_direction(motion_str);
|
||||
binding->fingers_count = atoi(fingers_count_str);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue