📄 wvdialbrain.cc
字号:
bool WvDialBrain::is_welcome_msg( const char * buf )/**************************************************/// Thanks to dsb for this one, 3/10/98.{ return( sent_login && ( strstr( buf, "mtu" ) || strstr( buf, "ip address is" ) ) );}BrainToken * WvDialBrain::tokenize( char * left, char * right )/*************************************************************/{ BrainToken * token_list = NULL; BrainToken * new_token = NULL; BrainToken * prev_token = NULL; char * p; if( left == NULL || right == NULL || right <= left ) return( NULL ); p = left; while( p <= right ) { // If *p is a null or a new-line, we are done. if( *p == '\0' || isnewline( *p ) ) break; // Skip whitespace in the string. if( isspace( *p ) ) { p++; continue; } // If it's a letter, we've got the beginning of a word. if( isalpha( *p ) ) { char * end = p+1; new_token = new BrainToken; new_token->type = TOK_WORD; new_token->next = NULL; if( token_list == NULL ) token_list = new_token; else prev_token->next = new_token; while( end <= right && isalpha( *end ) ) end++; new_token->tok_str = new char[ end - p + 1 ]; strncpy( new_token->tok_str, p, end - p ); new_token->tok_str[ end-p ] = '\0'; p = end; // skip to the end of the word for next time prev_token = new_token; continue; } // If it's a digit, we've got the beginning of a number. if( isdigit( *p ) ) { char * end = p+1; new_token = new BrainToken; new_token->type = TOK_NUMBER; new_token->next = NULL; if( token_list == NULL ) token_list = new_token; else prev_token->next = new_token; while( end <= right && isdigit( *end ) ) end++; new_token->tok_str = new char[ end - p + 1 ]; strncpy( new_token->tok_str, p, end - p ); new_token->tok_str[ end-p ] = '\0'; p = end; // skip to the end of the number for next time prev_token = new_token; continue; } // If it's useful punctuation (brackets and such), grab it. if( strchr( brackets, *p ) ) { new_token = new BrainToken; new_token->type = TOK_PUNCT; new_token->next = NULL; if( token_list == NULL ) token_list = new_token; else prev_token->next = new_token; new_token->tok_char = *p; p++; prev_token = new_token; continue; } // If it's anything else, ignore it. p++; } return( token_list );}void WvDialBrain::token_list_done( BrainToken * token_list )/**********************************************************/{ BrainToken * next_token; while( token_list != NULL ) { next_token = token_list->next; if( token_list->type == TOK_WORD || token_list->type == TOK_NUMBER ) delete token_list->tok_str; delete token_list; token_list = next_token; }}void WvDialBrain::guess_menu_guts( BrainToken * token_list )/**********************************************************/// There are some cases which may occur in a valid menu line.// Number 1 is of the form "P for PPP"// Number 2 is of the form "1 - start PPP"// Number 3 is of the form "(1) start PPP"// Number 4 has the form "1 blah blah PPP". The first non-whitespace character// is a number, followed by more whitespace. We have to be paranoid here// to avoid seeing phone numbers and such.// We check for these cases in order.//// Okay, fine. This function now uses goto for no good reason. So shoot me.// At least it doesn't randomly return from the middle of the function before// trying all the cases...{ BrainToken * lmarker = NULL; BrainToken * rmarker = NULL; BrainToken * tok; char * prompt_resp = NULL; int index; /////////////// FIRST CASE // This should be generalized later, but for now we'll look for "FOR PPP", // and then examine the thing in front of THAT. If it's not punctuation, // we'll use it as a prompt response. If it IS punctuation, but is NOT // a bracket, we'll take the thing before THAT even, and use it as a prompt // response. for( tok = token_list; tok != NULL; tok = tok->next ) { bool failed = false; if( tok->type == TOK_PUNCT ) continue; // Only looking at words and numbers now. BrainToken * tok2 = tok->next; for( ; tok2 != NULL; tok2 = tok2->next ) { if( tok2->type != TOK_PUNCT ) break; // Only looking at punctuation after the word we're investigating. if( strchr( brackets, tok2->tok_char ) ) { failed = true; break; } } if( failed ) continue; if( !tok2 || !tok2->next ) break; // Now tok is the potential response, and tok2 is the next word or // number, as long as there were no brackets in between. // So now we can look for "for ppp". if( !strcmp( tok2->tok_str, "for" ) && !strcmp( tok2->next->tok_str, "ppp" ) ) { set_prompt_response( tok->tok_str ); return; } } /////////////// SECOND CASE // Find the first right-bracket on the line, and evaluate everything // before it. Things that are allowed are numbers, and words other // than "press" etc. for( tok = token_list; tok != NULL; tok = tok->next ) if( tok->type == TOK_PUNCT ) if( strchr( rbrackets, tok->tok_char ) ) { rmarker = tok; // leftmost right-bracket on this line. break; } if( rmarker == NULL ) goto three; // no right-bracket on this line. // Make sure "ppp" comes _AFTER_ the rmarker... So that we don't respond // to "I like food (ppp is fun too)" or similar things. for( tok = rmarker->next; tok != NULL; tok = tok->next ) if( tok->type == TOK_WORD && strcmp( tok->tok_str, "ppp" ) == 0 ) break; if( tok == NULL ) // We did not find "ppp" after the rmarker goto three; for( tok = token_list; tok != rmarker; tok = tok->next ) { // If we find punctuation in here, then Case Two is WRONG. // Also, handles things like "Press 5" or "Type ppp" correctly. // If there's more than one valid "thing", use the last one. if( tok->type == TOK_PUNCT ) { prompt_resp = NULL; break; } if( tok->type == TOK_NUMBER ) prompt_resp = tok->tok_str; if( tok->type == TOK_WORD ) if( strstr( menu_bad_words, tok->tok_str ) == NULL ) prompt_resp = tok->tok_str; } if( prompt_resp != NULL ) { // Case Two was successful! set_prompt_response( prompt_resp ); return; }three: /////////////// THIRD CASE // Find the first (and recursively innermost) matching pair of brackets. // For example: "This ('a', by the way) is what you type to start ppp." // will parse out simply the letter a. // // Start by finding the RIGHTmost right-bracket which immediately // follows the LEFTmost right-bracket (ie - no words in between). // In the above example, it is the first apostrophe. // // Nov 6/98: Ummmmm, does the above paragraph make sense? bool ready_to_break = false; rmarker = NULL; for( tok = token_list; tok != NULL; tok = tok->next ) { if( tok->type == TOK_PUNCT ) { if( strchr( lbrackets, tok->tok_char ) ) { lmarker = tok; ready_to_break = true; } } else { if( ready_to_break ) break; } } if( lmarker == NULL ) goto four; // no left-bracket on this line. // Now find the matching bit of punctuation in the remainder. // Watch for useful words as we do it... index = strchr( lbrackets, lmarker->tok_char ) - lbrackets; for( tok = lmarker->next; tok != NULL; tok = tok->next ) { if( tok->type == TOK_PUNCT ) { if( tok->tok_char == rbrackets[ index ] ) { rmarker = tok; break; } } else if( tok->type == TOK_WORD ) { if( strstr( menu_bad_words, tok->tok_str ) == NULL ) prompt_resp = tok->tok_str; } else // tok->type == TOK_NUMBER prompt_resp = tok->tok_str; } if( rmarker == NULL ) goto four; // no corresponding right-bracket on this line. // Make sure "ppp" comes _AFTER_ the rmarker... So that we don't respond // to "I like food (ppp is fun too)" or similar things. for( tok = rmarker->next; tok != NULL; tok = tok->next ) if( tok->type == TOK_WORD && strcmp( tok->tok_str, "ppp" ) == 0 ) break; if( tok == NULL ) // We did not find "ppp" after the rmarker goto four; if( prompt_resp != NULL ) { // Case Three was successful set_prompt_response( prompt_resp ); return; } four: /////////////// FOURTH CASE // This is a catch-all for punctuationless menus of the form: // 1 PPP // 2 Quit // Let's just assume the command is a single-digit number. This should // avoid accidentally parsing phone numbers or IP addresses. lmarker = token_list; if ( lmarker->type == TOK_NUMBER && lmarker->tok_str[0] && !lmarker->tok_str[1] ) { for ( tok = token_list; tok != NULL; tok = tok->next ) if (tok->type == TOK_WORD && strcmp( tok->tok_str, "ppp" ) == 0 ) break; if ( tok ) { set_prompt_response( lmarker->tok_str ); // Case Four worked! return; } } // Apparently this was not a valid menu option. Oh well. return;}void WvDialBrain::set_prompt_response( char * str )/*************************************************/{ WvString n; if( strcmp( str, prompt_response ) ) { n.setsize( strlen( str ) + 1 ); strcpy( n.edit(), str ); n.edit()[ strlen( str ) ] = '\0'; dialer->log( "Found a good menu option: \"%s\".\n", n ); prompt_response = n; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -