1 /* quote.c library routines for the Netwide Assembler
3 * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
4 * Julian Hall. All rights reserved. The software is
5 * redistributable under the license given in the file "LICENSE"
6 * distributed in the NASM archive.
17 #define numvalue(c) ((c)>='a' ? (c)-'a'+10 : (c)>='A' ? (c)-'A'+10 : (c)-'0')
19 char *nasm_quote(char *str
, size_t len
)
21 char c
, c1
, *p
, *q
, *nstr
, *ep
;
27 qlen
= 0; /* Length if we need `...` quotes */
28 for (p
= str
; p
< ep
; p
++) {
44 if (c
< ' ' || c
> '~') {
45 sq_ok
= dq_ok
= false;
58 c1
= (p
+1 < ep
) ? p
[1] : 0;
59 if (c
> 077 || (c1
>= '0' && c1
<= '7'))
60 qlen
+= 4; /* Must use the full form */
75 /* Use '...' or "..." */
76 nstr
= nasm_malloc(len
+3);
77 nstr
[0] = nstr
[len
+1] = sq_ok
? '\'' : '\"';
79 memcpy(nstr
+1, str
, len
);
81 /* Need to use `...` quoted syntax */
82 nstr
= nasm_malloc(qlen
+3);
85 for (p
= str
; p
< ep
; p
++) {
126 if (c
< ' ' || c
> '~') {
127 c1
= (p
+1 < ep
) ? p
[1] : 0;
128 if (c1
>= '0' && c1
<= '7')
129 q
+= sprintf(q
, "\\%03o", (unsigned char)c
);
131 q
+= sprintf(q
, "\\%o", (unsigned char)c
);
140 assert((size_t)(q
-nstr
) == qlen
+3);
145 static char *emit_utf8(char *q
, int32_t v
)
148 /* Impossible - do nothing */
149 } else if (v
<= 0x7f) {
151 } else if (v
<= 0x000007ff) {
152 *q
++ = 0xc0 | (v
>> 6);
153 *q
++ = 0x80 | (v
& 63);
154 } else if (v
<= 0x0000ffff) {
155 *q
++ = 0xe0 | (v
>> 12);
156 *q
++ = 0x80 | ((v
>> 6) & 63);
157 *q
++ = 0x80 | (v
& 63);
158 } else if (v
<= 0x001fffff) {
159 *q
++ = 0xf0 | (v
>> 18);
160 *q
++ = 0x80 | ((v
>> 12) & 63);
161 *q
++ = 0x80 | ((v
>> 6) & 63);
162 *q
++ = 0x80 | (v
& 63);
163 } else if (v
<= 0x03ffffff) {
164 *q
++ = 0xf8 | (v
>> 24);
165 *q
++ = 0x80 | ((v
>> 18) & 63);
166 *q
++ = 0x80 | ((v
>> 12) & 63);
167 *q
++ = 0x80 | ((v
>> 6) & 63);
168 *q
++ = 0x80 | (v
& 63);
170 *q
++ = 0xfc | (v
>> 30);
171 *q
++ = 0x80 | ((v
>> 24) & 63);
172 *q
++ = 0x80 | ((v
>> 18) & 63);
173 *q
++ = 0x80 | ((v
>> 12) & 63);
174 *q
++ = 0x80 | ((v
>> 6) & 63);
175 *q
++ = 0x80 | (v
& 63);
181 * Do an *in-place* dequoting of the specified string, returning the
182 * resulting length (which may be containing embedded nulls.)
184 * In-place replacement is possible since the unquoted length is always
185 * shorter than or equal to the quoted length.
187 size_t nasm_unquote(char *str
)
210 if ((bq
== '\'' || bq
== '\"') && bq
== eq
) {
211 /* '...' or "..." string */
212 memmove(str
, str
+1, ln
-2);
216 if (bq
== '`' || eq
== '`') {
228 state
= st_backslash
;
294 if (c
>= '0' && c
<= '7') {
295 nval
= (nval
<< 3) + (c
- '0');
301 p
--; /* Process this character again */
308 if ((c
>= '0' && c
<= '9') ||
309 (c
>= 'A' && c
<= 'F') ||
310 (c
>= 'a' && c
<= 'f')) {
311 nval
= (nval
<< 4) + numvalue(c
);
317 p
--; /* Process this character again */
318 *q
++ = ndig
? nval
: *escp
;
324 if ((c
>= '0' && c
<= '9') ||
325 (c
>= 'A' && c
<= 'F') ||
326 (c
>= 'a' && c
<= 'f')) {
327 nval
= (nval
<< 4) + numvalue(c
);
329 q
= emit_utf8(q
, nval
);
333 p
--; /* Process this character again */
335 q
= emit_utf8(q
, nval
);
351 *q
++ = ndig
? nval
: *escp
;
355 q
= emit_utf8(q
, nval
);
364 /* Otherwise, just return the input... */
369 * Find the end of a quoted string; returns the pointer to the terminating
370 * character (either the ending quote or the null character, if unterminated.)
372 char *nasm_skip_string(char *str
)
387 if (bq
== '\'' || bq
== '\"') {
388 /* '...' or "..." string */
389 for (p
= str
+1; *p
&& *p
!= bq
; p
++)
392 } else if (bq
== '`') {
402 state
= st_backslash
;
405 return p
-1; /* Found the end */
452 if (c
>= '0' && c
<= '7') {
456 p
--; /* Process this character again */
462 if ((c
>= '0' && c
<= '9') ||
463 (c
>= 'A' && c
<= 'F') ||
464 (c
>= 'a' && c
<= 'f')) {
468 p
--; /* Process this character again */
474 if ((c
>= '0' && c
<= '9') ||
475 (c
>= 'A' && c
<= 'F') ||
476 (c
>= 'a' && c
<= 'f')) {
480 p
--; /* Process this character again */
486 return p
; /* Unterminated string... */
488 return str
; /* Not a string... */