Complete.Org: Mailing Lists: Archives: freeciv-dev: May 1999:
[Freeciv-Dev] patch: data path
Home

[Freeciv-Dev] patch: data path

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: freeciv-dev@xxxxxxxxxxx
Subject: [Freeciv-Dev] patch: data path
From: David Pfitzner <dwp@xxxxxxxxxxxxxx>
Date: Wed, 26 May 1999 21:12:49 +1000 (EST)

David Pfitzner wrote:

> > On 1999-05-24 21:49:17, Martin Willemoes Hansen wrote:
> > > 4. Will 1.8.1 support home dirs? Like ~/freeciv
> > > 4a. A maps/scenarios, mods, savegames and tiles dir in ~/freeciv would
> > > make sence.

> I think a neat way to do this would be to make the datadir 
> PATH-like.

> (so, ~/freeciv vs ~/.freeciv ?)

Well, since ~/freeciv was a typo, plus everyone agrees on 
~/.freeciv :-), here is the patch.

The relevant env variable is now FREECIV_PATH, though you
won't usually need to set, it since it defaults to: (usually)
  "data:~/.freeciv:/usr/local/share/freeciv"
as planned.  You no longer need to set FREECIV_DATADIR
(eg, in the ser and civ scripts), though if it is set
it is prepended to the path.  (Not sure about that...)

This patch only affects things which currently use 
datafilename() (ruleset files, xpm files, and helpdata.txt),
and not yet eg civclientrc.

Regards,
-- David
diff -u -r --exclude-from exclude freeciv-cvs/civ fc-adv/civ
--- freeciv-cvs/civ     Wed Jun  3 19:18:12 1998
+++ fc-adv/civ  Wed May 26 14:46:03 1999
@@ -14,9 +14,10 @@
 #
 #***********************************************************************/
 DIR=`dirname $0`
-if [ "$FREECIV_DATADIR" = "" ] ; then
-    FREECIV_DATADIR=$DIR/data; export FREECIV_DATADIR
-fi
+
+#if [ "$FREECIV_DATADIR" = "" ] ; then
+#    FREECIV_DATADIR=$DIR/data; export FREECIV_DATADIR
+#fi
 
 [ -x $DIR/client/civclient ] && EXE=$DIR/client/civclient
 [ -x $DIR/civclient ] && EXE=$DIR/civclient
diff -u -r --exclude-from exclude freeciv-cvs/client/climisc.c 
fc-adv/client/climisc.c
--- freeciv-cvs/client/climisc.c        Tue Apr 20 00:11:47 1999
+++ fc-adv/client/climisc.c     Wed May 26 16:21:51 1999
@@ -42,22 +42,37 @@
 **************************************************************************/
 char *tilefilename(char *name)
 {
-  char *datadir=datafilename("");
   static char filename[256];
-  struct stat foo;
+  char *dname;
 
   /* first search tileset directory */
   if(tile_set_dir)  {
-    strcpy(filename,datadir);
-    strcat(filename,tile_set_dir);
+    strcpy(filename, tile_set_dir);
     if(filename[strlen(filename)-1]!='/') strcat(filename,"/");
-    strcat(filename,name);
-    if(!stat(filename,&foo)) return filename;
+    strcat(filename, name);
+    dname = datafilename(filename);
+    if (dname) return dname;
   }
 
   /* wasn't in tileset directory or no tileset specified, use default */
-  sprintf(filename,"%sdefault/%s",datadir,name);
-  return filename;
+  sprintf(filename, "default/%s", name);
+  dname = datafilename(filename);
+
+  /* might as well die now rather than pass the problem on: */
+  if (!dname) {
+    freelog(LOG_FATAL, "Could not find readable tile file \"%s\"", name);
+    if (tile_set_dir) {
+      freelog(LOG_FATAL, "Looked in \"%s\" and \"default\" subdirs in data 
path",
+             tile_set_dir);
+    } else {
+      freelog(LOG_FATAL, "Looked in \"default\" subdir in data path");
+    }
+    freelog(LOG_FATAL, "The data path may be set via"
+                      " the environment variable FREECIV_PATH");
+    freelog(LOG_FATAL, "Current data path is: \"%s\"", datafilename(NULL));
+    exit(1);
+  }
+  return dname;
 }
 
 
