summaryrefslogtreecommitdiffstats
path: root/sway/stringop.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/stringop.c')
-rw-r--r--sway/stringop.c118
1 files changed, 85 insertions, 33 deletions
diff --git a/sway/stringop.c b/sway/stringop.c
index 7a2c8317..31a036c3 100644
--- a/sway/stringop.c
+++ b/sway/stringop.c
@@ -1,5 +1,6 @@
1#include <stdlib.h> 1#include <stdlib.h>
2#include <stdio.h> 2#include <stdio.h>
3#include <string.h>
3#include <strings.h> 4#include <strings.h>
4#include <ctype.h> 5#include <ctype.h>
5#include "stringop.h" 6#include "stringop.h"
@@ -7,7 +8,7 @@
7#include "string.h" 8#include "string.h"
8#include "list.h" 9#include "list.h"
9 10
10const char *whitespace = " \f\n\r\t\v"; 11const char whitespace[] = " \f\n\r\t\v";
11 12
12/* Note: This returns 8 characters for trimmed_start per tab character. */ 13/* Note: This returns 8 characters for trimmed_start per tab character. */
13char *strip_whitespace(char *_str) { 14char *strip_whitespace(char *_str) {
@@ -105,40 +106,40 @@ char **split_args(const char *start, int *argc) {
105 bool in_char = false; 106 bool in_char = false;
106 bool escaped = false; 107 bool escaped = false;
107 const char *end = start; 108 const char *end = start;
108 while (*start) { 109 if (start) {
109 if (!in_token) { 110 while (*start) {
110 start = (end += strspn(end, whitespace)); 111 if (!in_token) {
111 in_token = true; 112 start = (end += strspn(end, whitespace));
112 } 113 in_token = true;
113 if (*end == '"' && !in_char && !escaped) { 114 }
114 in_string = !in_string; 115 if (*end == '"' && !in_char && !escaped) {
115 } else if (*end == '\'' && !in_string && !escaped) { 116 in_string = !in_string;
116 in_char = !in_char; 117 } else if (*end == '\'' && !in_string && !escaped) {
117 } else if (*end == '\\') { 118 in_char = !in_char;
118 escaped = !escaped; 119 } else if (*end == '\\') {
119 } else if (*end == '\0' || (!in_string && !in_char && !escaped 120 escaped = !escaped;
120 && strchr(whitespace, *end))) { 121 } else if (*end == '\0' || (!in_string && !in_char && !escaped
121 goto add_part; 122 && strchr(whitespace, *end))) {
122 } 123 goto add_token;
123 if (*end != '\\') { 124 }
124 escaped = false; 125 if (*end != '\\') {
125 } 126 escaped = false;
126 ++end; 127 }
127 continue; 128 ++end;
128 add_part: 129 continue;
129 if (end - start > 0) { 130 add_token:
130 char *token = malloc(end - start + 1); 131 if (end - start > 0) {
131 strncpy(token, start, end - start + 1); 132 char *token = malloc(end - start + 1);
132 token[end - start] = '\0'; 133 strncpy(token, start, end - start + 1);
133 strip_quotes(token); 134 token[end - start] = '\0';
134 unescape_string(token); 135 argv[*argc] = token;
135 argv[*argc] = token; 136 if (++*argc + 1 == alloc) {
136 if (++*argc + 1 == alloc) { 137 argv = realloc(argv, (alloc *= 2) * sizeof(char *));
137 argv = realloc(argv, (alloc *= 2) * sizeof(char *)); 138 }
138 } 139 }
140 in_token = false;
141 escaped = false;
139 } 142 }
140 in_token = false;
141 escaped = false;
142 } 143 }
143 argv[*argc] = NULL; 144 argv[*argc] = NULL;
144 return argv; 145 return argv;
@@ -312,6 +313,56 @@ char *join_list(list_t *list, char *separator) {
312 return res; 313 return res;
313} 314}
314 315
316char *cmdsep(char **stringp, const char *delim) {
317 // skip over leading delims
318 char *head = *stringp + strspn(*stringp, delim);
319 // Find end token
320 char *tail = *stringp += strcspn(*stringp, delim);
321 // Set stringp to begining of next token
322 *stringp += strspn(*stringp, delim);
323 // Set stringp to null if last token
324 if (!**stringp) *stringp = NULL;
325 // Nullify end of first token
326 *tail = 0;
327 return head;
328}
329
330char *argsep(char **stringp, const char *delim) {
331 char *start = *stringp;
332 char *end = start;
333 bool in_string = false;
334 bool in_char = false;
335 bool escaped = false;
336 while (1) {
337 if (*end == '"' && !in_char && !escaped) {
338 in_string = !in_string;
339 } else if (*end == '\'' && !in_string && !escaped) {
340 in_char = !in_char;
341 } else if (*end == '\\') {
342 escaped = !escaped;
343 } else if (*end == '\0') {
344 *stringp = NULL;
345 goto found;
346 } else if (!in_string && !in_char && !escaped && strchr(delim, *end)) {
347 if (end - start) {
348 *(end++) = 0;
349 *stringp = end + strspn(end, delim);;
350 if (!**stringp) *stringp = NULL;
351 goto found;
352 } else {
353 ++start;
354 end = start;
355 }
356 }
357 if (*end != '\\') {
358 escaped = false;
359 }
360 ++end;
361 }
362 found:
363 return start;
364}
365
315char *strdup(const char *str) { 366char *strdup(const char *str) {
316 char *dup = malloc(strlen(str) + 1); 367 char *dup = malloc(strlen(str) + 1);
317 if (dup) { 368 if (dup) {
@@ -319,3 +370,4 @@ char *strdup(const char *str) {
319 } 370 }
320 return dup; 371 return dup;
321} 372}
373