2 * Redistribution and use in source and binary forms, with or without
3 * modification, are permitted provided that the following conditions
5 * 1. Redistributions of source code must retain the above copyright
6 * notice, this list of conditions and the following disclaimer.
7 * 2. Redistributions in binary form must reproduce the above copyright
8 * notice, this list of conditions and the following disclaimer in the
9 * documentation and/or other materials provided with the distribution.
14 * $FreeBSD: src/sys/boot/common/interp_backslash.c,v 1.4.2.1 2000/12/28 13:12:34 ps Exp $
16 * Routine for doing backslash elimination.
21 #include "bootstrap.h"
23 #define DIGIT(x) (isdigit(x) ? (x) - '0' : islower(x) ? (x) + 10 - 'a' : (x) + 10 - 'A')
26 * backslash: Return malloc'd copy of str with all standard "backslash
27 * processing" done on it. Original can be free'd if desired.
33 * Remove backslashes from the strings. Turn \040 etc. into a single
34 * character (we allow eight bit values). Currently NUL is not
37 * Turn "\n" and "\t" into '\n' and '\t' characters. Etc.
44 if ((new_str = strdup(str)) == NULL)
56 /* preserve backslashed quotes, dollar signs */
61 new_str[i++] = *str++;
103 case '0': case '1': case '2': case '3': case '4':
104 case '5': case '6': case '7': case '8': case '9': {
107 /* Three digit octal constant? */
108 if (*str >= '0' && *str <= '3' &&
109 *(str + 1) >= '0' && *(str + 1) <= '7' &&
110 *(str + 2) >= '0' && *(str + 2) <= '7') {
112 val = (DIGIT(*str) << 6) + (DIGIT(*(str + 1)) << 3) +
115 /* Allow null value if user really wants to shoot
116 at feet, but beware! */
122 /* One or two digit hex constant?
123 * If two are there they will both be taken.
124 * Use \z to split them up if this is not wanted.
127 (*(str + 1) == 'x' || *(str + 1) == 'X') &&
128 isxdigit(*(str + 2))) {
129 val = DIGIT(*(str + 2));
130 if (isxdigit(*(str + 3))) {
131 val = (val << 4) + DIGIT(*(str + 3));
136 /* Yep, allow null value here too */
144 new_str[i++] = *str++;
154 new_str[i++] = *str++;
160 * The final character was a '\'. Put it in as a single backslash.