6 #include "expression.h"
8 static const char *parse_escape(const char *p
, unsigned *val
, const char *end
, int bits
, struct position pos
)
19 case 'a': c
= '\a'; break;
20 case 'b': c
= '\b'; break;
21 case 't': c
= '\t'; break;
22 case 'n': c
= '\n'; break;
23 case 'v': c
= '\v'; break;
24 case 'f': c
= '\f'; break;
25 case 'r': c
= '\r'; break;
26 case 'e': c
= '\e'; break;
28 unsigned mask
= -(1U << (bits
- 4));
29 for (c
= 0; p
< end
; c
= (c
<< 4) + d
) {
35 "hex escape sequence out of range");
45 while (p
< end
&& (d
= *p
++ - '0') < 8)
47 if ((c
& 0400) && bits
< 9)
49 "octal escape sequence out of range");
52 default: /* everything else is left as is */
55 *val
= c
& ~((~0U << (bits
- 1)) << 1);
59 void get_char_constant(struct token
*token
, unsigned long long *val
)
61 const char *p
= token
->embedded
, *end
;
63 int type
= token_type(token
);
67 p
= token
->string
->data
;
68 end
= p
+ token
->string
->length
;
70 case TOKEN_CHAR_EMBEDDED_0
... TOKEN_CHAR_EMBEDDED_3
:
71 end
= p
+ type
- TOKEN_CHAR
;
74 end
= p
+ type
- TOKEN_WIDE_CHAR
;
76 p
= parse_escape(p
, &v
, end
,
77 type
< TOKEN_WIDE_CHAR
? bits_in_char
: 32, token
->pos
);
80 "multi-character character constant");
84 struct token
*get_string_constant(struct token
*token
, struct expression
*expr
)
86 struct string
*string
= token
->string
;
87 struct token
*next
= token
->next
, *done
= NULL
;
88 int stringtype
= token_type(token
);
89 int is_wide
= stringtype
== TOKEN_WIDE_STRING
;
90 static char buffer
[MAX_STRING
];
95 switch (token_type(next
)) {
96 case TOKEN_WIDE_STRING
:
105 bits
= is_wide
? 32 : bits_in_char
;
106 while (token
!= done
) {
108 const char *p
= token
->string
->data
;
109 const char *end
= p
+ token
->string
->length
- 1;
111 p
= parse_escape(p
, &v
, end
, bits
, token
->pos
);
112 if (len
< MAX_STRING
)
118 if (len
> MAX_STRING
) {
119 warning(token
->pos
, "trying to concatenate %d-character string (%d bytes max)", len
, MAX_STRING
);
123 if (len
>= string
->length
) /* can't cannibalize */
124 string
= __alloc_string(len
+1);
125 string
->length
= len
+1;
126 memcpy(string
->data
, buffer
, len
);
127 string
->data
[len
] = '\0';
128 expr
->string
= string
;
129 expr
->wide
= is_wide
;