6 #include "expression.h"
9 static const char *parse_escape(const char *p
, unsigned *val
, const char *end
, int bits
, struct position pos
)
20 case 'a': c
= '\a'; break;
21 case 'b': c
= '\b'; break;
22 case 't': c
= '\t'; break;
23 case 'n': c
= '\n'; break;
24 case 'v': c
= '\v'; break;
25 case 'f': c
= '\f'; break;
26 case 'r': c
= '\r'; break;
27 case 'e': c
= '\e'; break;
29 unsigned mask
= -(1U << (bits
- 4));
30 for (c
= 0; p
< end
; c
= (c
<< 4) + d
) {
37 "hex escape sequence out of range");
47 while (p
< end
&& (d
= *p
- '0') < 8) {
51 if ((c
& 0400) && bits
< 9)
53 "octal escape sequence out of range");
56 default: /* everything else is left as is */
59 *val
= c
& ~((~0U << (bits
- 1)) << 1);
63 void get_char_constant(struct token
*token
, unsigned long long *val
)
65 const char *p
= token
->embedded
, *end
;
67 int type
= token_type(token
);
71 p
= token
->string
->data
;
72 end
= p
+ token
->string
->length
- 1;
74 case TOKEN_CHAR_EMBEDDED_0
... TOKEN_CHAR_EMBEDDED_3
:
75 end
= p
+ type
- TOKEN_CHAR
;
78 end
= p
+ type
- TOKEN_WIDE_CHAR
;
80 p
= parse_escape(p
, &v
, end
,
81 type
< TOKEN_WIDE_CHAR
? bits_in_char
: 32, token
->pos
);
84 "multi-character character constant");
88 struct token
*get_string_constant(struct token
*token
, struct expression
*expr
)
90 struct string
*string
= token
->string
;
91 struct token
*next
= token
->next
, *done
= NULL
;
92 int stringtype
= token_type(token
);
93 int is_wide
= stringtype
== TOKEN_WIDE_STRING
;
94 static char buffer
[MAX_STRING
];
100 switch (token_type(next
)) {
101 case TOKEN_WIDE_STRING
:
110 bits
= is_wide
? 32 : bits_in_char
;
111 while (token
!= done
) {
113 const char *p
= token
->string
->data
;
114 const char *end
= p
+ token
->string
->length
- 1;
118 p
= parse_escape(p
, &v
, end
, bits
, token
->pos
);
119 if (len
< MAX_STRING
)
125 if (len
> MAX_STRING
) {
126 warning(token
->pos
, "trying to concatenate %d-character string (%d bytes max)", len
, MAX_STRING
);
130 if (esc_count
|| len
>= string
->length
) {
131 if (string
->immutable
|| len
>= string
->length
) /* can't cannibalize */
132 string
= __alloc_string(len
+1);
133 string
->length
= len
+1;
134 memcpy(string
->data
, buffer
, len
);
135 string
->data
[len
] = '\0';
137 expr
->string
= string
;
138 expr
->wide
= is_wide
;