summaryrefslogtreecommitdiff
path: root/src/parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser.c')
-rw-r--r--src/parser.c62
1 files changed, 26 insertions, 36 deletions
diff --git a/src/parser.c b/src/parser.c
index 2615ac3..8e598d0 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -1,12 +1,13 @@
#define _POSIX_C_SOURCE 200809L
-#include <X11/Xlib.h>
#include <ctype.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
-#include <unistd.h>
#include <string.h>
+#include <unistd.h>
+#include <wordexp.h>
#include <X11/keysym.h>
+#include <X11/Xlib.h>
#include "parser.h"
#include "defs.h"
@@ -315,7 +316,12 @@ found:;
if (*act == '"' && !strcmp(key, "bind")) {
b->type = TYPE_CMD;
b->action.cmd = build_argv(strip_quotes(act));
+ if (!b->action.cmd) {
+ fprintf(stderr, "sxwmrc:%d: failed to parse command: %s\n", lineno, act);
+ b->type = -1;
+ }
}
+
else {
b->type = TYPE_FUNC;
Bool found = False;
@@ -421,39 +427,23 @@ KeySym parse_keysym(const char *key)
const char **build_argv(const char *cmd)
{
- char *dup = strdup(cmd);
- char *saveptr = NULL;
- const char **argv = malloc(MAX_ARGS * sizeof(*argv));
- int i = 0;
-
- char *tok = strtok_r(dup, " \t", &saveptr);
- while (tok && i < MAX_ARGS - 1) {
- if (*tok == '"') {
- char *end = tok + strlen(tok) - 1;
- if (*end == '"') {
- *end = '\0';
- argv[i++] = strdup(tok + 1);
- }
- else {
- char *quoted = strdup(tok + 1);
- while ((tok = strtok_r(NULL, " \t", &saveptr)) && *tok != '"') {
- quoted = realloc(quoted, strlen(quoted) + strlen(tok) + 2);
- strcat(quoted, " ");
- strcat(quoted, tok);
- }
- if (tok && *tok == '"') {
- quoted = realloc(quoted, strlen(quoted) + strlen(tok));
- strcat(quoted, tok);
- }
- argv[i++] = quoted;
- }
- }
- else {
- argv[i++] = strdup(tok);
- }
- tok = strtok_r(NULL, " \t", &saveptr);
+ wordexp_t p;
+ if (wordexp(cmd, &p, 0) != 0 || p.we_wordc == 0) {
+ fprintf(stderr, "sxwm: wordexp failed for cmd: '%s'\n", cmd);
+ return NULL;
}
- argv[i] = NULL;
- free(dup);
+
+ const char **argv = malloc((p.we_wordc + 1) * sizeof(char *));
+ if (!argv) {
+ wordfree(&p);
+ return NULL;
+ }
+
+ for (size_t i = 0; i < p.we_wordc; i++) {
+ argv[i] = strdup(p.we_wordv[i]);
+ }
+ argv[p.we_wordc] = NULL;
+
+ wordfree(&p);
return argv;
-}
+} \ No newline at end of file