diff -u -r --exclude-from exclude freeciv-cvs/client/gui-gtk/graphics.c 
fc-adv/client/gui-gtk/graphics.c
--- freeciv-cvs/client/gui-gtk/graphics.c       Mon May 17 22:44:19 1999
+++ fc-adv/client/gui-gtk/graphics.c    Wed May 26 14:11:48 1999
@@ -349,9 +349,6 @@
 
   if(!(im=gdk_imlib_load_image(filename))) {
     freelog(LOG_FATAL, "Failed reading XPM file: %s", filename);
-    freelog(LOG_FATAL, "The environment variable FREECIV_DATADIR is '%s'",
-        getenv("FREECIV_DATADIR") ? getenv("FREECIV_DATADIR") : "");
-    freelog(LOG_FATAL, "Check if you got read permissions to the file");
     exit(1);
   }
 
diff -u -r --exclude-from exclude freeciv-cvs/client/gui-gtk/helpdlg.c 
fc-adv/client/gui-gtk/helpdlg.c
--- freeciv-cvs/client/gui-gtk/helpdlg.c        Wed May 26 20:39:20 1999
+++ fc-adv/client/gui-gtk/helpdlg.c     Wed May 26 21:03:26 1999
@@ -161,6 +161,7 @@
   static int booted=0;
   
   FILE *fs;
+  char *dfname;
   char buf[512], *p;
   char expect[32], name[MAX_LENGTH_NAME+2];
   char seen[MAX_LAST], *pname;
@@ -191,8 +192,18 @@
     freelog(LOG_DEBUG, "Rebooting help texts");
   }    
   
-  fs=fopen(datafilename("helpdata.txt"), "r");
-  if(fs==NULL) {
+  dfname = datafilename("helpdata.txt");
+  if (dfname == NULL) {
+    freelog(LOG_NORMAL, "Could not find readable helpdata.txt in data path");
+    freelog(LOG_NORMAL, "The data path may be set via"
+                       " the environment variable FREECIV_PATH");
+    freelog(LOG_NORMAL, "Current data path is: \"%s\"", datafilename(NULL));
+    freelog(LOG_NORMAL, "Did not read help texts");
+    return;
+  }
+  fs = fopen(dfname, "r");
+  if (fs == NULL) {
+    /* this is now unlikely to happen */
     freelog(LOG_NORMAL, "failed reading help-texts");
     return;
   }
diff -u -r --exclude-from exclude freeciv-cvs/client/gui-xaw/graphics.c 
fc-adv/client/gui-xaw/graphics.c
--- freeciv-cvs/client/gui-xaw/graphics.c       Wed May 12 21:33:12 1999
+++ fc-adv/client/gui-xaw/graphics.c    Wed May 26 14:11:31 1999
@@ -361,11 +361,7 @@
       color_error();
       goto again;
     }
-    
     freelog(LOG_FATAL, "Failed reading XPM file: %s", filename);
-    freelog(LOG_FATAL, "The environment variable FREECIV_DATADIR is '%s'",
-       getenv("FREECIV_DATADIR") ? getenv("FREECIV_DATADIR") : "");
-    freelog(LOG_FATAL, "Check if you got read permissions to the file");
     exit(1);
   }
 
diff -u -r --exclude-from exclude freeciv-cvs/client/gui-xaw/helpdlg.c 
fc-adv/client/gui-xaw/helpdlg.c
--- freeciv-cvs/client/gui-xaw/helpdlg.c        Sat May  1 14:07:25 1999
+++ fc-adv/client/gui-xaw/helpdlg.c     Wed May 26 21:03:29 1999
@@ -162,6 +162,7 @@
   static int booted=0;
   
   FILE *fs;
+  char *dfname;
   char buf[512], *p;
   char expect[32], name[MAX_LENGTH_NAME+2];
   char seen[MAX_LAST], *pname;
@@ -192,8 +193,18 @@
     freelog(LOG_DEBUG, "Rebooting help texts");
   }    
   
-  fs=fopen(datafilename("helpdata.txt"), "r");
-  if(fs==NULL) {
+  dfname = datafilename("helpdata.txt");
+  if (dfname == NULL) {
+    freelog(LOG_NORMAL, "Could not find readable helpdata.txt in data path");
+    freelog(LOG_NORMAL, "The data path may be set via"
+                       " the environment variable FREECIV_PATH");
+    freelog(LOG_NORMAL, "Current data path is: \"%s\"", datafilename(NULL));
+    freelog(LOG_NORMAL, "Did not read help texts");
+    return;
+  }
+  fs = fopen(dfname, "r");
+  if (fs == NULL) {
+    /* this is now unlikely to happen */
     freelog(LOG_NORMAL, "failed reading help-texts");
     return;
   }
diff -u -r --exclude-from exclude freeciv-cvs/common/shared.c 
fc-adv/common/shared.c
--- freeciv-cvs/common/shared.c Mon Apr 26 17:16:17 1999
+++ fc-adv/common/shared.c      Wed May 26 15:10:30 1999
@@ -14,15 +14,16 @@
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
+#include <assert.h>
 
 #include <shared.h>
 #include <mem.h>
+#include <log.h>
 
 #ifndef FREECIV_DATADIR
 #define FREECIV_DATADIR "data"
 #endif
 
-
 /* Random Number Generator variables */
 RANDOM_TYPE RandomState[56];
 int iRandJ, iRandK, iRandX; 
@@ -335,30 +336,203 @@
    mode = mode+1 % 2;
 }
 
