@@ -340,15 +340,60 @@ static struct token *dup_list(struct token *list)
return res;
}
+static int token_sequence_length(struct token *token)
+{
+ int length = 0, whitespace = 0;
+
+ if (!token)
+ return 0;
+ while (!eof_token(token)) {
+ const char *val = show_token(token);
+ int len = strlen(val);
+
+ if (whitespace)
+ length++;
+ length += len;
+ token = token->next;
+ whitespace = token->pos.whitespace;
+ }
+ return length;
+}
+
+static void token_sequence_to_string(struct string *s, struct token *token)
+{
+ char *ptr = s->data;
+ int whitespace = 0;
+
+ *ptr = 0;
+ if (!token)
+ return;
+ while (!eof_token(token)) {
+ const char *val = show_token(token);
+ int len = strlen(val);
+
+ if (ptr + whitespace + len >= s->data + s->length) {
+ sparse_error(token->pos, "too long token expansion");
+ break;
+ }
+
+ if (whitespace)
+ *ptr++ = ' ';
+ memcpy(ptr, val, len);
+ ptr += len;
+ token = token->next;
+ whitespace = token->pos.whitespace;
+ }
+ *ptr = 0;
+}
+
static struct token *stringify(struct token *arg)
{
- const char *s = show_token_sequence(arg);
- int size = strlen(s)+1;
+ int size = token_sequence_length(arg)+1;
struct token *token = __alloc_token(0);
struct string *string = __alloc_string(size);
- memcpy(string->data, s, size);
string->length = size;
+ token_sequence_to_string(string, arg);
token->pos = arg->pos;
token_type(token) = TOKEN_STRING;
token->string = string;