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
) {
36 "hex escape sequence out of range");
46 while (p
< end
&& (d
= *p
- '0') < 8) {
50 if ((c
& 0400) && bits
< 9)
52 "octal escape sequence out of range");
55 default: /* everything else is left as is */
58 *val
= c
& ~((~0U << (bits
- 1)) << 1);
62 void get_char_constant(struct token
*token
, unsigned long long *val
)
64 const char *p
= token
->embedded
, *end
;
66 int type
= token_type(token
);
70 p
= token
->string
->data
;
71 end
= p
+ token
->string
->length
- 1;
73 case TOKEN_CHAR_EMBEDDED_0
... TOKEN_CHAR_EMBEDDED_3
:
74 end
= p
+ type
- TOKEN_CHAR
;
77 end
= p
+ type
- TOKEN_WIDE_CHAR
;
79 p
= parse_escape(p
, &v
, end
,
80 type
< TOKEN_WIDE_CHAR
? bits_in_char
: 32, token
->pos
);
83 "multi-character character constant");
87 struct token
*get_string_constant(struct token
*token
, struct expression
*expr
)
89 struct string
*string
= token
->string
;
90 struct token
*next
= token
->next
, *done
= NULL
;
91 int stringtype
= token_type(token
);
92 int is_wide
= stringtype
== TOKEN_WIDE_STRING
;
93 static char buffer
[MAX_STRING
];
99 switch (token_type(next
)) {
100 case TOKEN_WIDE_STRING
:
109 bits
= is_wide
? 32 : bits_in_char
;
110 while (token
!= done
) {
112 const char *p
= token
->string
->data
;
113 const char *end
= p
+ token
->string
->length
- 1;
115 p
= parse_escape(p
, &v
, end
, bits
, token
->pos
);
116 if (len
< MAX_STRING
)
123 if (len
> MAX_STRING
) {
124 warning(token
->pos
, "trying to concatenate %d-character string (%d bytes max)", len
, MAX_STRING
);
128 if (len
>= string
->length
|| parts
> 1) /* safe to reuse the string buffer */
129 string
= __alloc_string(len
+1);
130 string
->length
= len
+1;
131 memcpy(string
->data
, buffer
, len
);
132 string
->data
[len
] = '\0';
133 expr
->string
= string
;
134 expr
->wide
= is_wide
;