+/***************************************************************************
+  Returns 's' incremented to first non-space character.
+***************************************************************************/
+char *remove_leading_spaces(char *s)
+{
+  assert(s!=NULL);
+  while(*s && isspace(*s)) {
+    s++;
+  }
+  return s;
+}
+
+/***************************************************************************
+  Terminates string pointed to by 's' to remove traling spaces;
+  Note 's' must point to writeable memory!
+***************************************************************************/
+void remove_trailing_spaces(char *s)
+{
+  char *t;
+  
+  assert(s!=NULL);
+  t = s + strlen(s) -1;
+  while(t>=s && isspace(*t)) {
+    *t = '\0';
+    t--;
+  }
+}
 
 /***************************************************************************
-Prepend the data directory to the filename to get the
-relative path to a file in the data directory.
-Use environment variable and check that its sane.
-(Used to be in client/climisc.c)
-The returned pointer points to static memory, so this can
-only supply one filename at a time.
+  As remove_trailing_spaces(), for specified char.
+***************************************************************************/
+void remove_trailing_char(char *s, char trailing)
+{
+  char *t;
+  
+  assert(s!=NULL);
+  t = s + strlen(s) -1;
+  while(t>=s && (*t) == trailing) {
+    *t = '\0';
+    t--;
+  }
+}
+
+/***************************************************************************
+  Returns string which gives users home dir, as specified by $HOME.
+  Gets value once, and then caches result.
+  If $HOME is not set, give a log message and returns NULL.
+  Note the caller should not mess with the returned pointer or
+  the string pointed to.
+***************************************************************************/
+char *user_home_dir(void)
+{
+  static int init = 0;
+  static char *home_dir = NULL;
+  
+  if (!init) {
+    char *env = getenv("HOME");
+    if (env) {
+      home_dir = mystrdup(env);                /* never free()d */
+      freelog(LOG_DEBUG, "HOME is %s", home_dir);
+    } else {
+      freelog(LOG_NORMAL, "Could not find home directory (HOME is not set)");
+      home_dir = NULL;
+    }
+    init = 1;
+  }
+  return home_dir;
+}
+
+/***************************************************************************
+  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 colon-separated list of directories.)
+  (For backward compatability the directory specified by $FREECIV_DATADIR
+  (if any) is prepended to this path.  (Is this desirable?))
+  '~' 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.
 ***************************************************************************/
 char *datafilename(char *filename)
 {
-  static char* datadir=0;
-  static char  realfile[512];
-  if(!datadir) {
-    if((datadir = getenv("FREECIV_DATADIR"))) {
-      int i;
-      for(i=strlen(datadir)-1; i>=0 && isspace((int)datadir[i]); i--)
-       datadir[i] = '\0';
-      if(datadir[i] == '/')
-       datadir[i] = '\0';
+  static int init = 0;
+  static int num_dirs = 0;
+  static char **dirs = NULL;
+  static char *realfile = NULL;
+  static int n_alloc_realfile = 0;
+  int i;
+
+  if (!init) {
+    char *tok;
+    char *path = getenv("FREECIV_PATH");
+    char *data = getenv("FREECIV_DATADIR");
+    if (!path) {
+      path = "data:~/.freeciv:" FREECIV_DATADIR;
+      /* Note: pre-processor string concatenation.
+       * The leading "data" means in the current dir.
+       */
+    }
+    if (data) {
+      char *tmp = fc_malloc(strlen(data) + strlen(path) + 2);
+      sprintf(tmp, "%s:%s", data, path);
+      path = tmp;
     } else {
-      datadir = FREECIV_DATADIR; /* correct if not 'data' is the default */
-    };
-  };
-  sprintf(realfile,"%s/%s",datadir,filename);
-  return(realfile);
+      path = mystrdup(path);   /* something we can strtok */
+    }
+    
+    tok = strtok(path, ":");
+    do {
+      int i;                   /* strlen(tok), or -1 as flag */
+      
+      tok = remove_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_NORMAL, "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_DEBUG, "No HOME, skipping data path component %s", tok);
+           i = 0;
+         } else {
+           char *tmp = fc_malloc(strlen(home) + i);    /* +1 -1 */
+           sprintf(tmp, "%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++;
+       dirs = fc_realloc(dirs, num_dirs*sizeof(char*));
+       dirs[num_dirs-1] = mystrdup(tok);
+       freelog(LOG_DEBUG, "Data path component (%d): %s", num_dirs-1, tok);
+       if (i == -1) {
+         free(tok);
+       }
+      }
+
+      tok = strtok(NULL, ":");
+    } while(tok != NULL);
+
+    free(path);
+    init = 1;
+  }
+
+  if (filename == NULL) {
+    int len = 1;               /* in case num_dirs==0 */
+    for(i=0; i<num_dirs; i++) {
+      len += strlen(dirs[i]) + 1; /* ':' or '\0' */
+    }
+    if (len > n_alloc_realfile) {
+      realfile = fc_realloc(realfile, len);
+      n_alloc_realfile = len;
+    }
+    realfile[0] = '\0';
+    for(i=0; i<num_dirs; i++) {
+      strcat(realfile, dirs[i]);
+      if(i != num_dirs-1) {
+       strcat(realfile, ":");
+      }
+    }
+    return realfile;
+  }
+  
+  for(i=0; i<num_dirs; i++) {
+    FILE *fp;                  /* see if we can open the file */
+    int len = strlen(dirs[i]) + strlen(filename) + 2;
+    
+    if (len > n_alloc_realfile) {
+      realfile = fc_realloc(realfile, len);
+      n_alloc_realfile = len;
+    } 
+    sprintf(realfile,"%s/%s", dirs[i], filename);
+    fp = fopen(realfile, "r");
+    if (fp) {
+      fclose(fp);
+      return realfile;
+    }
+  }
+  return NULL;
 }
