static void test_sabotage_other_fail(CuTest *tc) { unit *u, *u2; region *r; order *ord; message *msg; setup_sabotage(); r = test_create_region(0, 0, 0); assert(r); u = test_create_unit(test_create_faction(NULL), r); u2 = test_create_unit(test_create_faction(NULL), r); assert(u && u2); u2->ship = test_create_ship(r, test_create_shiptype("boat")); assert(u2->ship); u->ship = u2->ship; ship_update_owner(u->ship); assert(ship_owner(u->ship) == u); ord = create_order(K_SABOTAGE, u->faction->locale, "SCHIFF"); assert(ord); CuAssertIntEquals(tc, 0, sabotage_cmd(u2, ord)); msg = test_get_last_message(u2->faction->msgs); CuAssertStrEquals(tc, "destroy_ship_1", test_get_messagetype(msg)); msg = test_get_last_message(u->faction->msgs); CuAssertStrEquals(tc, "destroy_ship_3", test_get_messagetype(msg)); CuAssertPtrNotNull(tc, r->ships); free_order(ord); test_cleanup(); }
static void test_getunit(CuTest *tc) { unit *u, *u2; order *ord; attrib *a; struct region *r; struct locale *lang; struct terrain_type *t_plain; test_cleanup(); lang = get_or_create_locale("de"); test_translate_param(lang, P_TEMP, "TEMP"); /* note that the english order is FIGHT, not COMBAT, so this is a poor example */ t_plain = test_create_terrain("plain", LAND_REGION); u = test_create_unit(test_create_faction(0), test_create_region(0, 0, t_plain)); a = a_add(&u->attribs, a_new(&at_alias)); a->data.i = atoi36("42"); /* this unit is also TEMP 42 */ r = test_create_region(1, 0, t_plain); ord = create_order(K_GIVE, lang, itoa36(u->no)); init_order(ord); CuAssertIntEquals(tc, GET_UNIT, getunit(u->region, u->faction, &u2)); CuAssertPtrEquals(tc, u, u2); init_order(ord); CuAssertIntEquals(tc, GET_NOTFOUND, getunit(r, u->faction, &u2)); CuAssertPtrEquals(tc, NULL, u2); free_order(ord); ord = create_order(K_GIVE, lang, itoa36(u->no + 1)); init_order(ord); CuAssertIntEquals(tc, GET_NOTFOUND, getunit(u->region, u->faction, &u2)); CuAssertPtrEquals(tc, NULL, u2); free_order(ord); ord = create_order(K_GIVE, lang, "0"); init_order(ord); CuAssertIntEquals(tc, GET_PEASANTS, getunit(u->region, u->faction, &u2)); CuAssertPtrEquals(tc, NULL, u2); free_order(ord); ord = create_order(K_GIVE, lang, "TEMP 42"); init_order(ord); CuAssertIntEquals(tc, GET_UNIT, getunit(u->region, u->faction, &u2)); CuAssertPtrEquals(tc, u, u2); free_order(ord); test_cleanup(); }
static void test_tax_cmd(CuTest *tc) { order *ord; faction *f; region *r; unit *u; item_type *sword, *silver; request *taxorders = 0; test_cleanup(); config_set("taxing.perlevel", "20"); test_create_world(); f = test_create_faction(NULL); r = findregion(0, 0); assert(r && f); u = test_create_unit(f, r); ord = create_order(K_TAX, f->locale, ""); assert(ord); tax_cmd(u, ord, &taxorders); CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "error48")); test_clear_messages(u->faction); silver = get_resourcetype(R_SILVER)->itype; sword = it_get_or_create(rt_get_or_create("sword")); new_weapontype(sword, 0, 0.0, NULL, 0, 0, 0, SK_MELEE, 1); i_change(&u->items, sword, 1); set_level(u, SK_MELEE, 1); tax_cmd(u, ord, &taxorders); CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "error_no_tax_skill")); test_clear_messages(u->faction); set_level(u, SK_TAXING, 1); tax_cmd(u, ord, &taxorders); CuAssertPtrEquals(tc, 0, test_find_messagetype(u->faction->msgs, "error_no_tax_skill")); CuAssertPtrNotNull(tc, taxorders); rsetmoney(r, 11); expandtax(r, taxorders); CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "income")); /* taxing is in multiples of 10 */ CuAssertIntEquals(tc, 10, i_get(u->items, silver)); test_clear_messages(u->faction); i_change(&u->items, silver, -i_get(u->items, silver)); rsetmoney(r, 1000); taxorders = 0; tax_cmd(u, ord, &taxorders); expandtax(r, taxorders); CuAssertIntEquals(tc, 20, i_get(u->items, silver)); test_clear_messages(u->faction); free_order(ord); test_cleanup(); }
static void test_read_unitid(CuTest *tc) { unit *u; order *ord; attrib *a; struct locale *lang; struct terrain_type *t_plain; test_cleanup(); lang = get_or_create_locale("de"); test_translate_param(lang, P_TEMP, "TEMP"); /* note that the english order is FIGHT, not COMBAT, so this is a poor example */ t_plain = test_create_terrain("plain", LAND_REGION); u = test_create_unit(test_create_faction(0), test_create_region(0, 0, t_plain)); a = a_add(&u->attribs, a_new(&at_alias)); a->data.i = atoi36("42"); /* this unit is also TEMP 42 */ ord = create_order(K_GIVE, lang, "TEMP 42"); init_order(ord); CuAssertIntEquals(tc, u->no, read_unitid(u->faction, u->region)); free_order(ord); ord = create_order(K_GIVE, lang, "8"); init_order(ord); CuAssertIntEquals(tc, 8, read_unitid(u->faction, u->region)); free_order(ord); ord = create_order(K_GIVE, lang, ""); init_order(ord); CuAssertIntEquals(tc, -1, read_unitid(u->faction, u->region)); free_order(ord); ord = create_order(K_GIVE, lang, "TEMP"); init_order(ord); CuAssertIntEquals(tc, -1, read_unitid(u->faction, u->region)); free_order(ord); // bug https://bugs.eressea.de/view.php?id=1685 ord = create_order(K_GIVE, lang, "##"); init_order(ord); CuAssertIntEquals(tc, -1, read_unitid(u->faction, u->region)); free_order(ord); test_cleanup(); }
void create_ship(region * r, unit * u, const struct ship_type *newtype, int want, order * ord) { ship *sh; int msize; const construction *cons = newtype->construction; order *new_order; if (!eff_skill(u, SK_SHIPBUILDING, r)) { cmistake(u, ord, 100, MSG_PRODUCE); return; } if (besieged(u)) { cmistake(u, ord, 60, MSG_PRODUCE); return; } /* check if skill and material for 1 size is available */ if (eff_skill(u, cons->skill, r) < cons->minskill) { ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder, "error_build_skill_low", "value", cons->minskill)); return; } msize = maxbuild(u, cons); if (msize == 0) { cmistake(u, ord, 88, MSG_PRODUCE); return; } if (want > 0) want = _min(want, msize); else want = msize; sh = new_ship(newtype, r, u->faction->locale); if (leave(u, false)) { if (fval(u_race(u), RCF_CANSAIL)) { u_set_ship(u, sh); } } new_order = create_order(K_MAKE, u->faction->locale, "%s %i", LOC(u->faction->locale, parameters[P_SHIP]), sh->no); replace_order(&u->orders, ord, new_order); free_order(new_order); build_ship(u, sh, want); }
static void test_parse_maketemp(CuTest *tc) { char cmd[32]; order *ord; struct locale * lang = get_or_create_locale("en"); locale_setstring(lang, keyword(K_MAKE), "MAKE"); locale_setstring(lang, keyword(K_MAKETEMP), "MAKETEMP"); locale_setstring(lang, "TEMP", "TEMP"); init_locale(lang); ord = parse_order("MAKET herp", lang); CuAssertPtrNotNull(tc, ord); CuAssertStrEquals(tc, "MAKETEMP herp", get_command(ord, cmd, sizeof(cmd))); CuAssertIntEquals(tc, K_MAKETEMP, getkeyword(ord)); CuAssertIntEquals(tc, K_MAKETEMP, init_order(ord)); CuAssertStrEquals(tc, "herp", getstrtoken()); free_order(ord); }
static void test_give_herbs(CuTest * tc) { struct give env = { 0 }; struct order *ord; test_setup_ex(tc); env.f2 = env.f1 = test_create_faction(NULL); setup_give(&env); i_change(&env.src->items, env.itype, 10); ord = create_order(K_GIVE, env.f1->locale, "%s %s", itoa36(env.dst->no), LOC(env.f1->locale, parameters[P_HERBS])); assert(ord); give_cmd(env.src, ord); CuAssertIntEquals(tc, 0, i_get(env.src->items, env.itype)); CuAssertIntEquals(tc, 10, i_get(env.dst->items, env.itype)); free_order(ord); test_teardown(); }
static void test_create_order(CuTest *tc) { char cmd[32]; order *ord; struct locale * lang; test_cleanup(); lang = get_or_create_locale("en"); locale_setstring(lang, "keyword::move", "MOVE"); ord = create_order(K_MOVE, lang, "NORTH"); CuAssertPtrNotNull(tc, ord); CuAssertIntEquals(tc, K_MOVE, getkeyword(ord)); CuAssertStrEquals(tc, "MOVE NORTH", get_command(ord, cmd, sizeof(cmd))); CuAssertIntEquals(tc, K_MOVE, init_order(ord)); CuAssertStrEquals(tc, "NORTH", getstrtoken()); free_order(ord); test_cleanup(); }
static void test_sabotage_self(CuTest *tc) { unit *u; region *r; order *ord; setup_sabotage(); r = test_create_region(0, 0, 0); assert(r); u = test_create_unit(test_create_faction(NULL), r); assert(u && u->faction && u->region == r); u->ship = test_create_ship(r, test_create_shiptype("boat")); assert(u->ship); ord = create_order(K_SABOTAGE, u->faction->locale, "SCHIFF"); assert(ord); CuAssertIntEquals(tc, 0, sabotage_cmd(u, ord)); CuAssertPtrEquals(tc, 0, r->ships); free_order(ord); test_cleanup(); }
static void test_give_invalid_target(CuTest *tc) { /* bug https://bugs.eressea.de/view.php?id=1685 */ struct give env = { 0 }; order *ord; test_setup_ex(tc); env.f1 = test_create_faction(NULL); env.f2 = 0; setup_give(&env); i_change(&env.src->items, env.itype, 10); ord = create_order(K_GIVE, env.f1->locale, "## KRAUT"); assert(ord); give_cmd(env.src, ord); CuAssertIntEquals(tc, 10, i_get(env.src->items, env.itype)); CuAssertPtrNotNull(tc, test_find_messagetype(env.f1->msgs, "feedback_unit_not_found")); free_order(ord); test_teardown(); }
static void test_setstealth_cmd(CuTest *tc) { unit *u; const struct locale *lang; test_setup(); u = test_create_unit(test_create_faction(0), test_create_region(0,0,0)); lang = u->faction->locale; u->flags = UFL_ANON_FACTION|UFL_SIEGE; u->thisorder = create_order(K_SETSTEALTH, lang, "%s %s", LOC(lang, parameters[P_FACTION]), LOC(lang, parameters[P_NOT])); setstealth_cmd(u, u->thisorder); CuAssertIntEquals(tc, UFL_SIEGE, u->flags); free_order(u->thisorder); u->thisorder = create_order(K_SETSTEALTH, lang, "%s", LOC(lang, parameters[P_FACTION])); setstealth_cmd(u, u->thisorder); CuAssertIntEquals(tc, UFL_SIEGE|UFL_ANON_FACTION, u->flags); test_cleanup(); }
/** remove the unit from memory. * this frees all memory that's only accessible through the unit, * and you should already have called uunhash and removed the unit from the * region. */ void free_unit(unit * u) { free(u->name); free(u->display); free_order(u->thisorder); free_orders(&u->orders); if (u->skills) free(u->skills); while (u->items) { item *it = u->items->next; u->items->next = NULL; i_free(u->items); u->items = it; } while (u->attribs) a_remove(&u->attribs, u->attribs); while (u->reservations) { struct reservation *res = u->reservations; u->reservations = res->next; free(res); } }
static void test_give_men_requires_contact(CuTest * tc) { struct give env = { 0 }; message * msg; order *ord; test_setup_ex(tc); env.f1 = test_create_faction(NULL); env.f2 = test_create_faction(NULL); setup_give(&env); msg = give_men(1, env.src, env.dst, NULL); CuAssertStrEquals(tc, "feedback_no_contact", test_get_messagetype(msg)); CuAssertIntEquals(tc, 1, env.dst->number); CuAssertIntEquals(tc, 1, env.src->number); ord = create_order(K_GIVE, env.f1->locale, "%s ALLES PERSONEN", itoa36(env.dst->no)); test_clear_messages(env.f1); give_cmd(env.src, ord); CuAssertPtrEquals(tc, NULL, test_find_messagetype(env.f1->msgs, "give_person")); CuAssertPtrNotNull(tc, test_find_messagetype(env.f1->msgs, "feedback_no_contact")); msg_release(msg); free_order(ord); test_teardown(); }
static void test_sabotage_other_success(CuTest *tc) { unit *u, *u2; region *r; order *ord; setup_sabotage(); r = test_create_region(0, 0, 0); assert(r); u = test_create_unit(test_create_faction(NULL), r); u2 = test_create_unit(test_create_faction(NULL), r); assert(u && u2); u2->ship = test_create_ship(r, test_create_shiptype("boat")); assert(u2->ship); u->ship = u2->ship; ship_update_owner(u->ship); assert(ship_owner(u->ship) == u); ord = create_order(K_SABOTAGE, u->faction->locale, "SCHIFF"); assert(ord); set_level(u2, SK_SPY, 1); CuAssertIntEquals(tc, 0, sabotage_cmd(u2, ord)); CuAssertPtrEquals(tc, 0, r->ships); free_order(ord); test_cleanup(); }
int teach_cmd(unit * u, struct order *ord) { static const curse_type *gbdream_ct = NULL; plane *pl; region *r = u->region; int teaching, i, j, count, academy = 0; skill_t sk = NOSKILL; if (gbdream_ct == 0) gbdream_ct = ct_find("gbdream"); if (gbdream_ct) { if (get_curse(u->region->attribs, gbdream_ct)) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "gbdream_noteach", "")); return 0; } } if ((u_race(u)->flags & RCF_NOTEACH) || fval(u, UFL_WERE)) { cmistake(u, ord, 274, MSG_EVENT); return 0; } pl = rplane(r); if (pl && fval(pl, PFL_NOTEACH)) { cmistake(u, ord, 273, MSG_EVENT); return 0; } teaching = u->number * 30 * TEACHNUMBER; if ((i = get_effect(u, oldpotiontype[P_FOOL])) > 0) { /* Trank "Dumpfbackenbrot" */ i = _min(i, u->number * TEACHNUMBER); /* Trank wirkt pro Schueler, nicht pro Lehrer */ teaching -= i * 30; change_effect(u, oldpotiontype[P_FOOL], -i); j = teaching / 30; ADDMSG(&u->faction->msgs, msg_message("teachdumb", "teacher amount", u, j)); } if (teaching == 0) return 0; count = 0; init_order(ord); #if TEACH_ALL if (getparam(u->faction->locale) == P_ANY) { unit *student = r->units; skill_t teachskill[MAXSKILLS]; int i = 0; do { sk = getskill(u->faction->locale); teachskill[i++] = sk; } while (sk != NOSKILL); while (teaching && student) { if (student->faction == u->faction) { if (LongHunger(student)) continue; if (getkeyword(student->thisorder) == K_STUDY) { /* Input ist nun von student->thisorder !! */ init_order(student->thisorder); sk = getskill(student->faction->locale); if (sk != NOSKILL && teachskill[0] != NOSKILL) { for (i = 0; teachskill[i] != NOSKILL; ++i) if (sk == teachskill[i]) break; sk = teachskill[i]; } if (sk != NOSKILL && eff_skill_study(u, sk, r) - TEACHDIFFERENCE > eff_skill_study(student, sk, r)) { teaching -= teach_unit(u, student, teaching, sk, true, &academy); } } } student = student->next; } #ifdef TEACH_FRIENDS while (teaching && student) { if (student->faction != u->faction && alliedunit(u, student->faction, HELP_GUARD)) { if (LongHunger(student)) continue; if (getkeyword(student->thisorder) == K_STUDY) { /* Input ist nun von student->thisorder !! */ init_order(student->thisorder); sk = getskill(student->faction->locale); if (sk != NOSKILL && eff_skill_study(u, sk, r) - TEACHDIFFERENCE >= eff_skill(student, sk, r)) { teaching -= teach_unit(u, student, teaching, sk, true, &academy); } } } student = student->next; } #endif } else #endif { char zOrder[4096]; order *new_order; zOrder[0] = '\0'; init_order(ord); while (!parser_end()) { unit *u2; bool feedback; getunit(r, u->faction, &u2); ++count; /* Falls die Unit nicht gefunden wird, Fehler melden */ if (!u2) { char tbuf[20]; const char *uid; const char *token; /* Finde den string, der den Fehler verursacht hat */ parser_pushstate(); init_order(ord); for (j = 0; j != count - 1; ++j) { /* skip over the first 'count' units */ getunit(r, u->faction, NULL); } token = getstrtoken(); /* Beginne die Fehlermeldung */ if (isparam(token, u->faction->locale, P_TEMP)) { token = getstrtoken(); sprintf(tbuf, "%s %s", LOC(u->faction->locale, parameters[P_TEMP]), token); uid = tbuf; } else { uid = token; } ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "unitnotfound_id", "id", uid)); parser_popstate(); continue; } feedback = u->faction == u2->faction || alliedunit(u2, u->faction, HELP_GUARD); /* Neuen Befehl zusammenbauen. TEMP-Einheiten werden automatisch in * ihre neuen Nummern uebersetzt. */ if (zOrder[0]) strcat(zOrder, " "); strcat(zOrder, unitid(u2)); if (getkeyword(u2->thisorder) != K_STUDY) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "teach_nolearn", "student", u2)); continue; } /* Input ist nun von u2->thisorder !! */ parser_pushstate(); init_order(u2->thisorder); sk = getskill(u2->faction->locale); parser_popstate(); if (sk == NOSKILL) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "teach_nolearn", "student", u2)); continue; } /* u is teacher, u2 is student */ if (eff_skill_study(u2, sk, r) > eff_skill_study(u, sk, r) - TEACHDIFFERENCE) { if (feedback) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "teach_asgood", "student", u2)); } continue; } if (sk == SK_MAGIC) { /* ist der Magier schon spezialisiert, so versteht er nur noch * Lehrer seines Gebietes */ sc_mage *mage1 = get_mage(u); sc_mage *mage2 = get_mage(u2); if (!mage2 || !mage1 || (mage2->magietyp != M_GRAY && mage1->magietyp != mage2->magietyp)) { if (feedback) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_different_magic", "target", u2)); } continue; } } teaching -= teach_unit(u, u2, teaching, sk, false, &academy); } new_order = create_order(K_TEACH, u->faction->locale, "%s", zOrder); replace_order(&u->orders, ord, new_order); free_order(new_order); /* parse_order & set_order have each increased the refcount */ } if (academy && sk != NOSKILL) { academy = academy / 30; /* anzahl gelehrter wochen, max. 10 */ learn_skill(u, sk, academy / 30.0 / TEACHNUMBER); } return 0; }
/************************************************************************* * int main *************************************************************************/ int main(int argc, char *argv[]) { /* Data structures. */ int num_motifs; /* The number of motifs in the model. */ MOTIF_T motifs[2 * MAX_MOTIFS]; /* The motifs. */ STRING_LIST_T* motif_occurrences = NULL; /* Strings describing occurrences of motifs */ BOOLEAN_T has_reverse_strand = FALSE; /* MEME file contained both strands */ ARRAY_T* background; /* Background probs for alphabet. */ ORDER_T* order_spacing; /* Linear HMM order and spacing. */ MATRIX_T* transp_freq = NULL; /* Matrix of inter-motif transitions freqs. */ MATRIX_T* spacer_ave = NULL; /* Matrix of average spacer lengths. */ MHMM_T * the_hmm = NULL; /* The HMM being constructed. */ /* Command line parameters. */ char * meme_filename; /* Input file containg motifs. */ char * hmm_type_str; /* HMM type. */ HMM_T hmm_type; STRING_LIST_T* requested_motifs; /* Indices of requested motifs. */ int request_n; /* The user asked for the first n motifs. */ double e_threshold; /* E-value threshold for motif inclusion. */ double complexity_threshold; // For eliminating low-complexity motifs. double p_threshold; /* p-value threshold for motif occurences. */ char* order_string; /* Motif order and spacing. */ int spacer_states; /* Number of states in each spacer. */ BOOLEAN_T fim; /* Represent spacers as free insertion modules? */ BOOLEAN_T keep_unused; // Drop unused inter-motif transitions? double trans_pseudo; /* Transition pseudocount. */ double spacer_pseudo; // Spacer (self-loop) pseudocount. */ char* description; // Descriptive text to be stored in model. BOOLEAN_T print_header; /* Print file header? */ BOOLEAN_T print_params; /* Print parameter summary? */ BOOLEAN_T print_time; /* Print timing data (dummy: always false). */ /* Local variables. */ int i_motif; /********************************************** * COMMAND LINE PROCESSING **********************************************/ // Define command line options. cmdoption const options[] = { {"type", OPTIONAL_VALUE}, {"description", REQUIRED_VALUE}, {"motif", REQUIRED_VALUE}, {"nmotifs", REQUIRED_VALUE}, {"ethresh", REQUIRED_VALUE}, {"lowcomp", REQUIRED_VALUE}, {"pthresh", REQUIRED_VALUE}, {"order", REQUIRED_VALUE}, {"nspacer", REQUIRED_VALUE}, {"fim", NO_VALUE}, {"keep-unused", NO_VALUE}, {"transpseudo", REQUIRED_VALUE}, {"spacerpseudo", REQUIRED_VALUE}, {"verbosity", REQUIRED_VALUE}, {"noheader", NO_VALUE}, {"noparams", NO_VALUE}, {"notime", NO_VALUE}, {"quiet", NO_VALUE}, }; int option_count = 18; int option_index = 0; // Define the usage message. char usage[1000] = ""; strcat(usage, "USAGE: mhmm [options] <MEME file>\n"); strcat(usage, "\n"); strcat(usage, " Options:\n"); strcat(usage, " --type [linear|complete|star] (default=linear)\n"); strcat(usage, " --description <string> (may be repeated)\n"); strcat(usage, " --motif <motif #> (may be repeated)\n"); strcat(usage, " --nmotifs <#>\n"); strcat(usage, " --ethresh <E-value>\n"); strcat(usage, " --lowcomp <value>\n"); strcat(usage, " --pthresh <p-value>\n"); strcat(usage, " --order <string>\n"); strcat(usage, " --nspacer <spacer length> (default=1)\n"); strcat(usage, " --fim\n"); strcat(usage, " --keep-unused\n"); strcat(usage, " --transpseudo <pseudocount>\n"); strcat(usage, " --spacerpseudo <pseudocount>\n"); strcat(usage, " --verbosity 1|2|3|4|5 (default=2)\n"); strcat(usage, " --noheader\n"); strcat(usage, " --noparams\n"); strcat(usage, " --notime\n"); strcat(usage, " --quiet\n"); strcat(usage, "\n"); /* Make sure various options are set to NULL or defaults. */ meme_filename = NULL; hmm_type_str = NULL; hmm_type = INVALID_HMM; requested_motifs = new_string_list(); request_n = 0; e_threshold = 0.0; complexity_threshold = 0.0; p_threshold = 0.0; order_string = NULL; spacer_states = DEFAULT_SPACER_STATES, fim = FALSE; keep_unused = FALSE; trans_pseudo = DEFAULT_TRANS_PSEUDO; spacer_pseudo = DEFAULT_SPACER_PSEUDO; description = NULL; print_header = TRUE; print_params = TRUE; print_time = FALSE; simple_setopt(argc, argv, option_count, options); // Parse the command line. while (1) { int c = 0; char* option_name = NULL; char* option_value = NULL; const char * message = NULL; // Read the next option, and break if we're done. c = simple_getopt(&option_name, &option_value, &option_index); if (c == 0) { break; } else if (c < 0) { simple_getopterror(&message); die("Error processing command line options (%s)\n", message); } if (strcmp(option_name, "type") == 0) { if (option_value != NULL) { hmm_type_str = option_value; } } else if (strcmp(option_name, "description") == 0) { description = option_value; } else if (strcmp(option_name, "motif") == 0) { add_string(option_value, requested_motifs); } else if (strcmp(option_name, "nmotifs") == 0) { request_n = atoi(option_value); } else if (strcmp(option_name, "ethresh") == 0) { e_threshold = atof(option_value); } else if (strcmp(option_name, "lowcomp") == 0) { complexity_threshold = atof(option_value); } else if (strcmp(option_name, "pthresh") == 0) { p_threshold = atof(option_value); } else if (strcmp(option_name, "order") == 0) { order_string = option_value; } else if (strcmp(option_name, "nspacer") == 0) { spacer_states = atoi(option_value); } else if (strcmp(option_name, "fim") == 0) { fim = TRUE; } else if (strcmp(option_name, "keep-unused") == 0) { keep_unused = TRUE; } else if (strcmp(option_name, "transpseudo") == 0) { trans_pseudo = atof(option_value); } else if (strcmp(option_name, "spacerpseudo") == 0) { spacer_pseudo = atof(option_value); } else if (strcmp(option_name, "verbosity") == 0) { verbosity = (VERBOSE_T)atoi(option_value); } else if (strcmp(option_name, "noheader") == 0) { print_header = FALSE; } else if (strcmp(option_name, "noparams") == 0) { print_params = FALSE; } else if (strcmp(option_name, "notime") == 0) { print_time = FALSE; } else if (strcmp(option_name, "quiet") == 0) { print_header = print_params = print_time = FALSE; verbosity = QUIET_VERBOSE; } } // Read the single required argument. if (option_index + 1 != argc) { fprintf(stderr, "%s", usage); exit(1); } meme_filename = argv[option_index]; // Set up motif requests. if (request_n != 0) { if (get_num_strings(requested_motifs) != 0) { die("Can't combine the -motif and -nmotifs options.\n"); } else { for (i_motif = 0; i_motif < request_n; i_motif++) { char motif_id[MAX_MOTIF_ID_LENGTH + 1]; sprintf(motif_id, "%d", i_motif + 1); add_string(motif_id, requested_motifs); } } } /* Set the model type. */ hmm_type = convert_enum_type_str(hmm_type_str, LINEAR_HMM, HMM_STRS, NUM_HMM_T); /* Gotta have positive spacer length. */ if (spacer_states <= 0) { die("Negative spacer length (%d).\n", spacer_states); } /* Make sure motifs weren't selected redundantly. */ // FIXME: Add tests for complexity threshold. if ((get_num_strings(requested_motifs) != 0) && (e_threshold != 0.0)) { die("Can't use -motif or -nmotifs with -ethresh."); } if ((get_num_strings(requested_motifs) != 0) && (order_string != NULL)) { die("Can't use -motif or -nmotifs with -order."); } if ((order_string != NULL) && (e_threshold != 0.0)) { die("Can't use -ethresh and -order."); } /* Prevent trying to build a complete or star model with ordering. */ if (order_string != NULL) { if (hmm_type == COMPLETE_HMM) die("Can't specify motif order with a completely connected model."); else if (hmm_type == STAR_HMM) die("Can't specify motif order with a star model."); } // Parse the order string. order_spacing = create_order(order_string); /********************************************** * READING THE MOTIFS **********************************************/ BOOLEAN_T read_file = FALSE; double pseudocount = 0; read_meme_file( meme_filename, "motif-file", // Take bg freq. from motif file. pseudocount, REQUIRE_PSPM, &num_motifs, motifs, &motif_occurrences, &has_reverse_strand, &background ); process_raw_motifs_for_model( &num_motifs, motifs, motif_occurrences, requested_motifs, has_reverse_strand, keep_unused, p_threshold, e_threshold, complexity_threshold, &order_spacing, &transp_freq, &spacer_ave, trans_pseudo, spacer_pseudo ); /********************************************** * BUILDING THE HMM **********************************************/ /* Build the motif-based HMM. */ if (hmm_type == LINEAR_HMM) { if (order_spacing != NULL) { reorder_motifs(order_spacing, &num_motifs, motifs); } else { die("No order specified for the motifs.\n" "For the linear model the motif file must contain motif occurence\n" "data or the motif order must be specified using " "the --order option."); } build_linear_hmm( background, order_spacing, spacer_states, motifs, num_motifs, fim, &the_hmm ); } else if (hmm_type == COMPLETE_HMM) { build_complete_hmm( background, spacer_states, motifs, num_motifs, transp_freq, spacer_ave, fim, &the_hmm ); } else if (hmm_type == STAR_HMM) { build_star_hmm( background, spacer_states, motifs, num_motifs, fim, &the_hmm ); } // Add some global information. copy_string(&(the_hmm->motif_file), meme_filename); /********************************************** * WRITING THE HMM **********************************************/ /* Print the header. */ if (print_header) write_header( program, "", description, meme_filename, NULL, NULL, stdout ); /* Write the HMM. */ write_mhmm(verbosity, the_hmm, stdout); /* Print the program parameters. */ if (print_params) { printf("Program parameters for mhmm\n"); printf(" MEME file: %s\n", meme_filename); printf(" Motifs:"); write_string_list(" ", requested_motifs, stdout); printf("\n"); printf(" Model topology: %s\n", convert_enum_type(hmm_type, HMM_STRS, NUM_HMM_T)); printf(" States per spacer: %d\n", spacer_states); printf(" Spacers are free-insertion modules: %s\n", boolean_to_string(fim)); printf("\n"); } free_array(background); free_string_list(requested_motifs); free_order(order_spacing); free_matrix(transp_freq); free_matrix(spacer_ave); for (i_motif = 0; i_motif < num_motifs; i_motif++) free_motif(&(motifs[i_motif])); free_mhmm(the_hmm); return(0); }
/*********************************************************************** * Parse the motif occurrences. * * Each motif occurence string contains the following items * - sequence id, * - sequence p-value, * - number n of motif occurrences, and * - length of sequence. * * This is followed by n triples containing * - motif id, * - occurrence position, and * - occurrence p-value. * ***********************************************************************/ static void parse_motif_occurrences( STRING_LIST_T* motif_occurrences, // List of motif occurences OUT BOOLEAN_T has_reverse_strand, // File included both strands? IN double p_threshold, // P-value to include motif occurences. OUT ORDER_T** order_spacing, // Motif order and spacing (linear HMM) // IN OUT. MATRIX_T** transp_freq, // Motif-to-motif transitions. OUT MATRIX_T** spacer_ave, // Average inter-motif distances. OUT int num_motifs, // Number of motifs retrieved. IN MOTIF_T* motifs // The retrieved motifs. IN ) { ORDER_T* new_order; // New order and spacing. BOOLEAN_T find_order; // Should we look for the motif order? // If we already have a motif order and spacing, don't find any more. if (*order_spacing == NULL) { find_order = TRUE; } else { find_order = FALSE; } new_order = NULL; // Allocate the matrices. *transp_freq = allocate_matrix(num_motifs + 2, num_motifs + 2); *spacer_ave = allocate_matrix(num_motifs + 2, num_motifs + 2); init_matrix(0.0, *transp_freq); init_matrix(0.0, *spacer_ave); int num_occurrence_strings = get_num_strings(motif_occurrences); int i; for (i = 0; i < num_occurrence_strings; i++) { char* sequence_id; // ID of the current sequence. float sequence_p; // pvalue of the entire sequence. int num_occurs; // Number of motif occurences in this sequence. int seq_length; // Length of the current sequence. int i_occur; // Index of the current occurrence. char prev_motif[MAX_MOTIF_ID_LENGTH + 1]; // Index of the previous motif. int prev_position; // Location of the right edge of previous motif. float motif_p; // P-value of the current occurrence. char *c; // Dummy to hold return of strtok. char* line = get_nth_string(i, motif_occurrences); /* Read the sequence identifier, p-value, number of occurrences and length. */ // tlb; sscanf crashes if strtok returns NULL so pass it "" then sequence_id = strtok(line, " "); if (sequence_id == NULL) { die("Error reading motif occurrences.\n%s", line); } if (sscanf((c=strtok(NULL, " "))?c:"", "%f", &sequence_p) != 1) { die("Can't read p-value of sequence %s.", sequence_id); } if (sscanf((c=strtok(NULL, " "))?c:"", "%d", &num_occurs) != 1) { die("Can't read number of motif occurences in sequence %s.", sequence_id); } if (sscanf((c=strtok(NULL, " "))?c:"", "%d", &seq_length) != 1) { die("Can't read length of sequence %s.", sequence_id); } if (verbosity > NORMAL_VERBOSE) { fprintf(stderr, "Reading motif occurrences for sequence %s.\n", sequence_id); } // If requested, try to create an order string. if (find_order) { new_order = create_empty_order(num_occurs, sequence_p); } // Accumulate motif occurence data. sprintf(prev_motif, "%d", 0); prev_position = 0; for (i_occur = 0; i_occur < num_occurs; i_occur++) { char motif_id[MAX_MOTIF_ID_LENGTH + 1]; // ID of the current motif. int motif_position; // Position of the current motif occurrence. char *c; // Dummy to hold return of strtok. // Read the three values. if (sscanf((c=strtok(NULL, " "))?c:"", "%s", motif_id) != 1) { die("Can't read index of occurrence %d in sequence %s.", i_occur, sequence_id); } if (sscanf((c=strtok(NULL, " "))?c:"", "%d", &motif_position) != 1) { die("Can't read position of occurrence %d in sequence %s.", i_occur, sequence_id); } if (sscanf((c=strtok(NULL, " "))?c:"", "%f", &motif_p) != 1) { die("Can't read p-value of occurrence %d in sequence %s.", i_occur, sequence_id); } // Only include motifs that have been retained if (have_motif(motif_id, num_motifs, motifs)) { // Make sure we have strand information in the ID. if (has_reverse_strand) { add_strand(motif_id); } // Record this occurrence. record_occurrence(sequence_id, motif_id, p_threshold, motif_p, prev_motif, &prev_position, motif_position, *transp_freq, *spacer_ave, new_order, num_motifs, motifs); /* Motifs are stored in order of their motif IDs, but they are indexed from zero rather than one. */ prev_position = motif_position + (motifs[find_matrix_location(motifs, motif_id, num_motifs) - 1]).length; } } assert(seq_length >= prev_position); // Record the transition to the end state. record_occurrence(sequence_id, END_TRANSITION, p_threshold, motif_p, prev_motif, &prev_position, seq_length, *transp_freq, *spacer_ave, new_order, num_motifs, motifs); // Decide whether to keep the new order object. if (find_order) { if ((get_num_distinct(new_order) > get_num_distinct(*order_spacing)) || (((get_num_distinct(new_order) == get_num_distinct(*order_spacing)) && (get_pvalue(new_order) < get_pvalue(*order_spacing))))) { if (verbosity > NORMAL_VERBOSE) { fprintf(stderr, "Storing order from sequence %s (%g < %g).\n", sequence_id, get_pvalue(new_order), get_pvalue(*order_spacing)); print_order_and_spacing(stderr, new_order); } free_order(*order_spacing); *order_spacing = new_order; } else { free_order(new_order); } } } }
int teach_cmd(unit * teacher, struct order *ord) { plane *pl; region *r = teacher->region; skill_t sk_academy = NOSKILL; int teaching, i, j, count, academy_students = 0; if (r->attribs) { if (get_curse(r->attribs, &ct_gbdream)) { ADDMSG(&teacher->faction->msgs, msg_feedback(teacher, ord, "gbdream_noteach", "")); return 0; } } if ((u_race(teacher)->flags & RCF_NOTEACH) || fval(teacher, UFL_WERE)) { cmistake(teacher, ord, 274, MSG_EVENT); return 0; } pl = rplane(r); if (pl && fval(pl, PFL_NOTEACH)) { cmistake(teacher, ord, 273, MSG_EVENT); return 0; } teaching = teacher->number * TEACHNUMBER; if ((i = get_effect(teacher, oldpotiontype[P_FOOL])) > 0) { /* Trank "Dumpfbackenbrot" */ if (i > teaching) i = teaching; /* Trank wirkt pro Schueler, nicht pro Lehrer */ teaching -= i; change_effect(teacher, oldpotiontype[P_FOOL], -i); j = teaching; ADDMSG(&teacher->faction->msgs, msg_message("teachdumb", "teacher amount", teacher, j)); } if (teaching <= 0) return 0; count = 0; init_order_depr(ord); #if TEACH_ALL if (getparam(teacher->faction->locale) == P_ANY) { skill_t sk; unit *scholar; skill_t teachskill[MAXSKILLS]; int t = 0; do { sk = getskill(teacher->faction->locale); teachskill[t] = getskill(teacher->faction->locale); } while (sk != NOSKILL); for (scholar = r->units; teaching > 0 && scholar; scholar = scholar->next) { if (LongHunger(scholar)) { continue; } else if (scholar->faction == teacher->faction) { if (getkeyword(scholar->thisorder) == K_STUDY) { /* Input ist nun von student->thisorder !! */ init_order(scholar->thisorder, scholar->faction->locale); sk = getskill(scholar->faction->locale); if (sk != NOSKILL && teachskill[0] != NOSKILL) { for (t = 0; teachskill[t] != NOSKILL; ++t) { if (sk == teachskill[t]) { break; } } sk = teachskill[t]; } if (sk != NOSKILL && effskill_study(teacher, sk) - TEACHDIFFERENCE > effskill_study(scholar, sk)) { teaching -= teach_unit(teacher, scholar, teaching, sk, true, &academy_students); } } } #ifdef TEACH_FRIENDS else if (alliedunit(teacher, scholar->faction, HELP_GUARD)) { if (getkeyword(scholar->thisorder) == K_STUDY) { /* Input ist nun von student->thisorder !! */ init_order(scholar->thisorder, scholar->faction->locale); sk = getskill(scholar->faction->locale); if (sk != NOSKILL && effskill_study(teacher, sk) - TEACHDIFFERENCE >= effskill(scholar, sk, NULL)) { teaching -= teach_unit(teacher, scholar, teaching, sk, true, &academy_students); } } } #endif } } else #endif { char zOrder[4096]; size_t sz = sizeof(zOrder); order *new_order; zOrder[0] = '\0'; init_order_depr(ord); while (!parser_end()) { skill_t sk; unit *scholar; bool feedback; getunit(r, teacher->faction, &scholar); ++count; /* Falls die Unit nicht gefunden wird, Fehler melden */ if (!scholar) { char tbuf[20]; const char *uid; const char *token; /* Finde den string, der den Fehler verursacht hat */ parser_pushstate(); init_order_depr(ord); for (j = 0; j != count - 1; ++j) { /* skip over the first 'count' units */ getunit(r, teacher->faction, NULL); } token = getstrtoken(); /* Beginne die Fehlermeldung */ if (isparam(token, teacher->faction->locale, P_TEMP)) { token = getstrtoken(); sprintf(tbuf, "%s %s", LOC(teacher->faction->locale, parameters[P_TEMP]), token); uid = tbuf; } else { uid = token; } ADDMSG(&teacher->faction->msgs, msg_feedback(teacher, ord, "unitnotfound_id", "id", uid)); parser_popstate(); continue; } feedback = teacher->faction == scholar->faction || alliedunit(scholar, teacher->faction, HELP_GUARD); /* Neuen Befehl zusammenbauen. TEMP-Einheiten werden automatisch in * ihre neuen Nummern uebersetzt. */ if (zOrder[0]) { strncat(zOrder, " ", sz - 1); --sz; } sz -= str_strlcpy(zOrder + 4096 - sz, itoa36(scholar->no), sz); if (getkeyword(scholar->thisorder) != K_STUDY) { ADDMSG(&teacher->faction->msgs, msg_feedback(teacher, ord, "teach_nolearn", "student", scholar)); continue; } /* Input ist nun von student->thisorder !! */ parser_pushstate(); init_order(scholar->thisorder, scholar->faction->locale); sk = getskill(scholar->faction->locale); parser_popstate(); if (sk == NOSKILL) { ADDMSG(&teacher->faction->msgs, msg_feedback(teacher, ord, "teach_nolearn", "student", scholar)); continue; } if (effskill_study(scholar, sk) > effskill_study(teacher, sk) - TEACHDIFFERENCE) { if (feedback) { ADDMSG(&teacher->faction->msgs, msg_feedback(teacher, ord, "teach_asgood", "student", scholar)); } continue; } if (sk == SK_MAGIC) { /* ist der Magier schon spezialisiert, so versteht er nur noch * Lehrer seines Gebietes */ magic_t mage2 = unit_get_magic(scholar); if (mage2 != M_GRAY) { magic_t mage1 = unit_get_magic(teacher); if (mage1 != mage2) { if (feedback) { ADDMSG(&teacher->faction->msgs, msg_feedback(teacher, ord, "error_different_magic", "target", scholar)); } continue; } } } sk_academy = sk; teaching -= teach_unit(teacher, scholar, teaching, sk, false, &academy_students); } new_order = create_order(K_TEACH, teacher->faction->locale, "%s", zOrder); replace_order(&teacher->orders, ord, new_order); free_order(new_order); /* parse_order & set_order have each increased the refcount */ } if (academy_students > 0 && sk_academy!=NOSKILL) { academy_teaching_bonus(teacher, sk_academy, academy_students); } init_order_depr(NULL); return 0; }
int build_building(unit * u, const building_type * btype, int id, int want, order * ord) { region *r = u->region; int n = want, built = 0; building *b = NULL; /* einmalige Korrektur */ const char *btname; order *new_order = NULL; const struct locale *lang = u->faction->locale; static int rule_other = -1; assert(u->number); assert(btype->construction); if (eff_skill(u, SK_BUILDING, r) == 0) { cmistake(u, ord, 101, MSG_PRODUCE); return 0; } /* Falls eine Nummer angegeben worden ist, und ein Gebaeude mit der * betreffenden Nummer existiert, ist b nun gueltig. Wenn keine Burg * gefunden wurde, dann wird nicht einfach eine neue erbaut. Ansonsten * baut man an der eigenen burg weiter. */ /* Wenn die angegebene Nummer falsch ist, KEINE Burg bauen! */ if (id > 0) { /* eine Nummer angegeben, keine neue Burg bauen */ b = findbuilding(id); if (!b || b->region != u->region) { /* eine Burg mit dieser Nummer gibt es hier nicht */ /* vieleicht Tippfehler und die eigene Burg ist gemeint? */ if (u->building && u->building->type == btype) { b = u->building; } else { /* keine neue Burg anfangen wenn eine Nummer angegeben war */ cmistake(u, ord, 6, MSG_PRODUCE); return 0; } } } else if (u->building && u->building->type == btype) { b = u->building; } if (b) btype = b->type; if (fval(btype, BTF_UNIQUE) && buildingtype_exists(r, btype, false)) { /* only one of these per region */ cmistake(u, ord, 93, MSG_PRODUCE); return 0; } if (besieged(u)) { /* units under siege can not build */ cmistake(u, ord, 60, MSG_PRODUCE); return 0; } if (btype->flags & BTF_NOBUILD) { /* special building, cannot be built */ cmistake(u, ord, 221, MSG_PRODUCE); return 0; } if ((r->terrain->flags & LAND_REGION) == 0) { /* special terrain, cannot build */ cmistake(u, ord, 221, MSG_PRODUCE); return 0; } if (btype->flags & BTF_ONEPERTURN) { if (b && fval(b, BLD_EXPANDED)) { cmistake(u, ord, 318, MSG_PRODUCE); return 0; } n = 1; } if (b) { if (rule_other < 0) { rule_other = get_param_int(global.parameters, "rules.build.other_buildings", 1); } if (!rule_other) { unit *owner = building_owner(b); if (!owner || owner->faction != u->faction) { cmistake(u, ord, 1222, MSG_PRODUCE); return 0; } } } if (b) built = b->size; if (n <= 0 || n == INT_MAX) { if (b == NULL) { if (btype->maxsize > 0) { n = btype->maxsize - built; } else { n = INT_MAX; } } else { if (b->type->maxsize > 0) { n = b->type->maxsize - built; } else { n = INT_MAX; } } } built = build(u, btype->construction, built, n); switch (built) { case ECOMPLETE: /* the building is already complete */ cmistake(u, ord, 4, MSG_PRODUCE); break; case ENOMATERIALS: ADDMSG(&u->faction->msgs, msg_materials_required(u, ord, btype->construction, want)); break; case ELOWSKILL: case ENEEDSKILL: /* no skill, or not enough skill points to build */ cmistake(u, ord, 50, MSG_PRODUCE); break; } if (built <= 0) { return built; } /* at this point, the building size is increased. */ if (b == NULL) { /* build a new building */ b = new_building(btype, r, lang); b->type = btype; fset(b, BLD_MAINTAINED | BLD_WORKING); /* Die Einheit befindet sich automatisch im Inneren der neuen Burg. */ if (u->number && leave(u, false)) { u_set_building(u, b); } } btname = LOC(lang, btype->_name); if (want - built <= 0) { /* gebäude fertig */ new_order = default_order(lang); } else if (want != INT_MAX) { /* reduzierte restgröße */ const char *hasspace = strchr(btname, ' '); if (hasspace) { new_order = create_order(K_MAKE, lang, "%d \"%s\" %i", n - built, btname, b->no); } else { new_order = create_order(K_MAKE, lang, "%d %s %i", n - built, btname, b->no); } } else if (btname) { /* Neues Haus, Befehl mit Gebäudename */ const char *hasspace = strchr(btname, ' '); if (hasspace) { new_order = create_order(K_MAKE, lang, "\"%s\" %i", btname, b->no); } else { new_order = create_order(K_MAKE, lang, "%s %i", btname, b->no); } } if (new_order) { replace_order(&u->orders, ord, new_order); free_order(new_order); } b->size += built; fset(b, BLD_EXPANDED); update_lighthouse(b); ADDMSG(&u->faction->msgs, msg_message("buildbuilding", "building unit size", b, u, built)); return built; }
void main_loop(int argc, char *argv[], int max_hosts) { int i; int host; int *targeted_host; FileData local_file_data; FileData remote_file_data; Order *order; Direction direction; bool use_cache; char *top_dir; FtpInit(); targeted_host = get_targeted_host(argc, argv, max_hosts); for (i = 0;; i++) { host = targeted_host[i]; if (host == -1) { break; } message(PROCESS, cfgSectionNumberToName(host), 0, host); direction = get_direction(host); get_local_file_data(&local_file_data, host); if (command_line_option.rebuild_cache) { /* -r | --rebuild-cache */ rebuild_cache(host); free_file_data(&local_file_data); continue; } if (command_line_option.catch_up) { /* -R | --catch-up */ catch_up(&local_file_data, host); free_file_data(&local_file_data); continue; } if (direction == DOWNLOAD || !does_cache_exist(host)) { if (direction == DOWNLOAD) { printf(_("Rebuilding cache for downloading...\n")); } else { printf(_("Cache file is not found.\nCreating a new one...\n")); } if (connect_to_remote_host(host) != 0) { free_file_data(&local_file_data); continue; } get_remote_file_data(&remote_file_data, host); use_cache = FALSE; } else { load_cache(&remote_file_data, host); use_cache = TRUE; } order = compare_both_hosts_and_generate_order(&local_file_data, &remote_file_data, config.local_top_dir[host], config.remote_top_dir[host], direction, host); if (!does_need_update(order)) { disconnect_from_remote_host(host); if (direction == UPLOAD) { printf(_("The remote host doesn't need updating.\n")); } else { printf(_("The local host doesn't need updating.\n")); } if (!use_cache) { save_cache(&remote_file_data, host); } free_file_data(&remote_file_data); free_file_data(&local_file_data); continue; } if(command_line_option.list) { disconnect_from_remote_host(host); put_listing_of_updated_file(order, direction); free_file_data(&remote_file_data); free_file_data(&local_file_data); continue; } if(command_line_option.nlist) { disconnect_from_remote_host(host); put_the_number_of_updated_file(order, direction); free_file_data(&remote_file_data); free_file_data(&local_file_data); continue; } if (!use_cache) { printf("\n"); } put_num_updated_file(order, direction); if (connect_to_remote_host(host) != 0) { free_file_data(&remote_file_data); free_file_data(&local_file_data); continue; } if (direction == UPLOAD) { top_dir = str_concat(config.remote_top_dir[host], "/", NULL); } else { top_dir = str_concat(config.local_top_dir[host], "/", NULL); } message(ENTER, top_dir, 0, host); execute_order(order, &remote_file_data, direction, host); message(LEAVE, top_dir, 0, host); free(top_dir); free_order(order); disconnect_from_remote_host(host); save_cache(&remote_file_data, host); free_file_data(&remote_file_data); free_file_data(&local_file_data); } free(targeted_host); }