bool IC_CmdLineParser::handleChar( wchar_t wc, WideString& cmdName, array<WideString>& args ) { static const wchar_t spaceChar = ( wchar_t )' '; static const wchar_t escapeChar = ( wchar_t )'\\'; static const wchar_t quoteChar = ( wchar_t )'\"'; if ( wc == spaceChar ) { if ( !isQuoted() ) { shoveTmpString( cmdName, args ); } else { tmpString += ( spaceChar ); bShouldAddLast = true; } } else if ( wc == quoteChar ) { if ( isEscaped() ) { tmpString += quoteChar; bShouldAddLast = true; setEscaped( false ); } else if ( isQuoted() ) { shoveTmpString( cmdName, args ); setQuoted( false ); } else { setQuoted( true ); } } else if ( wc == escapeChar ) { if ( isEscaped() ) { tmpString += escapeChar; bShouldAddLast = true; setEscaped( false ); } else { setEscaped( true ); } } else { if ( isEscaped() ) { return false; } tmpString += wc; bShouldAddLast = true; } return true; }
QStringList CommandExecutionEngine::tokenize(const QString& string, const QString& quoteSymbols, const QString& escapeSymbols) { QStringList result; QString str; QChar quote; for (int i = 0; i < string.size(); ++i) { if ( quote.isNull() ) { if ( quoteSymbols.contains(string[i]) ) { if ( !str.isNull() ) result.append(tokenizeNonQuoted(str.simplified())); quote = string[i]; str = quote; } else str.append(string[i]); } else { if ( string[i] == quote && !isEscaped(string, i, escapeSymbols) ) { result.append(str + quote); quote = QChar(); str = QString(); } } } if ( !str.isNull() ) result.append(tokenizeNonQuoted(str.simplified())); return result; }
/*! * @if jp * @brief 文字列の末尾の空白文字を削除する * @else * @brief Erase the tail blank characters of string * @endif */ void eraseTailBlank(std::string& str) { if (str.empty()) return; while ((str[str.size() - 1] == ' ' || str[str.size() - 1] == '\t') && !isEscaped(str, str.size() - 1)) str.erase(str.size() - 1, 1); }
QString Parameter::toString(bool debug, short level) const { QString prefixes; if(isEscaped()) prefixes += "\\"; if(isParented()) prefixes += "@"; return concatenateStrings(prefixes + label(), ": ", defaultValue() ? defaultValue()->toString(debug, level) : ""); }
bool LexicalAnalyzer::matchString(const QString &s, int &matchedLength) { matchedLength = 0; if (!s.startsWith('\"')) return false; int i = 1; while (i < s.length() && (s.at(i) != '\"' || isEscaped(s, i, '\"'))) ++i; if (s.length() == i || s.at(i) != '\"') return false; matchedLength = i + 1; return true; }
/** * Find next argument in command */ int CmdMessenger::findNext(char *str, char delim) { int pos = 0; bool escaped; ArglastChar = NULL; while (*str != '\0') { escaped = isEscaped(str,escape_character,&ArglastChar); if (*str==field_separator && !escaped) { return pos; } else { str++; pos++; } } return pos; }
bool CommandExecutionEngine::doQuotesMatch(const QString& string, const QString& quoteSymbols, const QString& escapeSymbols) { QChar quote; for (int i = 0; i < string.size(); ++i) { if ( quote.isNull() ) { if ( quoteSymbols.contains(string[i]) ) quote = string[i]; } else { if ( string[i] == quote && !isEscaped(string, i, escapeSymbols) ) quote = QChar(); } } return quote.isNull(); }
/** * Processes bytes and determines message state */ uint8_t CmdMessenger::processLine(char serialChar) { messageState = kProccesingMessage; //char serialChar = (char)serialByte; bool escaped = isEscaped(&serialChar,escape_character,&CmdlastChar); if((serialChar == command_separator) && !escaped) { commandBuffer[bufferIndex]=0; if(bufferIndex > 0) { messageState = kEndOfMessage; current = commandBuffer; CmdlastChar='\0'; } reset(); } else { commandBuffer[bufferIndex]=serialChar; bufferIndex++; if (bufferIndex >= bufferLastIndex) reset(); } return messageState; }
/** * Find next argument in command */ int CmdMessenger::findNext(char *str, char delim) { int pos = 0; bool escaped = false; bool EOL = false; ArglastChar = '\0'; while (true) { escaped = isEscaped(str,escape_character,&ArglastChar); EOL = (*str == '\0' && !escaped); if (EOL) { return pos; } if (*str==field_separator && !escaped) { return pos; } else { str++; pos++; } } return pos; }
/** * Processes bytes and determines message state */ uint8_t CmdMessenger::processLine(int serialByte) { messageState = kProccesingMessage; char serialChar = (char)serialByte; bool escaped = isEscaped(&serialChar,escape_character,&CmdlastChar); // *comms << "1, " << (int) serialChar << " ;"; if (serialByte > 0 || escaped) { if((serialChar == command_separator) && !escaped) { buffer[bufferIndex]=0; if(bufferIndex > 0) { messageState = kEndOfMessage; current = buffer; CmdlastChar='\0'; } reset(); } else { buffer[bufferIndex]=serialByte; bufferIndex++; if (bufferIndex >= bufferLastIndex) reset(); } } return messageState; }
// The function walks the given buffer and provides two things: // - an array of absolute positions of the beginning of each line // - a deque of found comments void getLineShiftsAndComments( const char * buffer, int * lineShifts, std::deque< CommentLine > & comments ) { int absPos = 0; char symbol; int line = 1; int column = 1; ExpectState expectState = expectCommentStart; CommentLine comment; /* index 0 is not used; The first line starts with shift 0 */ lineShifts[ 1 ] = 0; while ( buffer[ absPos ] != '\0' ) { symbol = buffer[ absPos ]; if ( symbol == '#' ) { if ( expectState == expectCommentStart ) { comment.begin = absPos; comment.line = line; comment.pos = column; expectState = expectCommentEnd; ++absPos; ++column; continue; } } else if ( expectState != expectCommentEnd ) { if ( symbol == '\"' || symbol == '\'' ) { if ( isEscaped( buffer, absPos ) ) { ++absPos; ++column; continue; } // It is not escaped some kind of quote if ( symbol == '\"' && ( expectState == expectClosingSingleQuote || expectState == expectClosingTripleSingleQuote ) ) { // " inside ' or ''' ++absPos; ++column; continue; } if ( symbol == '\'' && ( expectState == expectClosingDoubleQuote || expectState == expectClosingTripleDoubleQuote ) ) { // ' inside " or """ ++absPos; ++column; continue; } // String literal beginning case if ( expectState == expectCommentStart ) { if ( isTriple( buffer, absPos ) == true ) { if ( symbol == '\"' ) expectState = expectClosingTripleDoubleQuote; else expectState = expectClosingTripleSingleQuote; absPos += 3; column += 3; } else { if ( symbol == '\"' ) expectState = expectClosingDoubleQuote; else expectState = expectClosingSingleQuote; ++absPos; ++column; } continue; } // String literal end case if ( expectState == expectClosingSingleQuote || expectState == expectClosingDoubleQuote ) { expectState = expectCommentStart; ++absPos; ++column; continue; } else if ( expectState == expectClosingTripleSingleQuote || expectState == expectClosingTripleDoubleQuote ) { if ( isTriple( buffer, absPos ) == true ) { expectState = expectCommentStart; absPos += 3; column += 3; continue; } ++absPos; ++column; continue; } else throw std::runtime_error( "Fatal error: unknown quote state" ); } } if ( symbol == '\r' ) { comment.end = absPos - 1; // will not harm but will unify the code ++absPos; if ( buffer[ absPos ] == '\n' ) { ++absPos; } ++line; lineShifts[ line ] = absPos; column = 1; if ( expectState == expectCommentEnd ) { comment.detectType( buffer ); comments.push_back( comment ); comment.begin = -1; expectState = expectCommentStart; } continue; } if ( symbol == '\n' ) { comment.end = absPos - 1; // will not harm but will unify the code ++absPos; ++line; lineShifts[ line ] = absPos; column = 1; if ( expectState == expectCommentEnd ) { comment.detectType( buffer ); comments.push_back( comment ); comment.begin = -1; expectState = expectCommentStart; } continue; } ++absPos; ++column; } if ( comment.begin != -1 ) { // Need to flush the collected comment comment.detectType( buffer ); comment.end = absPos - 1; comments.push_back( comment ); } return; }
static int strsearch_init(mapidflib_function_instance_t *instance, MAPI_UNUSED int fd) //Initializes the function { char *str, *strbak; int off, dpth; unsigned char *tmpstr, *tstrbak; unsigned char *ret; // holds the final parsed string int len=0; // length of the final parsed string unsigned short pattern_ctr = 0; char hexpair[3]; mapiFunctArg* fargs; struct mapid_strsearch_pattern *pattern = NULL; struct mapid_strsearch_pattern *lastptrn, *tmpptrn = NULL; fargs=instance->args; str = getargstr(&fargs); off = getargint(&fargs); dpth = getargint(&fargs); /* parse pattern * * Non printable characters or general binary content can be specified by * using pipes enclosing the binary data which are represented in hex * values for each byte. For example, 'abcd' is the same as '|61 62 63 * 64|' or 'ab|63 64|' or '|61|b|6364|. If the pipe character needs to be * searched, it should be preceeded by a '\'. */ strbak = str; // backup pointer tstrbak = tmpstr = (unsigned char *)malloc(strlen(str)*sizeof(char)); ret=tmpstr; hexpair[2]='\0'; while(*str!='\0') { // Two pipes "||" separates two match strings. // A||B will match both a packet with either A or B in it. if (*str == '|' && *(str+1) == '|') // Should be safe since last char will be '\0' { if (!isEscaped(str)) { len=tmpstr-ret; if (len <= 0) { // Empty OR node, skip str += 2; continue; } if((dpth > 0) && (dpth < len)) { DEBUG_CMD(Debug_Message("The depth (%d) is less than the size of the pattern (%d)", dpth, len)); return MDLIB_STRSEARCH_DEPTH_LESS_THAN_PTRN_ERR; } tmpptrn = malloc(sizeof(struct mapid_strsearch_pattern)); tmpptrn->str = (unsigned char *)malloc(len * sizeof(char)); tmpptrn->slen = len; tmpptrn->offset = off; tmpptrn->depth = dpth; memcpy(tmpptrn->str, ret, len); //compute Boyer-Moore's shift and skip tables tmpptrn->shift = make_shift((char *)ret, len); tmpptrn->skip = make_skip((char *)ret, len); tmpptrn->next = NULL; if (pattern == NULL) { pattern = tmpptrn; lastptrn = tmpptrn; } else { lastptrn->next = tmpptrn; lastptrn = tmpptrn; } tmpptrn = NULL; ret = tmpstr; pattern_ctr++; } else { *tmpstr=*str; tmpstr++; } str++; } // '|' means that hex mode begins unless it is escaped \| // every hex number consists of two characters ,e.g A is written as 0A else if(*str=='|') { if(!isEscaped(str)) { int hexcount=0; str++; //parse until closing '|' while(*str!='|') { if(*str=='\0') { return MDLIB_STRSEARCH_UNTERMINATED_PIPE_ERR; } // |AC DE| => ignore white spaces between hex numbers if(*str==' ') { str++; continue; } //convert hex to character hexpair[hexcount++]=*str; if(hexcount==2) { hexcount=0; sscanf(hexpair,"%x",(int *)tmpstr); tmpstr++; } str++; } } else { *tmpstr=*str; tmpstr++; } } // special case for escape character '\\' else if(*str=='\\') { if(isEscaped(str)) { *tmpstr=*str; tmpstr++; } } else { *tmpstr=*str; tmpstr++; } str++; } len=tmpstr-ret; /* end of pattern parsing */ /* Arne: Will fix it later funct = fhlp_get_first(); while (funct) { if(strcmp(funct->name,"STR_SEARCH")==0) if(funct->internal_data) if(memcmp(((struct mapid_strsearch *)funct->internal_data)->str, ret, ((struct mapid_strsearch *)funct->internal_data)->slen) == 0) if(((struct mapid_strsearch *)funct->internal_data)->offset == off && ((struct mapid_strsearch *)funct->internal_data)->depth == dpth){ instance->internal_data = funct->internal_data; printf("added optimised string search: %s offset: %d depth: %d\n",strbak, off, dpth); return 0; } funct = funct->next; } */ if((dpth > 0) && (dpth < len)) { DEBUG_CMD(Debug_Message("The depth (%d) is less than the size of the pattern (%d)", dpth, len)); return MDLIB_STRSEARCH_DEPTH_LESS_THAN_PTRN_ERR; } if (len > 0) { tmpptrn = malloc(sizeof(struct mapid_strsearch_pattern)); tmpptrn->str = (unsigned char *)malloc(len * sizeof(char)); tmpptrn->slen = len; tmpptrn->offset = off; tmpptrn->depth = dpth; memcpy(tmpptrn->str, ret, len); //compute Boyer-Moore's shift and skip tables tmpptrn->shift = make_shift((char *)ret, len); tmpptrn->skip = make_skip((char *)ret, len); tmpptrn->next = NULL; if (pattern == NULL) pattern = tmpptrn; else lastptrn->next = tmpptrn; pattern_ctr++; } if (pattern == NULL) { // Invalid search term return MDLIB_STRSEARCH_NOT_A_VALID_SEARCH_STRING; } instance->internal_data = malloc(sizeof(struct mapid_strsearch)); /* ((struct mapid_strsearch *)instance->internal_data)->str = (unsigned char *)malloc(len * sizeof(char)); ((struct mapid_strsearch *)instance->internal_data)->slen = len; ((struct mapid_strsearch *)instance->internal_data)->offset = off; ((struct mapid_strsearch *)instance->internal_data)->depth = dpth; memcpy(((struct mapid_strsearch *)instance->internal_data)->str, ret, len); //compute Boyer-Moore's shift and skip tables ((struct mapid_strsearch *)instance->internal_data)->shift = make_shift((char *)ret, len); ((struct mapid_strsearch *)instance->internal_data)->skip = make_skip((char *)ret, len); */ ((struct mapid_strsearch *)instance->internal_data)->pattern = pattern; ((struct mapid_strsearch *)instance->internal_data)->num_patterns = pattern_ctr; ((struct mapid_strsearch *)instance->internal_data)->currentIteration = 0; DEBUG_CMD(Debug_Message("added string search: %s offset: %d depth: %d nodes: %u", strbak, off, dpth, pattern_ctr)); free(tstrbak); return 0; }