+
diff -u -r --exclude-from exclude freeciv-cvs/common/shared.h 
fc-adv/common/shared.h
--- freeciv-cvs/common/shared.h Mon May 24 19:30:35 1999
+++ fc-adv/common/shared.h      Wed May 26 14:40:58 1999
@@ -112,11 +112,17 @@
 char *get_dot_separated_int(unsigned val);
 int mystrcasecmp(char *str0, char *str1);
 char *mystrerror(int errnum);
+int string_ptr_compare(const void *first, const void *second);
+
 RANDOM_TYPE myrand(int size);
 void mysrand(RANDOM_TYPE seed);
-int string_ptr_compare(const void *first, const void *second);
 void save_restore_random(void);
 
-char *datafilename(char *filename);    /* used to be in client/climisc */
+char *remove_leading_spaces(char *s);
+void remove_trailing_spaces(char *s);
+void remove_trailing_char(char *s, char trailing);
+
+char *user_home_dir(void);
+char *datafilename(char *filename);
 
 #endif
diff -u -r --exclude-from exclude freeciv-cvs/ser fc-adv/ser
--- freeciv-cvs/ser     Wed Jan 20 21:30:55 1999
+++ fc-adv/ser  Wed May 26 14:45:58 1999
@@ -14,9 +14,10 @@
 #
 #***********************************************************************/
 DIR=`dirname $0`
-if [ "$FREECIV_DATADIR" = "" ] ; then
-    FREECIV_DATADIR=$DIR/data; export FREECIV_DATADIR
-fi
+
+#if [ "$FREECIV_DATADIR" = "" ] ; then
+#    FREECIV_DATADIR=$DIR/data; export FREECIV_DATADIR
+#fi
 
 [ -x $DIR/server/civserver ] && EXE=$DIR/server/civserver
 [ -x $DIR/civserver ] && EXE=$DIR/civserver
diff -u -r --exclude-from exclude freeciv-cvs/server/ruleset.c 
fc-adv/server/ruleset.c
--- freeciv-cvs/server/ruleset.c        Thu Feb 11 18:05:59 1999
+++ fc-adv/server/ruleset.c     Wed May 26 16:21:06 1999
@@ -58,7 +58,15 @@
 
   sprintf(filename, "%s/%s.ruleset", subdir, whichset);
   dfilename = datafilename(filename);
-  if(!section_file_load(file,dfilename)) {
+  if (!dfilename) {
+    freelog(LOG_FATAL, "Could not find readable ruleset file %s in data path",
+           filename);
+    freelog(LOG_FATAL, "The data path may be set via"
+                      " the environment variable FREECIV_PATH");
+    freelog(LOG_FATAL, "Current data path is: \"%s\"", datafilename(NULL));
+    exit(1);
+  }
+  if (!section_file_load(file,dfilename)) {
     freelog(LOG_FATAL, "Could not load ruleset file %s", dfilename);
     exit(1);
   }

[Prev in Thread] Current Thread [Next in Thread]