diff --git a/src/league.c b/src/league.c index d03aedb2..97380af2 100644 --- a/src/league.c +++ b/src/league.c @@ -101,7 +101,7 @@ prom_rel_element_new(void) PromRelElement new; new.ranks[0] = new.ranks[1] = - new.from_table = 0; + new.from_table = new.num_teams = 0; new.dest_sid = NULL; new.type = PROM_REL_NONE; diff --git a/src/league_struct.h b/src/league_struct.h index 340731b9..aa0533c3 100644 --- a/src/league_struct.h +++ b/src/league_struct.h @@ -49,6 +49,13 @@ typedef struct gint from_table; /**< From which table to pick the teams in case there are several. Default: 0. */ gchar *dest_sid; /**< The id of the destination league. Default "" */ gint type; /**< Type. Promotion or relegation or none. */ + /** The maximum number of teams to promote/relegate. This can be different the + * size of the range of teams, since some leagues have teams + * (e.g. reserve teams) that may be inelligible for promotion. For example, + * a league could promote the top 2 elegible teams from positions 1-3. + * In that case ranks[0] = 1, ranks[1] = 3 and num_teams = 2. + */ + gint num_teams; } PromRelElement; /** diff --git a/src/xml_league.c b/src/xml_league.c index ca67d8d7..08273e41 100644 --- a/src/xml_league.c +++ b/src/xml_league.c @@ -57,6 +57,7 @@ #define TAG_PROM_REL_ELEMENT "prom_rel_element" #define TAG_PROM_REL_ELEMENT_RANK_START "rank_start" #define TAG_PROM_REL_ELEMENT_RANK_END "rank_end" +#define TAG_PROM_REL_ELEMENT_NUMBER_OF_TEAMS "number_of_teams" #define TAG_PROM_REL_ELEMENT_DEST_SID "dest_sid" #define TAG_PROM_REL_ELEMENT_TYPE "prom_rel_type" #define TAG_PROM_REL_ELEMENT_FROM_TABLE "from_table" @@ -101,6 +102,7 @@ enum XmlLeagueStates STATE_PROM_REL_ELEMENT, STATE_PROM_REL_ELEMENT_RANK_START, STATE_PROM_REL_ELEMENT_RANK_END, + STATE_PROM_REL_ELEMENT_NUMBER_OF_TEAMS, STATE_PROM_REL_ELEMENT_DEST_SID, STATE_PROM_REL_ELEMENT_TYPE, STATE_PROM_REL_ELEMENT_FROM_TABLE, @@ -247,6 +249,8 @@ xml_league_read_start_element (GMarkupParseContext *context, state = STATE_PROM_REL_ELEMENT_RANK_START; else if(strcmp(element_name, TAG_PROM_REL_ELEMENT_RANK_END) == 0) state = STATE_PROM_REL_ELEMENT_RANK_END; + else if(strcmp(element_name, TAG_PROM_REL_ELEMENT_NUMBER_OF_TEAMS) == 0) + state = STATE_PROM_REL_ELEMENT_NUMBER_OF_TEAMS; else if(strcmp(element_name, TAG_PROM_REL_ELEMENT_DEST_SID) == 0) state = STATE_PROM_REL_ELEMENT_DEST_SID; else if(strcmp(element_name, TAG_PROM_REL_ELEMENT_TYPE) == 0) @@ -327,6 +331,7 @@ xml_league_read_end_element (GMarkupParseContext *context, state = STATE_PROM_GAMES; else if(strcmp(element_name, TAG_PROM_REL_ELEMENT_RANK_START) == 0 || strcmp(element_name, TAG_PROM_REL_ELEMENT_RANK_END) == 0 || + strcmp(element_name, TAG_PROM_REL_ELEMENT_NUMBER_OF_TEAMS) == 0 || strcmp(element_name, TAG_PROM_REL_ELEMENT_DEST_SID) == 0 || strcmp(element_name, TAG_PROM_REL_ELEMENT_FROM_TABLE) == 0 || strcmp(element_name, TAG_PROM_REL_ELEMENT_TYPE) == 0) @@ -434,6 +439,10 @@ xml_league_read_text (GMarkupParseContext *context, g_array_index(new_league.prom_rel.elements, PromRelElement, new_league.prom_rel.elements->len - 1).ranks[1] = int_value; + else if(state == STATE_PROM_REL_ELEMENT_NUMBER_OF_TEAMS) + g_array_index(new_league.prom_rel.elements, + PromRelElement, + new_league.prom_rel.elements->len - 1).num_teams = int_value; else if(state == STATE_PROM_REL_ELEMENT_DEST_SID) misc_string_assign(&g_array_index(new_league.prom_rel.elements, PromRelElement, @@ -519,6 +528,7 @@ xml_league_read(const gchar *league_name, GArray *leagues) if(g_markup_parse_context_parse(context, file_contents, length, &error)) { + gint i; g_markup_parse_context_end_parse(context, NULL); g_markup_parse_context_free(context); g_free(file_contents); @@ -526,6 +536,18 @@ xml_league_read(const gchar *league_name, GArray *leagues) league_cup_adjust_rr_breaks(new_league.rr_breaks, new_league.round_robins, new_league.week_gap); league_cup_adjust_week_breaks(new_league.week_breaks, new_league.week_gap); g_array_append_val(leagues, new_league); + + for (i = 0; i < new_league.prom_rel.elements->len; i++) { + PromRelElement *elem = &g_array_index(new_league.prom_rel.elements, + PromRelElement, i); + /* If this value was specified in the xml, then we shouldn't try + * to compute it. */ + if (elem->num_teams != 0) + continue; + + elem->num_teams = (elem->ranks[1] - elem->ranks[0]) + 1; + } + } else { diff --git a/src/xml_loadsave_league.c b/src/xml_loadsave_league.c index 48a340a0..21d172d7 100644 --- a/src/xml_loadsave_league.c +++ b/src/xml_loadsave_league.c @@ -53,6 +53,7 @@ enum TAG_LEAGUE_PROM_REL_ELEMENTS, TAG_LEAGUE_PROM_REL_ELEMENT, TAG_LEAGUE_PROM_REL_ELEMENT_RANK, + TAG_LEAGUE_PROM_REL_ELEMENT_NUMBER_OF_TEAMS, TAG_LEAGUE_PROM_REL_ELEMENT_DEST_SID, TAG_LEAGUE_PROM_REL_ELEMENT_TYPE, TAG_LEAGUE_PROM_REL_ELEMENT_FROM_TABLE, @@ -187,6 +188,7 @@ xml_loadsave_league_end_element (GMarkupParseContext *context, } else if(tag == TAG_LEAGUE_PROM_REL_ELEMENT_RANK || tag == TAG_LEAGUE_PROM_REL_ELEMENT_DEST_SID || + tag == TAG_LEAGUE_PROM_REL_ELEMENT_NUMBER_OF_TEAMS || tag == TAG_LEAGUE_PROM_REL_ELEMENT_FROM_TABLE || tag == TAG_LEAGUE_PROM_REL_ELEMENT_TYPE) { @@ -296,6 +298,8 @@ xml_loadsave_league_text (GMarkupParseContext *context, new_prom_games.loser_sid = g_strdup(buf); else if(state == TAG_LEAGUE_PROM_REL_ELEMENT_RANK) new_element.ranks[promrankidx] = int_value; + else if(state == TAG_LEAGUE_PROM_REL_ELEMENT_NUMBER_OF_TEAMS) + new_element.num_teams = int_value; else if(state == TAG_LEAGUE_PROM_REL_ELEMENT_TYPE) new_element.type = int_value; else if(state == TAG_LEAGUE_PROM_REL_ELEMENT_FROM_TABLE) @@ -474,6 +478,8 @@ xml_loadsave_league_prom_rel_write(FILE *fil, const League *league) TAG_LEAGUE_PROM_REL_ELEMENT_RANK, I2); xml_write_int(fil, g_array_index(league->prom_rel.elements, PromRelElement, i).ranks[1], TAG_LEAGUE_PROM_REL_ELEMENT_RANK, I2); + xml_write_int(fil, g_array_index(league->prom_rel.elements, PromRelElement, i).num_teams, + TAG_LEAGUE_PROM_REL_ELEMENT_NUMBER_OF_TEAMS, I2); xml_write_int(fil, g_array_index(league->prom_rel.elements, PromRelElement, i).type, TAG_LEAGUE_PROM_REL_ELEMENT_TYPE, I2); xml_write_int(fil, g_array_index(league->prom_rel.elements, PromRelElement, i).from_table,