1*22028508SToomas Soome /* 2*22028508SToomas Soome * Redistribution and use in source and binary forms, with or without 3*22028508SToomas Soome * modification, are permitted provided that the following conditions 4*22028508SToomas Soome * are met: 5*22028508SToomas Soome * 1. Redistributions of source code must retain the above copyright 6*22028508SToomas Soome * notice, this list of conditions and the following disclaimer. 7*22028508SToomas Soome * 2. Redistributions in binary form must reproduce the above copyright 8*22028508SToomas Soome * notice, this list of conditions and the following disclaimer in the 9*22028508SToomas Soome * documentation and/or other materials provided with the distribution. 10*22028508SToomas Soome * 11*22028508SToomas Soome * Jordan K. Hubbard 12*22028508SToomas Soome * 29 August 1998 13*22028508SToomas Soome * 14*22028508SToomas Soome * Routine for doing backslash elimination. 15*22028508SToomas Soome */ 16*22028508SToomas Soome 17*22028508SToomas Soome #include <sys/cdefs.h> 18*22028508SToomas Soome 19*22028508SToomas Soome #include <stand.h> 20*22028508SToomas Soome #include <string.h> 21*22028508SToomas Soome #include "bootstrap.h" 22*22028508SToomas Soome 23*22028508SToomas Soome #define DIGIT(x) \ 24*22028508SToomas Soome (isdigit(x) ? (x) - '0' : islower(x) ? (x) + 10 - 'a' : (x) + 10 - 'A') 25*22028508SToomas Soome 26*22028508SToomas Soome /* 27*22028508SToomas Soome * backslash: Return malloc'd copy of str with all standard "backslash 28*22028508SToomas Soome * processing" done on it. Original can be free'd if desired. 29*22028508SToomas Soome */ 30*22028508SToomas Soome char * backslash(char * str)31*22028508SToomas Soomebackslash(char *str) 32*22028508SToomas Soome { 33*22028508SToomas Soome /* 34*22028508SToomas Soome * Remove backslashes from the strings. Turn \040 etc. into a single 35*22028508SToomas Soome * character (we allow eight bit values). Currently NUL is not 36*22028508SToomas Soome * allowed. 37*22028508SToomas Soome * 38*22028508SToomas Soome * Turn "\n" and "\t" into '\n' and '\t' characters. Etc. 39*22028508SToomas Soome * 40*22028508SToomas Soome */ 41*22028508SToomas Soome char *new_str; 42*22028508SToomas Soome int seenbs = 0; 43*22028508SToomas Soome int i = 0; 44*22028508SToomas Soome 45*22028508SToomas Soome if ((new_str = strdup(str)) == NULL) 46*22028508SToomas Soome return (NULL); 47*22028508SToomas Soome 48*22028508SToomas Soome while (*str) { 49*22028508SToomas Soome if (seenbs) { 50*22028508SToomas Soome seenbs = 0; 51*22028508SToomas Soome switch (*str) { 52*22028508SToomas Soome case '\\': 53*22028508SToomas Soome new_str[i++] = '\\'; 54*22028508SToomas Soome str++; 55*22028508SToomas Soome break; 56*22028508SToomas Soome 57*22028508SToomas Soome /* preserve backslashed quotes, dollar signs */ 58*22028508SToomas Soome case '\'': 59*22028508SToomas Soome case '"': 60*22028508SToomas Soome case '$': 61*22028508SToomas Soome new_str[i++] = '\\'; 62*22028508SToomas Soome new_str[i++] = *str++; 63*22028508SToomas Soome break; 64*22028508SToomas Soome 65*22028508SToomas Soome case 'b': 66*22028508SToomas Soome new_str[i++] = '\b'; 67*22028508SToomas Soome str++; 68*22028508SToomas Soome break; 69*22028508SToomas Soome 70*22028508SToomas Soome case 'f': 71*22028508SToomas Soome new_str[i++] = '\f'; 72*22028508SToomas Soome str++; 73*22028508SToomas Soome break; 74*22028508SToomas Soome 75*22028508SToomas Soome case 'r': 76*22028508SToomas Soome new_str[i++] = '\r'; 77*22028508SToomas Soome str++; 78*22028508SToomas Soome break; 79*22028508SToomas Soome 80*22028508SToomas Soome case 'n': 81*22028508SToomas Soome new_str[i++] = '\n'; 82*22028508SToomas Soome str++; 83*22028508SToomas Soome break; 84*22028508SToomas Soome 85*22028508SToomas Soome case 's': 86*22028508SToomas Soome new_str[i++] = ' '; 87*22028508SToomas Soome str++; 88*22028508SToomas Soome break; 89*22028508SToomas Soome 90*22028508SToomas Soome case 't': 91*22028508SToomas Soome new_str[i++] = '\t'; 92*22028508SToomas Soome str++; 93*22028508SToomas Soome break; 94*22028508SToomas Soome 95*22028508SToomas Soome case 'v': 96*22028508SToomas Soome new_str[i++] = '\13'; 97*22028508SToomas Soome str++; 98*22028508SToomas Soome break; 99*22028508SToomas Soome 100*22028508SToomas Soome case 'z': 101*22028508SToomas Soome str++; 102*22028508SToomas Soome break; 103*22028508SToomas Soome 104*22028508SToomas Soome case '0': case '1': case '2': case '3': case '4': 105*22028508SToomas Soome case '5': case '6': case '7': case '8': case '9': { 106*22028508SToomas Soome char val; 107*22028508SToomas Soome 108*22028508SToomas Soome /* Three digit octal constant? */ 109*22028508SToomas Soome if (*str >= '0' && *str <= '3' && 110*22028508SToomas Soome *(str + 1) >= '0' && *(str + 1) <= '7' && 111*22028508SToomas Soome *(str + 2) >= '0' && *(str + 2) <= '7') { 112*22028508SToomas Soome 113*22028508SToomas Soome val = (DIGIT(*str) << 6) + 114*22028508SToomas Soome (DIGIT(*(str + 1)) << 3) + 115*22028508SToomas Soome DIGIT(*(str + 2)); 116*22028508SToomas Soome 117*22028508SToomas Soome /* 118*22028508SToomas Soome * Allow null value if user really 119*22028508SToomas Soome * wants to shoot at feet, but beware! 120*22028508SToomas Soome */ 121*22028508SToomas Soome new_str[i++] = val; 122*22028508SToomas Soome str += 3; 123*22028508SToomas Soome break; 124*22028508SToomas Soome } 125*22028508SToomas Soome 126*22028508SToomas Soome /* 127*22028508SToomas Soome * One or two digit hex constant? 128*22028508SToomas Soome * If two are there they will both be taken. 129*22028508SToomas Soome * Use \z to split them up if this is not 130*22028508SToomas Soome * wanted. 131*22028508SToomas Soome */ 132*22028508SToomas Soome if (*str == '0' && 133*22028508SToomas Soome (*(str + 1) == 'x' || *(str + 1) == 'X') && 134*22028508SToomas Soome isxdigit(*(str + 2))) { 135*22028508SToomas Soome val = DIGIT(*(str + 2)); 136*22028508SToomas Soome if (isxdigit(*(str + 3))) { 137*22028508SToomas Soome val = (val << 4) + 138*22028508SToomas Soome DIGIT(*(str + 3)); 139*22028508SToomas Soome str += 4; 140*22028508SToomas Soome } else 141*22028508SToomas Soome str += 3; 142*22028508SToomas Soome /* Yep, allow null value here too */ 143*22028508SToomas Soome new_str[i++] = val; 144*22028508SToomas Soome break; 145*22028508SToomas Soome } 146*22028508SToomas Soome } 147*22028508SToomas Soome break; 148*22028508SToomas Soome 149*22028508SToomas Soome default: 150*22028508SToomas Soome new_str[i++] = *str++; 151*22028508SToomas Soome break; 152*22028508SToomas Soome } 153*22028508SToomas Soome } else { 154*22028508SToomas Soome if (*str == '\\') { 155*22028508SToomas Soome seenbs = 1; 156*22028508SToomas Soome str++; 157*22028508SToomas Soome } else 158*22028508SToomas Soome new_str[i++] = *str++; 159*22028508SToomas Soome } 160*22028508SToomas Soome } 161*22028508SToomas Soome 162*22028508SToomas Soome if (seenbs) { 163*22028508SToomas Soome /* 164*22028508SToomas Soome * The final character was a '\'. 165*22028508SToomas Soome * Put it in as a single backslash. 166*22028508SToomas Soome */ 167*22028508SToomas Soome new_str[i++] = '\\'; 168*22028508SToomas Soome } 169*22028508SToomas Soome new_str[i] = '\0'; 170*22028508SToomas Soome return (new_str); 171*22028508SToomas Soome } 172