// 每个option最多只有一个值(可调整代码逻辑以支持多个值) int OptionsParser::Parse(int argc, char** argv) { DeleteOptionVal(); int arg_index = 1; while(arg_index < argc) { string arg_cur(*(argv + arg_index)); if(arg_cur[0] != '-') { arg_index++; continue; } if(arg_cur[1] != '-' && arg_cur.size() == 2) { // short option name if(arg_index + 1 >= argc) { // current option is the last one UpdateOptionVal(arg_cur[1]); return 0; } string arg_next(*(argv + arg_index + 1)); if(arg_next[0] != '-') { // this option has a value UpdateOptionVal(arg_cur[1], arg_next); arg_index += 2; } else { // this option has no value UpdateOptionVal(arg_cur[1]); arg_index++; } } else if(arg_cur[1] == '-' && arg_cur.size() >= 4) { // long option name if(arg_index + 1 >= argc) { // current option is the last one UpdateOptionVal(arg_cur.substr(2)); return 0; } string arg_next(*(argv + arg_index + 1)); if(arg_next[0] != '-') { // this option has a value UpdateOptionVal(arg_cur.substr(2), arg_next); arg_index += 2; } else { // this option has no value UpdateOptionVal(arg_cur.substr(2)); arg_index++; } } else { fprintf(stderr, "Error: %s is an unvalid option.\n", arg_cur.c_str()); arg_index++; } } // while return 0; }
/** * Parse an integer "-" integer command construct * * @param int1 * First integer on output * @param int2 * Second integer on output * * @return * - TRUE if the int - int was found * - FALSE if the int - int was not found * * @date 990521: Original version. Plagerized from lcint. (maf) * */ int lcidi(int *int1, int *int2) { int temp ; Token *t; /* String should conform to a stict format, wherein there may be one dash (-) and the rest of the characters are digits (the only permited whitespace is end padding). The dash may not be the first character, nor the last character before the padding. */ if(!(t = arg()) || !token_is_string(t) || !strchr(t->str, '-')) { return FALSE; } if(sscanf(t->str, "%d-%d%n", int1, int2, &temp) != 2) { return FALSE; } if(temp != (int)strlen(t->str)) { return FALSE; } arg_next(); return TRUE; }
main(int argc,char *argv[]){ int x=0; arg_init(getenv("test_arg"),argc,argv); do{ x=arg_next(); printf("r=%d (%d)'%s'\n",x,argarg,argarg); }while(x >= 0); }
void loop_xboard(void) { position_t* pos = position_new(); color_t engineColor = C_BLACK; IF.info_depth = info_depth; IF.info_pv = info_pv; IF.info_curmove = info_curmove; IF.search_done = search_done; log_set_mode(MODE_GUI); log_line("xboard mode"); threads_init(pos); while (1) { char* line = get_line(); char* token = arg_start(line); if (!strcmp(token, "new")) { position_reset(pos); TT_clear(); engineColor = C_BLACK; InGame = 1; } else if (!strcmp(token, "quit")) { InGame = 0; threads_search_stop(); break; } else if (!strcmp(token, "protover")) { char* v = arg_next(); if (v && atoi(v) == 2) { send_line("feature myname=\"Walce\""); send_line("feature setboard=1 usermove=1 sigint=0 sigterm=0"); send_line("feature playother=1 ping=1 time=1 colors=0 name=1"); send_line("feature ics=1 analyze=1"); send_line("feature option=\"Search Depth -spin %d 0 20\"", 0); send_line("feature option=\"Thinking Time -spin %d 0 600000\"", 0); send_line("feature done=1"); } } else if (!strcmp(token, "random") || !strcmp(token, "bk") || !strcmp(token, "ics") || !strcmp(token, "name") || !strcmp(token, "accepted") || !strcmp(token, "computer") ) { ; // IGNORE } else if (!strcmp(token, "variant") || !strcmp(token, "rejected") || !strcmp(token, "draw") || !strcmp(token, "hint") || !strcmp(token, "hard") || !strcmp(token, "easy") || !strcmp(token, "rating") || !strcmp(token, "pause") || !strcmp(token, "resume") || !strcmp(token, "memory") || !strcmp(token, "cores") || !strcmp(token, "egtpath") ) { send_line("Error (not implemented yet): %s", token); } else if (!strcmp(token, "?")) { threads_search_stop(); } else if (!strcmp(token, "st")) { token = arg_next(); if (token) TC.l_time = atoi(token) * 1000; } else if (!strcmp(token, "level")) { char* moves = arg_next(); char* min = arg_next(); char* inc = arg_next(); char* sec = min ? strchr(min, ':') : NULL; if (sec) *sec++ = 0; if (inc) { int t = atoi(min) * 60 + (sec ? atoi(sec) : 0); TC.togo = atoi(moves); TC.ctime[0] = TC.otime[0] = t * 1000; TC.ctime[1] = TC.otime[1] = atoi(inc) * 1000; } } else if (!strcmp(token, "time")) { token = arg_next(); if (token) TC.ctime[0] = atoi(token) * 10; } else if (!strcmp(token, "otim")) { token = arg_next(); if (token) TC.otime[0] = atoi(token) * 10; } else if (!strcmp(token, "analyze")) { ModeAnalyze = 1; TC.infinite = 1; engineColor = pos->to_move; threads_search(); } else if (ModeAnalyze && !strcmp(token, "exit")) { threads_search_stop(); ModeAnalyze = 0; TC.infinite = 0; } else if (ModeAnalyze && !strcmp(token, ".")) { //send_line("Error (not implemented yet): %s", token); } else if (!strncmp(line, "result", 6)) { InGame = 0; threads_search_stop(); } else if (!strncmp(line, "force", 5)) { engineColor = C_NONE; } else if (!strcmp(token, "go")) { engineColor = pos->to_move; threads_search(); } else if (!strcmp(token, "playother")) { engineColor = 1 ^ pos->to_move; } else if (!strcmp(token, "white")) { pos->to_move = C_WHITE; engineColor = C_BLACK; } else if (!strcmp(token, "black")) { pos->to_move = C_BLACK; engineColor = C_WHITE; } else if (!strcmp(token, "sd")) { char* d = arg_next(); if (d) TC.l_depth = atoi(d); } else if (!strcmp(token, "ping")) { char* a = arg_rest(); if (a) send_line("pong %s", a); else send_line("pong"); } else if (!strcmp(token, "edit")) { send_line("Error (command not implemented): %s", token); } else if (!strcmp(token, "undo")) { if (!position_unmove(pos)) send_line("Error (command not legal now): %s", token); } else if (!strcmp(token, "remove")) { if (!position_unmove(pos) || !position_unmove(pos)) send_line("Error (command not legal now): %s", token); } else if (!strcmp(token, "setboard")) { char* b = arg_rest(); if (!b) send_line("Error (missing argument): %s", token); else position_set(pos, b); } else if (!strcmp(token, "post")) { ModePost = 1; } else if (!strcmp(token, "nopost")) { ModePost = 1; } else if (!strcmp(token, "option")) { char* o = arg_next_sep('='); char* v = arg_next(); if (!o) log_line("missing option"); else if (!strcmp(o, "Thinking Time")) { if (v) TC.l_time = atoi(v); } else if (!strcmp(o, "Search Depth")) { if (v) TC.l_depth = atoi(v); } else log_line("unknown option: %s", o); } else { if (!strcmp(token, "usermove")) token = arg_next(); threads_search_stop(); move_t move = parse_move(pos, token); if (!move) { send_line("Illegal move: %s", token); } else { position_move(pos, move); position_print(pos, C_WHITE); if (ModeAnalyze || engineColor == pos->to_move) threads_search(); } } } threads_exit(); position_destroy(pos); }
/** * Parse and evaluate a "logical" expression * * @param string * Character string containing logical expression. [c] * Must be of the form: "number logical number" where * number is an integer or floating point number and * logical is one of: 'LT', 'LE', 'GT', 'GE', 'EQ', 'NE'. * Integers are converted to floating before being evaluated. * Leading, trailing, and extra white space is ignored. * @param string_s * Length of \p string * @param result * - "TRUE" if expression is true * - "FALSE" if expression is false * - "ERROR" if and error occurred during parsing * @param result_s * Length of \p result * * @bug This should return an int (-1,0,1) * * @date 970129: Add parameter (0) to cnvatf. 0 means that if a string * of digits is too long, let it slide by. maf * @date 900606: Modified tests for reals to handle case where * both numbers are zero. * @date 871117: Changed tests of (in)equality of reals to include * the possible effects of roundoff. * These are now tests for equivalence not equality. * @date 871103: Added ability to check for (in)equality of strings. * @date 870811: Original version. * */ void evallogical(char *string, int string_s, char *result, int result_s) { UNUSED(string); UNUSED(string_s); int lresult; float x, y; Token *t1, *t2, *top; if(!(t1 = arg())) { goto ERROR; } arg_next(); if(!(top = arg())) { goto ERROR; } arg_next(); if(!(t2 = arg())) { goto ERROR; } arg_next(); /* - If first and third tokens are not floating point numbers (i.e. strings) * then the only tests that are allowed are "EQ" and "NE". */ if( (token_is_string(t1) || token_is_quoted_string(t1) || token_is_escape_string(t1)) && (token_is_string(t2) || token_is_quoted_string(t2) || token_is_escape_string(t2))) { lresult = strcmp(t1->str, t2->str); if(is_undefined(t1->str) && strcmp(t2->str, "-12345 ") == 0) { lresult = 0; } if(is_undefined(t2->str) && strcmp(t1->str, "-12345 ") == 0) { lresult = 0; } if( token_is_eq(top) ) { lresult = lresult == 0; goto L_8000; } else if( token_is_ne(top) ) { lresult = lresult != 0; goto L_8000; } else { goto ERROR; } } if(!token_is_number(t1) || !token_is_number(t2)) { if( (token_is_string(t1) || token_is_quoted_string(t1) || token_is_escape_string(t1)) && is_undefined(t1->str) && token_is_number(t2) ) { t1->value = -12345; } else if( (token_is_string(t2) || token_is_quoted_string(t2) || token_is_escape_string(t2)) && is_undefined(t2->str) && token_is_number(t1) ) { t2->value = -12345; } else { goto ERROR; } } /* - Evaluate logical expressions involving floating point numbers. */ if(token_is_lt(top)) { lresult = t1->value < t2->value; } else if(token_is_le(top)) { lresult = t1->value <= t2->value; } else if(token_is_gt(top)) { lresult = t1->value > t2->value; } else if(token_is_ge(top)) { lresult = t1->value >= t2->value; } else if(token_is_eq(top)) { /* y = t1 - t2; x = MAX((t1 + t2)/2, 1e-30) (t1-t2)/(t1+t2)/2 <= RNDOFF */ y = fabs( t1->value - t2->value ); x = fmax( 0.5*(t1->value + t2->value), VSMALL ); lresult = (y/x) <= RNDOFF; } else if(token_is_ne(top)) { y = fabs( t1->value - t2->value ); x = fmax( 0.5*(t1->value + t2->value), VSMALL ); lresult = (y/x) > RNDOFF; } else { goto ERROR; } L_8000: if( lresult ){ fstrncpy( result, result_s - 1, "TRUE", 4 ); } else{ fstrncpy( result, result_s - 1, "FALSE", 5 ); } return; ERROR: fstrncpy( result, result_s-1, "ERROR", 5 ); return; } /* end of function */
/** * Parse a range checked real variable pair command construct * * @param realmn * Minimum value * @param realmx * Maximum value * @param realv1 * First real value * @param realv2 * Second real value * * @return * - TRUE if the real pair was found * - FALSE if the real pair was not found * * @date 820622: Original version. * */ int lcrrcp(double realmn, double realmx, double *realv1, double *realv2) { int lcrrcp_v; int nerr; float rv; Token *t; /* - Get real variable from next symbol. * - Check variable against allowed range. * - Perform standard command error recovery if not found. * - Repeat for second real. */ L_2000: if((t = arg()) && token_is_number(t)) { //if( Itypcm[cmcom.jcom] == cmcom.inumbr ){ lcrrcp_v = TRUE; rv = t->value; if( rv >= realmn && rv <= realmx ){ *realv1 = rv; arg_next(); L_3000: if((t = arg()) && token_is_number(t)) { //if( Itypcm[cmcom.jcom] == cmcom.inumbr ){ rv = t->value; if( rv >= *realv1 && rv <= realmx ){ *realv2 = rv; arg_next(); } else{ cfmt( "OUTSIDE ALLOWED RANGE:",24 ); fprintf(stdout," Allowed range is: %16.5g%16.5g\n", *realv1, realmx ); cresp(); if( lcmore( &nerr ) ) goto L_3000; lcrrcp_v = TRUE; } } else{ cfmt( "NEED A REAL VARIABLE:",23 ); cresp(); if( lcmore( &nerr ) ) goto L_2000; lcrrcp_v = TRUE; } } else{ cfmt( "OUTSIDE ALLOWED RANGE:",24 ); fprintf(stdout," Allowed range is: %16.5g%16.5g\n", realmn, realmx ); cresp(); if( lcmore( &nerr ) ) goto L_2000; lcrrcp_v = TRUE; } } else{ lcrrcp_v = FALSE; } return( lcrrcp_v ); }