Skip to content

Commit

Permalink
Concatenate adjacent string literals
Browse files Browse the repository at this point in the history
  • Loading branch information
rui314 committed Sep 28, 2020
1 parent 72b9f01 commit 66c0a2e
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 0 deletions.
27 changes: 27 additions & 0 deletions preprocess.c
Original file line number Diff line number Diff line change
Expand Up @@ -919,12 +919,39 @@ static void init_macros(void) {
add_builtin("__LINE__", line_macro);
}

// Concatenate adjacent string literals into a single string literal
// as per the C spec.
static void join_adjacent_string_literals(Token *tok1) {
while (tok1->kind != TK_EOF) {
Token *tok2 = tok1->next;

if (tok1->kind != TK_STR || tok2->kind != TK_STR) {
tok1 = tok1->next;
continue;
}

Token *t = copy_token(tok1);
t->ty = array_of(tok1->ty->base, tok1->ty->array_len + tok2->ty->array_len - 1);
t->str = calloc(1, t->ty->size);
t->next = tok2->next;

int i = 0;
for (int j = 0; j < tok1->ty->size - tok1->ty->base->size; i++, j++)
t->str[i] = tok1->str[j];
for (int j = 0; j < tok2->ty->size; i++, j++)
t->str[i] = tok2->str[j];

*tok1 = *t;
}
}

// Entry point function of the preprocessor.
Token *preprocess(Token *tok) {
init_macros();
tok = preprocess2(tok);
if (cond_incl)
error_tok(cond_incl->tok, "unterminated conditional directive");
convert_keywords(tok);
join_adjacent_string_literals(tok);
return tok;
}
6 changes: 6 additions & 0 deletions test/string.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ int main() {
ASSERT(0, "\x00"[0]);
ASSERT(119, "\x77"[0]);

ASSERT(7, sizeof("abc" "def"));
ASSERT(9, sizeof("abc" "d" "efgh"));
ASSERT(0, strcmp("abc" "d" "\nefgh", "abcd\nefgh"));
ASSERT(0, !strcmp("abc" "d", "abcd\nefgh"));
ASSERT(0, strcmp("\x9" "0", "\t0"));

printf("OK\n");
return 0;
}
1 change: 1 addition & 0 deletions test/test.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ int assert(int expected, int actual, char *code);
int printf(char *fmt, ...);
int sprintf(char *buf, char *fmt, ...);
int strcmp(char *p, char *q);
int strncmp(char *p, char *q, long n);
int memcmp(char *p, char *q, long n);
void exit(int n);

0 comments on commit 66c0a2e

Please sign in to comment.