diff options
| author | Linus Torvalds <torvalds@home.transmeta.com> | 2003-03-30 22:30:28 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-07 20:59:55 -0700 |
| commit | 9d2258c5def38d3c161e8c2750b6e9fe62449bb3 (patch) | |
| tree | 1c07cd993957263d15f36b4122e85d103ff4c294 | |
| parent | c6555e8346ccaadb00d1fbe1e2ac83c452f4750b (diff) | |
| download | sparse-dev-9d2258c5def38d3c161e8c2750b6e9fe62449bb3.tar.gz | |
Start doing constant strings right: do proper concatenation of strings,
and evaluate their type to be arrays of char rather than just a pointer.
| -rw-r--r-- | evaluate.c | 31 | ||||
| -rw-r--r-- | expression.c | 41 | ||||
| -rw-r--r-- | expression.h | 4 | ||||
| -rw-r--r-- | show-parse.c | 3 | ||||
| -rw-r--r-- | token.h | 1 | ||||
| -rw-r--r-- | tokenize.c | 34 |
6 files changed, 91 insertions, 23 deletions
@@ -124,6 +124,21 @@ static int get_int_value(struct expression *expr, const char *str) return 1; } +static int evaluate_string(struct expression *expr) +{ + struct symbol *sym = alloc_symbol(expr->pos, SYM_ARRAY); + int length = expr->string->length; + + sym->array_size = length; + sym->bit_size = BITS_IN_CHAR * length; + sym->alignment = 1; + + sym->ctype.modifiers = MOD_CONST; + sym->ctype.base_type = &char_ctype; + expr->ctype = sym; + return 1; +} + static int evaluate_constant(struct expression *expr) { struct token *token = expr->token; @@ -720,6 +735,11 @@ int evaluate_expression(struct expression *expr) switch (expr->type) { case EXPR_CONSTANT: return evaluate_constant(expr); + case EXPR_VALUE: + warn(expr->pos, "value expression without a type"); + return 0; + case EXPR_STRING: + return evaluate_string(expr); case EXPR_SYMBOL: return evaluate_symbol(expr); case EXPR_BINOP: @@ -762,8 +782,15 @@ int evaluate_expression(struct expression *expr) return evaluate_dereference(expr); case EXPR_CALL: return evaluate_call(expr); - default: - break; + case EXPR_BITFIELD: + warn(expr->pos, "bitfield generated by parser"); + return 0; + case EXPR_CONDITIONAL: + // FIXME!! Conditional expression + return 0; + case EXPR_STATEMENT: + // FIXME!! Statement expression + return 0; } return 0; } diff --git a/expression.c b/expression.c index aff176b1..e2d41ccf 100644 --- a/expression.c +++ b/expression.c @@ -53,6 +53,37 @@ struct token *parens_expression(struct token *token, struct expression **expr, c return expect(token, ')', where); } +static struct token *string_expression(struct token *token, struct expression *expr) +{ + struct string *string = token->string; + struct token *next = token->next; + + if (token_type(next) == TOKEN_STRING) { + int totlen = string->length; + char *data; + + do { + totlen += next->string->length-1; + next = next->next; + } while (token_type(next) == TOKEN_STRING); + + string = __alloc_string(totlen); + string->length = totlen; + data = string->data; + next = token; + do { + struct string *s = next->string; + int len = s->length; + + next = next->next; + memcpy(data, s->data, len); + data += len-1; + } while (token_type(next) == TOKEN_STRING); + } + expr->string = string; + return next; +} + struct token *primary_expression(struct token *token, struct expression **tree) { struct expression *expr = NULL; @@ -74,13 +105,11 @@ struct token *primary_expression(struct token *token, struct expression **tree) break; } - case TOKEN_STRING: - expr = alloc_expression(token->pos, EXPR_CONSTANT); - expr->token = token; - do { - token = token->next; - } while (token_type(token) == TOKEN_STRING); + case TOKEN_STRING: { + expr = alloc_expression(token->pos, EXPR_STRING); + token = string_expression(token, expr); break; + } case TOKEN_SPECIAL: if (token->special == '(') { diff --git a/expression.h b/expression.h index f7be851f..21297b58 100644 --- a/expression.h +++ b/expression.h @@ -13,6 +13,7 @@ struct expression_list; enum expression_type { EXPR_CONSTANT, EXPR_VALUE, + EXPR_STRING, EXPR_SYMBOL, EXPR_BINOP, EXPR_ASSIGNMENT, @@ -41,6 +42,9 @@ struct expression { // EXPR_VALUE unsigned long long value; + // EXPR_STRING + struct string *string; + // EXPR_UNOP, EXPR_PREOP and EXPR_POSTOP struct expression *unop; diff --git a/show-parse.c b/show-parse.c index 0a55a21b..7e720933 100644 --- a/show-parse.c +++ b/show-parse.c @@ -445,6 +445,9 @@ void show_expression(struct expression *expr) case EXPR_VALUE: printf("(%lld)", expr->value); break; + case EXPR_STRING: + printf("%s", show_string(expr->string)); + break; case EXPR_SIZEOF: printf("sizeof("); if (expr->cast_type) @@ -143,6 +143,7 @@ extern struct ident *built_in_ident(const char *); extern struct token *built_in_token(int, const char *); extern const char *show_special(int); extern const char *show_ident(const struct ident *); +extern const char *show_string(const struct string *string); extern const char *show_token(const struct token *); extern struct token * tokenize(const char *, int, struct token *); extern struct token * tokenize_buffer(unsigned char *, unsigned long, struct token *); @@ -78,6 +78,23 @@ char *charstr(char *ptr, unsigned char c, unsigned char escape, unsigned char ne return ptr + sprintf(ptr, "%03o", c); } +const char *show_string(const struct string *string) +{ + static char buffer[256]; + char *ptr; + int i; + + ptr = buffer; + *ptr++ = '"'; + for (i = 0; i < string->length-1; i++) { + const unsigned char *p = string->data + i; + ptr = charstr(ptr, p[0], '"', p[1]); + } + *ptr++ = '"'; + *ptr = '\0'; + return buffer; +} + const char *show_token(const struct token *token) { static char buffer[256]; @@ -94,21 +111,8 @@ const char *show_token(const struct token *token) case TOKEN_IDENT: return show_ident(token->ident); - case TOKEN_STRING: { - char *ptr; - int i; - struct string *string = token->string; - - ptr = buffer; - *ptr++ = '"'; - for (i = 0; i < string->length-1; i++) { - unsigned char *p = string->data + i; - ptr = charstr(ptr, p[0], '"', p[1]); - } - *ptr++ = '"'; - *ptr = '\0'; - return buffer; - } + case TOKEN_STRING: + return show_string(token->string); case TOKEN_INTEGER: { const char *p = token->integer; |
