void tcp_init_with_env() { char tmp[256]; const char* tcp_flags_cfg = getenv(DNSCORE_TCP_FLAGS); if(tcp_flags_cfg != NULL) { strncpy(tmp, tcp_flags_cfg, sizeof(tmp)-1); tmp[sizeof(tmp) - 1] = '\0'; size_t tmp_len = strlen(tmp); for(int i = 0; i < tmp_len; i++) { if(tmp[i] == ',') { tmp[i] = ' '; } } const char *p = parse_skip_spaces(tmp); while(*p != '\0') { s32 keyword = -1; s32 word_len = parse_skip_word_specific(p, strlen(p), tcp_env_keywords, 4, &keyword); if(FAIL(word_len)) { break; } switch(keyword) { case 0: // nodelay tcp_nodelay = TRUE; break; case 1: // delay tcp_nodelay = FALSE; break; case 2: // cork tcp_cork = TRUE; break; case 3: // nocork tcp_cork = FALSE; break; default: osformatln(termerr, "syntax error in env %s", DNSCORE_TCP_FLAGS); flusherr(); break; } p += word_len; p = parse_skip_spaces(p); } } }
int Lang_Message_Add (t_lang *lang, char *msg_id, char *msg) { // Find message number (#define) by name int n = -1; for (int i = 0; Msg_Translation_Table[i].name; i++) { if (stricmp (msg_id, Msg_Translation_Table[i].name) == 0) { n = Msg_Translation_Table[i].value; break; } } if (n == -1) return (MEKA_ERR_UNKNOWN); // Store message if (lang->Messages [n]) { free (lang->Messages [n]); ConsolePrintf ("In %s: message \"%s\" redefined! Keeping new value.\n", lang->Name, msg_id); } // lang->Messages [n] = strdup (msg); lang->Messages[n] = parse_getword(NULL, 0, &msg, "\"", 0); // Verify that there's nothing after this line parse_skip_spaces(&msg); if (msg[0]) return (MEKA_ERR_SYNTAX); return (MEKA_ERR_OK); }
/* parse player name & rating */ static bool ggs_player_set(GGSPlayer *player, const char *name, const char *rating) { char word[WORD_SIZE]; if (name == NULL || *name == '\0') return false; parse_word(name, word, WORD_SIZE); player->name = string_duplicate(word); rating = parse_skip_spaces(rating); if (*rating == '(') ++rating; return ggs_parse_double(&(player->rating), rating); }
//----------------------------------------------------------------------------- // DB_Load_EntryOldFormat (char *line) // Load DB entry in old format from given line //----------------------------------------------------------------------------- static int DB_Load_EntryOldFormat(char *line) { t_db_entry *entry; t_meka_crc mekacrc; char * w; char buf[1024+1]; // Get MekaCRC sscanf (line, "%08X%08X", &mekacrc.v[0], &mekacrc.v[1]); line += 16 + 1; // Get name if (!(w = parse_getword(NULL, 0, &line, ",", ';'))) return (0); // Create and add entry to global list // Note that the old format doesn't store system nor crc32 entry = DB_Entry_New (-1, 0, &mekacrc); list_add (&DB.entries, entry); DB.entries_counter_format_old++; // Add default name DB_Name_New (entry, w, 0, FALSE); // Parse optional parameters while ((w = parse_getword(buf, 1024, &line, "=,", ';')) != NULL) { StrUpper(w); // printf ("field '%s'\n", w); if (!strcmp(w, "JAPNAME")) { if (!(w = parse_getword(NULL, 0, &line, ",", ';'))) return (0); DB_Name_New (entry, w, DB_COUNTRY_JP, FALSE); } else if (!strcmp(w, "VER")) { // In the old format, the 'VER' field holds both COUNTRY and VERSION char *wp; if (!(w = parse_getword(buf, 1024, &line, ",", ';'))) return (0); wp = buf; // printf("VER = %s\n", wp); // Get COUNTRY part if (!strnicmp (wp, "Brazilian", 9)) { wp += 9; entry->country |= DB_COUNTRY_BR; } else if (!strnicmp (wp, "English", 7)) { wp += 7; entry->country |= DB_COUNTRY_EU | DB_COUNTRY_US; } else if (!strnicmp (wp, "European", 8)) { wp += 8; entry->country |= DB_COUNTRY_EU; } else if (!strnicmp (wp, "Export", 6)) { wp += 6; entry->country |= DB_COUNTRY_EU | DB_COUNTRY_US; } else if (!strnicmp (wp, "French", 6)) { wp += 6; entry->country |= DB_COUNTRY_FR; } else if (!strnicmp (wp, "Hong-Kong", 9)) { wp += 9; entry->country |= DB_COUNTRY_HK; } else if (!strnicmp (wp, "International", 13)) { wp += 13; } else if (!strnicmp (wp, "Japanese", 8)) { wp += 8; entry->country |= DB_COUNTRY_JP; } else if (!strnicmp (wp, "Korean", 6)) { wp += 6; entry->country |= DB_COUNTRY_KR; } else if (!strnicmp (wp, "USA", 3)) { wp += 3; entry->country |= DB_COUNTRY_US; } // else // printf("Unknown country in version!"); // If there's anything left after known countries, it goes to VERSION if (*wp != EOSTR) { parse_skip_spaces (&wp); entry->version = strdup (wp); // printf("--> NEW VERSION = '%s'\n", entry->version); } } else if (!strcmp(w, "BAD")) entry->flags |= DB_FLAG_BAD; else if (!strcmp(w, "HACK")) entry->flags |= DB_FLAG_HACK; else if (!strcmp(w, "BIOS")) entry->flags |= DB_FLAG_BIOS; else if (!strcmp(w, "PROTO")) entry->flags |= DB_FLAG_PROTO; else if (!strcmp(w, "3D")) entry->flags |= DB_FLAG_EMU_3D; else if (!strcmp(w, "FLICKER")) entry->flags |= DB_FLAG_EMU_SPRITE_FLICKER; else if (!strcmp(w, "COMMENT")) { if (!(w = parse_getword(NULL, 0, &line, ",", ';'))) return (0); entry->comments = w; } else if (!strcmp(w, "ID")) { if (!(w = parse_getword(NULL, 0, &line, ",", ';'))) return (0); entry->product_no = w; } else if (!strcmp(w, "MAPPER")) { if (!(w = parse_getword(buf, 1024, &line, ",", ';'))) return (0); entry->emu_mapper = atoi(w); } else if (!strcmp(w, "TRANS")) { int value; if (!(w = parse_getword(buf, 1024, &line, ",", ';'))) return (0); // In TRANS field only, 'EN' can be specified. It currently gets the UK flag. if (!strcmp(w, "EN")) value = DB_COUNTRY_UK; else if ((value = DB_FindCountryFlagByName(w)) == -1) return (0); entry->trans_country = value; entry->flags |= DB_FLAG_TRANS; } else if (!strcmp(w, "TVTYPE")) { if (!(w = parse_getword(buf, 1024, &line, ",", ';'))) return (0); StrLower(w); if (!strcmp(w, "pal") || !strcmp(w, "secam") || !strcmp(w, "pal/secam")) entry->emu_tvtype = TVTYPE_PAL_SECAM; else if (!strcmp(w, "ntsc")) entry->emu_tvtype = TVTYPE_NTSC; else return (0); } else if (!strcmp(w, "AUTHORS")) { if (!(w = parse_getword(NULL, 0, &line, ",", ';'))) return (0); entry->authors = w; } else if (!strcmp(w, "DATE")) { if (!(w = parse_getword(buf, 1024, &line, ",", ';'))) return (0); // FIXME: yet ignored } else return (0); // Unknown field } // Ok return (1); }
//----------------------------------------------------------------------------- // DB_Load_Entry (char *line) // Load DB entry from given line //----------------------------------------------------------------------------- static int DB_Load_Entry (char *line) { t_db_entry *entry; int value; u32 crc_crc32; t_meka_crc crc_mekacrc; char * w; char buf[1024+1]; // Get system // FIXME: linear research with strcmp. Could be int compared, or even hashed. parse_getword(buf, 4, &line, " \t", ';'); value = DB_FindDriverIdByName(buf); if (value == -1) return (1); // Silent return if there's anything else than a system parse_skip_spaces (&line); // printf("line: %s\n", line); // Get CRC32 & MekaCRC if (sscanf (line, "%08x %08X%08X", &crc_crc32, &crc_mekacrc.v[0], &crc_mekacrc.v[1]) != 3) return (0); line += 8 + 1 + 16; parse_skip_spaces (&line); // Create and add entry to global list entry = DB_Entry_New (value, crc_crc32, &crc_mekacrc); // value hold system list_add (&DB.entries, entry); DB.entries_counter_format_new++; // Get and add default name if (!(w = parse_getword(NULL, 0, &line, "/", ';'))) return (0); DB_Name_New (entry, w, 0, FALSE); // Parse optional parameters while ((w = parse_getword(buf, 1024, &line, "=/", ';')) != NULL) { StrUpper(w); // printf ("field '%s'\n", w); if (!strncmp (w, "NAME_", 5)) { w += 5; if ((value = DB_FindCountryFlagByName(w)) == -1) return (0); if (!(w = parse_getword(NULL, 0, &line, "/", ';'))) break; DB_Name_New (entry, w, value, FALSE); // printf("adding country %d name %s", value, w); } else if (!strcmp(w, "COUNTRY")) { while (line[-1] == ',' || line[-1] == '=') { if (!(w = parse_getword(buf, 3, &line, ",/", ';'))) return (0); if ((value = DB_FindCountryFlagByName(w)) == -1) return (0); entry->country |= value; } } else if (!strcmp(w, "PRODUCT_NO")) { if (!(w = parse_getword(NULL, 0, &line, "/", ';'))) return (0); entry->product_no = w; } else if (!strcmp(w, "EMU_COUNTRY")) { if (!(w = parse_getword(buf, 1024, &line, ",/", ';'))) return (0); entry->emu_country = atoi(w); } else if (!strcmp(w, "EMU_INPUTS")) { if (!(w = parse_getword(buf, 1024, &line, "/", ';'))) return (0); StrLower(w); if (!strcmp(w, "joypad")) entry->emu_inputs = INPUT_JOYPAD; else if (!strcmp(w, "lightphaser")) entry->emu_inputs = INPUT_LIGHTPHASER; else if (!strcmp(w, "paddle")) entry->emu_inputs = INPUT_PADDLECONTROL; else if (!strcmp(w, "sportspad")) entry->emu_inputs = INPUT_SPORTSPAD; else if (!strcmp(w, "tvoekaki")) entry->emu_inputs = INPUT_GRAPHICBOARD; else if (!strcmp(w, "graphicboardv2")) entry->emu_inputs = INPUT_GRAPHICBOARD_V2; else return (0); } else if (!strcmp(w, "EMU_IPERIOD")) { if (!(w = parse_getword(buf, 1024, &line, "/", ';'))) return (0); entry->emu_iperiod = atoi(w); } else if (!strcmp(w, "EMU_MAPPER")) { if (!(w = parse_getword(buf, 1024, &line, "/", ';'))) return (0); entry->emu_mapper = atoi(w); } else if (!strcmp(w, "EMU_VDP")) { if (!(w = parse_getword(buf, 1024, &line, "/", ';'))) return (0); if ((entry->emu_vdp_model = VDP_Model_FindByName(w)) == -1) return (0); } else if (!strcmp(w, "EMU_TVTYPE")) { if (!(w = parse_getword(buf, 1024, &line, "/", ';'))) return (0); StrLower(w); if (!strcmp(w, "pal")) entry->emu_tvtype = TVTYPE_PAL_SECAM; else if (!strcmp(w, "ntsc")) entry->emu_tvtype = TVTYPE_NTSC; else return (0); } else if (!strcmp(w, "EMU_3D")) entry->flags |= DB_FLAG_EMU_3D; else if (!strcmp(w, "EMU_SPRITE_FLICKER")) entry->flags |= DB_FLAG_EMU_SPRITE_FLICKER; else if (!strcmp(w, "COMMENT")) { if (!(w = parse_getword(NULL, 0, &line, "/", ';'))) return (0); entry->comments = w; } else if (!strcmp(w, "FLAGS")) { while (line[-1] == ',' || line[-1] == '=') { if (!(w = parse_getword(buf, 16, &line, ",/", ';'))) return (0); if (!strcmp(w, "BAD")) entry->flags |= DB_FLAG_BAD; else if (!strcmp(w, "BIOS")) entry->flags |= DB_FLAG_BIOS; else if (!strcmp(w, "SMSGG_MODE")) entry->flags |= DB_FLAG_SMSGG_MODE; else if (!strcmp(w, "HACK")) entry->flags |= DB_FLAG_HACK; else if (!strcmp(w, "TRANS")) entry->flags |= DB_FLAG_TRANS; else if (!strcmp(w, "PROTO")) entry->flags |= DB_FLAG_PROTO; else if (!strcmp(w, "HOMEBREW")) entry->flags |= DB_FLAG_HOMEBREW; else return (0); } } else if (!strcmp(w, "TRANS")) { if (!(w = parse_getword(buf, 1024, &line, "/", ';'))) return (0); // In TRANS field only, 'EN' can be specified. It currently gets the UK flag. if (!strcmp(w, "EN")) value = DB_COUNTRY_UK; else if ((value = DB_FindCountryFlagByName(w)) == -1) return (0); entry->trans_country = value; } else if (!strcmp(w, "AUTHORS")) { if (!(w = parse_getword(NULL, 0, &line, "/", ';'))) return (0); entry->authors = w; } else if (!strcmp(w, "VERSION")) { if (!(w = parse_getword(NULL, 0, &line, "/", ';'))) return (0); entry->version = w; } else { // No error for empty fields (",,") // This is mainly to handle end of line comments ("FIELD=heh ; comment") if (strlen(w) > 0) return (0); } } // Ok return (1); }
/** * @brief ggs_parse_move * * Translate input word into time (as ms). * * @param time Time. * @param word Word. * @return true if parsing succeed. */ static bool ggs_parse_time(int *time, const char *word) { errno = 0; *time = string_to_time(parse_skip_spaces(word)); return errno == 0; }
/** * @brief ggs_parse_move * * Translate input word into a move. * * @param move Move. * @param word Word. * @return true if parsing succeed. */ static bool ggs_parse_move(int *move, const char *word) { *move = string_to_coordinate(parse_skip_spaces(word)); return *move != NOMOVE; }
/** * @brief Loop event. * @param ui user interface. */ void ui_loop_edax(UI *ui) { char *cmd = NULL, *param = NULL; Play *play = ui->play; char book_file[FILENAME_MAX]; unsigned long long histogram[129][65]; int repeat = options.repeat; histogram_init(histogram); // loop forever for (;;) { errno = 0; if (options.verbosity) { putchar('\n'); play_print(play, stdout); if (play_is_game_over(play)) printf("\n*** Game Over ***\n"); putchar('\n'); } if (log_is_open(edax_log)) { putc('\n', edax_log->f); play_print(play, edax_log->f); if (play_is_game_over(play)) fputs("\n*** Game Over ***\n", edax_log->f); putc('\n', edax_log->f); } // edax turn ? (automatic play mode) if (!ui_event_exist(ui) && !play_is_game_over(play) && (ui->mode == !play->player || ui->mode == 2)) { putchar('\n'); play_go(play, true); printf("\nEdax plays "); move_print(play_get_last_move(play)->x, 0, stdout); putchar('\n'); if (ui->mode != 2) play_ponder(play); // proceed by reading a command } else { /* automatic rules after a game over*/ if (play_is_game_over(play)) { if (options.auto_store) play_store(play); if (options.auto_swap && ui->mode < 2) ui->mode = !ui->mode; if (options.repeat && repeat > 1) { --repeat; play_new(play); continue; } if (options.auto_quit) { return; } if (options.auto_start) { play_new(play); continue; } } putchar('>'); fflush(stdout); ui_event_wait(ui, &cmd, ¶m); log_print(edax_log, "cmd=\"%s\" ; param=\"%s\"\n", cmd, param); putchar('\n'); if (cmd == NULL) { warn("unexpected null command?\n"); continue; } // skip empty lines or commented lines if (*cmd == '\0' || *cmd == '#') { // help } else if (strcmp(cmd, "help") == 0 || strcmp(cmd, "?") == 0) { if (*param == '\0' || strcmp(param, "options") == 0) help_options(); if (*param == '\0' || strcmp(param, "commands") == 0) help_commands(); if (*param == '\0' || strcmp(param, "book") == 0) help_book(); if (*param == '\0' || strcmp(param, "base") == 0) help_base(); if (*param == '\0' || strcmp(param, "test") == 0) help_test(); // new game from standard position } else if (strcmp(cmd, "i") == 0 || strcmp(cmd, "init") == 0) { board_init(play->initial_board); play_new(play); // new game from personnalized position } else if ((strcmp(cmd, "n") == 0 || strcmp(cmd, "new") == 0) && *param == '\0') { play_new(play); // open a saved game } else if (strcmp(cmd, "o") == 0 || strcmp(cmd, "open") == 0 || strcmp(cmd, "load") == 0) { play_load(play, param); // save a game } else if (strcmp(cmd, "s") == 0 || strcmp(cmd, "save") == 0) { play_save(play, param); // quit } else if (strcmp(cmd, "quit") == 0 || strcmp(cmd, "q") == 0 || strcmp(cmd, "exit") == 0) { free(cmd); free(param); return; } else if (!options.auto_quit && (strcmp(cmd, "eof") == 0 && (ui->mode != 2 || play_is_game_over(play)))){ free(cmd); free(param); return; // undo last move } else if (strcmp(cmd, "u") == 0 || strcmp(cmd, "undo") == 0) { play_undo(play); if (ui->mode == 0 || ui->mode == 1) play_undo(play); // redo last move } else if (strcmp(cmd, "r") == 0 || strcmp(cmd, "redo") == 0) { play_redo(play); if (ui->mode == 0 || ui->mode == 1) play_undo(play); // mode } else if (strcmp(cmd, "m") == 0 || strcmp(cmd, "mode") == 0) { ui->mode = string_to_int(param, 3); // analyze a game } else if (strcmp(cmd, "a") == 0 || strcmp(cmd, "analyze") == 0 || strcmp(cmd, "analyse") == 0) { play_analyze(play, string_to_int(param, play->n_game)); // set a new initial position } else if (strcmp(cmd, "setboard") == 0) { play_set_board(play, param); // vertical mirror } else if (strcmp(cmd, "vmirror") == 0) { play_symetry(play, 2); // horizontal mirror } else if (strcmp(cmd, "hmirror") == 0) { play_symetry(play, 1); // rotate } else if (strcmp(cmd, "rotate") == 0) { int angle = string_to_int(param, 90) % 360; if (angle < 0) angle += 360; switch (angle) { case 90: play_symetry(play, 5); break; case 180: play_symetry(play, 3); break; case 270: play_symetry(play, 6); break; default: warn("Rotate angle should be 90°, 180° or 270°"); break; } // direct symetry... } else if (strcmp(cmd, "symetry") == 0) { int sym = string_to_int(param, 1); if (sym < 0 || sym >= 16) warn("symetry parameter should be a number between 0 and 15\n"); else { if (sym & 8) play->player ^= 1; play_symetry(play, sym & 7); } // play a serie of moves } else if (strcmp(cmd, "play") == 0) { string_to_lowercase(param); play_game(play, param); // force edax to play an opening } else if (strcmp(cmd, "force") == 0) { string_to_lowercase(param); play_force_init(play, param); // solve a set of problems } else if (strcmp(cmd, "solve") == 0) { char problem_file[FILENAME_MAX + 1], *hard_file; hard_file = parse_word(param, problem_file, FILENAME_MAX); parse_word(hard_file, hard_file, FILENAME_MAX); obf_test(play->search, problem_file, hard_file); search_set_observer(play->search, edax_observer); // convert a set of problems in a .script file to a .obf file } else if (strcmp(cmd, "script-to-obf") == 0) { char script_file[FILENAME_MAX + 1], *obf_file; obf_file = parse_word(param, script_file, FILENAME_MAX); parse_word(obf_file, obf_file, FILENAME_MAX); script_to_obf(play->search, script_file, obf_file); search_set_observer(play->search, edax_observer); } else if (strcmp(cmd, "select-hard") == 0) { char full_file[FILENAME_MAX + 1], *hard_file; hard_file = parse_word(param, full_file, FILENAME_MAX); parse_word(hard_file, hard_file, FILENAME_MAX); obf_filter(full_file, hard_file); // game/position enumeration } else if (strcmp(cmd, "count") == 0) { char count_cmd[16], *count_param; int depth = 10, size = 8; count_param = parse_word(param, count_cmd, 15); count_param = parse_int(count_param, &depth); BOUND(depth, 1, 90, "max-ply"); if (count_param) parse_int(count_param, &size); BOUND(size, 6, 8, "board-size"); if (strcmp(count_cmd, "games") == 0) { // game enumeration quick_count_games(play->board, depth, size); } else if (strcmp(count_cmd, "positions") == 0) { // position enumeration count_positions(play->board, depth, size); } else if (strcmp(count_cmd, "shapes") == 0) { // shape enumeration count_shapes(play->board, depth, size); } else { warn("Unknown count command: \"%s %s\"\n", cmd, param); } } else if (strcmp(cmd, "perft") == 0) { int depth = 14; depth = string_to_int(param, 10); BOUND(depth, 1, 90, "max-ply"); count_games(play->board, depth); // game/position enumeration } else if (strcmp(cmd, "estimate") == 0) { int n = 1000; n = string_to_int(param, 10); BOUND(n, 1, 2000000000, "max-trials"); estimate_games(play->board, n); // seek highest mobility } else if (strcmp(cmd, "mobility") == 0) { int t = 3600; // 1 hour t = string_to_int(param, 10); BOUND(t, 1, 3600*24*365*10, "max time"); seek_highest_mobility(play->board, t); // seek a position } else if (strcmp(cmd, "seek") == 0) { Board target; Line solution; board_set(&target, param); line_init(&solution, play->player); if (seek_position(&target, play->board, &solution)) { printf("Solution found:\n"); line_print(&solution, 200, " ", stdout); putchar('\n'); } // bench (a serie of low level tests). } else if (strcmp(cmd, "bench") == 0) { bench(); // wtest test the engine against wthor theoretical scores } else if (strcmp(cmd, "wtest") == 0) { wthor_test(param, play->search); // make wthor games played by "Edax (Delorme)" as "Etudes" tournament. } else if (strcmp(cmd, "edaxify") == 0) { wthor_edaxify(param); // wtest test the engine against wthor theoretical scores } else if (strcmp(cmd, "weval") == 0) { wthor_eval(param, play->search, histogram); histogram_print(histogram); histogram_stats(histogram); histogram_to_ppm("weval.ppm", histogram); // go think! } else if (strcmp(cmd, "go") == 0) { if (play_is_game_over(play)) printf("\n*** Game Over ***\n"); else { play_go(play, true); printf("\nEdax plays "); move_print(play_get_last_move(play)->x, 0, stdout); putchar('\n'); } // hint for [n] moves } else if (strcmp(cmd, "hint") == 0) { int n = string_to_int(param, 1); BOUND(n, 1, 60, "n_moves"); play_hint(play, n); // stop thinking } else if (strcmp(cmd, "stop") == 0) { ui->mode = 3; // user move } else if (play_user_move(play, cmd)) { printf("\nYou play "); move_print(play_get_last_move(play)->x, 0, stdout); putchar('\n'); // debug pv } else if (strcmp(cmd, "debug-pv") == 0) { Move move[1]; if (parse_move(param, play->board, move) != param) { search_set_board(play->search, play->board, play->player); pv_debug(play->search, move, stdout); } } else if (strcmp(cmd, "options") == 0) { options_dump(stdout); #ifdef __unix__ } else if (strcmp(cmd, "resources") == 0) { struct rusage u; long long t; getrusage(RUSAGE_SELF, &u); t = 1000 * u.ru_utime.tv_sec + u.ru_utime.tv_usec / 1000; printf("user cpu time: "); time_print(t, false, stdout); printf("\n"); t = 1000 * u.ru_stime.tv_sec + u.ru_stime.tv_usec / 1000; printf("system cpu time: "); time_print(t, false, stdout); printf("\n"); printf("max resident memory: %ld\n", u.ru_maxrss); printf("page fault without I/O: %ld\n", u.ru_minflt); printf("page fault with I/O: %ld\n", u.ru_majflt); printf("number of input: %ld\n", u.ru_inblock); printf("number of output: %ld\n", u.ru_oublock); printf("number of voluntary context switch: %ld\n", u.ru_nvcsw); printf("number of unvoluntary context switch: %ld\n\n", u.ru_nivcsw); #endif // opening name } else if (strcmp(cmd, "opening") == 0) { const char *name; name = play_show_opening_name(play, opening_get_english_name); if (name == NULL) name = "?"; puts(name); // opening name in french } else if (strcmp(cmd, "ouverture") == 0) { const char *name; name = play_show_opening_name(play, opening_get_french_name); if (name == NULL) name = "?"; puts(name); // opening book commands } else if (strcmp(cmd, "book") == 0 || strcmp(cmd, "b") == 0) { char book_cmd[FILENAME_MAX + 1], *book_param; int val_1, val_2; Book *book = play->book; book->search = play->search; book->search->options.verbosity = book->options.verbosity; book_param = parse_word(param, book_cmd, FILENAME_MAX); // store the last played game if (strcmp(book_cmd, "store") == 0) { play_store(play); // turn book usage on } else if (strcmp(book_cmd, "on") == 0) { // learn options.book_allowed = true; // turn book usage off } else if (strcmp(book_cmd, "off") == 0) { // learn options.book_allowed = false; // set book randomness } else if (strcmp(book_cmd, "randomness") == 0) { // learn val_1 = 0; book_param = parse_int(book_param, &val_1); options.book_randomness = val_1; // set book depth (until which to learn) } else if (strcmp(book_cmd, "depth") == 0) { // learn val_1 = 36; book_param = parse_int(book_param, &val_1); book->options.n_empties = 61 - val_1; // create a new empty book } else if (strcmp(book_cmd, "new") == 0) { val_1 = 21; book_param = parse_int(book_param, &val_1); val_2 = 36; book_param = parse_int(book_param, &val_2); book_free(book) ; book_new(book, val_1, 61 - val_2); // load an opening book (binary format) from the disc } else if (strcmp(book_cmd, "load") == 0 || strcmp(book_cmd, "open") == 0) { book_free(book) ; parse_word(book_param, book_file, FILENAME_MAX); book_load(book, book_file); // save an opening book (binary format) to the disc } else if (strcmp(book_cmd, "save") == 0) { parse_word(book_param, book_file, FILENAME_MAX); book_save(book, book_file); // import an opening book (text format) } else if (strcmp(book_cmd, "import") == 0) { book_free(book); parse_word(book_param, book_file, FILENAME_MAX); book_import(book, book_file); book_link(book); book_fix(book); book_negamax(book); book_sort(book); // export an opening book (text format) } else if (strcmp(book_cmd, "export") == 0) { parse_word(book_param, book_file, FILENAME_MAX); book_export(book, book_file); // merge an opening book to the current one } else if (strcmp(book_cmd, "merge") == 0) { Book src[1]; parse_word(book_param, book_file, FILENAME_MAX); src->search = play->search; book_load(src, book_file); book_merge(book, src); book_free(src); warn("Book needs to be fixed before usage\n"); // fix an opening book } else if (strcmp(book_cmd, "fix") == 0) { book_fix(book); // do nothing (or edax is buggy) book_link(book); // links nodes book_negamax(book); // negamax nodes book_sort(book); // sort moves // negamax an opening book } else if (strcmp(book_cmd, "negamax") == 0) { book_negamax(book); // negamax nodes book_sort(book); // sort moves // check and correct solved positions of the book } else if (strcmp(book_cmd, "correct") == 0) { book_correct_solved(book); // do nothing (or edax is buggy) book_fix(book); // do nothing (or edax is buggy) book_link(book); // links nodes book_negamax(book); // negamax nodes book_sort(book); // sort moves // prune an opening book } else if (strcmp(book_cmd, "prune") == 0) { book_prune(book); // remove unreachable lines. book_fix(book); // do nothing (or edax is buggy) book_link(book); // links nodes book_negamax(book); // negamax nodes book_sort(book); // sort moves // show the current position as stored in the book } else if (strcmp(book_cmd, "show") == 0) { book_show(book, play->board); // show book general information } else if (strcmp(book_cmd, "info") == 0) { book_info(book); // show book general information } else if (strcmp(book_cmd, "stats") == 0) { book_stats(book); // set book verbosity } else if (strcmp(book_cmd, "verbose") == 0) { parse_int(book_param, &book->options.verbosity); book->search->options.verbosity = book->options.verbosity; // analyze a game from the opening book point of view } else if (strcmp(book_cmd, "a") == 0 || strcmp(book_cmd, "analyze") == 0 || strcmp(book_cmd, "analyse") == 0) { val_1 = string_to_int(book_param, play->n_game); BOUND(val_1, 1, play->n_game, "depth"); play_book_analyze(play, val_1); // add positions from a game database } else if (strcmp(book_cmd, "add") == 0) { Base base[1]; parse_word(book_param, book_file, FILENAME_MAX); base_init(base); base_load(base, book_file); book_add_base(book, base); base_free(base); // check positions from a game database } else if (strcmp(book_cmd, "check") == 0) { Base base[1]; parse_word(book_param, book_file, FILENAME_MAX); base_init(base); base_load(base, book_file); book_check_base(book, base); base_free(base); // extract positions } else if (strcmp(book_cmd, "problem") == 0) { val_1 = 24; book_param = parse_int(book_param, &val_1); BOUND(val_1, 0, 60, "number of empties"); val_2 = 10; book_param = parse_int(book_param, &val_2); BOUND(val_2, 1, 1000000, "number of positions"); book_extract_positions(book, val_1, val_2); // extract pv to a game database } else if (strcmp(book_cmd, "extract") == 0) { Base base[1]; parse_word(book_param, book_file, FILENAME_MAX); base_init(base); book_extract_skeleton(book, base); base_save(base, book_file); base_free(base); // add position using the "deviate algorithm" } else if (strcmp(book_cmd, "deviate") == 0) { val_1 = 2; book_param = parse_int(book_param, &val_1); BOUND(val_1, -129, 129, "relative error"); val_2 = 4; book_param = parse_int(book_param, &val_2); BOUND(val_2, 0, 65, "absolute error"); book_deviate(book, play->board, val_1, val_2); // add position using the "enhance algorithm" } else if (strcmp(book_cmd, "enhance") == 0) { val_1 = 2; book_param = parse_int(book_param, &val_1); BOUND(val_1, 0, 129, "midgame error"); val_2 = 4; book_param = parse_int(book_param, &val_2); BOUND(val_2, 0, 129, "endcut error"); book_enhance(book, play->board, val_1, val_2); // add position by filling hole in the book } else if (strcmp(book_cmd, "fill") == 0) { val_1 = 1; book_param = parse_int(book_param, &val_1); BOUND(val_1, 1, 61, "fill depth"); book_fill(book, val_1); // add positions by expanding positions with no-link } else if (strcmp(book_cmd, "play") == 0) { book_play(book); // add positions by expanding positions with no-link } else if (strcmp(book_cmd, "deepen") == 0) { book_deepen(book); // add book positions to the hash table } else if (strcmp(book_cmd, "feed-hash") == 0) { book_feed_hash(book, play->board, play->search); // wrong command ? } else { warn("Unknown book command: \"%s %s\"\n", cmd, param); } book->options.verbosity = book->search->options.verbosity; book->search->options.verbosity = options.verbosity; /* base TODO: add more actions... */ } else if (strcmp(cmd, "base") == 0) { char base_file[FILENAME_MAX + 1]; char base_cmd[512], *base_param; Base base[1]; base_init(base); base_param = parse_word(param, base_cmd, 511); base_param = parse_word(base_param, base_file, FILENAME_MAX); // extract problem from a game base if (strcmp(base_cmd, "problem") == 0) { char problem_file[FILENAME_MAX + 1]; int n_empties = 24; base_param = parse_int(base_param, &n_empties); base_param = parse_word(base_param, problem_file, FILENAME_MAX); base_load(base, base_file); base_to_problem(base, n_empties, problem_file); // extract FEN } else if (strcmp(base_cmd, "tofen") == 0) { char problem_file[FILENAME_MAX + 1]; int n_empties = 24; base_param = parse_int(base_param, &n_empties); base_param = parse_word(base_param, problem_file, FILENAME_MAX); base_load(base, base_file); base_to_FEN(base, n_empties, problem_file); // correct erroneous games } else if (strcmp(base_cmd, "correct") == 0) { int n_empties = 24; base_param = parse_int(base_param, &n_empties); base_load(base, base_file); base_analyze(base, play->search, n_empties, true); remove(base_file); base_save(base, base_file); // check erroneous games } else if (strcmp(base_cmd, "check") == 0) { int n_empties = 24; base_param = parse_int(base_param, &n_empties); base_load(base, base_file); base_analyze(base, play->search, n_empties, false); // terminate unfinished base } else if (strcmp(base_cmd, "complete") == 0) { base_load(base, base_file); base_complete(base, play->search); remove(base_file); base_save(base, base_file); // convert a base to another format } else if (strcmp(base_cmd, "convert") == 0) { base_load(base, base_file); base_param = parse_word(base_param, base_file, FILENAME_MAX); base_save(base, base_file); // make a base unique by removing identical games } else if (strcmp(base_cmd, "unique") == 0) { base_load(base, base_file); base_param = parse_word(base_param, base_file, FILENAME_MAX); base_unique(base); base_save(base, base_file); // compare two game bases } else if (strcmp(base_cmd, "compare") == 0) { char base_file_2[FILENAME_MAX + 1]; base_param = parse_word(base_param, base_file_2, FILENAME_MAX); base_compare(base_file, base_file_2); } else { warn("Unknown base command: \"%s %s\"\n", cmd, param); } base_free(base); /* edax options */ } else if (options_read(cmd, param)) { options_bound(); // parallel search changes: if (search_count_tasks(play->search) != options.n_task) { play_stop_pondering(play); search_set_task_number(play->search, options.n_task); } /* switch to another protocol */ } else if (strcmp(cmd, "nboard") == 0 && strcmp(param, "1") == 0) { free(cmd); free(param); play_stop_pondering(play); ui->free(ui); ui_switch(ui, "nboard"); ui->init(ui); ui->loop(ui); return; } else if (strcmp(cmd, "xboard") == 0) { free(cmd); free(param); play_stop_pondering(play); ui->free(ui); ui_switch(ui, "xboard"); ui->init(ui); ui->loop(ui); return; } else if (strcmp(cmd, "engine-protocol") == 0 && strcmp(param, "init") == 0) { free(cmd); free(param); play_stop_pondering(play); ui->free(ui); ui_switch(ui, "cassio"); engine_loop(); return; } else if (strcmp(cmd, "protocol_version") == 0) { free(cmd); free(param); play_stop_pondering(play); ui->free(ui); ui_switch(ui, "gtp"); ui->init(ui); puts("= 2\n"); fflush(stdout); ui->loop(ui); return; #ifdef TUNE_EDAX /* edax tuning */ } else if (strcmp(cmd, "tune") == 0) { char problem[FILENAME_MAX]; char *w_name; play_stop_pondering(play); w_name = parse_word(param, problem, FILENAME_MAX); tune_move_evaluate(play->search, problem, parse_skip_spaces(w_name)); search_set_observer(play->search, edax_observer); #endif /* illegal cmd/move */ } else { warn("Unknown command/Illegal move: \"%s %s\"\n", cmd, param); } } } }
static ya_result config_section_loggers_set_wild(struct config_section_descriptor_s *csd, const char *key, const char *value) { u32 debuglevel = 0; ya_result return_code; // next word(base,delimiter) // bool end_of_level = FALSE; do { char level[16]; value = parse_skip_spaces(value); if(*value == '\0') { break; } if(FAIL(return_code = parse_next_token(level, sizeof(level), value, SYSLOG_LEVEL_TOKEN_DELIMITER))) { return return_code; } // if the token has spaces between two chars, then we need to cut char *end_of_first_word = (char*)parse_next_blank(level); // level is not const if(*end_of_first_word != '\0') { char *start_of_next_word = (char*)parse_skip_spaces(end_of_first_word); // end_of_first_word is not const if(start_of_next_word != end_of_first_word) { // last loop iteration end_of_level = TRUE; } *end_of_first_word = '\0'; // adjust next word search start value += end_of_first_word - level + 1; } else { value += return_code + 1; // note: false positive from cppcheck } // u32 debuglevel_value; if(FAIL(get_value_from_casename(logger_debuglevels, level, &debuglevel_value))) { return CONFIG_LOGGER_INVALID_DEBUGLEVEL; } debuglevel |= debuglevel_value; } while(!end_of_level); for(;;) { char channel_name[64]; value = parse_skip_spaces(value); if(*value == '\0') { break; } if(FAIL(return_code = parse_next_token(channel_name, sizeof(channel_name), value, SYSLOG_CHANNEL_TOKEN_DELIMITER))) { return return_code; } if(*channel_name == '\0') { continue; } logger_handle_add_channel(key, (int)debuglevel, channel_name); value += return_code; if(*value == '\0') { break; } value++; } return SUCCESS; }
static int Load_Inputs_Src_Parse_Var (int VarIdx, char *s, t_input_src *input_src) { char w[256]; if (!parse_getword(w, sizeof(w), &s, " \t", ';', PARSE_FLAGS_NONE)) return MEKA_ERR_EMPTY; switch (VarIdx) { case 0: // type ----------------------------------------------------------- if (!strcmp(w, "keyboard")) { input_src->type = INPUT_SRC_TYPE_KEYBOARD; input_src->flags = INPUT_SRC_FLAGS_DIGITAL; input_src->Connected_and_Ready = TRUE; return MEKA_ERR_OK; } if (!strcmp(w, "joypad")) { input_src->type = INPUT_SRC_TYPE_JOYPAD; input_src->flags = INPUT_SRC_FLAGS_DIGITAL; input_src->Connected_and_Ready = FALSE; return MEKA_ERR_OK; } if (!strcmp(w, "mouse")) { input_src->type = INPUT_SRC_TYPE_MOUSE; input_src->flags = INPUT_SRC_FLAGS_ANALOG; input_src->Connected_and_Ready = (g_Env.mouse_installed ? TRUE : FALSE); return MEKA_ERR_OK; } return MEKA_ERR_SYNTAX; case 1: // enabled -------------------------------------------------------- if (!strcmp(w, "yes")) { input_src->enabled = TRUE; return MEKA_ERR_OK; } if (!strcmp(w, "no")) { input_src->enabled = FALSE; return MEKA_ERR_OK; } return MEKA_ERR_SYNTAX; case 2: // player --------------------------------------------------------- input_src->player = atoi(w) - 1; if (input_src->player != 0 && input_src->player != 1) return MEKA_ERR_SYNTAX; return MEKA_ERR_OK; case 3: // driver --------------------------------------------------------- if (input_src->type == INPUT_SRC_TYPE_JOYPAD) input_src->Driver = Config_Driver_Joy_Str_to_Int(w); return MEKA_ERR_OK; case 4: // connection ----------------------------------------------------- input_src->Connection_Port = atoi(w); if (input_src->Connection_Port > 0) input_src->Connection_Port -= 1; return MEKA_ERR_OK; case 5: // emulate_digital ------------------------------------------------ if (!strcmp (w, "yes")) { input_src->flags |= INPUT_SRC_FLAGS_EMULATE_DIGITAL; return MEKA_ERR_OK; } if (!strcmp (w, "no")) { input_src->flags &= ~INPUT_SRC_FLAGS_EMULATE_DIGITAL; return MEKA_ERR_OK; } return MEKA_ERR_SYNTAX; case 6: // emulate_analog ------------------------------------------------- if (!strcmp (w, "yes")) { input_src->flags |= INPUT_SRC_FLAGS_EMULATE_ANALOG; return MEKA_ERR_OK; } if (!strcmp (w, "no")) { input_src->flags &= ~INPUT_SRC_FLAGS_EMULATE_ANALOG; return MEKA_ERR_OK; } return MEKA_ERR_SYNTAX; case 7: // digital_falloff ------------------------------------------------ input_src->Analog_to_Digital_FallOff = atof (w); return MEKA_ERR_OK; case 8: // player_up ------------------------------------------------------ case 9: // player_down ---------------------------------------------------- case 10: // player_left ---------------------------------------------------- case 11: // player_right --------------------------------------------------- case 12: // player_button1 ------------------------------------------------- case 13: // player_button2 ------------------------------------------------- case 14: // player_start_pause --------------------------------------------- case 15: // player_reset --------------------------------------------------- { int MapIdx = INPUT_MAP_DIGITAL_UP + VarIdx - 8; // FIXME: ??? //if (MapIdx >= INPUT_MAP_DIGITAL_UP && MapIdx <= INPUT_MAP_DOWN && !(input_src->Result_Type & DIGITAL)) // return MEKA_ERR_INCOHERENT; if (!strcmp (w, "key")) { const t_key_info *key_info; if (input_src->type != INPUT_SRC_TYPE_KEYBOARD) return MEKA_ERR_INCOHERENT; //if (!Parse_LineGet (&w, &s)) // return MEKA_ERR_SYNTAX; parse_skip_spaces(&s); if (StrNull (s)) return MEKA_ERR_SYNTAX; key_info = KeyInfo_FindByName(s); if (key_info != NULL) { input_src->Map [MapIdx].Type = INPUT_MAP_TYPE_KEY; input_src->Map [MapIdx].Idx = key_info->scancode; } return MEKA_ERR_OK; } if (!strcmp (w, "joy")) { int stick, axis, dir; if (input_src->type != INPUT_SRC_TYPE_JOYPAD) return MEKA_ERR_INCOHERENT; if (!parse_getword(w, sizeof(w), &s, " \t", ';', PARSE_FLAGS_NONE) || strcmp(w, "stick") || !parse_getword(w, sizeof(w), &s, " \t", ';', PARSE_FLAGS_NONE)) return MEKA_ERR_SYNTAX; stick = atoi(w); if (!parse_getword(w, sizeof(w), &s, " \t", ';', PARSE_FLAGS_NONE) || strcmp(w, "axis") || !parse_getword(w, sizeof(w), &s, " \t", ';', PARSE_FLAGS_NONE)) return MEKA_ERR_SYNTAX; axis = atoi(w); if (!parse_getword(w, sizeof(w), &s, " \t", ';', PARSE_FLAGS_NONE) || strcmp(w, "dir") || !parse_getword(w, sizeof(w), &s, " \t", ';', PARSE_FLAGS_NONE)) return MEKA_ERR_SYNTAX; dir = atoi(w); input_src->Map [MapIdx].Type = INPUT_MAP_TYPE_JOY_AXIS; input_src->Map [MapIdx].Idx = MAKE_STICK_AXIS_DIR (stick, axis, dir); return MEKA_ERR_OK; } if (!strcmp (w, "joy_button")) { if (input_src->type != INPUT_SRC_TYPE_JOYPAD) return MEKA_ERR_INCOHERENT; if (!parse_getword(w, sizeof(w), &s, " \t", ';', PARSE_FLAGS_NONE)) return MEKA_ERR_SYNTAX; input_src->Map [MapIdx].Type = INPUT_MAP_TYPE_JOY_BUTTON; input_src->Map [MapIdx].Idx = atoi(w); return MEKA_ERR_OK; } if (!strcmp (w, "mouse_button")) { if (input_src->type != INPUT_SRC_TYPE_MOUSE) return MEKA_ERR_INCOHERENT; if (!parse_getword(w, sizeof(w), &s, " \t", ';', PARSE_FLAGS_NONE)) return MEKA_ERR_SYNTAX; input_src->Map [MapIdx].Type = INPUT_MAP_TYPE_MOUSE_BUTTON; input_src->Map [MapIdx].Idx = atoi(w); return MEKA_ERR_OK; } return MEKA_ERR_SYNTAX; } case 16: // player_x_axis -------------------------------------------------- case 17: // player_y_axis -------------------------------------------------- { int MapIdx = INPUT_MAP_ANALOG_AXIS_X + VarIdx - 16; if (!(input_src->flags & INPUT_SRC_FLAGS_ANALOG)) return MEKA_ERR_INCOHERENT; if (!strcmp (w, "mouse_axis")) { if (input_src->type != INPUT_SRC_TYPE_MOUSE) return MEKA_ERR_INCOHERENT; if (!parse_getword(w, sizeof(w), &s, " \t", ';', PARSE_FLAGS_NONE)) return MEKA_ERR_SYNTAX; input_src->Map [MapIdx].Type = input_src->Map [MapIdx + 2].Type = INPUT_MAP_TYPE_MOUSE_AXIS; input_src->Map [MapIdx].Idx = input_src->Map [MapIdx + 2].Idx = MAKE_AXIS(atoi(w)); return MEKA_ERR_OK; } return MEKA_ERR_SYNTAX; } case 18: // joy_driver ----------------------------------------------------- { Inputs.Sources_Joy_Driver = Config_Driver_Joy_Str_to_Int (w); return MEKA_ERR_OK; } case 19: // mouse_speed_x -------------------------------------------------- { Inputs.MouseSpeed_X = atoi (w); return MEKA_ERR_OK; } case 20: // mouse_speed_y -------------------------------------------------- { Inputs.MouseSpeed_Y = atoi (w); return MEKA_ERR_OK; } case 21: // cabinet_mode --------------------------------------------------- { Inputs.Cabinet_Mode = atoi (w); return MEKA_ERR_OK; } } return MEKA_ERR_SYNTAX; }
void Load_Inputs_Src_List (void) { int i; char w[256]; t_input_src * input_src = NULL; t_tfile * tf; t_list * lines; int line_cnt; // Open and read file ConsolePrint (Msg_Get (MSG_Inputs_Src_Loading)); tf = tfile_read (Inputs.FileName); if (tf == NULL) Quit_Msg (meka_strerror()); ConsolePrint ("\n"); // Parse each line line_cnt = 0; for (lines = tf->data_lines; lines; lines = lines->next) { char *line; line_cnt += 1; line = lines->elem; if (StrNull(line)) continue; if (line[0] == '[' && line[strlen(line) - 1] == ']') { input_src = Inputs_Sources_Add (StrNDup (line + 1, strlen(line) - 2)); // ConsolePrintf ("new source --> %s <--\n", CurSrc->Name); continue; } strlwr(line); if (!parse_getword(w, sizeof(w), &line, "=", ';', PARSE_FLAGS_NONE)) continue; for (i = 0; Inputs_Src_List_KeyWords[i]; i++) if (strcmp(w, Inputs_Src_List_KeyWords[i]) == 0) { // FIXME: this is ugly if (input_src == NULL && strcmp (w, "joy_driver") != 0 && strcmp (w, "mouse_speed_x") != 0 && strcmp (w, "mouse_speed_y") != 0 && strcmp (w, "cabinet_mode") != 0) { tfile_free(tf); Quit_Msg (Msg_Get (MSG_Inputs_Src_Missing), line_cnt); } parse_skip_spaces(&line); if (!parse_getword(w, sizeof(w), &line, "", ';', PARSE_FLAGS_NONE)) { tfile_free(tf); Quit_Msg (Msg_Get (MSG_Inputs_Src_Equal), line_cnt); } switch (Load_Inputs_Src_Parse_Var(i, w, input_src)) { case MEKA_ERR_SYNTAX: tfile_free(tf); Quit_Msg (Msg_Get (MSG_Inputs_Src_Syntax_Param), line_cnt); case MEKA_ERR_INCOHERENT : tfile_free(tf); Quit_Msg (Msg_Get (MSG_Inputs_Src_Inconsistency), line_cnt); break; // FIXME: EMPTY is not handled there } break; } if (!Inputs_Src_List_KeyWords [i]) { tfile_free(tf); Quit_Msg (Msg_Get (MSG_Inputs_Src_Unrecognized), line_cnt, w); } } // Free file data tfile_free(tf); // Verify that we have enough inputs sources if (Inputs.Sources_Max == 0) Quit_Msg (Msg_Get (MSG_Inputs_Src_Not_Enough)); }
static int Blitters_Parse_Line(char *s, char *s_case) { if (s[0] == '[') { Blitters.current = Blitter_New(&s_case[1]); if (Blitters.current != NULL) { Blitters.count++; list_add_to_end(&Blitters.list, Blitters.current); } return (MEKA_ERR_OK); } // Skip line when we're inside a blitter we can ignore if (Blitters.current == NULL) return (MEKA_ERR_OK); // Set attributes char w[256]; parse_getword(w, sizeof(w), &s, "=", ';', PARSE_FLAGS_NONE); int i; for (i = 0; Blitters_Def_Variables [i]; i++) if (!strcmp(w, Blitters_Def_Variables [i])) break; if (Blitters.current == NULL) return (MEKA_ERR_MISSING); switch (i) { // Resolution case 0: { int x, y; parse_skip_spaces(&s); if (sscanf(s, "%dx%d", &x, &y) == 2) { Blitters.current->res_x = x; Blitters.current->res_y = y; } return MEKA_ERR_OK; } // Blitter case 1: Blitters.current->blitter = Blitters_Str2Num (s); if (Blitters.current->blitter == BLITTER_TVMODE || Blitters.current->blitter == BLITTER_TVMODE_DOUBLE) Blitters.current->tv_colors = TRUE; else Blitters.current->tv_colors = FALSE; return MEKA_ERR_OK; case 2: if (!strcmp(w, "auto")) Blitters.current->refresh_rate = 0; else Blitters.current->refresh_rate = atoi(s); return MEKA_ERR_OK; // Stretch case 3: Blitters.current->stretch = BLITTER_STRETCH_MAX_INT; return MEKA_ERR_OK; } return MEKA_ERR_UNKNOWN; }