Commit ed3b28f1 authored by rswindell's avatar rswindell
Browse files

c_unescape_char/str now supports \ddd (for decimal character literals,

ala Synchronet text.dat) by default and octal format only if
C_UNESCAPE_OCTAL_SUPPORT is defined.
\X## is no longer supported (must use the C-standard \x##
Only 2 hex digits are now supported, longer streams of valid hex digits will
not be parsed as a literal character (unlike the C standard)
parent 58229598
......@@ -409,6 +409,13 @@ typedef struct {
#define SKIP_HEXDIGIT(p) while(*(p) && isxdigit((unsigned char)*(p))) (p)++;
#define FIND_HEXDIGIT(p) while(*(p) && !isxdigit((unsigned char)*(p))) (p)++;
#define HEX_CHAR_TO_INT(ch) (((ch)&0xf)+(((ch)>>6)&1)*9)
#define DEC_CHAR_TO_INT(ch) ((ch)&0xf)
#define OCT_CHAR_TO_INT(ch) ((ch)&0x7)
#ifndef isodigit
#define isodigit(ch) ((ch) >= '0' && (ch) <= '7')
#endif
/* Variable/buffer initialization (with zeros) */
#define ZERO_VAR(var) memset(&(var),0,sizeof(var))
#define ZERO_ARRAY(array) memset(array,0,sizeof(array))
......
/* genwrap.c */
/* General cross-platform development wrappers */
/* $Id$ */
// vi: tabstop=4
/****************************************************************************
* @format.tab-size 4 (Plain Text/Source Code File Header) *
......@@ -112,25 +111,51 @@ char DLLCALL c_unescape_char(char ch)
}
/****************************************************************************/
/* Return character value of C-escaped (\) character sequence */
/* (supports \Xhh and \0ooo escape sequences) */
/* This code currently has problems with sequences like: "\x01blue" */
/* Return character value of C-escaped (\) character literal sequence */
/* supports \x## (hex) and \### sequences (for octal or decimal)
/****************************************************************************/
char DLLCALL c_unescape_char_ptr(const char* str, char** endptr)
{
char ch;
if(toupper(*str)=='X')
ch=(char)strtol(++str,endptr,16);
else if(isdigit(*str))
ch=(char)strtol(++str,endptr,8);
else {
if(*str == 'x') {
int digits = 0; // \x## for hexadecimal character literals (only 2 digits supported)
++str;
ch = 0;
while(digits < 2 && isxdigit(*str)) {
ch *= 0x10;
ch += HEX_CHAR_TO_INT(*str);
str++;
digits++;
}
#ifdef C_UNESCAPE_OCTAL_SUPPORT
} else if(isodigit(*str)) {
int digits = 0; // \### for octal character literals (only 3 digits supported)
ch = 0;
while(digits < 3 && isodigit(*str)) {
ch *= 8;
ch += OCT_CHAR_TO_INT(*str);
str++;
digits++;
}
#else
} else if(isdigit(*str)) {
int digits = 0; // \### for decimal charater literals (only 3 digits supported)
ch = 0;
while(digits < 3 && isdigit(*str)) {
ch *= 10;
ch += DEC_CHAR_TO_INT(*str);
str++;
digits++;
}
#endif
} else
ch=c_unescape_char(*(str++));
if(endptr!=NULL)
*endptr=(char*)str;
}
return(ch);
if(endptr!=NULL)
*endptr=(char*)str;
return ch;
}
/****************************************************************************/
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment