Re: Standard function to convert "\t" to '\t' (etc.)?



Gordon Burditt wrote:

In BSD there are non-standard functions strunvis(), strunvisx(),
strvis(), and strvisx() which translate strings from and to a visual
representation of the string. There are several visual representations,
one of them being C-style, and another being octal escapes. strunvis()
decodes all these escapes back into a string. The strvis*() forms
have many options as to what to encode.

It isn't that I didn't already have my own code for this (see below my signature, includes not shown, it needs limits.h). I just wanted to know if there might not be a function always present in the C library that would do this.

Thanks,

David Mathog

/* Convert text form for special characters in a string to the
corresponding (unsigned) character. Handles:
Some C escape sequences: \\, \a,\b,\f,\t,\r, and \n.
ASCII control characters like ^J (masks the 2nd character
retaining only the lowest 6 bits)
For a lone "^" use "/^".
Numerically specified character values as \###,\o###,\x## (3,3,
and 2 digits, as shown, ONLY)
Range is 0-255.
Returns 1 on success, 0 on error
*/
int convert_escape(char *string){
unsigned char *parsed;
unsigned char *scan;
#define NORMAL 0
#define ESCAPE 1
#define CONTROL 2
#define DNUMERIC 3
#define ONUMERIC 4
#define XNUMERIC 5
int state = NORMAL;
int sum = 0;
int count = 0;
int status = 1;
int ok = 1;
for(scan = parsed = (unsigned char *) string; ok; scan++){
switch(state){
case NORMAL:
switch(*scan){
case '\\':
state=ESCAPE;
break;
case '^':
state=CONTROL;
break;
case '\0':
*parsed = *scan; ok = 0;
break;
default:
*parsed=*scan; parsed++;
}
break;
case ESCAPE:
switch(*scan){
case '\\':
state=NORMAL; *parsed=*scan; parsed++;
break;
case 'a':
state=NORMAL; *parsed='\a'; parsed++;
break;
case 'b':
state=NORMAL; *parsed='\b'; parsed++;
break;
case 'f':
state=NORMAL; *parsed='\f'; parsed++;
break;
case 't':
state=NORMAL; *parsed='\t'; parsed++;
break;
case 'r':
state=NORMAL; *parsed='\r'; parsed++;
break;
case 'n':
state=NORMAL; *parsed='\n'; parsed++;
break;
case 'd':
state=DNUMERIC; sum=0; count=0;
break;
case 'o':
state=ONUMERIC; sum=0; count=0;
break;
case 'x':
state=XNUMERIC; sum=0; count=0;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
state=DNUMERIC; sum = *scan - '0'; count=1;
break;
case '\0':
ok = status = 0;
break;
default:
state=NORMAL; *parsed=*scan; parsed++;
}
break;
case CONTROL:
if(*scan=='\0'){
ok = status = 0;
}
else {
state=NORMAL; *parsed = *scan & 31; parsed++;
}
break;
case DNUMERIC:
switch(*scan){
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
sum=(10*sum) + (*scan - '0');
if(++count == 3){ /* There must be exactly 3 digits */
if(sum > UCHAR_MAX){
ok = status = 0;
}
else {
state = NORMAL; *parsed=sum; parsed++;
}
}
break;
default:
ok = status = 0;
}
break;
case ONUMERIC:
switch(*scan){
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
sum= (8*sum) + (*scan - '0');
if(++count == 3){ /* There must be exactly 3 digits */
if(sum > UCHAR_MAX){
ok = status = 0;
}
else {
state = NORMAL; *parsed=sum; parsed++;
}
}
break;
default:
ok = status = 0;
}
break;
case XNUMERIC:
switch(*scan){
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
sum=(16*sum) + (*scan - '0');
if(++count == 2){ /* There must be exactly 2 digits */
state = NORMAL; *parsed=sum; parsed++;
}
break;
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
sum=(16*sum) + (10 + *scan - 'A');
if(++count == 2){ /* There must be exactly 2 digits */
state = NORMAL; *parsed=sum; parsed++;
}
break;
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
sum=(16*sum) + (10 + *scan - 'a');
if(++count == 2){ /* There must be exactly 2 digits */
state = NORMAL; *parsed=sum; parsed++;
}
break;
default:
ok = status = 0;
}
break;
default: /* catch what should be an impossible state */
ok = status = 0;
}
}
return(status);
}
.



Relevant Pages

  • Re: Getting Starting in JavaScript et al
    ... To date I have had three epiphanies where I have suddenly "got" javascript and realized how utterly diffident my previous understanding of the subject had been. ... Identifying and understanding the types of values that javascript uses; that there are 5 primitive data types (boolean, number, string, null and the undefined type). ... tab would then contain the tab character, ... Javascript has escape sequences that start with a backslash, but there are a number of types. ...
    (comp.lang.javascript)
  • RfD: Escaped Strings S" (v6.3)
    ... Escape character is case sensitive, ... the S" string can only contain printable characters, ... impact of char in the file word sets. ...
    (comp.lang.forth)
  • RfD: Escaped Strings version 4
    ... the S" string can only contain printable characters, ... the S" string cannot contain the '"' character, ... as an escape character for the entry of characters that cannot be ... \b BS (backspace, ASCII 8) ...
    (comp.lang.forth)
  • RfD: Escaped Strings version 4
    ... the S" string can only contain printable characters, ... the S" string cannot contain the '"' character, ... as an escape character for the entry of characters that cannot be ... \b BS (backspace, ASCII 8) ...
    (comp.lang.forth)
  • Re: problems with opening files due to files path
    ... GUI or it is a console app. ... of what an escape character and escape sequence is. ... character) inside a string specially, it makes the character after the ...
    (comp.lang.python)