#include <stdlib.h>
#include <string.h>
#include <ctype.h>
/* This function returns a new, dynamically allocated string
* with escape sequences parsed out, or NULL on error. */
char* parseEscapes(const char* str0) {
if (str0 == NULL) return NULL;
char* str = strdup(str0);
if (str == NULL) return NULL;
int i, escOffset = 0;
for (i=0; str[i] != '\0'; i++) {
if (str[i] == '\\' && str[i+1] != '\0') {
switch (str[i+1]) {
case '\\': str[i-escOffset] = '\\'; break;
case '\'': str[i-escOffset] = '\''; break;
case '"': str[i-escOffset] = '"'; break;
case 'n': str[i-escOffset] = '\n'; break;
case 'r': str[i-escOffset] = '\r'; break;
case 't': str[i-escOffset] = '\t'; break;
case 'e': str[i-escOffset] = 0x1B; break;
case 'a': str[i-escOffset] = '\a'; break;
case 'v': str[i-escOffset] = '\v'; break;
case 'b': str[i-escOffset] = '\b'; break;
case 'f': str[i-escOffset] = '\f'; break;
case 'x': case 'X': {
/* Using sscanf() seemed like it would be too error prone */
char hexstr[3];
int j;
for (j=0; j<2; j++) {
if (isxdigit(str[i+2+j])) hexstr[j] = str[i+2+j];
else break;
}
if (j==0) {str[i-escOffset] = str[i+1]; break; }
hexstr[j] = '\0';
str[i-escOffset] = (char) strtol(hexstr, NULL, 16);
i += j;
escOffset += j;
break;
}
default:
if (str[i+1] >= '0' && str[i+1] < '8') {
/* Using sscanf() seemed like it would be too error prone */
char octstr[4];
int j;
for (j=0; j<3; j++) {
if (str[i+1+j] >= '0' && str[i+1+j] < '8') octstr[j] = str[i+1+j];
else break;
}
if (j==0) {str[i-escOffset] = str[i+1]; break; }
octstr[j] = '\0';
str[i-escOffset] = (char) strtol(octstr, NULL, 8);
i += j-1;
escOffset += j-1;
} else str[i-escOffset] = str[i+1];
}
escOffset++;
i++;
} else str[i-escOffset] = str[i];
}
str[i-escOffset] = 0;
return str;
}