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