1 /* ----------------------------------------------------------------------- *
3 * Copyright 1996-2009 The NASM Authors - All Rights Reserved
4 * See the file AUTHORS included with the NASM distribution for
5 * the specific copyright holders.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * ----------------------------------------------------------------------- */
45 char *nasm_quote(char *str
, size_t len
)
47 char c
, c1
, *p
, *q
, *nstr
, *ep
;
54 qlen
= 0; /* Length if we need `...` quotes */
55 for (p
= str
; p
< ep
; p
++) {
71 if (c
< ' ' || c
> '~') {
72 sq_ok
= dq_ok
= false;
85 c1
= (p
+1 < ep
) ? p
[1] : 0;
86 if (c1
>= '0' && c1
<= '7')
87 uc
= 0377; /* Must use the full form */
104 if (sq_ok
|| dq_ok
) {
105 /* Use '...' or "..." */
106 nstr
= nasm_malloc(len
+3);
107 nstr
[0] = nstr
[len
+1] = sq_ok
? '\'' : '\"';
110 memcpy(nstr
+1, str
, len
);
112 /* Need to use `...` quoted syntax */
113 nstr
= nasm_malloc(qlen
+3);
116 for (p
= str
; p
< ep
; p
++) {
157 if (c
< ' ' || c
> '~') {
158 c1
= (p
+1 < ep
) ? p
[1] : 0;
159 if (c1
>= '0' && c1
<= '7')
160 uc
= 0377; /* Must use the full form */
165 *q
++ = ((unsigned char)c
>> 6) + '0';
167 *q
++ = (((unsigned char)c
>> 3) & 7) + '0';
168 *q
++ = ((unsigned char)c
& 7) + '0';
178 nasm_assert((size_t)(q
-nstr
) == qlen
+3);
183 static char *emit_utf8(char *q
, int32_t v
)
186 /* Impossible - do nothing */
187 } else if (v
<= 0x7f) {
189 } else if (v
<= 0x000007ff) {
190 *q
++ = 0xc0 | (v
>> 6);
191 *q
++ = 0x80 | (v
& 63);
192 } else if (v
<= 0x0000ffff) {
193 *q
++ = 0xe0 | (v
>> 12);
194 *q
++ = 0x80 | ((v
>> 6) & 63);
195 *q
++ = 0x80 | (v
& 63);
196 } else if (v
<= 0x001fffff) {
197 *q
++ = 0xf0 | (v
>> 18);
198 *q
++ = 0x80 | ((v
>> 12) & 63);
199 *q
++ = 0x80 | ((v
>> 6) & 63);
200 *q
++ = 0x80 | (v
& 63);
201 } else if (v
<= 0x03ffffff) {
202 *q
++ = 0xf8 | (v
>> 24);
203 *q
++ = 0x80 | ((v
>> 18) & 63);
204 *q
++ = 0x80 | ((v
>> 12) & 63);
205 *q
++ = 0x80 | ((v
>> 6) & 63);
206 *q
++ = 0x80 | (v
& 63);
208 *q
++ = 0xfc | (v
>> 30);
209 *q
++ = 0x80 | ((v
>> 24) & 63);
210 *q
++ = 0x80 | ((v
>> 18) & 63);
211 *q
++ = 0x80 | ((v
>> 12) & 63);
212 *q
++ = 0x80 | ((v
>> 6) & 63);
213 *q
++ = 0x80 | (v
& 63);
219 * Do an *in-place* dequoting of the specified string, returning the
220 * resulting length (which may be containing embedded nulls.)
222 * In-place replacement is possible since the unquoted length is always
223 * shorter than or equal to the quoted length.
225 * *ep points to the final quote, or to the null if improperly quoted.
227 size_t nasm_unquote(char *str
, char **ep
)
252 /* '...' or "..." string */
253 while ((c
= *p
) && c
!= bq
) {
270 state
= st_backslash
;
283 escp
= p
; /* Beginning of argument sequence */
332 ndig
= 2; /* Up to two more digits */
342 if (c
>= '0' && c
<= '7') {
343 nval
= (nval
<< 3) + (c
- '0');
349 p
--; /* Process this character again */
356 if ((c
>= '0' && c
<= '9') ||
357 (c
>= 'A' && c
<= 'F') ||
358 (c
>= 'a' && c
<= 'f')) {
359 nval
= (nval
<< 4) + numvalue(c
);
365 p
--; /* Process this character again */
366 *q
++ = (p
> escp
) ? nval
: escp
[-1];
372 if ((c
>= '0' && c
<= '9') ||
373 (c
>= 'A' && c
<= 'F') ||
374 (c
>= 'a' && c
<= 'f')) {
375 nval
= (nval
<< 4) + numvalue(c
);
377 q
= emit_utf8(q
, nval
);
381 p
--; /* Process this character again */
383 q
= emit_utf8(q
, nval
);
399 *q
++ = (p
> escp
) ? nval
: escp
[-1];
403 q
= emit_utf8(q
, nval
);
412 /* Not a quoted string, just return the input... */
413 p
= q
= strchr(str
, '\0');
423 * Find the end of a quoted string; returns the pointer to the terminating
424 * character (either the ending quote or the null character, if unterminated.)
426 char *nasm_skip_string(char *str
)
437 if (bq
== '\'' || bq
== '\"') {
438 /* '...' or "..." string */
439 for (p
= str
+1; *p
&& *p
!= bq
; p
++)
442 } else if (bq
== '`') {
452 state
= st_backslash
;
455 return p
-1; /* Found the end */
463 * Note: for the purpose of finding the end of the string,
464 * all successor states to st_backslash are functionally
465 * equivalent to st_start, since either a backslash or
466 * a backquote will force a return to the st_start state.
472 return p
; /* Unterminated string... */
474 return str
; /* Not a string... */