shithub: puzzles

Download patch

ref: b3243d75043cf1d70beb88d2a36eaebfe85c2c3f
parent: de67801b0fd3dfa11777c1ef86cd617baf376b7b
author: Simon Tatham <anakin@pobox.com>
date: Sun Oct 1 09:53:24 EDT 2017

Return error messages as 'const char *', not 'char *'.

They're never dynamically allocated, and are almost always string
literals, so const is more appropriate.

--- a/blackbox.c
+++ b/blackbox.c
@@ -184,7 +184,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if (params->w < 2 || params->h < 2)
         return "Width and height must both be at least two";
@@ -247,7 +247,7 @@
     return ret;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     int nballs, dlen = strlen(desc), i;
     unsigned char *bmp;
@@ -458,7 +458,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     return dupstr("S");
 }
--- a/bridges.c
+++ b/bridges.c
@@ -795,7 +795,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if (params->w < 3 || params->h < 3)
         return "Width and height must be at least 3";
@@ -1989,7 +1989,7 @@
     return ret;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     int i, wh = params->w * params->h;
 
@@ -2573,7 +2573,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     char *ret;
     game_state *solved;
--- a/cube.c
+++ b/cube.c
@@ -534,7 +534,7 @@
     classes[thisclass]++;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     int classes[5];
     int i;
@@ -842,7 +842,7 @@
     return ret;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     int area = grid_area(params->d1, params->d2, solids[params->solid]->order);
     int i, j;
@@ -1000,7 +1000,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     return NULL;
 }
--- a/devel.but
+++ b/devel.but
@@ -664,7 +664,8 @@
 
 \S{backend-validate-params} \cw{validate_params()}
 
-\c char *(*validate_params)(const game_params *params, int full);
+\c const char *(*validate_params)(const game_params *params,
+\c                                int full);
 
 This function takes a \c{game_params} structure as input, and checks
 that the parameters described in it fall within sensible limits. (At
@@ -749,7 +750,8 @@
 
 \S{backend-validate-desc} \cw{validate_desc()}
 
-\c char *(*validate_desc)(const game_params *params, const char *desc);
+\c const char *(*validate_desc)(const game_params *params,
+\c                              const char *desc);
 
 This function is given a game description, and its job is to
 validate that it describes a puzzle which makes sense.
@@ -1053,7 +1055,7 @@
 \S{backend-solve} \cw{solve()}
 
 \c char *(*solve)(const game_state *orig, const game_state *curr,
-\c                const char *aux, char **error);
+\c                const char *aux, const char **error);
 
 This function is called when the user selects the \q{Solve} option
 from the menu.
@@ -3154,8 +3156,8 @@
 
 \H{midend-set-config} \cw{midend_set_config()}
 
-\c char *midend_set_config(midend *me, int which,
-\c                         config_item *cfg);
+\c const char *midend_set_config(midend *me, int which,
+\c                               config_item *cfg);
 
 Passes the mid-end the results of a configuration dialog box.
 \c{which} should have the same value which it had when
@@ -3176,7 +3178,7 @@
 
 \H{midend-game-id} \cw{midend_game_id()}
 
