/* Clear a GRF Config list */ void ClearGRFConfigList(GRFConfig **config) { GRFConfig *c, *next; for (c = *config; c != NULL; c = next) { next = c->next; ClearGRFConfig(&c); } *config = NULL; }
/** * Removes duplicates from lists of GRFConfigs. These duplicates * are introduced when the _grfconfig_static GRFs are appended * to the _grfconfig on a newgame or savegame. As the parameters * of the static GRFs could be different that the parameters of * the ones used non-statically. This can result in desyncs in * multiplayers, so the duplicate static GRFs have to be removed. * * This function _assumes_ that all static GRFs are placed after * the non-static GRFs. * * @param list the list to remove the duplicates from */ static void RemoveDuplicatesFromGRFConfigList(GRFConfig *list) { GRFConfig *prev; GRFConfig *cur; if (list == NULL) return; for (prev = list, cur = list->next; cur != NULL; prev = cur, cur = cur->next) { if (cur->grfid != list->grfid) continue; prev->next = cur->next; ClearGRFConfig(&cur); cur = prev; // Just go back one so it continues as normal later on } RemoveDuplicatesFromGRFConfigList(list->next); }
bool GRFFileScanner::AddFile(const char *filename, size_t basepath_length) { GRFConfig *c = CallocT<GRFConfig>(1); c->filename = strdup(filename + basepath_length); bool added = true; if (FillGRFDetails(c, false)) { if (_all_grfs == NULL) { _all_grfs = c; } else { /* Insert file into list at a position determined by its * name, so the list is sorted as we go along */ GRFConfig **pd, *d; bool stop = false; for (pd = &_all_grfs; (d = *pd) != NULL; pd = &d->next) { if (c->grfid == d->grfid && memcmp(c->md5sum, d->md5sum, sizeof(c->md5sum)) == 0) added = false; /* Because there can be multiple grfs with the same name, make sure we checked all grfs with the same name, * before inserting the entry. So insert a new grf at the end of all grfs with the same name, instead of * just after the first with the same name. Avoids doubles in the list. */ if (strcasecmp(c->name, d->name) <= 0) { stop = true; } else if (stop) { break; } } if (added) { c->next = d; *pd = c; } } } else { added = false; } if (!added) { /* File couldn't be opened, or is either not a NewGRF or is a * 'system' NewGRF or it's already known, so forget about it. */ ClearGRFConfig(&c); } return added; }