random_free(me->random);
sfree(me->states);
sfree(me->desc);
+ sfree(me->privdesc);
sfree(me->seedstr);
sfree(me->aux_info);
me->ourgame->free_params(me->params);
}
me->presets[me->npresets] = preset;
- me->preset_names[me->npresets] = name;
+ me->preset_names[me->npresets] = dupstr(name);
me->npresets++;
}
}
static char *midend_game_id_int(midend_data *me, char *id, int defmode)
{
char *error, *par, *desc, *seed;
+ game_params *newcurparams, *newparams, *oldparams1, *oldparams2;
+ int free_params;
seed = strchr(id, '#');
desc = strchr(id, ':');
}
}
+ /*
+ * We must be reasonably careful here not to modify anything in
+ * `me' until we have finished validating things. This function
+ * must either return an error and do nothing to the midend, or
+ * return success and do everything; nothing in between is
+ * acceptable.
+ */
+ newcurparams = newparams = oldparams1 = oldparams2 = NULL;
+
if (par) {
- game_params *tmpparams;
- tmpparams = me->ourgame->dup_params(me->params);
- me->ourgame->decode_params(tmpparams, par);
- error = me->ourgame->validate_params(tmpparams);
+ newcurparams = me->ourgame->dup_params(me->params);
+ me->ourgame->decode_params(newcurparams, par);
+ error = me->ourgame->validate_params(newcurparams);
if (error) {
- me->ourgame->free_params(tmpparams);
+ me->ourgame->free_params(newcurparams);
return error;
}
- if (me->curparams)
- me->ourgame->free_params(me->curparams);
- me->curparams = tmpparams;
+ oldparams1 = me->curparams;
/*
* Now filter only the persistent parts of this state into
* received a params string in which case the whole lot is
* persistent.
*/
+ oldparams2 = me->params;
if (seed || desc) {
- char *tmpstr = me->ourgame->encode_params(tmpparams, FALSE);
- me->ourgame->decode_params(me->params, tmpstr);
+ char *tmpstr;
+
+ newparams = me->ourgame->dup_params(me->params);
+
+ tmpstr = me->ourgame->encode_params(newcurparams, FALSE);
+ me->ourgame->decode_params(newparams, tmpstr);
+
sfree(tmpstr);
} else {
- me->ourgame->free_params(me->params);
- me->params = me->ourgame->dup_params(tmpparams);
+ newparams = me->ourgame->dup_params(newcurparams);
+ }
+ free_params = TRUE;
+ } else {
+ newcurparams = me->curparams;
+ newparams = me->params;
+ free_params = FALSE;
+ }
+
+ if (desc) {
+ error = me->ourgame->validate_desc(newparams, desc);
+ if (error) {
+ if (free_params) {
+ if (newcurparams)
+ me->ourgame->free_params(newcurparams);
+ if (newparams)
+ me->ourgame->free_params(newparams);
+ }
+ return error;
}
}
+ /*
+ * Now we've got past all possible error points. Update the
+ * midend itself.
+ */
+ me->params = newparams;
+ me->curparams = newcurparams;
+ if (oldparams1)
+ me->ourgame->free_params(oldparams1);
+ if (oldparams2)
+ me->ourgame->free_params(oldparams2);
+
sfree(me->desc);
sfree(me->privdesc);
me->desc = me->privdesc = NULL;
me->seedstr = NULL;
if (desc) {
- error = me->ourgame->validate_desc(me->params, desc);
- if (error)
- return error;
-
me->desc = dupstr(desc);
me->genmode = GOT_DESC;
sfree(me->aux_info);
#define wr(h,s) do { \
char hbuf[80]; \
char *str = (s); \
- sprintf(hbuf, "%-8.8s:%d:", (h), strlen(str)); \
+ sprintf(hbuf, "%-8.8s:%d:", (h), (int)strlen(str)); \
write(wctx, hbuf, strlen(hbuf)); \
write(wctx, str, strlen(str)); \
write(wctx, "\n", 1); \
uistr = val;
val = NULL;
} else if (!strcmp(key, "TIME")) {
- elapsed = strtod(val, NULL);
+ elapsed = atof(val);
} else if (!strcmp(key, "NSTATES")) {
nstates = atoi(val);
if (nstates <= 0) {
midend_set_timer(me);
+ if (me->drawstate)
+ me->ourgame->free_drawstate(me->drawstate);
+ me->drawstate =
+ me->ourgame->new_drawstate(me->states[me->statepos-1].state);
+ midend_size_new_drawstate(me);
+
ret = NULL; /* success! */
cleanup: