1 /* $NetBSD: interp_backslash.c,v 1.2 2006/04/22 07:58:53 cherry Exp $ */
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
16 * Routine for doing backslash elimination.
19 #include <sys/cdefs.h>
20 /* __FBSDID("$FreeBSD: src/sys/boot/common/interp_backslash.c,v 1.6 2003/08/25 23:30:41 obrien Exp $"); */
22 #include <lib/libsa/stand.h>
23 #include <lib/libsa/loadfile.h>
24 #include <lib/libkern/libkern.h>
26 #include "bootstrap.h"
28 #define DIGIT(x) (isdigit(x) ? (x) - '0' : islower(x) ? (x) + 10 - 'a' : (x) + 10 - 'A')
31 * backslash: Return malloc'd copy of str with all standard "backslash
32 * processing" done on it. Original can be free'd if desired.
38 * Remove backslashes from the strings. Turn \040 etc. into a single
39 * character (we allow eight bit values). Currently NUL is not
42 * Turn "\n" and "\t" into '\n' and '\t' characters. Etc.
49 if ((new_str
= strdup(str
)) == NULL
)
61 /* preserve backslashed quotes, dollar signs */
66 new_str
[i
++] = *str
++;
100 new_str
[i
++] = '\13';
108 case '0': case '1': case '2': case '3': case '4':
109 case '5': case '6': case '7': case '8': case '9': {
112 /* Three digit octal constant? */
113 if (*str
>= '0' && *str
<= '3' &&
114 *(str
+ 1) >= '0' && *(str
+ 1) <= '7' &&
115 *(str
+ 2) >= '0' && *(str
+ 2) <= '7') {
117 val
= (DIGIT(*str
) << 6) + (DIGIT(*(str
+ 1)) << 3) +
120 /* Allow null value if user really wants to shoot
121 at feet, but beware! */
127 /* One or two digit hex constant?
128 * If two are there they will both be taken.
129 * Use \z to split them up if this is not wanted.
132 (*(str
+ 1) == 'x' || *(str
+ 1) == 'X') &&
133 isxdigit(*(str
+ 2))) {
134 val
= DIGIT(*(str
+ 2));
135 if (isxdigit(*(str
+ 3))) {
136 val
= (val
<< 4) + DIGIT(*(str
+ 3));
141 /* Yep, allow null value here too */
149 new_str
[i
++] = *str
++;
159 new_str
[i
++] = *str
++;
165 * The final character was a '\'. Put it in as a single backslash.