/* @@@HEAD@@@ // Miscellaneous operations. */ #include "config.h" #include <stdio.h> #include <stdlib.h> #include "defs.h" #include "y.tab.h" #include "cdc_types.h" #include "execute.h" /* hardcoded wordsize, bad bad, but faster than mallocing it */ #define WORDSIZE 255 #define add_as_ident(__i) { \ *word = __i, word++, *word = NULL; \ d.type = SYMBOL; \ d.u.symbol = ident_get(w); \ list = list_add(list, &d); \ w[0] = NULL; \ word = w; \ ident_discard(d.u.symbol); \ } #define add_as_str(__w) { \ if (wlen) { \ sw = string_from_chars(__w, wlen); \ d.type = STRING; \ d.u.str = sw; \ list = list_add(list, &d); \ string_discard(sw); \ __w[0] = NULL; \ word = __w; \ wlen = 0; \ } \ } list_t * tokenize_cml(string_t * str) { /* not that registering these will make much of a diff */ register int escaped; int wlen; char * s, w[WORDSIZE], * word; list_t * list; data_t d; string_t * sw; /* initialize everything */ escaped = 0; s = string_chars(str); w[0] = NULL; word = w; wlen = 0; list = list_new(0); for (; *s != NULL; s++) { if (escaped) { escaped--; /* break the word, its all we can do with a restricted buffer */ if ((wlen + 1) == (WORDSIZE - 1)) add_as_str(w); wlen++, *word = *s, word++, *word = NULL; } else { switch (*s) { case '\\': escaped = 1; break; case ' ': add_as_str(w) break; case '{': case '}': case '[': case ']': case '=': case '"': case ':': add_as_str(w); add_as_ident(*s); break; default: wlen++, *word = *s, word++, *word = NULL; break; } } } if (wlen) add_as_str(w); return list; } void op_tokenize_cml(void) { data_t * args, * elem; list_t * list; string_t * str; if (!func_init_1(&args, LIST)) return; list = args[0].u.list; str = string_new(0); /* Join the list into a single string, denote line breaks */ for (elem = list_first(list); elem; elem = list_next(list, elem)) { if (elem->type != STRING) { string_discard(str); cthrow(type_id, "Line %d (%D) is not a string.", elem - list_first(list), elem); return; } str = string_add_chars(str, elem->u.str->s, elem->u.str->len); str = string_add_chars(str, "{_ln}", 5); } /* the old list was just a pointer to args, which gets popped */ list = tokenize_cml(str); pop(1); push_list(list); list_discard(list); }