[Freeciv-Dev] client string options: choosing from a list (v3) (PR#1856)
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Andreas Kemnade wrote:
Raimar Falke writes:
> readdir(3) is in SVID 3, POSIX, BSD 4.3. You have to do the matching
> by yourself however.
opendir/readdir/closedir are even present in mingw32. So it can be
used on windows, too.
OK, here's a new version using opendir/readdir/closedir.
Will this compile on windows (it won't have GUI support yet, of course)?
Will it compile on other platforms freeciv claims to work on?
jason
Index: client/audio.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/audio.c,v
retrieving revision 1.11
diff -u -r1.11 audio.c
--- client/audio.c 2002/07/23 02:48:45 1.11
+++ client/audio.c 2002/08/02 19:58:35
@@ -17,12 +17,15 @@
#include <string.h>
#include <assert.h>
+#include <stdio.h>
#include <stdlib.h>
+#include "audio.h"
#include "support.h"
#include "fcintl.h"
#include "log.h"
#include "capability.h"
+#include "mem.h"
#include "shared.h"
#include "registry.h"
#include "audio_none.h"
@@ -46,6 +49,7 @@
#include "audio.h"
#define MAX_NUM_PLUGINS 3
+#define SNDSPEC_SUFFIX ".spec"
/* keep it open throughout */
static struct section_file tagstruct, *tagfile = &tagstruct;
@@ -54,6 +58,43 @@
static int num_plugins_used = 0;
static int selected_plugin = -1;
+/**********************************************************************
+ Returns a static, NULL-terminated list of all sound plugins
+ available on the system. This function is unfortunately similar to
+ audio_get_all_plugin_names().
+***********************************************************************/
+const char **get_soundplugin_list(void)
+{
+ static const char* plugin_list[MAX_NUM_PLUGINS + 1];
+ int i;
+
+ for (i = 0; i < num_plugins_used; i++) {
+ plugin_list[i] = plugins[i].name;
+ }
+ assert(i <= MAX_NUM_PLUGINS);
+ plugin_list[i] = NULL;
+
+ return plugin_list;
+}
+
+/**********************************************************************
+ Returns a static list of soundsets available on the system by
+ searching all data directories for files matching SNDSPEC_SUFFIX.
+ The list is NULL-terminated.
+***********************************************************************/
+const char **get_soundset_list(void)
+{
+ static const char **audio_list = NULL;
+
+ if (!audio_list) {
+ /* Note: this means you must restart the client after installing a new
+ soundset. */
+ audio_list = datafilelist(SNDSPEC_SUFFIX);
+ }
+
+ return audio_list;
+}
+
/**************************************************************************
Add a plugin.
**************************************************************************/
@@ -128,6 +169,24 @@
#endif
}
+static char *soundspec_fullname(const char *soundset_name)
+{
+ char *soundset_default = "stdsounds"; /* Do not i18n! */
+ char *fname, *dname;
+
+ fname = fc_malloc(strlen(soundset_name) + strlen(SNDSPEC_SUFFIX) + 1);
+ sprintf(fname, "%s" SNDSPEC_SUFFIX, soundset_name);
+
+ dname = datafilename(fname);
+ if (dname
+ || strcmp(soundset_name, soundset_default) == 0) {
+ free(fname);
+ return NULL;
+ }
+
+ return soundspec_fullname(soundset_default);
+}
+
/**************************************************************************
Initialize audio system and autoselect a plugin
**************************************************************************/
@@ -161,7 +220,7 @@
exit(EXIT_FAILURE);
}
freelog(LOG_VERBOSE, "Initializing sound using %s...", spec_name);
- filename = datafilename(spec_name);
+ filename = soundspec_fullname(spec_name);
if (!filename) {
freelog(LOG_ERROR, _("Cannot find audio spec-file \"%s\"."), spec_name);
freelog(LOG_ERROR, _("To get sound you need to download a sound set!"));
Index: client/audio.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/audio.h,v
retrieving revision 1.2
diff -u -r1.2 audio.h
--- client/audio.h 2002/04/23 22:51:22 1.2
+++ client/audio.h 2002/08/02 19:58:35
@@ -28,6 +28,9 @@
bool (*play) (const char *const tag, const char *const path, bool repeat);
};
+const char **get_soundplugin_list(void);
+const char **get_soundset_list(void);
+
void audio_init(void);
void audio_real_init(const char *const spec_name,
const char *const prefered_plugin_name);
Index: client/options.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/options.c,v
retrieving revision 1.62
diff -u -r1.62 options.c
--- client/options.c 2002/07/23 02:48:45 1.62
+++ client/options.c 2002/08/02 19:58:36
@@ -20,6 +20,7 @@
#include <stdlib.h>
#include <string.h>
+#include "audio.h"
#include "clinet.h"
#include "events.h"
#include "fcintl.h"
@@ -28,6 +29,7 @@
#include "registry.h"
#include "shared.h"
#include "support.h"
+#include "tilespec.h"
#include "version.h"
#include "mem.h"
@@ -44,7 +46,7 @@
int default_server_port = DEFAULT_SOCK_PORT;
char default_metaserver[512] = METALIST_ADDR;
char default_tile_set_name[512] = "\0";
-char default_sound_set_name[512] = "stdsounds.spec";
+char default_sound_set_name[512] = "stdsounds";
char default_sound_plugin_name[512] = "\0";
/** Local Options: **/
@@ -66,22 +68,27 @@
bool meta_accelerators = TRUE;
#define GEN_INT_OPTION(name, desc) { #name, desc, COT_INT, \
- &name, NULL, NULL, 0, NULL }
+ &name, NULL, NULL, 0, NULL, NULL }
#define GEN_BOOL_OPTION(name, desc) { #name, desc, COT_BOOL, \
- NULL, &name, NULL, 0, NULL }
-#define GEN_STR_OPTION(name, desc) { #name, desc, COT_STR, \
- NULL, NULL, name, sizeof(name), NULL }
+ NULL, &name, NULL, 0, NULL, NULL }
+#define GEN_STR_OPTION(name, desc, dflt) { #name, desc, COT_STR, \
+ NULL, NULL, name, sizeof(name), \
+ dflt, NULL }
#define GEN_OPTION_TERMINATOR { NULL, NULL, COT_BOOL, \
NULL, NULL, NULL, 0, NULL }
client_option options[] = {
- GEN_STR_OPTION(default_player_name, N_("Default player's username")),
- GEN_STR_OPTION(default_server_host, N_("Default server")),
+ GEN_STR_OPTION(default_player_name, N_("Default player's username"),
+ NULL),
+ GEN_STR_OPTION(default_server_host, N_("Default server"), NULL),
GEN_INT_OPTION(default_server_port, N_("Default server's port")),
- GEN_STR_OPTION(default_metaserver, N_("Default metaserver")),
- GEN_STR_OPTION(default_tile_set_name, N_("Default tileset")),
- GEN_STR_OPTION(default_sound_set_name, N_("Default name of sound set")),
- GEN_STR_OPTION(default_sound_plugin_name, N_("Default sound plugin")),
+ GEN_STR_OPTION(default_metaserver, N_("Default metaserver"), NULL),
+ GEN_STR_OPTION(default_tile_set_name, N_("Default tileset"),
+ get_tileset_list),
+ GEN_STR_OPTION(default_sound_set_name, N_("Default name of sound set"),
+ get_soundset_list),
+ GEN_STR_OPTION(default_sound_plugin_name, N_("Default sound plugin"),
+ get_soundplugin_list),
GEN_BOOL_OPTION(solid_color_behind_units, N_("Solid unit background color")),
GEN_BOOL_OPTION(sound_bell_at_new_turn, N_("Sound bell at new turn")),
Index: client/options.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/options.h,v
retrieving revision 1.18
diff -u -r1.18 options.h
--- client/options.h 2002/07/23 02:48:45 1.18
+++ client/options.h 2002/08/02 19:58:36
@@ -59,6 +59,10 @@
char *p_string_value;
size_t string_length;
+ /* A function to return a static NULL-terminated list of possible
+ string values, or NULL for none. */
+ const char **(*p_string_vals)(void);
+
/* volatile */
void *p_gui_data;
} client_option;
Index: client/tilespec.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.c,v
retrieving revision 1.81
diff -u -r1.81 tilespec.c
--- client/tilespec.c 2002/07/27 14:14:23 1.81
+++ client/tilespec.c 2002/08/02 19:58:37
@@ -50,6 +50,8 @@
#include "tilespec.h"
+#define TILESPEC_SUFFIX ".tilespec"
+
char *main_intro_filename;
char *minimap_intro_filename;
@@ -115,6 +117,24 @@
static bool no_backdrop = FALSE;
/**********************************************************************
+ Returns a static list of tilesets available on the system by
+ searching all data directories for files matching TILESPEC_SUFFIX.
+ The list is NULL-terminated.
+***********************************************************************/
+const char **get_tileset_list(void)
+{
+ static const char **tileset_list = NULL;
+
+ if (!tileset_list) {
+ /* Note: this means you must restart the client after installing a new
+ tileset. */
+ tileset_list = datafilelist(TILESPEC_SUFFIX);
+ }
+
+ return tileset_list;
+}
+
+/**********************************************************************
Gets full filename for tilespec file, based on input name.
Returned data is allocated, and freed by user as required.
Input name may be null, in which case uses default.
@@ -135,8 +155,8 @@
if (tileset_name[0] == '\0') {
tileset_name = tileset_default;
}
- fname = fc_malloc(strlen(tileset_name)+16);
- sprintf(fname, "%s.tilespec", tileset_name);
+ fname = fc_malloc(strlen(tileset_name) + strlen(TILESPEC_SUFFIX) + 1);
+ sprintf(fname, "%s" TILESPEC_SUFFIX, tileset_name);
dname = datafilename(fname);
if (dname) {
Index: client/tilespec.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.h,v
retrieving revision 1.28
diff -u -r1.28 tilespec.h
--- client/tilespec.h 2002/04/06 11:42:57 1.28
+++ client/tilespec.h 2002/08/02 19:58:37
@@ -26,6 +26,8 @@
struct unit;
struct player;
+const char **get_tileset_list(void);
+
void tilespec_read_toplevel(const char *tileset_name);
void tilespec_load_tiles(void);
Index: client/gui-xaw/optiondlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-xaw/optiondlg.c,v
retrieving revision 1.19
diff -u -r1.19 optiondlg.c
--- client/gui-xaw/optiondlg.c 2002/07/23 02:47:38 1.19
+++ client/gui-xaw/optiondlg.c 2002/08/02 19:58:37
@@ -22,9 +22,12 @@
#include <X11/StringDefs.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/Label.h>
+#include <X11/Xaw/List.h>
#include <X11/Xaw/Command.h>
+#include <X11/Xaw/MenuButton.h>
#include <X11/Xaw/SimpleMenu.h>
#include <X11/Xaw/Scrollbar.h>
+#include <X11/Xaw/SmeBSB.h>
#include <X11/Xaw/AsciiText.h>
#include <X11/Xaw/Toggle.h>
@@ -77,7 +80,8 @@
XtVaSetValues((Widget) o->p_gui_data, XtNstring, valstr, NULL);
break;
case COT_STR:
- XtVaSetValues((Widget) o->p_gui_data, XtNstring,
+ XtVaSetValues((Widget) o->p_gui_data,
+ o->p_string_vals ? "label" : XtNstring,
o->p_string_value, NULL);
break;
}
@@ -90,6 +94,18 @@
+/****************************************************************
+ Callback to change the entry for a string option that has
+ a fixed list of possible entries.
+*****************************************************************/
+static void stropt_change_callback(Widget w,
+ XtPointer client_data,
+ XtPointer call_data)
+{
+ char* val = (char*)client_data;
+
+ XtVaSetValues(XtParent(XtParent(w)), "label", val, NULL);
+}
/****************************************************************
...
@@ -151,8 +167,49 @@
NULL);
XtAddCallback(prev_widget, XtNcallback, toggle_callback, NULL);
break;
- case COT_INT:
case COT_STR:
+ if (o->p_string_vals) {
+ int i;
+ const char **vals = (*o->p_string_vals)();
+ Widget popupmenu;
+
+ prev_widget = XtVaCreateManagedWidget(o->name,
+ menuButtonWidgetClass,
+ option_form,
+ XtNfromHoriz, longest_label,
+ XtNfromVert, o->p_gui_data,
+ NULL);
+
+ popupmenu = XtVaCreatePopupShell("menu",
+ simpleMenuWidgetClass,
+ prev_widget,
+ NULL);
+
+ for (i = 0; vals[i]; i++) {
+ Widget entry = XtVaCreateManagedWidget(vals[i], smeBSBObjectClass,
+ popupmenu, NULL);
+ XtAddCallback(entry, XtNcallback, stropt_change_callback,
+ (XtPointer)(vals[i]));
+ }
+
+ if (i == 0) {
+ /* We could disable this if there was just one possible choice,
+ too, but for values that are uninitialized (empty) this
+ would be confusing. */
+ XtSetSensitive(prev_widget, FALSE);
+ }
+
+#if 0
+ /* Setting the lable before the widget is drawn causes it to be
+ sized appropriately; if the value is empty this can be a
+ problem. */
+ XtVaSetValues(prev_widget, "label", o->p_string_value, NULL);
+#endif
+
+ break;
+ }
+ /* else fall through */
+ case COT_INT:
prev_widget =
XtVaCreateManagedWidget("input", asciiTextWidgetClass, option_form,
XtNfromHoriz, longest_label,
@@ -219,7 +276,9 @@
sscanf(dp, "%d", o->p_int_value);
break;
case COT_STR:
- XtVaGetValues(o->p_gui_data, XtNstring, &dp, NULL);
+ XtVaGetValues(o->p_gui_data,
+ o->p_string_vals ? "label" : XtNstring,
+ &dp, NULL);
mystrlcpy(o->p_string_value,dp,o->string_length);
break;
}
Index: common/shared.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/shared.c,v
retrieving revision 1.86
diff -u -r1.86 shared.c
--- common/shared.c 2002/06/12 07:24:47 1.86
+++ common/shared.c 2002/08/02 19:58:38
@@ -15,10 +15,13 @@
#endif
#include <assert.h>
+#include <dirent.h>
+#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/types.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
@@ -711,96 +714,226 @@
}
/***************************************************************************
- Returns a filename to access the specified file from a data directory;
- The file may be in any of the directories in the data path, which is
- specified internally or may be set as the environment variable
- $FREECIV_PATH. (A separated list of directories, where the separator
- itself can specified internally.)
- '~' at the start of a component (provided followed by '/' or '\0')
- is expanded as $HOME.
+ Returns a list of data directory paths, in the order in which they should
+ be searched. These paths are specified internally or may be set as the
+ environment variable $FREECIV_PATH (a separated list of directories,
+ where the separator itself is specified internally, platform-dependent).
+ '~' at the start of a component (provided followed by '/' or '\0') is
+ expanded as $HOME.
- If the specified 'filename' is NULL, the returned string contains
- the effective data path. (But this should probably only be used
- for debug output.)
-
- Returns NULL if the specified filename cannot be found in any of the
- data directories. (A file is considered "found" if it can be read-opened.)
- The returned pointer points to static memory, so this function can
- only supply one filename at a time.
+ The returned value is a static NULL-terminated list of strings.
+
+ num_dirs, if not NULL, will be set to the number of entries in the list.
***************************************************************************/
-char *datafilename(const char *filename)
+static const char **get_data_dirs(int *num_dirs)
{
- static char *path = NULL;
- static int num_dirs = 0;
- static char **dirs = NULL;
- static struct astring realfile = ASTRING_INIT;
- int i;
-
- if (!path) {
- char *tok;
- char *path2;
+ char *path, *path2, *tok;
+ static int num = 0;
+ static const char **dirs = NULL;
- path = getenv("FREECIV_PATH");
- if (!path) {
- path = DEFAULT_DATA_PATH;
- } else if (*path == '\0') {
- freelog(LOG_ERROR, _("FREECIV_PATH is set but empty; "
- "using default path instead."));
- path = DEFAULT_DATA_PATH;
+ /* The first time this function is called it will search and allocate
+ * the directory listing. Subsequently we will already know the list
+ * and can just return it. */
+ if (dirs) {
+ if (num_dirs) {
+ *num_dirs = num;
}
- assert(path != NULL);
+ return dirs;
+ }
- path2 = mystrdup(path); /* something we can strtok */
+ path = getenv("FREECIV_PATH");
+ if (!path) {
+ path = DEFAULT_DATA_PATH;
+ } else if (*path == '\0') {
+ freelog(LOG_ERROR, _("FREECIV_PATH is set but empty; "
+ "using default path instead."));
+ path = DEFAULT_DATA_PATH;
+ }
+ assert(path != NULL);
+
+ path2 = mystrdup(path); /* something we can strtok */
- tok = strtok(path2, PATH_SEPARATOR);
- do {
- int i; /* strlen(tok), or -1 as flag */
-
- tok = skip_leading_spaces(tok);
- remove_trailing_spaces(tok);
- if (strcmp(tok, "/")!=0) {
- remove_trailing_char(tok, '/');
- }
+ tok = strtok(path2, PATH_SEPARATOR);
+ do {
+ int i; /* strlen(tok), or -1 as flag */
+
+ tok = skip_leading_spaces(tok);
+ remove_trailing_spaces(tok);
+ if (strcmp(tok, "/")!=0) {
+ remove_trailing_char(tok, '/');
+ }
- i = strlen(tok);
- if (tok[0] == '~') {
- if (i>1 && tok[1] != '/') {
- freelog(LOG_ERROR, "For \"%s\" in data path cannot expand '~'"
- " except as '~/'; ignoring", tok);
- i = 0; /* skip this one */
+ i = strlen(tok);
+ if (tok[0] == '~') {
+ if (i>1 && tok[1] != '/') {
+ freelog(LOG_ERROR, "For \"%s\" in data path cannot expand '~'"
+ " except as '~/'; ignoring", tok);
+ i = 0; /* skip this one */
+ } else {
+ char *home = user_home_dir();
+ if (!home) {
+ freelog(LOG_VERBOSE,
+ "No HOME, skipping data path component %s", tok);
+ i = 0;
} else {
- char *home = user_home_dir();
- if (!home) {
- freelog(LOG_VERBOSE,
- "No HOME, skipping data path component %s", tok);
- i = 0;
- } else {
- int len = strlen(home) + i; /* +1 -1 */
- char *tmp = fc_malloc(len);
- my_snprintf(tmp, len, "%s%s", home, tok+1);
- tok = tmp;
- i = -1; /* flag to free tok below */
- }
+ int len = strlen(home) + i; /* +1 -1 */
+ char *tmp = fc_malloc(len);
+ my_snprintf(tmp, len, "%s%s", home, tok + 1);
+ tok = tmp;
+ i = -1; /* flag to free tok below */
}
+ }
+ }
+ if (i != 0) {
+ /* We could check whether the directory exists and
+ * is readable etc? Don't currently. */
+ num++;
+ dirs = fc_realloc(dirs, num * sizeof(char*));
+ dirs[num - 1] = mystrdup(tok);
+ freelog(LOG_VERBOSE, "Data path component (%d): %s", num - 1, tok);
+ if (i == -1) {
+ free(tok);
+ tok = NULL;
}
- if (i != 0) {
- /* We could check whether the directory exists and
- * is readable etc? Don't currently. */
- num_dirs++;
- dirs = fc_realloc(dirs, num_dirs*sizeof(char*));
- dirs[num_dirs-1] = mystrdup(tok);
- freelog(LOG_VERBOSE, "Data path component (%d): %s", num_dirs-1, tok);
- if (i == -1) {
- free(tok);
- tok = NULL;
+ }
+
+ tok = strtok(NULL, PATH_SEPARATOR);
+ } while(tok);
+
+ /* NULL-terminate the list. */
+ dirs = fc_realloc(dirs, (num + 1) * sizeof(char*));
+ dirs[num] = NULL;
+
+ free(path2);
+
+ if (num_dirs) {
+ *num_dirs = num;
+ }
+ return dirs;
+}
+
+/***************************************************************************
+ Returns a NULL-terminated list of filenames in the data directories
+ matching the given suffix.
+
+ The list is allocated when the function is called; it should either be
+ stored permanently or de-allocated (by free'ing each element and the
+ whole list).
+
+ The list is unsorted and may include duplicates (for now). The suffixes
+ are removed from the filenames before the list is returned.
+***************************************************************************/
+const char **datafilelist(const char* suffix)
+{
+ const char **dirs = get_data_dirs(NULL);
+ char **file_list = NULL;
+ int num_matches = 0;
+ int list_size = 0;
+ int dir_num, i, j;
+ int suffix_len = strlen(suffix);
+
+ assert(!strchr(suffix, '/'));
+
+ /* First assemble a full list of names. */
+ for (dir_num = 0; dirs[dir_num]; dir_num++) {
+ DIR* dir;
+ struct dirent *entry;
+
+ /* Open the directory for reading. */
+ dir = opendir(dirs[dir_num]);
+ if (!dir) {
+ freelog(LOG_ERROR, "Could not read data directory %s: %s.",
+ dirs[dir_num], strerror(errno));
+ continue;
+ }
+
+ /* Scan all entries in the directory. */
+ while ( (entry = readdir(dir)) ) {
+ int len = strlen(entry->d_name);
+
+ /* Make sure the file name matches. */
+ if (len << suffix_len
+ && !strcmp(suffix, entry->d_name + len - suffix_len)) {
+ /* Strdup the entry so we can safely write to it. */
+ char *match = mystrdup(entry->d_name);
+ char *next;
+ char *orig_match = match;
+
+ /* Make sure the list is big enough; grow exponentially to keep
+ constant ammortized overhead. */
+ if (num_matches >= list_size) {
+ list_size = list_size > 0 ? list_size * 2 : 10;
+ file_list = fc_realloc(file_list, list_size * sizeof(*file_list));
}
+
+ /* Clip the suffix. */
+ match[len - suffix_len] = '\0';
+
+ /* Skip past leading directories. */
+ while ( (next = strchr(match, '/')) ) {
+ match = next + 1;
+ }
+
+ /* Make sure the entry isn't empty (i.e. "~/.freeciv/.tilespec"). */
+ if (match[0] == '\0') {
+ continue;
+ }
+
+ file_list[num_matches++] = mystrdup(match);
+
+ free(orig_match);
}
+ }
+
+
+ closedir(dir);
+ }
+
+ /* Sort the list. */
+ qsort(file_list, num_matches, sizeof(*file_list), compare_strings_ptrs);
+
+ /* Remove duplicates (easy since it's sorted). */
+ i = j = 0;
+ while (j < num_matches) {
+ char *this = file_list[j];
+
+ for (j++; j < num_matches && !strcmp(this, file_list[j]); j++) {
+ free(file_list[j]);
+ }
- tok = strtok(NULL, PATH_SEPARATOR);
- } while(tok);
+ file_list[i] = this;
- free(path2);
+ i++;
}
+ num_matches = i;
+
+ /* NULL-terminate the whole thing. */
+ file_list = fc_realloc(file_list,
+ (num_matches + 1) * sizeof(*file_list));
+ file_list[num_matches] = NULL;
+
+ return (const char **)file_list;
+}
+
+/***************************************************************************
+ Returns a filename to access the specified file from a data directory by
+ searching all data directories (as specified by get_data_dirs) for the
+ file.
+
+ If the specified 'filename' is NULL, the returned string contains
+ the effective data path. (But this should probably only be used
+ for debug output.)
+
+ Returns NULL if the specified filename cannot be found in any of the
+ data directories. (A file is considered "found" if it can be read-opened.)
+ The returned pointer points to static memory, so this function can
+ only supply one filename at a time.
+***************************************************************************/
+char *datafilename(const char *filename)
+{
+ int num_dirs, i;
+ const char **dirs = get_data_dirs(&num_dirs);
+ static struct astring realfile = ASTRING_INIT;
if (!filename) {
int len = 1; /* in case num_dirs==0 */
@@ -812,7 +945,7 @@
realfile.str[0] = '\0';
for(i=0; i<num_dirs; i++) {
(void) mystrlcat(realfile.str, dirs[i], len);
- if(i != num_dirs-1) {
+ if (i < num_dirs) {
(void) mystrlcat(realfile.str, PATH_SEPARATOR, len);
}
}
Index: common/shared.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/shared.h,v
retrieving revision 1.95
diff -u -r1.95 shared.h
--- common/shared.h 2002/05/25 17:44:08 1.95
+++ common/shared.h 2002/08/02 19:58:38
@@ -109,6 +109,7 @@
char *user_home_dir(void);
char *user_username(void);
+const char **datafilelist(const char *suffix);
char *datafilename(const char *filename);
char *datafilename_required(const char *filename);
- [Freeciv-Dev] client string options: choosing from a list (v3) (PR#1856),
Jason Short <=
|
|