/**************************************************************************** ** *F GetStr() . . . . . . . . . . . . . . . . . . . . . get a string, local ** ** 'GetStr' reads a string from the current input file into the variable ** 'STATE(ValueObj)' and sets 'Symbol' to 'S_STRING'. The opening double ** quote '"' of the string is the current character pointed to by 'In'. ** ** A string is a sequence of characters delimited by double quotes '"'. It ** must not include '"' or <newline> characters, but the escape sequences ** '\"' or '\n' can be used instead. The escape sequence '\<newline>' is ** ignored, making it possible to split long strings over multiple lines. ** ** An error is raised if the string includes a <newline> character or if the ** file ends before the closing '"'. */ static void GetStr(void) { Obj string = 0; Char buf[1024]; UInt i = 0; Char c = PEEK_CURR_CHAR(); while (c != '"' && c != '\n' && c != '\377') { if (c == '\\') { c = GetEscapedChar(); } i = AddCharToBuf(&string, buf, sizeof(buf), i, c); // read the next character c = GET_NEXT_CHAR(); } // append any remaining data to STATE(ValueObj) STATE(ValueObj) = AppendBufToString(string, buf, i); if (c == '\n') SyntaxError("String must not include <newline>"); if (c == '\377') { *STATE(In) = '\0'; SyntaxError("String must end with \" before end of file"); } }
/**************************************************************************** ** *F GetChar() . . . . . . . . . . . . . . . . . get a single character, local ** ** 'GetChar' reads the next character from the current input file into the ** variable 'STATE(Value)' and sets 'Symbol' to 'S_CHAR'. The opening single quote ** '\'' of the character is the current character pointed to by 'In'. ** ** A character is a single character delimited by single quotes '\''. It ** must not be '\'' or <newline>, but the escape sequences '\\\'' or '\n' ** can be used instead. */ static void GetChar(void) { /* skip '\'' */ Char c = GET_NEXT_CHAR(); /* handle escape equences */ if ( c == '\n' ) { SyntaxError("Character literal must not include <newline>"); } else { if ( c == '\\' ) { STATE(Value)[0] = GetEscapedChar(); } else { /* put normal chars into 'STATE(Value)' */ STATE(Value)[0] = c; } /* read the next character */ c = GET_NEXT_CHAR(); /* check for terminating single quote, and skip */ if ( c == '\'' ) { c = GET_NEXT_CHAR(); } else { SyntaxError("Missing single quote in character constant"); } } }
unsigned short LinkObjectStore::GetHashIdx(const char* str, unsigned short max_idx, unsigned int &full_index) { if (*str) { // Calculate a hashing index based on the input string, unescaping // any URL escapes as we go along unsigned int val = 0; register unsigned int val1; register const unsigned char* tmp = (const unsigned char*) str; while (*tmp) { int len1; register unsigned char val2; register unsigned char val_a, val_b, val_c, val_d; val1 = 0; val_a = tmp[0]; val_b = tmp[1]; val_c = (val_b ? tmp[2] : 0); val_d = (val_c ? tmp[3] : 0); if(val_a != '%' && val_b != '%' && val_c != '%' && val_d != '%') { // Simple hashing if there are no escaped characters in // this chunk. val1 = (((unsigned int) val_a) << 24) | (((unsigned int) val_b) << 16) | (((unsigned int) val_c) << 8) | val_d; if(val_d) { tmp+=4; } else { val = 33*val ^ val1; break; } } else { // Hash each character by itself when there are escaped // characters. for(len1 = 4; len1 > 0 && *tmp;len1--,tmp++) { val1 <<= 8; val2 = *tmp; if(val2 =='%' && tmp[1] && tmp[2]) { // Unescape only if it is a proper hexadecimal escape. if (uni_isxdigit(tmp[1]) && uni_isxdigit(tmp[2])) { val2 = GetEscapedChar(tmp[1], tmp[2]); tmp += 2; } } val1 |= val2; } if(len1) { val1 <<= (len1 << 3); // multiply by 8 } } val = 33*val ^ val1; } full_index = val; return (unsigned short)(val % max_idx); } else { full_index = 0; return 0; } }