From: Lukas Krickl Date: Fri, 17 Nov 2023 16:07:54 +0000 (+0100) Subject: Added tests for string tokens and escaping X-Git-Url: https://git.krickl.dev/?a=commitdiff_plain;h=5c115091742826cf501a1ba8234cc24ddf8c6fad;p=ulas%2F.git Added tests for string tokens and escaping --- diff --git a/src/test.c b/src/test.c index 7790083..5295c94 100644 --- a/src/test.c +++ b/src/test.c @@ -152,6 +152,17 @@ void test_preproc(void) { assert(tok.lit.val.intv == (expected_val)); \ } +#define ASSERT_STR_TOTOK(expected_val, expected_rc, token) \ + { \ + int rc = 0; \ + struct ulas_tok tok = ulas_totok((token), strlen(token), &rc); \ + assert((expected_rc) == rc); \ + assert(tok.type == ULAS_TOKLITERAL); \ + assert(tok.lit.type == ULAS_STR); \ + assert(strcmp((expected_val), tok.lit.val.strv) == 0); \ + free(tok.lit.val.strv); \ + } + void test_totok(void) { TESTBEGIN("totok"); @@ -171,6 +182,11 @@ void test_totok(void) { // unterminated escape ASSERT_INT_TOTOK('\n', -1, "'\\n"); + // string token + ASSERT_STR_TOTOK("test", 0, "\"test\""); + + ASSERT_STR_TOTOK("test\n\"123\"", 0, "\"test\\n\\\"123\\\"\""); + TESTEND("totok"); } diff --git a/src/ulas.c b/src/ulas.c index 763079b..5ddb9bd 100644 --- a/src/ulas.c +++ b/src/ulas.c @@ -258,11 +258,53 @@ struct ulas_tok ulas_totok(char *buf, unsigned long n, int *rc) { buf++; switch (first) { + case '+': + case '-': + case '*': + case '/': + case '!': + case '~': + case '|': + case '&': + case '%': + case '(': + case ')': + case '[': + case ']': + case ',': case ';': + // single char tokens tok.type = first; goto end; case '"': // string + tok.type = ULAS_TOKLITERAL; + tok.lit.type = ULAS_STR; + + // FIXME: this likely mallocs a few extra bytes + // but honestly its probably fine + tok.lit.val.strv = malloc(n * sizeof(char) + 1); + memset(tok.lit.val.strv, 0, n); + + long i = 0; + while (*buf && *buf != '\"') { + if (*buf == '\\') { + buf++; + tok.lit.val.strv[i] = ulas_unescape(*buf, rc); + } else { + tok.lit.val.strv[i] = *buf; + } + i++; + buf++; + } + tok.lit.val.strv[i] = '\0'; + + if (*buf != '\"') { + *rc = -1; + ULASERR("Unterminated string sequence\n"); + goto end; + } + buf++; break; default: if (isdigit(first)) {