summaryrefslogtreecommitdiff
path: root/src/preproc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/preproc.c')
-rw-r--r--src/preproc.c38
1 files changed, 29 insertions, 9 deletions
diff --git a/src/preproc.c b/src/preproc.c
index 6aa7748..5669ce4 100644
--- a/src/preproc.c
+++ b/src/preproc.c
@@ -3,6 +3,20 @@
#include "syntax.h"
#include "utils.h"
+
+typedef struct {
+ StrVec completed_fields;
+ String open_buf;
+} SplitBuilder;
+
+
+void consolidate_split_builder(SplitBuilder* builder) {
+ if (builder->open_buf.count > 0) {
+ push_to_StrVec(&builder->completed_fields, inner(&builder->open_buf));
+ builder->open_buf = make_String(256);
+ }
+}
+
void split_str_on_space(char* str, StrVec* result) {
String buf = make_String(256);
for (int pos = 0; str[pos] != '\0'; pos++) {
@@ -21,35 +35,41 @@ void split_str_on_space(char* str, StrVec* result) {
}
-void process_chunk(Chunk chunk, StrVec* result, ShellState* shstate) {
+void process_chunk(Chunk chunk, SplitBuilder* builder, ShellState* shstate) {
assert(!(chunk.qmode == SINGLE_Q && chunk.kind != CHUNK_LIT));
- char* chunk_val;
+ char* chunk_str;
switch (chunk.kind) {
case CHUNK_LIT:
- chunk_val = chunk.as.lit_str;
+ chunk_str = chunk.as.lit_str;
break;
case CHUNK_VAR:
- chunk_val = get_var(chunk.as.varname, shstate);
+ chunk_str = get_var(chunk.as.varname, shstate);
break;
default:
exit(77);
}
if (chunk.qmode == UN_Q) {
- split_str_on_space(chunk_val, result);
+ StrVec split_str = make_StrVec(32);
+ split_str_on_space(chunk_str, &split_str);
+ append_str_to_String(&builder->open_buf, *get_from_StrVec(&split_str, 0));
+ consolidate_split_builder(builder);
+ for (int i = 1; i < split_str.count; i++) {
+ push_to_StrVec(&builder->completed_fields, *get_from_StrVec(&split_str, i));
+ }
} else {
- push_to_StrVec(result, chunk_val);
+ append_str_to_String(&builder->open_buf, chunk_str);
}
}
StrVec process_word(Word word, ShellState* shstate) {
- StrVec result = make_StrVec(256);
+ SplitBuilder split_bui = {.completed_fields = make_StrVec(256), .open_buf = make_String(256)};
for (int i = 0; i < word.count; i++) {
Chunk chunk = *get_from_Word(&word, i);
- process_chunk(chunk, &result, shstate);
+ process_chunk(chunk, &split_bui, shstate);
}
- return result;
+ return split_bui.completed_fields;
}