parseEscapes

C

Public Domain

Parse common escape sequences in a string

Download (right click, save as, rename as appropriate)

Embed

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#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;
}