From 0daba5ce242fa28c1ff81f93cae51902adefd217 Mon Sep 17 00:00:00 2001 From: Christoph Mallon Date: Thu, 20 Dec 2007 16:04:08 +0000 Subject: [PATCH] Implement wide string literal concatenation (with normal string literals, too). [r18814] --- lexer.c | 42 ++++++++++++++++++++++++++++++++++++++++++ lexer.h | 5 ++++- parser.c | 56 +++++++++++++++++++++++++++++++++++++++----------------- 3 files changed, 85 insertions(+), 18 deletions(-) diff --git a/lexer.c b/lexer.c index 4956dfc..749db3d 100644 --- a/lexer.c +++ b/lexer.c @@ -685,6 +685,48 @@ string_t concat_strings(const string_t *const s1, const string_t *const s2) #endif } +wide_string_t concat_string_wide_string(const string_t *const s1, const wide_string_t *const s2) +{ + const size_t len1 = s1->size - 1; + const size_t len2 = s2->size - 1; + + wchar_rep_t *const concat = obstack_alloc(&symbol_obstack, (len1 + len2 + 1) * sizeof(*concat)); + const char *const src = s1->begin; + for (size_t i = 0; i != len1; ++i) { + concat[i] = src[i]; + } + memcpy(concat + len1, s2->begin, (len2 + 1) * sizeof(*concat)); + + return (wide_string_t){ concat, len1 + len2 + 1 }; +} + +wide_string_t concat_wide_strings(const wide_string_t *const s1, const wide_string_t *const s2) +{ + const size_t len1 = s1->size - 1; + const size_t len2 = s2->size - 1; + + wchar_rep_t *const concat = obstack_alloc(&symbol_obstack, (len1 + len2 + 1) * sizeof(*concat)); + memcpy(concat, s1->begin, len1 * sizeof(*concat)); + memcpy(concat + len1, s2->begin, (len2 + 1) * sizeof(*concat)); + + return (wide_string_t){ concat, len1 + len2 + 1 }; +} + +wide_string_t concat_wide_string_string(const wide_string_t *const s1, const string_t *const s2) +{ + const size_t len1 = s1->size - 1; + const size_t len2 = s2->size - 1; + + wchar_rep_t *const concat = obstack_alloc(&symbol_obstack, (len1 + len2 + 1) * sizeof(*concat)); + memcpy(concat, s1->begin, len1 * sizeof(*concat)); + const char *const src = s2->begin; + for (size_t i = 0; i != len2 + 1; ++i) { + concat[i] = src[i]; + } + + return (wide_string_t){ concat, len1 + len2 + 1 }; +} + static void parse_string_literal(void) { const unsigned start_linenr = lexer_token.source_position.linenr; diff --git a/lexer.h b/lexer.h index 35827e9..a1a5d76 100644 --- a/lexer.h +++ b/lexer.h @@ -16,6 +16,9 @@ void exit_lexer(void); void lexer_open_stream(FILE *stream, const char *input_name); -string_t concat_strings(const string_t *s1, const string_t *s2); +string_t concat_strings( const string_t *s1, const string_t *s2); +wide_string_t concat_string_wide_string(const string_t *s1, const wide_string_t *s2); +wide_string_t concat_wide_strings( const wide_string_t *s1, const wide_string_t *s2); +wide_string_t concat_wide_string_string(const wide_string_t *s1, const string_t *s2); #endif diff --git a/parser.c b/parser.c index 6c97705..fe527a4 100644 --- a/parser.c +++ b/parser.c @@ -3121,23 +3121,46 @@ static expression_t *expected_expression_error(void) */ static expression_t *parse_string_const(void) { - expression_t *cnst = allocate_expression_zero(EXPR_STRING_LITERAL); - cnst->base.type = type_char_ptr; - cnst->string.value = parse_string_literals(); - - return cnst; -} + wide_string_t wres; + if (token.type == T_STRING_LITERAL) { + string_t res = token.v.string; + next_token(); + while (token.type == T_STRING_LITERAL) { + res = concat_strings(&res, &token.v.string); + next_token(); + } + if (token.type != T_WIDE_STRING_LITERAL) { + expression_t *const cnst = allocate_expression_zero(EXPR_STRING_LITERAL); + cnst->base.type = type_char_ptr; + cnst->string.value = res; + return cnst; + } -/** - * Parse a wide string constant. - */ -static expression_t *parse_wide_string_const(void) -{ - expression_t *const cnst = allocate_expression_zero(EXPR_WIDE_STRING_LITERAL); - cnst->base.type = type_wchar_t_ptr; - cnst->wide_string.value = token.v.wide_string; /* TODO concatenate */ + wres = concat_string_wide_string(&res, &token.v.wide_string); + } else { + wres = token.v.wide_string; + } next_token(); - return cnst; + + for (;;) { + switch (token.type) { + case T_WIDE_STRING_LITERAL: + wres = concat_wide_strings(&wres, &token.v.wide_string); + break; + + case T_STRING_LITERAL: + wres = concat_wide_string_string(&wres, &token.v.string); + break; + + default: { + expression_t *const cnst = allocate_expression_zero(EXPR_WIDE_STRING_LITERAL); + cnst->base.type = type_wchar_t_ptr; + cnst->wide_string.value = wres; + return cnst; + } + } + next_token(); + } } /** @@ -3739,9 +3762,8 @@ static expression_t *parse_primary_expression(void) case T_FLOATINGPOINT: return parse_float_const(); case T_STRING_LITERAL: - return parse_string_const(); case T_WIDE_STRING_LITERAL: - return parse_wide_string_const(); + return parse_string_const(); case T_IDENTIFIER: return parse_reference(); case T___FUNCTION__: -- 2.20.1