-\c char *midend_game_id(midend *me, char *id);
+\c const char *midend_game_id(midend *me, char *id);
 
 Passes the mid-end a string game ID (of any of the valid forms
 \cq{params}, \cq{params:description} or \cq{params#seed}) which the
@@ -3244,7 +3246,7 @@
 
 \H{midend-solve} \cw{midend_solve()}
 
-\c char *midend_solve(midend *me);
+\c const char *midend_solve(midend *me);
 
 Requests the mid-end to perform a Solve operation.
 
@@ -3316,9 +3318,8 @@
 
 \H{midend-deserialise} \cw{midend_deserialise()}
 
-\c char *midend_deserialise(midend *me,
-\c                          int (*read)(void *ctx, void *buf, int len),
-\c                          void *rctx);
+\c const char *midend_deserialise(midend *me,
+\c     int (*read)(void *ctx, void *buf, int len), void *rctx);
 
 This function is the counterpart to \cw{midend_serialise()}. It
 calls the supplied \cw{read} function repeatedly to read a quantity
@@ -3355,9 +3356,8 @@
 
 \H{identify-game} \cw{identify_game()}
 
-\c char *identify_game(char **name,
-\c                     int (*read)(void *ctx, void *buf, int len),
-\c                     void *rctx);
+\c const char *identify_game(char **name,
+\c     int (*read)(void *ctx, void *buf, int len), void *rctx);
 
 This function examines a serialised midend stream, of the same kind
 used by \cw{midend_serialise()} and \cw{midend_deserialise()}, and
--- a/dominosa.c
+++ b/dominosa.c
@@ -191,7 +191,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if (params->n < 1)
         return "Maximum face number must be at least one";
@@ -744,7 +744,7 @@
     return ret;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     int n = params->n, w = n+2, h = n+1, wh = w*h;
     int *occurrences;
@@ -871,7 +871,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     int n = state->params.n, w = n+2, h = n+1, wh = w*h;
     int *placements;
--- a/emcc.c
+++ b/emcc.c
@@ -656,7 +656,7 @@
         /*
          * User hit OK.
          */
-        char *err = midend_set_config(me, cfg_which, cfg);
+        const char *err = midend_set_config(me, cfg_which, cfg);
 
         if (err) {
             /*
@@ -766,7 +766,7 @@
         break;
       case 9:                          /* Solve */
         if (thegame.can_solve) {
-            char *msg = midend_solve(me);
+            const char *msg = midend_solve(me);
             if (msg)
                 js_error_box(msg);
         }
@@ -863,7 +863,7 @@
  */
 int main(int argc, char **argv)
 {
-    char *param_err;
+    const char *param_err;
     float *colours;
     int i;
 
--- a/fifteen.c
+++ b/fifteen.c
@@ -134,7 +134,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if (params->w < 2 || params->h < 2)
 	return "Width and height must both be at least two";
@@ -270,7 +270,7 @@
     return ret;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     const char *p;
     char *err;
@@ -379,7 +379,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     return dupstr("S");
 }
@@ -1126,7 +1126,8 @@
 {
     game_params *params;
     game_state *state;
-    char *id = NULL, *desc, *err;
+    char *id = NULL, *desc;
+    const char *err;
     int grade = FALSE;
     char *progname = argv[0];
 
--- a/filling.c
+++ b/filling.c
@@ -184,7 +184,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if (params->w < 1) return "Width must be at least one";
     if (params->h < 1) return "Height must be at least one";
@@ -1266,7 +1266,7 @@
     return sresize(description, j, char);
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     const int sz = params->w * params->h;
     const char m = '0' + max(max(params->w, params->h), 3);
@@ -1338,7 +1338,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     if (aux == NULL) {
         const int w = state->shared->params.w;
--- a/flip.c
+++ b/flip.c
@@ -178,7 +178,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if (params->w <= 0 || params->h <= 0)
         return "Width and height must both be greater than zero";
@@ -592,7 +592,7 @@
     return ret;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     int w = params->w, h = params->h, wh = w * h;
     int mlen = (wh*wh+3)/4, glen = (wh+3)/4;
@@ -669,7 +669,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     int w = state->w, h = state->h, wh = w * h;
     unsigned char *equations, *solution, *shortest;
--- a/flood.c
+++ b/flood.c
@@ -205,7 +205,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if (params->w < 2 && params->h < 2)
         return "Grid must contain at least two squares";
@@ -589,7 +589,7 @@
     return desc;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     int w = params->w, h = params->h, wh = w*h;
     int i;
@@ -683,7 +683,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     int w = state->w, h = state->h, wh = w*h;
     char *moves, *ret, *p;
--- a/galaxies.c
+++ b/galaxies.c
@@ -277,7 +277,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if (params->w < 3 || params->h < 3)
         return "Width and height must both be at least 3";
@@ -1570,7 +1570,7 @@
     return NULL;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     char *why = NULL;
     game_state *dummy = load_game(params, desc, &why);
@@ -2254,7 +2254,7 @@
 
 #ifndef EDITOR
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     game_state *tosolve;
     char *ret;
@@ -3771,7 +3771,8 @@
 int main(int argc, char **argv)
 {
     game_params *p;
-    char *id = NULL, *desc, *err;
+    char *id = NULL, *desc;
+    const char *err;
     game_state *s;
     int diff, do_soak = 0, verbose = 0;
     random_state *rs;
--- a/gtk.c
+++ b/gtk.c
@@ -1492,8 +1492,8 @@
 }
 
 #if GTK_CHECK_VERSION(3,0,0)
-int message_box(GtkWidget *parent, char *title, char *msg, int centre,
-		int type)
+int message_box(GtkWidget *parent, const char *title, const char *msg,
+                int centre, int type)
 {
     GtkWidget *window;
     gint ret;
@@ -1587,7 +1587,7 @@
 }
 #endif /* GTK_CHECK_VERSION(3,0,0) */
 
-void error_box(GtkWidget *parent, char *msg)
+void error_box(GtkWidget *parent, const char *msg)
 {
     message_box(parent, "Error", msg, FALSE, MB_OK);
 }
@@ -1595,7 +1595,7 @@
 static void config_ok_button_clicked(GtkButton *button, gpointer data)
 {
     frontend *fe = (frontend *)data;
-    char *err;
+    const char *err;
 
     err = midend_set_config(fe->me, fe->cfg_which, fe->cfg);
 
@@ -2298,7 +2298,8 @@
 static void menu_load_event(GtkMenuItem *menuitem, gpointer data)
 {
     frontend *fe = (frontend *)data;
-    char *name, *err;
+    char *name;
+    const char *err;
 
     name = file_selector(fe, "Enter name of saved game file to load", FALSE);
 
@@ -2329,7 +2330,7 @@
 static void menu_solve_event(GtkMenuItem *menuitem, gpointer data)
 {
     frontend *fe = (frontend *)data;
-    char *msg;
+    const char *msg;
 
     msg = midend_solve(fe->me);
 
@@ -2488,7 +2489,7 @@
     fe->me = midend_new(fe, &thegame, &gtk_drawing, fe);
 
     if (arg) {
-	char *err;
+	const char *err;
 	FILE *fp;
 
 	errbuf[0] = '\0';
@@ -3170,7 +3171,8 @@
 	 * generated descriptive game IDs.)
 	 */
 	while (ngenerate == 0 || i < n) {
-	    char *pstr, *err, *seed;
+	    char *pstr, *seed;
+            const char *err;
             struct rusage before, after;
 
 	    if (ngenerate == 0) {
@@ -3224,7 +3226,7 @@
                  * re-entering the same game id, and then try to solve
                  * it.
                  */
-                char *game_id, *err;
+                char *game_id;
 
                 game_id = midend_get_game_id(me);
                 err = midend_game_id(me, game_id);
@@ -3269,7 +3271,7 @@
 		sprintf(realname, "%s%d%s", savefile, i, savesuffix);
 
                 if (soln) {
-                    char *err = midend_solve(me);
+                    const char *err = midend_solve(me);
                     if (err) {
                         fprintf(stderr, "%s: unable to show solution: %s\n",
                                 realname, err);
--- a/guess.c
+++ b/guess.c
@@ -206,7 +206,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if (params->ncolours < 2 || params->npegs < 2)
 	return "Trivial solutions are uninteresting";
@@ -280,7 +280,7 @@
     return ret;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     unsigned char *bmp;
     int i;
@@ -360,7 +360,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     return dupstr("S");
 }
--- a/inertia.c
+++ b/inertia.c
@@ -191,7 +191,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     /*
      * Avoid completely degenerate cases which only have one
@@ -585,7 +585,7 @@
     return gengrid(params->w, params->h, rs);
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     int w = params->w, h = params->h, wh = w*h;
     int starts = 0, gems = 0, i;
@@ -729,7 +729,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     int w = currstate->p.w, h = currstate->p.h, wh = w*h;
     int *nodes, *nodeindex, *edges, *backedges, *edgei, *backedgei, *circuit;
@@ -1733,7 +1733,8 @@
 	    assert(ret->solnpos < ret->soln->len); /* or gems == 0 */
 	    assert(!ret->dead); /* or not a solution */
 	} else {
-	    char *error = NULL, *soln = solve_game(NULL, ret, NULL, &error);
+	    const char *error = NULL;
+            char *soln = solve_game(NULL, ret, NULL, &error);
 	    if (!error) {
 		install_new_solution(ret, soln);
 		sfree(soln);
--- a/keen.c
+++ b/keen.c
@@ -211,7 +211,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if (params->w < 3 || params->w > 9)
         return "Grid size must be between 3 and 9";
@@ -1203,7 +1203,7 @@
  * Gameplay.
  */
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     int w = params->w, a = w*w;
     int *dsf;
@@ -1345,7 +1345,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     int w = state->par.w, a = w*w;
     int i, ret;
@@ -2379,7 +2379,8 @@
 {
     game_params *p;
     game_state *s;
-    char *id = NULL, *desc, *err;
+    char *id = NULL, *desc;
+    const char *err;
     int grade = FALSE;
     int ret, diff, really_show_working = FALSE;
 
--- a/lightup.c
+++ b/lightup.c
@@ -342,7 +342,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if (params->w < 2 || params->h < 2)
         return "Width and height must be at least 2";
@@ -1624,7 +1624,7 @@
     return ret;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     int i;
     for (i = 0; i < params->w*params->h; i++) {
@@ -1695,7 +1695,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     game_state *solved;
     char *move = NULL, buf[80];
@@ -2326,7 +2326,8 @@
 {
     game_params *p;
     game_state *s;
-    char *id = NULL, *desc, *err, *result;
+    char *id = NULL, *desc, *result;
+    const char *err;
     int nsol, diff, really_verbose = 0;
     unsigned int sflags;
 
--- a/loopy.c
+++ b/loopy.c
@@ -232,7 +232,7 @@
     char *clue_satisfied;
 };
 
-static char *validate_desc(const game_params *params, const char *desc);
+static const char *validate_desc(const game_params *params, const char *desc);
 static int dot_order(const game_state* state, int i, char line_type);
 static int face_order(const game_state* state, int i, char line_type);
 static solver_state *solve_game_rec(const solver_state *sstate);
@@ -675,7 +675,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if (params->type < 0 || params->type >= NUM_GRID_TYPES)
         return "Illegal grid type";
@@ -756,7 +756,7 @@
 
 /* We require that the params pass the test in validate_params and that the
  * description fills the entire game area */
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     int count = 0;
     grid *g;
@@ -2908,7 +2908,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     char *soln = NULL;
     solver_state *sstate, *new_sstate;
@@ -3687,7 +3687,8 @@
 {
     game_params *p;
     game_state *s;
-    char *id = NULL, *desc, *err;
+    char *id = NULL, *desc;
+    const char *err;
     int grade = FALSE;
     int ret, diff;
 #if 0 /* verbose solver not supported here (yet) */
--- a/magnets.c
+++ b/magnets.c
@@ -227,7 +227,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if (params->w < 2) return "Width must be at least one";
     if (params->h < 2) return "Height must be at least one";
@@ -534,7 +534,7 @@
     return state;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     const char *prob;
     game_state *st = new_game_int(params, desc, &prob);
@@ -1450,7 +1450,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     game_state *solved = dup_game(currstate);
     char *move = NULL;
@@ -2535,7 +2535,8 @@
 int main(int argc, const char *argv[])
 {
     int print = 0, soak = 0, solved = 0, ret;
-    char *id = NULL, *desc, *desc_gen = NULL, *err, *aux = NULL;
+    char *id = NULL, *desc, *desc_gen = NULL, *aux = NULL;
+    const char *err;
     game_state *s = NULL;
     game_params *p = NULL;
     random_state *rs = NULL;
--- a/map.c
+++ b/map.c
@@ -248,7 +248,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if (params->w < 2 || params->h < 2)
 	return "Width and height must be at least two";
@@ -1776,7 +1776,7 @@
     return NULL;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     int w = params->w, h = params->h, wh = w*h, n = params->n;
     int area;
@@ -2186,7 +2186,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     if (!aux) {
 	/*
@@ -3235,7 +3235,8 @@
 {
     game_params *p;
     game_state *s;
-    char *id = NULL, *desc, *err;
+    char *id = NULL, *desc;
+    const char *err;
     int grade = FALSE;
     int ret, diff, really_verbose = FALSE;
     struct solver_scratch *sc;
--- a/midend.c
+++ b/midend.c
@@ -116,7 +116,7 @@
 /*
  * Forward reference.
  */
-static char *midend_deserialise_internal(
+static const char *midend_deserialise_internal(
     midend *me, int (*read)(void *ctx, void *buf, int len), void *rctx,
     char *(*check)(void *ctx, midend *, const struct deserialise_data *),
     void *cctx);
@@ -483,7 +483,8 @@
      */
     if (me->ourgame->can_solve && me->aux_info) {
 	game_state *s;
-	char *msg, *movestr;
+	const char *msg;
+        char *movestr;
 
 	msg = NULL;
 	movestr = me->ourgame->solve(me->states[0].state,
@@ -600,7 +601,7 @@
 
 static int midend_undo(midend *me)
 {
-    char *deserialise_error;
+    const char *deserialise_error;
 
     if (me->statepos > 1) {
         if (me->ui)
@@ -1392,9 +1393,10 @@
     return NULL;
 }
 
-static char *midend_game_id_int(midend *me, char *id, int defmode)
+static const char *midend_game_id_int(midend *me, char *id, int defmode)
 {
-    char *error, *par, *desc, *seed;
+    const char *error;
+    char *par, *desc, *seed;
     game_params *newcurparams, *newparams, *oldparams1, *oldparams2;
     int free_params;
 
@@ -1564,7 +1566,7 @@
     return NULL;
 }
 
-char *midend_game_id(midend *me, char *id)
+const char *midend_game_id(midend *me, char *id)
 {
     return midend_game_id_int(me, id, DEF_PARAMS);
 }
@@ -1597,9 +1599,9 @@
     return ret;
 }
 
-char *midend_set_config(midend *me, int which, config_item *cfg)
+const char *midend_set_config(midend *me, int which, config_item *cfg)
 {
-    char *error;
+    const char *error;
     game_params *params;
 
     switch (which) {
@@ -1645,10 +1647,11 @@
 	return NULL;
 }
 
-char *midend_solve(midend *me)
+const char *midend_solve(midend *me)
 {
     game_state *s;
-    char *msg, *movestr;
+    const char *msg;
+    char *movestr;
 
     if (!me->ourgame->can_solve)
 	return "This game does not support the Solve operation";
@@ -1907,7 +1910,7 @@
  * Like midend_deserialise proper, this function returns NULL on
  * success, or an error message.
  */
-static char *midend_deserialise_internal(
+static const char *midend_deserialise_internal(
     midend *me, int (*read)(void *ctx, void *buf, int len), void *rctx,
     char *(*check)(void *ctx, midend *, const struct deserialise_data *data),
     void *cctx)
@@ -2274,7 +2277,7 @@
     return ret;
 }
 
-char *midend_deserialise(
+const char *midend_deserialise(
     midend *me, int (*read)(void *ctx, void *buf, int len), void *rctx)
 {
     return midend_deserialise_internal(me, read, rctx, NULL, NULL);
@@ -2287,8 +2290,9 @@
  * allocated and should be caller-freed), or an error message on
  * failure.
  */
-char *identify_game(char **name, int (*read)(void *ctx, void *buf, int len),
-                    void *rctx)
+const char *identify_game(char **name,
+                          int (*read)(void *ctx, void *buf, int len),
+                          void *rctx)
 {
     int nstates = 0, statepos = -1, gotstates = 0;
     int started = FALSE;
@@ -2385,7 +2389,7 @@
     return ret;
 }
 
-char *midend_print_puzzle(midend *me, document *doc, int with_soln)
+const char *midend_print_puzzle(midend *me, document *doc, int with_soln)
 {
     game_state *soln = NULL;
 
@@ -2393,7 +2397,8 @@
 	return "No game set up to print";/* _shouldn't_ happen! */
 
     if (with_soln) {
-	char *msg, *movestr;
+	const char *msg;
+        char *movestr;
 
 	if (!me->ourgame->can_solve)
 	    return "This game does not support the Solve operation";
--- a/mines.c
+++ b/mines.c
@@ -239,7 +239,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     /*
      * Lower limit on grid size: each dimension must be at least 3.
@@ -1988,7 +1988,7 @@
     }
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     int wh = params->w * params->h;
     int x, y;
@@ -2298,7 +2298,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     if (!state->layout->mines) {
 	*error = "Game has not been started yet";
@@ -3227,7 +3227,8 @@
 {
     game_params *p;
     game_state *s;
-    char *id = NULL, *desc, *err;
+    char *id = NULL, *desc;
+    const char *err;
     int y, x;
 
     while (--argc > 0) {
--- a/nestedvm.c
+++ b/nestedvm.c
@@ -259,7 +259,7 @@
 void jcallback_config_ok()
 {
     frontend *fe = (frontend *)_fe;
-    char *err;
+    const char *err;
 
     err = midend_set_config(fe->me, fe->cfg_which, fe->cfg);
 
@@ -377,7 +377,7 @@
 int jcallback_solve_event()
 {
     frontend *fe = (frontend *)_fe;
-    char *msg;
+    const char *msg;
 
     msg = midend_solve(fe->me);
 
--- a/net.c
+++ b/net.c
@@ -306,7 +306,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if (params->width <= 0 || params->height <= 0)
 	return "Width and height must both be greater than zero";
@@ -1591,7 +1591,7 @@
     return desc;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     int w = params->width, h = params->height;
     int i;
@@ -1742,7 +1742,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     unsigned char *tiles;
     char *ret;
--- a/netslide.c
+++ b/netslide.c
@@ -302,7 +302,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if (params->width <= 1 || params->height <= 1)
 	return "Width and height must both be greater than one";
@@ -689,7 +689,7 @@
     return desc;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     int w = params->width, h = params->height;
     int i;
@@ -879,7 +879,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     if (!aux) {
 	*error = "Solution not known for this puzzle";
--- a/nullgame.c
+++ b/nullgame.c
@@ -78,7 +78,7 @@
     return NULL;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     return NULL;
 }
@@ -89,7 +89,7 @@
     return dupstr("FIXME");
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     return NULL;
 }
@@ -119,7 +119,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     return NULL;
 }
--- a/osx.m
+++ b/osx.m
@@ -789,7 +789,7 @@
 	const char *name = [[[op filenames] objectAtIndex:0]
                                cStringUsingEncoding:
                                    [NSString defaultCStringEncoding]];
-	char *err;
+	const char *err;
 
         FILE *fp = fopen(name, "r");
 
@@ -836,7 +836,7 @@
 
 - (void)solveGame:(id)sender
 {
-    char *msg;
+    const char *msg;
 
     msg = midend_solve(me);
 
--- a/palisade.c
+++ b/palisade.c
@@ -155,7 +155,7 @@
  * +---+   the dominos is horizontal or vertical.            +---+---+
  */
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     int w = params->w, h = params->h, k = params->k, wh = w * h;
 
@@ -701,7 +701,7 @@
     return sresize(numbers, p - numbers, clue);
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
 
     int w = params->w, h = params->h, wh = w*h, squares = 0;
@@ -782,7 +782,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     int w = state->shared->params.w, h = state->shared->params.h, wh = w*h;
     borderflag *move;
--- a/pattern.c
+++ b/pattern.c
@@ -171,7 +171,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if (params->w <= 0 || params->h <= 0)
 	return "Width and height must both be greater than zero";
@@ -885,7 +885,7 @@
     return desc;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     int i, n, rowspace;
     const char *p;
@@ -1045,7 +1045,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *ai, char **error)
+                        const char *ai, const char **error)
 {
     unsigned char *matrix;
     int w = state->common->w, h = state->common->h;
@@ -2021,7 +2021,8 @@
 {
     game_params *p;
     game_state *s;
-    char *id = NULL, *desc, *err;
+    char *id = NULL, *desc;
+    const char *err;
 
     while (--argc > 0) {
         char *p = *++argv;
--- a/pearl.c
+++ b/pearl.c
@@ -268,7 +268,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if (params->w < 5) return "Width must be at least five";
     if (params->h < 5) return "Height must be at least five";
@@ -1387,7 +1387,7 @@
     return desc;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     int i, sizesofar;
     const int totalsize = params->w * params->h;
@@ -1721,7 +1721,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     game_state *solved = dup_game(state);
     int i, ret, sz = state->shared->sz;
@@ -2707,7 +2707,8 @@
     game_params *p = NULL;
     random_state *rs = NULL;
     time_t seed = time(NULL);
-    char *id = NULL, *err;
+    char *id = NULL;
+    const char *err;
 
     setvbuf(stdout, NULL, _IONBF, 0);
 
--- a/pegs.c
+++ b/pegs.c
@@ -178,7 +178,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if (full && (params->w <= 3 || params->h <= 3))
 	return "Width and height must both be greater than three";
@@ -656,7 +656,7 @@
     return ret;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     int len = params->w * params->h;
 
@@ -707,7 +707,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     return NULL;
 }
--- a/puzzles.h
+++ b/puzzles.h
@@ -311,13 +311,13 @@
 int midend_wants_statusbar(midend *me);
 enum { CFG_SETTINGS, CFG_SEED, CFG_DESC, CFG_FRONTEND_SPECIFIC };
 config_item *midend_get_config(midend *me, int which, char **wintitle);
-char *midend_set_config(midend *me, int which, config_item *cfg);
-char *midend_game_id(midend *me, char *id);
+const char *midend_set_config(midend *me, int which, config_item *cfg);
+const char *midend_game_id(midend *me, char *id);
 char *midend_get_game_id(midend *me);
 char *midend_get_random_seed(midend *me);
 int midend_can_format_as_text_now(midend *me);
 char *midend_text_format(midend *me);
-char *midend_solve(midend *me);
+const char *midend_solve(midend *me);
 int midend_status(midend *me);
 int midend_can_undo(midend *me);
 int midend_can_redo(midend *me);
@@ -326,14 +326,15 @@
 void midend_serialise(midend *me,
                       void (*write)(void *ctx, void *buf, int len),
                       void *wctx);
-char *midend_deserialise(midend *me,
-                         int (*read)(void *ctx, void *buf, int len),
-                         void *rctx);
-char *identify_game(char **name, int (*read)(void *ctx, void *buf, int len),
-                    void *rctx);
+const char *midend_deserialise(midend *me,
+                               int (*read)(void *ctx, void *buf, int len),
+                               void *rctx);
+const char *identify_game(char **name,
+                          int (*read)(void *ctx, void *buf, int len),
+                          void *rctx);
 void midend_request_id_changes(midend *me, void (*notify)(void *), void *ctx);
 /* Printing functions supplied by the mid-end */
-char *midend_print_puzzle(midend *me, document *doc, int with_soln);
+const char *midend_print_puzzle(midend *me, document *doc, int with_soln);
 int midend_tilesize(midend *me);
 
 /*
@@ -589,10 +590,10 @@
     int can_configure;
     config_item *(*configure)(const game_params *params);
     game_params *(*custom_params)(const config_item *cfg);
-    char *(*validate_params)(const game_params *params, int full);
+    const char *(*validate_params)(const game_params *params, int full);
     char *(*new_desc)(const game_params *params, random_state *rs,
 		      char **aux, int interactive);
-    char *(*validate_desc)(const game_params *params, const char *desc);
+    const char *(*validate_desc)(const game_params *params, const char *desc);
     game_state *(*new_game)(midend *me, const game_params *params,
                             const char *desc);
     game_state *(*dup_game)(const game_state *state);
@@ -599,7 +600,7 @@
     void (*free_game)(game_state *state);
     int can_solve;
     char *(*solve)(const game_state *orig, const game_state *curr,
-                   const char *aux, char **error);
+                   const char *aux, const char **error);
     int can_format_as_text_ever;
     int (*can_format_as_text_now)(const game_params *params);
     char *(*text_format)(const game_state *state);
--- a/range.c
+++ b/range.c
@@ -308,7 +308,7 @@
 static move *solve_internal(const game_state *state, move *base, int diff);
 
 static char *solve_game(const game_state *orig, const game_state *curpos,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     int const n = orig->params.w * orig->params.h;
     move *const base = snewn(n, move);
@@ -906,7 +906,7 @@
     return k;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     int const w = params->w, h = params->h;
     if (w < 1) return "Error: width is less than 1";
@@ -1073,7 +1073,7 @@
     return desc;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     int const n = params->w * params->h;
     int squares = 0;
--- a/rect.c
+++ b/rect.c
@@ -214,7 +214,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if (params->w <= 0 || params->h <= 0)
 	return "Width and height must both be greater than zero";
@@ -1773,7 +1773,7 @@
     return desc;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     int area = params->w * params->h;
     int squares = 0;
@@ -1974,7 +1974,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *ai, char **error)
+                        const char *ai, const char **error)
 {
     unsigned char *vedge, *hedge;
     int x, y, len;
--- a/samegame.c
+++ b/samegame.c
@@ -281,7 +281,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if (params->w < 1 || params->h < 1)
 	return "Width and height must both be positive";
@@ -942,7 +942,7 @@
     return ret;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     int area = params->w * params->h, i;
     const char *p = desc;
@@ -1012,7 +1012,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     return NULL;
 }
--- a/signpost.c
+++ b/signpost.c
@@ -415,7 +415,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if (params->w < 1) return "Width must be at least one";
     if (params->h < 1) return "Height must be at least one";
@@ -843,7 +843,7 @@
     return ret;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     char *ret = NULL;
 
@@ -1337,7 +1337,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     game_state *tosolve;
     char *ret = NULL;
@@ -1559,7 +1559,7 @@
     if (move[0] == 'S') {
         game_params p;
 	game_state *tmp;
-        char *valid;
+        const char *valid;
 	int i;
 
         p.w = state->w; p.h = state->h;
@@ -2328,7 +2328,8 @@
 
 static void process_desc(char *id)
 {
-    char *desc, *err, *solvestr;
+    char *desc, *solvestr;
+    const char *err;
     game_params *p;
     game_state *s;
 
@@ -2372,7 +2373,8 @@
 
 int main(int argc, const char *argv[])
 {
-    char *id = NULL, *desc, *err, *aux = NULL;
+    char *id = NULL, *desc, *aux = NULL;
+    const char *err;
     int soak = 0, verbose = 0, stdin_desc = 0, n = 1, i;
     char *seedstr = NULL, newseed[16];
 
--- a/singles.c
+++ b/singles.c
@@ -251,7 +251,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if (params->w < 2 || params->h < 2)
 	return "Width and neight must be at least two";
@@ -1181,7 +1181,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     game_state *solved = dup_game(currstate);
     char *move = NULL;
@@ -1410,7 +1410,7 @@
     return ret;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     char *ret = NULL;
 
@@ -1906,7 +1906,8 @@
 
 int main(int argc, char **argv)
 {
-    char *id = NULL, *desc, *desc_gen = NULL, *tgame, *err, *aux;
+    char *id = NULL, *desc, *desc_gen = NULL, *tgame, *aux;
+    const char *err;
     game_state *s = NULL;
     game_params *p = NULL;
     int soln, soak = 0, ret = 1;
--- a/sixteen.c
+++ b/sixteen.c
@@ -169,7 +169,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if (params->w < 2 || params->h < 2)
 	return "Width and height must both be at least two";
@@ -396,7 +396,7 @@
 }
 
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     const char *p;
     char *err;
@@ -504,7 +504,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     return dupstr("S");
 }
--- a/slant.c
+++ b/slant.c
@@ -213,7 +213,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     /*
      * (At least at the time of writing this comment) The grid
@@ -1212,7 +1212,7 @@
     return desc;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     int w = params->w, h = params->h, W = w+1, H = h+1;
     int area = W*H;
@@ -1456,7 +1456,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     int w = state->p.w, h = state->p.h;
     signed char *soln;
@@ -2189,7 +2189,8 @@
 {
     game_params *p;
     game_state *s;
-    char *id = NULL, *desc, *err;
+    char *id = NULL, *desc;
+    const char *err;
     int grade = FALSE;
     int ret, diff, really_verbose = FALSE;
     struct solver_scratch *sc;
--- a/solo.c
+++ b/solo.c
@@ -501,7 +501,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if (params->c < 2)
 	return "Both dimensions must be at least 2";
@@ -3854,7 +3854,8 @@
  * end of the block spec, and return an error string or NULL if everything
  * is OK. The DSF is stored in *PDSF.
  */
-static char *spec_to_dsf(const char **pdesc, int **pdsf, int cr, int area)
+static const char *spec_to_dsf(const char **pdesc, int **pdsf,
+                               int cr, int area)
 {
     const char *desc = *pdesc;
     int pos = 0;
@@ -3922,7 +3923,7 @@
     return NULL;
 }
 
-static char *validate_grid_desc(const char **pdesc, int range, int area)
+static const char *validate_grid_desc(const char **pdesc, int range, int area)
 {
     const char *desc = *pdesc;
     int squares = 0;
@@ -3952,11 +3953,11 @@
     return NULL;
 }
 
-static char *validate_block_desc(const char **pdesc, int cr, int area,
-				 int min_nr_blocks, int max_nr_blocks,
-				 int min_nr_squares, int max_nr_squares)
+static const char *validate_block_desc(const char **pdesc, int cr, int area,
+                                       int min_nr_blocks, int max_nr_blocks,
+                                       int min_nr_squares, int max_nr_squares)
 {
-    char *err;
+    const char *err;
     int *dsf;
 
     err = spec_to_dsf(pdesc, &dsf, cr, area);
@@ -4029,10 +4030,10 @@
     return NULL;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     int cr = params->c * params->r, area = cr*cr;
-    char *err;
+    const char *err;
 
     err = validate_grid_desc(&desc, cr, area);
     if (err)
@@ -4109,7 +4110,7 @@
 	    state->immutable[i] = TRUE;
 
     if (r == 1) {
-	char *err;
+	const char *err;
 	int *dsf;
 	assert(*desc == ',');
 	desc++;
@@ -4127,7 +4128,7 @@
     make_blocks_from_whichblock(state->blocks);
 
     if (params->killer) {
-	char *err;
+	const char *err;
 	int *dsf;
 	assert(*desc == ',');
 	desc++;
@@ -4227,7 +4228,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *ai, char **error)
+                        const char *ai, const char **error)
 {
     int cr = state->cr;
     char *ret;
@@ -5577,7 +5578,8 @@
 {
     game_params *p;
     game_state *s;
-    char *id = NULL, *desc, *err;
+    char *id = NULL, *desc;
+    const char *err;
     int grade = FALSE;
     struct difficulty dlev;
 
--- a/tents.c
+++ b/tents.c
@@ -400,7 +400,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     /*
      * Generating anything under 4x4 runs into trouble of one kind
@@ -1186,7 +1186,7 @@
     return ret;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     int w = params->w, h = params->h;
     int area, i;
@@ -1312,7 +1312,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     int w = state->p.w, h = state->p.h;
 
@@ -2650,7 +2650,8 @@
 {
     game_params *p;
     game_state *s, *s2;
-    char *id = NULL, *desc, *err;
+    char *id = NULL, *desc;
+    const char *err;
     int grade = FALSE;
     int ret, diff, really_verbose = FALSE;
     struct solver_scratch *sc;
--- a/towers.c
+++ b/towers.c
@@ -235,7 +235,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if (params->w < 3 || params->w > 9)
         return "Grid size must be between 3 and 9";
@@ -799,7 +799,7 @@
  * Gameplay.
  */
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     int w = params->w, a = w*w;
     const char *p = desc;
@@ -967,7 +967,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     int w = state->par.w, a = w*w;
     int i, ret;
@@ -2018,7 +2018,8 @@
 {
     game_params *p;
     game_state *s;
-    char *id = NULL, *desc, *err;
+    char *id = NULL, *desc;
+    const char *err;
     int grade = FALSE;
     int ret, diff, really_show_working = FALSE;
 
--- a/tracks.c
+++ b/tracks.c
@@ -182,7 +182,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     /*
      * Generating anything under 4x4 runs into trouble of one kind
@@ -782,7 +782,7 @@
     return desc;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     int i = 0, w = params->w, h = params->h, in = 0, out = 0;
 
@@ -1364,7 +1364,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     game_state *solved;
     int ret;
--- a/twiddle.c
+++ b/twiddle.c
@@ -201,7 +201,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if (params->n < 2)
 	return "Rotating block size must be at least two";
@@ -422,7 +422,7 @@
     return ret;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     const char *p;
     int w = params->w, h = params->h, wh = w*h;
@@ -533,7 +533,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     return dupstr("S");
 }
--- a/undead.c
+++ b/undead.c
@@ -191,7 +191,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if ((params->w * params->h ) > 54)  return "Grid is too big";
     if (params->w < 3)                  return "Width must be at least 3";
@@ -1436,7 +1436,7 @@
     return state;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     int i;
     int w = params->w, h = params->h;
@@ -1489,7 +1489,7 @@
 }
 
 static char *solve_game(const game_state *state_start, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     int p;
     int *old_guess;
--- a/unequal.c
+++ b/unequal.c
@@ -248,7 +248,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if (params->order < 3 || params->order > 32)
         return "Order must be between 3 and 32";
@@ -1291,7 +1291,7 @@
     return state;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     char *why = NULL;
     game_state *dummy = load_game(params, desc, &why);
@@ -1304,7 +1304,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     game_state *solved;
     int r;
@@ -2123,7 +2123,7 @@
 
 static void check(game_params *p)
 {
-    char *msg = validate_params(p, 1);
+    const char *msg = validate_params(p, 1);
     if (msg) {
         fprintf(stderr, "%s: %s", quis, msg);
         exit(1);
@@ -2231,7 +2231,8 @@
         int i;
         for (i = 0; i < argc; i++) {
             const char *id = *argv++;
-            char *desc = strchr(id, ':'), *err;
+            char *desc = strchr(id, ':');
+            const char *err;
             p = default_params();
             if (desc) {
                 *desc++ = '\0';
--- a/unfinished/group.c
+++ b/unfinished/group.c
@@ -240,7 +240,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if (params->w < 3 || params->w > 26)
         return "Grid size must be between 3 and 26";
@@ -777,7 +777,7 @@
  * Gameplay.
  */
 
-static char *validate_grid_desc(const char **pdesc, int range, int area)
+static const char *validate_grid_desc(const char **pdesc, int range, int area)
 {
     const char *desc = *pdesc;
     int squares = 0;
@@ -807,7 +807,7 @@
     return NULL;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     int w = params->w, a = w*w;
     const char *p = desc;
@@ -907,7 +907,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     int w = state->par.w, a = w*w;
     int i, ret;
@@ -2106,7 +2106,8 @@
 {
     game_params *p;
     game_state *s;
-    char *id = NULL, *desc, *err;
+    char *id = NULL, *desc;
+    const char *err;
     digit *grid;
     int grade = FALSE;
     int ret, diff, really_show_working = FALSE;
--- a/unfinished/separate.c
+++ b/unfinished/separate.c
@@ -170,7 +170,7 @@
     return NULL;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     return NULL;
 }
@@ -646,7 +646,7 @@
     return desc;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     return NULL;
 }
@@ -676,7 +676,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     return NULL;
 }
--- a/unfinished/slide.c
+++ b/unfinished/slide.c
@@ -273,7 +273,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if (params->w > MAXWID)
 	return "Width must be at most " STR(MAXWID);
@@ -886,7 +886,7 @@
     return ret;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     int w = params->w, h = params->h, wh = w*h;
     int *active, *link;
@@ -1121,7 +1121,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     int *moves;
     int nmoves;
--- a/unfinished/sokoban.c
+++ b/unfinished/sokoban.c
@@ -233,7 +233,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if (params->w < 4 || params->h < 4)
 	return "Width and height must both be at least 4";
@@ -802,7 +802,7 @@
     return desc;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     int w = params->w, h = params->h;
     int area = 0;
@@ -899,7 +899,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     return NULL;
 }
--- a/unruly.c
+++ b/unruly.c
@@ -273,7 +273,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if ((params->w2 & 1) || (params->h2 & 1))
         return "Width and height must both be even";
@@ -315,7 +315,7 @@
     return NULL;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     int w2 = params->w2, h2 = params->h2;
     int s = w2 * h2;
@@ -1174,7 +1174,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     game_state *solved = dup_game(state);
     struct unruly_scratch *scratch = unruly_new_scratch(solved);
@@ -1972,7 +1972,8 @@
 
     game_params *params = NULL;
 
-    char *id = NULL, *desc = NULL, *err;
+    char *id = NULL, *desc = NULL;
+    const char *err;
 
     quis = argv[0];
 
--- a/untangle.c
+++ b/untangle.c
@@ -202,7 +202,7 @@
     return ret;
 }
 
-static char *validate_params(const game_params *params, int full)
+static const char *validate_params(const game_params *params, int full)
 {
     if (params->n < 4)
         return "Number of points must be at least four";
@@ -731,7 +731,7 @@
     return ret;
 }
 
-static char *validate_desc(const game_params *params, const char *desc)
+static const char *validate_desc(const game_params *params, const char *desc)
 {
     int a, b;
 
@@ -878,7 +878,7 @@
 }
 
 static char *solve_game(const game_state *state, const game_state *currstate,
-                        const char *aux, char **error)
+                        const char *aux, const char **error)
 {
     int n = state->params.n;
     int matrix[4];
--- a/windows.c
+++ b/windows.c
@@ -1002,7 +1002,7 @@
     document *doc;
     midend *nme = NULL;  /* non-interactive midend for bulk puzzle generation */
     int i;
-    char *err = NULL;
+    const char *err = NULL;
 
     /*
      * Create our document structure and fill it up with puzzles.
@@ -1586,7 +1586,7 @@
         midend_new_game(me);
     } else {
         FILE *fp;
-        char *err_param, *err_load;
+        const char *err_param, *err_load;
 
         /*
          * See if arg is a valid filename of a save game file.
@@ -2103,7 +2103,8 @@
     }
 }
 
-static char *frontend_set_config(frontend *fe, int which, config_item *cfg)
+static const char *frontend_set_config(
+    frontend *fe, int which, config_item *cfg)
 {
     if (which < CFG_FRONTEND_SPECIFIC) {
 	return midend_set_config(fe->me, which, cfg);
@@ -2276,7 +2277,8 @@
 	 */
 	if ((LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)) {
 	    if (LOWORD(wParam) == IDOK) {
-		char *err = frontend_set_config(fe, fe->cfg_which, fe->cfg);
+		const char *err = frontend_set_config(
+                    fe, fe->cfg_which, fe->cfg);
 
 		if (err) {
 		    MessageBox(hwnd, err, "Validation error",
@@ -3015,7 +3017,7 @@
 	    break;
 	  case IDM_SOLVE:
 	    {
-		char *msg = midend_solve(fe->me);
+		const char *msg = midend_solve(fe->me);
 		if (msg)
 		    MessageBox(hwnd, msg, "Unable to solve",
 			       MB_ICONERROR | MB_OK);
@@ -3107,7 +3109,8 @@
 			fclose(fp);
 		    } else {
 			FILE *fp = fopen(filename, "r");
-			char *err = NULL;
+			const char *err = NULL;
+                        char *err_w = NULL;
                         midend *me = fe->me;
 #ifdef COMBINED
                         char *id_name;
@@ -3135,7 +3138,8 @@
                                     "supported by this program";
                             } else {
                                 me = midend_for_new_game(fe, gamelist[i], NULL,
-                                                         FALSE, FALSE, &err);
+                                                         FALSE, FALSE, &err_w);
+                                err = err_w;
                                 rewind(fp); /* for the actual load */
                             }
                             sfree(id_name);
@@ -3148,6 +3152,7 @@
 
 			if (err) {
 			    MessageBox(hwnd, err, "Error", MB_ICONERROR|MB_OK);
+                            sfree(err_w);
 			    break;
 			}