mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2026-02-04 04:06:21 -05:00
feat: add config check in mango cli
This commit is contained in:
parent
5172444e08
commit
bcee63fa76
2 changed files with 354 additions and 117 deletions
|
|
@ -405,7 +405,10 @@ int32_t parse_double_array(const char *input, double *output,
|
|||
char *endptr;
|
||||
double val = strtod(token, &endptr);
|
||||
if (endptr == token || *endptr != '\0') {
|
||||
fprintf(stderr, "Error: Invalid number in array: %s\n", token);
|
||||
fprintf(
|
||||
stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Invalid number in array: %s\n",
|
||||
token);
|
||||
free(dup);
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -457,7 +460,9 @@ void parse_bind_flags(const char *str, KeyBinding *kb) {
|
|||
kb->ispassapply = true;
|
||||
break;
|
||||
default:
|
||||
// 忽略其他字符或可根据需要处理错误
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Unknown bind flag: %c\n",
|
||||
suffix[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -547,13 +552,14 @@ static bool starts_with_ignore_case(const char *str, const char *prefix) {
|
|||
|
||||
uint32_t parse_mod(const char *mod_str) {
|
||||
if (!mod_str || !*mod_str) {
|
||||
return 0;
|
||||
return UINT32_MAX;
|
||||
}
|
||||
|
||||
uint32_t mod = 0;
|
||||
char input_copy[256];
|
||||
char *token;
|
||||
char *saveptr = NULL;
|
||||
bool match_success = false;
|
||||
|
||||
// 复制并转换为小写
|
||||
strncpy(input_copy, mod_str, sizeof(input_copy) - 1);
|
||||
|
|
@ -591,35 +597,56 @@ uint32_t parse_mod(const char *mod_str) {
|
|||
case 108:
|
||||
mod |= WLR_MODIFIER_ALT;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,
|
||||
"unknown modifier keycode: \033[1m\033[31m%s\n",
|
||||
token);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 完整的 modifier 检查(保留原始所有检查项)
|
||||
if (strstr(token, "super") || strstr(token, "super_l") ||
|
||||
strstr(token, "super_r")) {
|
||||
if (!strcmp(token, "super") || !strcmp(token, "super_l") ||
|
||||
!strcmp(token, "super_r")) {
|
||||
mod |= WLR_MODIFIER_LOGO;
|
||||
match_success = true;
|
||||
}
|
||||
if (strstr(token, "ctrl") || strstr(token, "ctrl_l") ||
|
||||
strstr(token, "ctrl_r")) {
|
||||
if (!strcmp(token, "ctrl") || !strcmp(token, "ctrl_l") ||
|
||||
!strcmp(token, "ctrl_r")) {
|
||||
mod |= WLR_MODIFIER_CTRL;
|
||||
match_success = true;
|
||||
}
|
||||
if (strstr(token, "shift") || strstr(token, "shift_l") ||
|
||||
strstr(token, "shift_r")) {
|
||||
if (!strcmp(token, "shift") || !strcmp(token, "shift_l") ||
|
||||
!strcmp(token, "shift_r")) {
|
||||
mod |= WLR_MODIFIER_SHIFT;
|
||||
match_success = true;
|
||||
}
|
||||
if (strstr(token, "alt") || strstr(token, "alt_l") ||
|
||||
strstr(token, "alt_r")) {
|
||||
if (!strcmp(token, "alt") || !strcmp(token, "alt_l") ||
|
||||
!strcmp(token, "alt_r")) {
|
||||
mod |= WLR_MODIFIER_ALT;
|
||||
match_success = true;
|
||||
}
|
||||
if (strstr(token, "hyper") || strstr(token, "hyper_l") ||
|
||||
strstr(token, "hyper_r")) {
|
||||
if (!strcmp(token, "hyper") || !strcmp(token, "hyper_l") ||
|
||||
!strcmp(token, "hyper_r")) {
|
||||
mod |= WLR_MODIFIER_MOD3;
|
||||
match_success = true;
|
||||
}
|
||||
if (!strcmp(token, "none")) {
|
||||
match_success = true;
|
||||
}
|
||||
}
|
||||
|
||||
token = strtok_r(NULL, "+", &saveptr);
|
||||
}
|
||||
|
||||
if (!match_success) {
|
||||
mod = UINT32_MAX;
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Unknown modifier: "
|
||||
"\033[1m\033[31m%s\n",
|
||||
mod_str);
|
||||
}
|
||||
|
||||
return mod;
|
||||
}
|
||||
|
||||
|
|
@ -735,13 +762,17 @@ KeySymCode parse_key(const char *key_str, bool isbindsym) {
|
|||
// 无法解析的键名
|
||||
kc.type = KEY_TYPE_SYM;
|
||||
kc.keysym = XKB_KEY_NoSymbol;
|
||||
fprintf(
|
||||
stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Unknown key: \033[1m\033[31m%s\n",
|
||||
key_str);
|
||||
// keycode 字段保持为0
|
||||
}
|
||||
|
||||
return kc;
|
||||
}
|
||||
|
||||
int32_t parse_button(const char *str) {
|
||||
uint32_t parse_button(const char *str) {
|
||||
// 将输入字符串转换为小写
|
||||
char lowerStr[20];
|
||||
int32_t i = 0;
|
||||
|
|
@ -769,7 +800,11 @@ int32_t parse_button(const char *str) {
|
|||
} else if (strcmp(lowerStr, "btn_task") == 0) {
|
||||
return BTN_TASK;
|
||||
} else {
|
||||
return 0;
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Unknown button: "
|
||||
"\033[1m\033[31m%s\n",
|
||||
str);
|
||||
return UINT32_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1115,7 +1150,7 @@ void run_exec_once() {
|
|||
}
|
||||
}
|
||||
|
||||
void parse_option(Config *config, char *key, char *value) {
|
||||
bool parse_option(Config *config, char *key, char *value) {
|
||||
if (strcmp(key, "keymode") == 0) {
|
||||
snprintf(config->keymode, sizeof(config->keymode), "%.27s", value);
|
||||
} else if (strcmp(key, "animations") == 0) {
|
||||
|
|
@ -1166,53 +1201,70 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
int32_t num =
|
||||
parse_double_array(value, config->animation_curve_move, 4);
|
||||
if (num != 4) {
|
||||
fprintf(stderr, "Error: Failed to parse animation_curve_move: %s\n",
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Failed to parse "
|
||||
"animation_curve_move: %s\n",
|
||||
value);
|
||||
return false;
|
||||
}
|
||||
} else if (strcmp(key, "animation_curve_open") == 0) {
|
||||
int32_t num =
|
||||
parse_double_array(value, config->animation_curve_open, 4);
|
||||
if (num != 4) {
|
||||
fprintf(stderr, "Error: Failed to parse animation_curve_open: %s\n",
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Failed to parse "
|
||||
"animation_curve_open: %s\n",
|
||||
value);
|
||||
return false;
|
||||
}
|
||||
} else if (strcmp(key, "animation_curve_tag") == 0) {
|
||||
int32_t num = parse_double_array(value, config->animation_curve_tag, 4);
|
||||
if (num != 4) {
|
||||
fprintf(stderr, "Error: Failed to parse animation_curve_tag: %s\n",
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Failed to parse "
|
||||
"animation_curve_tag: %s\n",
|
||||
value);
|
||||
return false;
|
||||
}
|
||||
} else if (strcmp(key, "animation_curve_close") == 0) {
|
||||
int32_t num =
|
||||
parse_double_array(value, config->animation_curve_close, 4);
|
||||
if (num != 4) {
|
||||
fprintf(stderr,
|
||||
"Error: Failed to parse animation_curve_close: %s\n",
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Failed to parse "
|
||||
"animation_curve_close: %s\n",
|
||||
value);
|
||||
return false;
|
||||
}
|
||||
} else if (strcmp(key, "animation_curve_focus") == 0) {
|
||||
int32_t num =
|
||||
parse_double_array(value, config->animation_curve_focus, 4);
|
||||
if (num != 4) {
|
||||
fprintf(stderr,
|
||||
"Error: Failed to parse animation_curve_focus: %s\n",
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Failed to parse "
|
||||
"animation_curve_focus: %s\n",
|
||||
value);
|
||||
return false;
|
||||
}
|
||||
} else if (strcmp(key, "animation_curve_opafadein") == 0) {
|
||||
int32_t num =
|
||||
parse_double_array(value, config->animation_curve_opafadein, 4);
|
||||
if (num != 4) {
|
||||
fprintf(stderr,
|
||||
"Error: Failed to parse animation_curve_opafadein: %s\n",
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Failed to parse "
|
||||
"animation_curve_opafadein: %s\n",
|
||||
value);
|
||||
return false;
|
||||
}
|
||||
} else if (strcmp(key, "animation_curve_opafadeout") == 0) {
|
||||
int32_t num =
|
||||
parse_double_array(value, config->animation_curve_opafadeout, 4);
|
||||
if (num != 4) {
|
||||
fprintf(stderr,
|
||||
"Error: Failed to parse animation_curve_opafadeout: %s\n",
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Failed to parse "
|
||||
"animation_curve_opafadeout: %s\n",
|
||||
value);
|
||||
return false;
|
||||
}
|
||||
} else if (strcmp(key, "scroller_structs") == 0) {
|
||||
config->scroller_structs = atoi(value);
|
||||
|
|
@ -1333,8 +1385,10 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
config->scroller_proportion_preset =
|
||||
(float *)malloc(float_count * sizeof(float));
|
||||
if (!config->scroller_proportion_preset) {
|
||||
fprintf(stderr, "Error: Memory allocation failed\n");
|
||||
return;
|
||||
fprintf(
|
||||
stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Memory allocation failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 3. 解析 value 中的浮点数
|
||||
|
|
@ -1346,14 +1400,15 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
|
||||
while (token != NULL && i < float_count) {
|
||||
if (sscanf(token, "%f", &value_set) != 1) {
|
||||
fprintf(stderr,
|
||||
"Error: Invalid float value in "
|
||||
"scroller_proportion_preset: %s\n",
|
||||
token);
|
||||
fprintf(
|
||||
stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Invalid float value in "
|
||||
"scroller_proportion_preset: %s\n",
|
||||
token);
|
||||
free(value_copy);
|
||||
free(config->scroller_proportion_preset);
|
||||
config->scroller_proportion_preset = NULL;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Clamp the value between 0.0 and 1.0 (or your desired range)
|
||||
|
|
@ -1367,13 +1422,14 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
// 4. 检查解析的浮点数数量是否匹配
|
||||
if (i != float_count) {
|
||||
fprintf(stderr,
|
||||
"Error: Invalid scroller_proportion_preset format: %s\n",
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Invalid "
|
||||
"scroller_proportion_preset format: %s\n",
|
||||
value);
|
||||
free(value_copy);
|
||||
free(config->scroller_proportion_preset); // 释放已分配的内存
|
||||
config->scroller_proportion_preset = NULL; // 防止野指针
|
||||
config->scroller_proportion_preset_count = 0;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
config->scroller_proportion_preset_count = float_count;
|
||||
|
||||
|
|
@ -1392,8 +1448,10 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
config->circle_layout = (char **)malloc(string_count * sizeof(char *));
|
||||
memset(config->circle_layout, 0, string_count * sizeof(char *));
|
||||
if (!config->circle_layout) {
|
||||
fprintf(stderr, "Error: Memory allocation failed\n");
|
||||
return;
|
||||
fprintf(
|
||||
stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Memory allocation failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 3. 解析 value 中的字符串
|
||||
|
|
@ -1408,7 +1466,9 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
config->circle_layout[i] = strdup(cleaned_token);
|
||||
if (!config->circle_layout[i]) {
|
||||
fprintf(stderr,
|
||||
"Error: Memory allocation failed for string: %s\n",
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Memory allocation "
|
||||
"failed for "
|
||||
"string: %s\n",
|
||||
token);
|
||||
// 释放之前分配的内存
|
||||
for (int32_t j = 0; j < i; j++) {
|
||||
|
|
@ -1418,7 +1478,7 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
free(value_copy);
|
||||
config->circle_layout = NULL; // 防止野指针
|
||||
config->circle_layout_count = 0;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
token = strtok(NULL, ",");
|
||||
i++;
|
||||
|
|
@ -1426,7 +1486,10 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
|
||||
// 4. 检查解析的字符串数量是否匹配
|
||||
if (i != string_count) {
|
||||
fprintf(stderr, "Error: Invalid circle_layout format: %s\n", value);
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Invalid circle_layout "
|
||||
"format: %s\n",
|
||||
value);
|
||||
// 释放之前分配的内存
|
||||
for (int32_t j = 0; j < i; j++) {
|
||||
free(config->circle_layout[j]);
|
||||
|
|
@ -1435,7 +1498,7 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
free(value_copy);
|
||||
config->circle_layout = NULL; // 防止野指针
|
||||
config->circle_layout_count = 0;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
config->circle_layout_count = string_count;
|
||||
|
||||
|
|
@ -1542,7 +1605,11 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
} else if (strcmp(key, "rootcolor") == 0) {
|
||||
int64_t color = parse_color(value);
|
||||
if (color == -1) {
|
||||
fprintf(stderr, "Error: Invalid rootcolor format: %s\n", value);
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Invalid rootcolor format: "
|
||||
"%s\n",
|
||||
value);
|
||||
return false;
|
||||
} else {
|
||||
convert_hex_to_rgba(config->rootcolor, color);
|
||||
}
|
||||
|
|
@ -1550,58 +1617,89 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
} else if (strcmp(key, "shadowscolor") == 0) {
|
||||
int64_t color = parse_color(value);
|
||||
if (color == -1) {
|
||||
fprintf(stderr, "Error: Invalid shadowscolor format: %s\n", value);
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Invalid shadowscolor "
|
||||
"format: %s\n",
|
||||
value);
|
||||
return false;
|
||||
} else {
|
||||
convert_hex_to_rgba(config->shadowscolor, color);
|
||||
}
|
||||
} else if (strcmp(key, "bordercolor") == 0) {
|
||||
int64_t color = parse_color(value);
|
||||
if (color == -1) {
|
||||
fprintf(stderr, "Error: Invalid bordercolor format: %s\n", value);
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Invalid bordercolor "
|
||||
"format: %s\n",
|
||||
value);
|
||||
return false;
|
||||
} else {
|
||||
convert_hex_to_rgba(config->bordercolor, color);
|
||||
}
|
||||
} else if (strcmp(key, "focuscolor") == 0) {
|
||||
int64_t color = parse_color(value);
|
||||
if (color == -1) {
|
||||
fprintf(stderr, "Error: Invalid focuscolor format: %s\n", value);
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Invalid focuscolor "
|
||||
"format: %s\n",
|
||||
value);
|
||||
return false;
|
||||
} else {
|
||||
convert_hex_to_rgba(config->focuscolor, color);
|
||||
}
|
||||
} else if (strcmp(key, "maximizescreencolor") == 0) {
|
||||
int64_t color = parse_color(value);
|
||||
if (color == -1) {
|
||||
fprintf(stderr, "Error: Invalid maximizescreencolor format: %s\n",
|
||||
value);
|
||||
fprintf(
|
||||
stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Invalid maximizescreencolor "
|
||||
"format: %s\n",
|
||||
value);
|
||||
return false;
|
||||
} else {
|
||||
convert_hex_to_rgba(config->maximizescreencolor, color);
|
||||
}
|
||||
} else if (strcmp(key, "urgentcolor") == 0) {
|
||||
int64_t color = parse_color(value);
|
||||
if (color == -1) {
|
||||
fprintf(stderr, "Error: Invalid urgentcolor format: %s\n", value);
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Invalid urgentcolor "
|
||||
"format: %s\n",
|
||||
value);
|
||||
return false;
|
||||
} else {
|
||||
convert_hex_to_rgba(config->urgentcolor, color);
|
||||
}
|
||||
} else if (strcmp(key, "scratchpadcolor") == 0) {
|
||||
int64_t color = parse_color(value);
|
||||
if (color == -1) {
|
||||
fprintf(stderr, "Error: Invalid scratchpadcolor format: %s\n",
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Invalid scratchpadcolor "
|
||||
"format: %s\n",
|
||||
value);
|
||||
return false;
|
||||
} else {
|
||||
convert_hex_to_rgba(config->scratchpadcolor, color);
|
||||
}
|
||||
} else if (strcmp(key, "globalcolor") == 0) {
|
||||
int64_t color = parse_color(value);
|
||||
if (color == -1) {
|
||||
fprintf(stderr, "Error: Invalid globalcolor format: %s\n", value);
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Invalid globalcolor "
|
||||
"format: %s\n",
|
||||
value);
|
||||
return false;
|
||||
} else {
|
||||
convert_hex_to_rgba(config->globalcolor, color);
|
||||
}
|
||||
} else if (strcmp(key, "overlaycolor") == 0) {
|
||||
int64_t color = parse_color(value);
|
||||
if (color == -1) {
|
||||
fprintf(stderr, "Error: Invalid overlaycolor format: %s\n", value);
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Invalid overlaycolor "
|
||||
"format: %s\n",
|
||||
value);
|
||||
return false;
|
||||
} else {
|
||||
convert_hex_to_rgba(config->overlaycolor, color);
|
||||
}
|
||||
|
|
@ -1611,8 +1709,9 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
sizeof(ConfigMonitorRule));
|
||||
if (!config->monitor_rules) {
|
||||
fprintf(stderr,
|
||||
"Error: Failed to allocate memory for monitor rules\n");
|
||||
return;
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Failed to allocate "
|
||||
"memory for monitor rules\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
ConfigMonitorRule *rule =
|
||||
|
|
@ -1630,6 +1729,7 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
rule->refresh = 0.0f;
|
||||
rule->vrr = 0;
|
||||
|
||||
bool parse_error = false;
|
||||
char *token = strtok(value, ",");
|
||||
while (token != NULL) {
|
||||
char *colon = strchr(token, ':');
|
||||
|
|
@ -1659,19 +1759,29 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
rule->refresh = CLAMP_FLOAT(atof(val), 0.001f, 1000.0f);
|
||||
} else if (strcmp(key, "vrr") == 0) {
|
||||
rule->vrr = CLAMP_INT(atoi(val), 0, 1);
|
||||
} else {
|
||||
fprintf(
|
||||
stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Unknown monitor rule "
|
||||
"option:\033[1m\033[31m %s\n",
|
||||
key);
|
||||
parse_error = true;
|
||||
}
|
||||
}
|
||||
token = strtok(NULL, ",");
|
||||
}
|
||||
|
||||
config->monitor_rules_count++;
|
||||
return !parse_error;
|
||||
} else if (strcmp(key, "tagrule") == 0) {
|
||||
config->tag_rules =
|
||||
realloc(config->tag_rules,
|
||||
(config->tag_rules_count + 1) * sizeof(ConfigTagRule));
|
||||
if (!config->tag_rules) {
|
||||
fprintf(stderr, "Error: Failed to allocate memory for tag rules\n");
|
||||
return;
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Failed to allocate "
|
||||
"memory for tag rules\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
ConfigTagRule *rule = &config->tag_rules[config->tag_rules_count];
|
||||
|
|
@ -1686,6 +1796,7 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
rule->no_render_border = 0;
|
||||
rule->no_hide = 0;
|
||||
|
||||
bool parse_error = false;
|
||||
char *token = strtok(value, ",");
|
||||
while (token != NULL) {
|
||||
char *colon = strchr(token, ':');
|
||||
|
|
@ -1711,20 +1822,28 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
rule->nmaster = CLAMP_INT(atoi(val), 1, 99);
|
||||
} else if (strcmp(key, "mfact") == 0) {
|
||||
rule->mfact = CLAMP_FLOAT(atof(val), 0.1f, 0.9f);
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Unknown tag rule "
|
||||
"option:\033[1m\033[31m %s\n",
|
||||
key);
|
||||
parse_error = true;
|
||||
}
|
||||
}
|
||||
token = strtok(NULL, ",");
|
||||
}
|
||||
|
||||
config->tag_rules_count++;
|
||||
return !parse_error;
|
||||
} else if (strcmp(key, "layerrule") == 0) {
|
||||
config->layer_rules =
|
||||
realloc(config->layer_rules,
|
||||
(config->layer_rules_count + 1) * sizeof(ConfigLayerRule));
|
||||
if (!config->layer_rules) {
|
||||
fprintf(stderr,
|
||||
"Error: Failed to allocate memory for layer rules\n");
|
||||
return;
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Failed to allocate "
|
||||
"memory for layer rules\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
ConfigLayerRule *rule = &config->layer_rules[config->layer_rules_count];
|
||||
|
|
@ -1738,6 +1857,7 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
rule->noanim = 0;
|
||||
rule->noshadow = 0;
|
||||
|
||||
bool parse_error = false;
|
||||
char *token = strtok(value, ",");
|
||||
while (token != NULL) {
|
||||
char *colon = strchr(token, ':');
|
||||
|
|
@ -1761,6 +1881,13 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
rule->noanim = CLAMP_INT(atoi(val), 0, 1);
|
||||
} else if (strcmp(key, "noshadow") == 0) {
|
||||
rule->noshadow = CLAMP_INT(atoi(val), 0, 1);
|
||||
} else {
|
||||
fprintf(
|
||||
stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Unknown layer rule "
|
||||
"option:\033[1m\033[31m %s\n",
|
||||
key);
|
||||
parse_error = true;
|
||||
}
|
||||
}
|
||||
token = strtok(NULL, ",");
|
||||
|
|
@ -1772,14 +1899,16 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
}
|
||||
|
||||
config->layer_rules_count++;
|
||||
return !parse_error;
|
||||
} else if (strcmp(key, "windowrule") == 0) {
|
||||
config->window_rules =
|
||||
realloc(config->window_rules,
|
||||
(config->window_rules_count + 1) * sizeof(ConfigWinRule));
|
||||
if (!config->window_rules) {
|
||||
fprintf(stderr,
|
||||
"Error: Failed to allocate memory for window rules\n");
|
||||
return;
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Failed to allocate "
|
||||
"memory for window rules\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
ConfigWinRule *rule = &config->window_rules[config->window_rules_count];
|
||||
|
|
@ -1835,6 +1964,7 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
|
||||
rule->globalkeybinding = (KeyBinding){0};
|
||||
|
||||
bool parse_error = false;
|
||||
char *token = strtok(value, ",");
|
||||
while (token != NULL) {
|
||||
char *colon = strchr(token, ':');
|
||||
|
|
@ -1934,17 +2064,37 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
rule->globalkeybinding.mod = parse_mod(mod_str);
|
||||
rule->globalkeybinding.keysymcode =
|
||||
parse_key(keysym_str, false);
|
||||
if (rule->globalkeybinding.mod == UINT32_MAX) {
|
||||
return false;
|
||||
}
|
||||
if (rule->globalkeybinding.keysymcode.type ==
|
||||
KEY_TYPE_SYM &&
|
||||
rule->globalkeybinding.keysymcode.keysym ==
|
||||
XKB_KEY_NoSymbol) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
fprintf(
|
||||
stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Unknown window rule "
|
||||
"option:\033[1m\033[31m %s\n",
|
||||
key);
|
||||
parse_error = true;
|
||||
}
|
||||
}
|
||||
token = strtok(NULL, ",");
|
||||
}
|
||||
config->window_rules_count++;
|
||||
return !parse_error;
|
||||
} else if (strncmp(key, "env", 3) == 0) {
|
||||
|
||||
char env_type[256], env_value[256];
|
||||
if (sscanf(value, "%255[^,],%255[^\n]", env_type, env_value) < 2) {
|
||||
fprintf(stderr, "Error: Invalid bind format: %s\n", value);
|
||||
return;
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Invalid bind format: "
|
||||
"\033[1m\033[31m%s\n",
|
||||
value);
|
||||
return false;
|
||||
}
|
||||
trim_whitespace(env_type);
|
||||
trim_whitespace(env_value);
|
||||
|
|
@ -1959,8 +2109,9 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
free(env->type);
|
||||
free(env->value);
|
||||
free(env);
|
||||
fprintf(stderr, "Error: Failed to allocate memory for env\n");
|
||||
return;
|
||||
fprintf(stderr, "\033[1m\033[31m[ERROR]:\033[33m Failed to "
|
||||
"allocate memory for env\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
config->env[config->env_count] = env;
|
||||
|
|
@ -1970,15 +2121,18 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
char **new_exec =
|
||||
realloc(config->exec, (config->exec_count + 1) * sizeof(char *));
|
||||
if (!new_exec) {
|
||||
fprintf(stderr, "Error: Failed to allocate memory for exec\n");
|
||||
return;
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Failed to allocate "
|
||||
"memory for exec\n");
|
||||
return false;
|
||||
}
|
||||
config->exec = new_exec;
|
||||
|
||||
config->exec[config->exec_count] = strdup(value);
|
||||
if (!config->exec[config->exec_count]) {
|
||||
fprintf(stderr, "Error: Failed to duplicate exec string\n");
|
||||
return;
|
||||
fprintf(stderr, "\033[1m\033[31m[ERROR]:\033[33m Failed to "
|
||||
"duplicate exec string\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
config->exec_count++;
|
||||
|
|
@ -1988,15 +2142,19 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
char **new_exec_once = realloc(
|
||||
config->exec_once, (config->exec_once_count + 1) * sizeof(char *));
|
||||
if (!new_exec_once) {
|
||||
fprintf(stderr, "Error: Failed to allocate memory for exec_once\n");
|
||||
return;
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Failed to allocate "
|
||||
"memory for exec_once\n");
|
||||
return false;
|
||||
}
|
||||
config->exec_once = new_exec_once;
|
||||
|
||||
config->exec_once[config->exec_once_count] = strdup(value);
|
||||
if (!config->exec_once[config->exec_once_count]) {
|
||||
fprintf(stderr, "Error: Failed to duplicate exec_once string\n");
|
||||
return;
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Failed to duplicate "
|
||||
"exec_once string\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
config->exec_once_count++;
|
||||
|
|
@ -2007,8 +2165,9 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
(config->key_bindings_count + 1) * sizeof(KeyBinding));
|
||||
if (!config->key_bindings) {
|
||||
fprintf(stderr,
|
||||
"Error: Failed to allocate memory for key bindings\n");
|
||||
return;
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Failed to allocate "
|
||||
"memory for key bindings\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
KeyBinding *binding = &config->key_bindings[config->key_bindings_count];
|
||||
|
|
@ -2023,8 +2182,11 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
"^,],%255[^\n]",
|
||||
mod_str, keysym_str, func_name, arg_value, arg_value2,
|
||||
arg_value3, arg_value4, arg_value5) < 3) {
|
||||
fprintf(stderr, "Error: Invalid bind format: %s\n", value);
|
||||
return;
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Invalid bind format: "
|
||||
"\033[1m\033[31m%s\n",
|
||||
value);
|
||||
return false;
|
||||
}
|
||||
trim_whitespace(mod_str);
|
||||
trim_whitespace(keysym_str);
|
||||
|
|
@ -2057,7 +2219,9 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
binding->func =
|
||||
parse_func_name(func_name, &binding->arg, arg_value, arg_value2,
|
||||
arg_value3, arg_value4, arg_value5);
|
||||
if (!binding->func) {
|
||||
if (!binding->func || binding->mod == UINT32_MAX ||
|
||||
(binding->keysymcode.type == KEY_TYPE_SYM &&
|
||||
binding->keysymcode.keysym == XKB_KEY_NoSymbol)) {
|
||||
if (binding->arg.v) {
|
||||
free(binding->arg.v);
|
||||
binding->arg.v = NULL;
|
||||
|
|
@ -2070,7 +2234,13 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
free(binding->arg.v3);
|
||||
binding->arg.v3 = NULL;
|
||||
}
|
||||
fprintf(stderr, "Error: Unknown function in bind: %s\n", func_name);
|
||||
if (!binding->func)
|
||||
fprintf(
|
||||
stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Unknown dispatch in bind: "
|
||||
"\033[1m\033[31m%s\n",
|
||||
func_name);
|
||||
return false;
|
||||
} else {
|
||||
config->key_bindings_count++;
|
||||
}
|
||||
|
|
@ -2081,8 +2251,9 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
(config->mouse_bindings_count + 1) * sizeof(MouseBinding));
|
||||
if (!config->mouse_bindings) {
|
||||
fprintf(stderr,
|
||||
"Error: Failed to allocate memory for mouse bindings\n");
|
||||
return;
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Failed to allocate "
|
||||
"memory for mouse bindings\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
MouseBinding *binding =
|
||||
|
|
@ -2098,8 +2269,11 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
"^,],%255[^\n]",
|
||||
mod_str, button_str, func_name, arg_value, arg_value2,
|
||||
arg_value3, arg_value4, arg_value5) < 3) {
|
||||
fprintf(stderr, "Error: Invalid mousebind format: %s\n", value);
|
||||
return;
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Invalid mousebind format: "
|
||||
"%s\n",
|
||||
value);
|
||||
return false;
|
||||
}
|
||||
trim_whitespace(mod_str);
|
||||
trim_whitespace(button_str);
|
||||
|
|
@ -2118,7 +2292,8 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
binding->func =
|
||||
parse_func_name(func_name, &binding->arg, arg_value, arg_value2,
|
||||
arg_value3, arg_value4, arg_value5);
|
||||
if (!binding->func) {
|
||||
if (!binding->func || binding->mod == UINT32_MAX ||
|
||||
binding->button == UINT32_MAX) {
|
||||
if (binding->arg.v) {
|
||||
free(binding->arg.v);
|
||||
binding->arg.v = NULL;
|
||||
|
|
@ -2131,8 +2306,12 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
free(binding->arg.v3);
|
||||
binding->arg.v3 = NULL;
|
||||
}
|
||||
fprintf(stderr, "Error: Unknown function in mousebind: %s\n",
|
||||
func_name);
|
||||
if (!binding->func)
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Unknown dispatch in "
|
||||
"mousebind: \033[1m\033[31m%s\n",
|
||||
func_name);
|
||||
return false;
|
||||
} else {
|
||||
config->mouse_bindings_count++;
|
||||
}
|
||||
|
|
@ -2142,8 +2321,9 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
(config->axis_bindings_count + 1) * sizeof(AxisBinding));
|
||||
if (!config->axis_bindings) {
|
||||
fprintf(stderr,
|
||||
"Error: Failed to allocate memory for axis bindings\n");
|
||||
return;
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Failed to allocate "
|
||||
"memory for axis bindings\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
AxisBinding *binding =
|
||||
|
|
@ -2159,8 +2339,11 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
"^,],%255[^\n]",
|
||||
mod_str, dir_str, func_name, arg_value, arg_value2,
|
||||
arg_value3, arg_value4, arg_value5) < 3) {
|
||||
fprintf(stderr, "Error: Invalid axisbind format: %s\n", value);
|
||||
return;
|
||||
fprintf(
|
||||
stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Invalid axisbind format: %s\n",
|
||||
value);
|
||||
return false;
|
||||
}
|
||||
|
||||
trim_whitespace(mod_str);
|
||||
|
|
@ -2181,7 +2364,7 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
parse_func_name(func_name, &binding->arg, arg_value, arg_value2,
|
||||
arg_value3, arg_value4, arg_value5);
|
||||
|
||||
if (!binding->func) {
|
||||
if (!binding->func || binding->mod == UINT32_MAX) {
|
||||
if (binding->arg.v) {
|
||||
free(binding->arg.v);
|
||||
binding->arg.v = NULL;
|
||||
|
|
@ -2194,8 +2377,12 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
free(binding->arg.v3);
|
||||
binding->arg.v3 = NULL;
|
||||
}
|
||||
fprintf(stderr, "Error: Unknown function in axisbind: %s\n",
|
||||
func_name);
|
||||
if (!binding->func)
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Unknown dispatch in "
|
||||
"axisbind: \033[1m\033[31m%s\n",
|
||||
func_name);
|
||||
return false;
|
||||
} else {
|
||||
config->axis_bindings_count++;
|
||||
}
|
||||
|
|
@ -2206,8 +2393,9 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
sizeof(SwitchBinding));
|
||||
if (!config->switch_bindings) {
|
||||
fprintf(stderr,
|
||||
"Error: Failed to allocate memory for switch bindings\n");
|
||||
return;
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Failed to allocate "
|
||||
"memory for switch bindings\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
SwitchBinding *binding =
|
||||
|
|
@ -2223,8 +2411,11 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
"^\n]",
|
||||
fold_str, func_name, arg_value, arg_value2, arg_value3,
|
||||
arg_value4, arg_value5) < 3) {
|
||||
fprintf(stderr, "Error: Invalid switchbind format: %s\n", value);
|
||||
return;
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Invalid switchbind "
|
||||
"format: %s\n",
|
||||
value);
|
||||
return false;
|
||||
}
|
||||
trim_whitespace(fold_str);
|
||||
trim_whitespace(func_name);
|
||||
|
|
@ -2252,8 +2443,13 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
free(binding->arg.v3);
|
||||
binding->arg.v3 = NULL;
|
||||
}
|
||||
fprintf(stderr, "Error: Unknown function in switchbind: %s\n",
|
||||
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Unknown dispatch in "
|
||||
"switchbind: "
|
||||
"\033[1m\033[31m%s\n",
|
||||
func_name);
|
||||
return false;
|
||||
} else {
|
||||
config->switch_bindings_count++;
|
||||
}
|
||||
|
|
@ -2264,8 +2460,9 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
(config->gesture_bindings_count + 1) * sizeof(GestureBinding));
|
||||
if (!config->gesture_bindings) {
|
||||
fprintf(stderr,
|
||||
"Error: Failed to allocate memory for axis gesturebind\n");
|
||||
return;
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Failed to allocate "
|
||||
"memory for axis gesturebind\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
GestureBinding *binding =
|
||||
|
|
@ -2281,8 +2478,11 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
"^,],%255[^,],%255[^\n]",
|
||||
mod_str, motion_str, fingers_count_str, func_name, arg_value,
|
||||
arg_value2, arg_value3, arg_value4, arg_value5) < 4) {
|
||||
fprintf(stderr, "Error: Invalid gesturebind format: %s\n", value);
|
||||
return;
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Invalid gesturebind "
|
||||
"format: %s\n",
|
||||
value);
|
||||
return false;
|
||||
}
|
||||
|
||||
trim_whitespace(mod_str);
|
||||
|
|
@ -2305,7 +2505,7 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
parse_func_name(func_name, &binding->arg, arg_value, arg_value2,
|
||||
arg_value3, arg_value4, arg_value5);
|
||||
|
||||
if (!binding->func) {
|
||||
if (!binding->func || binding->mod == UINT32_MAX) {
|
||||
if (binding->arg.v) {
|
||||
free(binding->arg.v);
|
||||
binding->arg.v = NULL;
|
||||
|
|
@ -2318,8 +2518,12 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
free(binding->arg.v3);
|
||||
binding->arg.v3 = NULL;
|
||||
}
|
||||
fprintf(stderr, "Error: Unknown function in axisbind: %s\n",
|
||||
func_name);
|
||||
if (!binding->func)
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Unknown dispatch in "
|
||||
"axisbind: \033[1m\033[31m%s\n",
|
||||
func_name);
|
||||
return false;
|
||||
} else {
|
||||
config->gesture_bindings_count++;
|
||||
}
|
||||
|
|
@ -2327,22 +2531,30 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
} else if (strncmp(key, "source", 6) == 0) {
|
||||
parse_config_file(config, value);
|
||||
} else {
|
||||
fprintf(stderr, "Error: Unknown key: %s\n", key);
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Unknown keyword: "
|
||||
"\033[1m\033[31m%s\n",
|
||||
key);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void parse_config_line(Config *config, const char *line) {
|
||||
bool parse_config_line(Config *config, const char *line) {
|
||||
char key[256], value[256];
|
||||
if (sscanf(line, "%255[^=]=%255[^\n]", key, value) != 2) {
|
||||
// fprintf(stderr, "Error: Invalid line format: %s\n", line);
|
||||
return;
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Invalid line format: %s",
|
||||
line);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Then trim each part separately
|
||||
trim_whitespace(key);
|
||||
trim_whitespace(value);
|
||||
|
||||
parse_option(config, key, value);
|
||||
return parse_option(config, key, value);
|
||||
}
|
||||
|
||||
void parse_config_file(Config *config, const char *file_path) {
|
||||
|
|
@ -2361,7 +2573,9 @@ void parse_config_file(Config *config, const char *file_path) {
|
|||
} else {
|
||||
const char *home = getenv("HOME");
|
||||
if (!home) {
|
||||
fprintf(stderr, "Error: HOME environment variable not set.\n");
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m HOME environment "
|
||||
"variable not set.\n");
|
||||
return;
|
||||
}
|
||||
snprintf(full_path, sizeof(full_path), "%s/.config/mango/%s", home,
|
||||
|
|
@ -2375,7 +2589,8 @@ void parse_config_file(Config *config, const char *file_path) {
|
|||
|
||||
const char *home = getenv("HOME");
|
||||
if (!home) {
|
||||
fprintf(stderr, "Error: HOME environment variable not set.\n");
|
||||
fprintf(stderr, "\033[1m\033[31m[ERROR]:\033[33m HOME environment "
|
||||
"variable not set.\n");
|
||||
return;
|
||||
}
|
||||
snprintf(full_path, sizeof(full_path), "%s%s", home, file_path + 1);
|
||||
|
|
@ -2392,11 +2607,21 @@ void parse_config_file(Config *config, const char *file_path) {
|
|||
}
|
||||
|
||||
char line[512];
|
||||
bool parse_correct = true;
|
||||
uint32_t line_count = 0;
|
||||
while (fgets(line, sizeof(line), file)) {
|
||||
line_count++;
|
||||
if (line[0] == '#' || line[0] == '\n') {
|
||||
continue;
|
||||
}
|
||||
parse_config_line(config, line);
|
||||
parse_correct = parse_config_line(config, line);
|
||||
if (!parse_correct) {
|
||||
fprintf(stderr,
|
||||
"\033[1;31m╰─\033[1;33m[Index]\033[0m "
|
||||
"\033[1;36m%s\033[0m:\033[1;35m%d\033[0m\n"
|
||||
" \033[1;36m╰─\033[0;33m%s\033[0m\n\n",
|
||||
file_path, line_count, line);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
|
|
|
|||
30
src/mango.c
30
src/mango.c
|
|
@ -6160,17 +6160,22 @@ int32_t main(int32_t argc, char *argv[]) {
|
|||
char *startup_cmd = NULL;
|
||||
int32_t c;
|
||||
|
||||
while ((c = getopt(argc, argv, "s:c:hdv")) != -1) {
|
||||
if (c == 's')
|
||||
while ((c = getopt(argc, argv, "s:c:hdvp")) != -1) {
|
||||
if (c == 's') {
|
||||
startup_cmd = optarg;
|
||||
else if (c == 'd')
|
||||
} else if (c == 'd') {
|
||||
log_level = WLR_DEBUG;
|
||||
else if (c == 'v')
|
||||
die("mango " VERSION);
|
||||
else if (c == 'c')
|
||||
} else if (c == 'v') {
|
||||
printf("mango " VERSION "\n");
|
||||
return EXIT_SUCCESS;
|
||||
} else if (c == 'c') {
|
||||
cli_config_path = optarg;
|
||||
else
|
||||
} else if (c == 'p') {
|
||||
parse_config();
|
||||
return EXIT_SUCCESS;
|
||||
} else {
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
if (optind < argc)
|
||||
goto usage;
|
||||
|
|
@ -6184,7 +6189,14 @@ int32_t main(int32_t argc, char *argv[]) {
|
|||
run(startup_cmd);
|
||||
cleanup();
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
usage:
|
||||
die("Usage: %s [-v] [-d] [-c config file] [-s startup command]", argv[0]);
|
||||
printf("Usage: mango [OPTIONS]\n"
|
||||
"\n"
|
||||
"Options:\n"
|
||||
" -v Show mango version\n"
|
||||
" -d Enable debug log\n"
|
||||
" -c <file> Use custom configuration file\n"
|
||||
" -s <command> Execute startup command\n"
|
||||
" -p Check configuration file error\n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue