rsalz@bbn.com (Rich Salz) (06/01/90)
In <6550.26639B0A@puddle.fidonet.org> cspw.quagga@p0.f4.n494.z5.fidonet.org (cspw quagga) writes: >Is there an easy way to read a string into a buffer with automatic run-time >translation of the escape sequences? I want to do something like this: > > { char fmt[100]; > gets(fmt); > descape(fmt); /* ... This is the function I need */ > printf(fmt,123); > ... > } /* ** Convert C escape sequences in a string. Returns a pointer to ** malloc'd space, or NULL if malloc failed. */ #include <stdio.h> #include <ctype.h> #define OCTDIG(c) ('0' <= (c) && (c) <= '7') #define HEXDIG(c) isxdigit(c) char * UnEscapify(text) register char *text; { extern char *malloc(); register char *p; char *save; int i; if ((save = malloc(strlen(text) + 1)) == NULL) return NULL; for (p = save; *text; text++, p++) { if (*text != '\\') *p = *text; else { switch (*++text) { default: /* Undefined; ignore it */ case '\'': case '\\': case '"': case '?': *p = *text; break; case '\0': *p = '\0'; return save; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': for (*p = 0, i = 0; OCTDIG(*text) && i < 3; text++, i++) *p = (*p << 3) + *text - '0'; text--; break; case 'x': for (*p = 0; *++text && isxdigit(*text); ) if (isdigit(*text)) *p = (*p << 4) + *text - '0'; else if (isupper(*text)) *p = (*p << 4) + *text - 'A'; else *p = (*p << 4) + *text - 'a'; text--; break; case 'a': *p = '\007'; break; /* Alert */ case 'b': *p = '\b'; break; /* Backspace */ case 'f': *p = '\f'; break; /* Form feed */ case 'n': *p = '\n'; break; /* New line */ case 'r': *p = '\r'; break; /* Carriage return */ case 't': *p = '\t'; break; /* Horizontal tab */ case 'v': *p = '\n'; break; /* Vertical tab */ } } } *p = '\0'; return save; } #ifdef TEST main() { char buff[256]; char *p; printf("Enter strings, EOF to quit:\n"); while (gets(buff)) { if ((p = UnEscapify(buff)) == NULL) { perror("Malloc failed"); abort(); } printf("|%s|\n", p); free(p); } exit(0); } #endif /*TEST */ -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net. Use a domain-based address or give alternate paths, or you may lose out.
rsalz@bbn.com (Rich Salz) (06/01/90)
Oops... From: Kevin Braunsdorf <ksb@nostromo.cc.purdue.edu> To: rsalz@BBN.COM In article <2596@litchi.bbn.com> you write: | case 'x': | for (*p = 0; *++text && isxdigit(*text); ) | if (isdigit(*text)) | *p = (*p << 4) + *text - '0'; | else if (isupper(*text)) | *p = (*p << 4) + *text - 'A'; | else | *p = (*p << 4) + *text - 'a'; | text--; | break; Nope. You forgot to add 10 for the 'a' and 'A' case. *p = (*p << 4) + *text - 'A' + 10; else *p = (*p << 4) + *text - 'a' + 10; Sorry about that. -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net. Use a domain-based address or give alternate paths, or you may lose out.