Parse a string literal (with escape handling) into the token list. * *pos points at the character after the opening quote; updated past closing quote. */
| 93 | /* Parse a string literal (with escape handling) into the token list. |
| 94 | * *pos points at the character after the opening quote; updated past closing quote. */ |
| 95 | static void lex_string_literal(const char *input, int len, int *pos, char quote, |
| 96 | cbm_lex_result_t *out) { |
| 97 | int start = *pos; |
| 98 | char buf[CBM_SZ_4K]; |
| 99 | int blen = 0; |
| 100 | const int max_blen = CBM_SZ_4K - 1; |
| 101 | while (*pos < len && input[*pos] != quote) { |
| 102 | if (input[*pos] == '\\' && *pos + SKIP_ONE < len) { |
| 103 | (*pos)++; |
| 104 | if (blen < max_blen) { |
| 105 | switch (input[*pos]) { |
| 106 | case 'n': |
| 107 | buf[blen++] = '\n'; |
| 108 | break; |
| 109 | case 't': |
| 110 | buf[blen++] = '\t'; |
| 111 | break; |
| 112 | case '\\': |
| 113 | buf[blen++] = '\\'; |
| 114 | break; |
| 115 | default: |
| 116 | buf[blen++] = input[*pos]; |
| 117 | break; |
| 118 | } |
| 119 | } |
| 120 | } else { |
| 121 | if (blen < max_blen) { |
| 122 | buf[blen++] = input[*pos]; |
| 123 | } |
| 124 | } |
| 125 | (*pos)++; |
| 126 | } |
| 127 | buf[blen] = '\0'; |
| 128 | if (*pos < len) { |
| 129 | (*pos)++; /* skip closing quote */ |
| 130 | } |
| 131 | lex_push(out, TOK_STRING, buf, start - SKIP_ONE); |
| 132 | } |
| 133 | |
| 134 | /* Keyword table (case-insensitive lookup) */ |
| 135 | typedef struct { |