Skip to content

Commit

Permalink
Add parsing of hex literals in strings
Browse files Browse the repository at this point in the history
With this patch it is possible to give character values by using
the common '\xHH' escape where H is a hexadecimal digit.
  • Loading branch information
markuspf committed Feb 13, 2016
1 parent 56c6abc commit 64d1e9d
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
19 changes: 19 additions & 0 deletions src/scanner.c
Original file line number Diff line number Diff line change
Expand Up @@ -1869,6 +1869,13 @@ void GetStr ( void )
else if ( *TLS(In) == '>' ) TLS(Value)[i] = '\01';
else if ( *TLS(In) == '<' ) TLS(Value)[i] = '\02';
else if ( *TLS(In) == 'c' ) TLS(Value)[i] = '\03';
else if ( *TLS(In) == 'x' ) {
GET_CHAR(); a = *TLS(In); GET_CHAR(); b = *TLS(In);
if (!( IsHexDigit(a) && IsHexDigit(b) )) {
SyntaxError("Expecting two hexadecimal digits after \\x in string");
}
TLS(Value)[i] = CharHexDigit(a)*16 + CharHexDigit(b);
}
else if ( IsDigit( *TLS(In) ) ) {
a = *TLS(In); GET_CHAR(); b = *TLS(In); GET_CHAR(); c = *TLS(In);
if (!( IsDigit(b) && IsDigit(c) )){
Expand Down Expand Up @@ -2054,6 +2061,18 @@ void GetChar ( void )
else if ( *TLS(In) == '>' ) TLS(Value)[0] = '\01';
else if ( *TLS(In) == '<' ) TLS(Value)[0] = '\02';
else if ( *TLS(In) == 'c' ) TLS(Value)[0] = '\03';
else if ( *TLS(In) == 'x' ) {
GET_CHAR(); c = *TLS(In);
if (!IsHexDigit(c)) {
SyntaxError("Expecting hexadecimal digit in character constant");
}
TLS(Value)[0] = CharHexDigit(c) * 16;
GET_CHAR(); c = *TLS(In);
if (!IsHexDigit(c)) {
SyntaxError("Expecting hexadecimal digit in character constant");
}
TLS(Value)[0] += CharHexDigit(c);
}
else if ( *TLS(In) >= '0' && *TLS(In) <= '7' ) {
/* escaped three digit octal numbers are allowed in input */
c = 64 * (*TLS(In) - '0');
Expand Down
25 changes: 25 additions & 0 deletions src/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,16 @@ extern UInt SyTimeChildrenSys ( void );
*/
#define IsDigit(ch) (isdigit((unsigned int)ch))


/****************************************************************************
**
*F IsHexDigit( <ch> ) . . . . . . . . . . . . . . . is a character a digit
**
** 'IsDigit' returns 1 if its character argument is a digit from the ranges
** '0..9' or 'a..f' and 0 otherwise.
*/
#define IsHexDigit(ch) (isxdigit((unsigned int)ch))

/****************************************************************************
**
*F IsSpace( <ch> ) . . . . . . . . . . . . . . . .is a character whitespace
Expand All @@ -640,6 +650,21 @@ extern UInt SyTimeChildrenSys ( void );
#define IsSpace(ch) (isspace((unsigned int)ch))


/****************************************************************************
**
*F IntHexDigit( <ch> ) . . . . . . . . . . turn a single hex digit into int
**
*/
inline Char CharHexDigit( const Char ch ) {
if (ch >= 'a') {
return (ch - 'a' + 10);
} else if (ch >= 'A') {
return (ch - 'A' + 10);
} else {
return (ch - '0');
}
};

/****************************************************************************
**
*F SyIntString( <string> ) . . . . . . . . extract a C integer from a string
Expand Down

0 comments on commit 64d1e9d

Please sign in to comment.