X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=spectrwm.c;h=251b74643acc18cc60a27e010187534b8190ec91;hb=a91fc9f2e2492eabbfc24463bd90e5e0aec51cc1;hp=00972db72d49b291ecef2ccf95372365ab8f330e;hpb=b2c1286094d53b3bab5abae50191c3d7d294960e;p=spectrwm.git diff --git a/spectrwm.c b/spectrwm.c index 00972db..251b746 100644 --- a/spectrwm.c +++ b/spectrwm.c @@ -870,6 +870,7 @@ RB_HEAD(key_tree, key); /* function prototypes */ void adjust_font(struct ws_win *); +char *argsep(char **); void bar_cleanup(struct swm_region *); void bar_extra_setup(void); void bar_extra_stop(void); @@ -6255,24 +6256,73 @@ spawn_select(struct swm_region *r, union arg *args, const char *spawn_name, free(real_args); } +/* Argument tokenizer. */ +char * +argsep(char **sp) { + int single_quoted = 0, double_quoted = 0; + char *arg, *cp, *next; + + if (*sp == NULL) + return NULL; + + /* Eat and move characters until end of argument is found. */ + for (arg = next = cp = *sp; *cp != '\0'; ++cp) { + if (!double_quoted && *cp == '\'') { + /* Eat single-quote. */ + single_quoted = !single_quoted; + } else if (!single_quoted && *cp == '"') { + /* Eat double-quote. */ + double_quoted = !double_quoted; + } else if (!single_quoted && *cp == '\\' && *(cp + 1) == '"') { + /* Eat backslash; copy escaped character to arg. */ + *next++ = *(++cp); + } else if (!single_quoted && !double_quoted && *cp == '\\' && + (*(cp + 1) == '\'' || *(cp + 1) == ' ')) { + /* Eat backslash; move escaped character. */ + *next++ = *(++cp); + } else if (!single_quoted && !double_quoted && + (*cp == ' ' || *cp == '\t')) { + /* Terminate argument. */ + *next++ = '\0'; + /* Point sp to beginning of next argument. */ + *sp = ++cp; + break; + } else { + /* Move regular character. */ + *next++ = *cp; + } + } + + /* Terminate argument if end of string. */ + if (*cp == '\0') { + *next = '\0'; + *sp = NULL; + } + + return arg; +} + void spawn_insert(const char *name, const char *args, int flags) { - char *arg, *cp, *ptr; struct spawn_prog *sp; + char *arg, *dup, *ptr; - DNPRINTF(SWM_D_SPAWN, "spawn_insert: %s\n", name); + DNPRINTF(SWM_D_SPAWN, "spawn_insert: %s[%s]\n", name, args); + + if (args == NULL || *args == '\0') + return; if ((sp = calloc(1, sizeof *sp)) == NULL) err(1, "spawn_insert: calloc"); if ((sp->name = strdup(name)) == NULL) err(1, "spawn_insert: strdup"); - /* convert the arguments to an argument list */ - if ((ptr = cp = strdup(args)) == NULL) + /* Convert the arguments to an argument list. */ + if ((ptr = dup = strdup(args)) == NULL) err(1, "spawn_insert: strdup"); - while ((arg = strsep(&ptr, " \t")) != NULL) { - /* empty field; skip it */ + while ((arg = argsep(&ptr)) != NULL) { + /* Null argument; skip it. */ if (*arg == '\0') continue; @@ -6283,10 +6333,11 @@ spawn_insert(const char *name, const char *args, int flags) if ((sp->argv[sp->argc - 1] = strdup(arg)) == NULL) err(1, "spawn_insert: strdup"); } - free(cp); + free(dup); sp->flags = flags; + DNPRINTF(SWM_D_SPAWN, "arg %d: [%s]\n", sp->argc, sp->argv[sp->argc-1]); TAILQ_INSERT_TAIL(&spawns, sp, entry); DNPRINTF(SWM_D_SPAWN, "spawn_insert: leave\n"); } @@ -6347,6 +6398,9 @@ setconfspawn(const char *selector, const char *value, int flags) { char *args; + if (selector == NULL || strlen(selector) == 0) + return (1); + args = expand_tilde(value); DNPRINTF(SWM_D_SPAWN, "setconfspawn: [%s] [%s]\n", selector, args); @@ -6595,8 +6649,9 @@ setconfbinding(const char *selector, const char *value, int flags) /* suppress unused warning since var is needed */ (void)flags; - DNPRINTF(SWM_D_KEY, "setconfbinding: enter\n"); - if (selector == NULL) { + DNPRINTF(SWM_D_KEY, "setconfbinding: enter selector: [%s], " + "value: [%s]\n", selector, value); + if (selector == NULL || strlen(selector) == 0) { DNPRINTF(SWM_D_KEY, "setconfbinding: unbind %s\n", value); if (parsekeys(value, mod_key, &mod, &ks) == 0) { kfid = KF_INVALID; @@ -7113,7 +7168,7 @@ setconfquirk(const char *selector, const char *value, int flags) /* suppress unused warning since var is needed */ (void)flags; - if (selector == NULL) + if (selector == NULL || strlen(selector) == 0) return (0); if ((str = strdup(selector)) == NULL) @@ -7226,9 +7281,6 @@ setconfvalue(const char *selector, const char *value, int flags) int i, ws_id, num_screens; char *b, *str; - /* suppress unused warning since var is needed */ - (void)selector; - switch (flags) { case SWM_S_BAR_ACTION: free(bar_argv[0]); @@ -7468,7 +7520,9 @@ setconfmodkey(const char *selector, const char *value, int flags) int setconfcolor(const char *selector, const char *value, int flags) { - setscreencolor(value, ((selector == NULL)?-1:atoi(selector)), flags); + setscreencolor(value, + (selector == NULL || strlen(selector) == 0) ? -1 : atoi(selector), + flags); return (0); }