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 */
57 warning(pos
, "unknown escape sequence: '\\%c'", c
);
63 break; /* those are legal, so no warnings */
65 *val
= c
& ~((~0U << (bits
- 1)) << 1);
69 void get_char_constant(struct token
*token
, unsigned long long *val
)
71 const char *p
= token
->embedded
, *end
;
73 int type
= token_type(token
);
77 p
= token
->string
->data
;
78 end
= p
+ token
->string
->length
- 1;
80 case TOKEN_CHAR_EMBEDDED_0
... TOKEN_CHAR_EMBEDDED_3
:
81 end
= p
+ type
- TOKEN_CHAR
;
84 end
= p
+ type
- TOKEN_WIDE_CHAR
;
86 p
= parse_escape(p
, &v
, end
,
87 type
< TOKEN_WIDE_CHAR
? bits_in_char
: 32, token
->pos
);
90 "multi-character character constant");
94 struct token
*get_string_constant(struct token
*token
, struct expression
*expr
)
96 struct string
*string
= token
->string
;
97 struct token
*next
= token
->next
, *done
= NULL
;
98 int stringtype
= token_type(token
);
99 int is_wide
= stringtype
== TOKEN_WIDE_STRING
;
100 static char buffer
[MAX_STRING
];
106 switch (token_type(next
)) {
107 case TOKEN_WIDE_STRING
:
116 bits
= is_wide
? 32 : bits_in_char
;
117 while (token
!= done
) {
119 const char *p
= token
->string
->data
;
120 const char *end
= p
+ token
->string
->length
- 1;
124 p
= parse_escape(p
, &v
, end
, bits
, token
->pos
);
125 if (len
< MAX_STRING
)
131 if (len
> MAX_STRING
) {
132 warning(token
->pos
, "trying to concatenate %d-character string (%d bytes max)", len
, MAX_STRING
);
136 if (esc_count
|| len
>= string
->length
) {
137 if (string
->immutable
|| len
>= string
->length
) /* can't cannibalize */
138 string
= __alloc_string(len
+1);
139 string
->length
= len
+1;
140 memcpy(string
->data
, buffer
, len
);
141 string
->data
[len
] = '\0';
143 expr
->string
= string
;
144 expr
->wide
= is_wide
;