rocksndiamonds-3.0.8
[rocksndiamonds.git] / src / libgame / misc.c
index cb06ff4697ac1488b8c07705a41734a5589f0985..06ca9357c65f87d792349e44d0fcacaf074098c7 100644 (file)
@@ -82,6 +82,26 @@ char *int2str(int number, int size)
   }
 }
 
+/* something similar to "int2str()" above, but allocates its own memory
+   and has a different interface; we cannot use "itoa()", because this
+   seems to be already defined when cross-compiling to the win32 target */
+
+char *i_to_a(unsigned int i)
+{
+  static char *a = NULL;
+
+  checked_free(a);
+
+  if (i > 2147483647)  /* yes, this is a kludge */
+    i = 2147483647;
+
+  a = checked_malloc(10 + 1);
+
+  sprintf(a, "%d", i);
+
+  return a;
+}
+
 
 /* ------------------------------------------------------------------------- */
 /* counter functions                                                         */
@@ -262,48 +282,6 @@ void WaitUntilDelayReached(unsigned long *counter_var, unsigned long delay)
 /* random generator functions                                                */
 /* ------------------------------------------------------------------------- */
 
-#if 0
-unsigned int SimpleRND(unsigned int max)
-{
-  return (random_linux_libc(RND_FREE) % max);
-}
-
-unsigned int InitSimpleRND(long seed)
-{
-  if (seed == NEW_RANDOMIZE)
-  {
-    struct timeval current_time;
-
-    gettimeofday(&current_time, NULL);
-    seed = (long)current_time.tv_usec;
-  }
-
-  srandom_linux_libc(RND_FREE, (unsigned int) seed);
-
-  return (unsigned int) seed;
-}
-
-unsigned int RND(unsigned int max)
-{
-  return (random_linux_libc(RND_GAME) % max);
-}
-
-unsigned int InitRND(long seed)
-{
-  if (seed == NEW_RANDOMIZE)
-  {
-    struct timeval current_time;
-
-    gettimeofday(&current_time, NULL);
-    seed = (long)current_time.tv_usec;
-  }
-
-  srandom_linux_libc(RND_GAME, (unsigned int) seed);
-
-  return (unsigned int) seed;
-}
-#endif
-
 unsigned int init_random_number(int nr, long seed)
 {
   if (seed == NEW_RANDOMIZE)
@@ -323,27 +301,10 @@ unsigned int init_random_number(int nr, long seed)
   return (unsigned int) seed;
 }
 
-#if 1
-unsigned int get_random_number(int nr, unsigned int max)
+unsigned int get_random_number(int nr, int max)
 {
   return (max > 0 ? random_linux_libc(nr) % max : 0);
 }
-#else
-unsigned int get_random_number(int nr, unsigned int max)
-{
-  unsigned int rnd = (max > 0 ? random_linux_libc(nr) % max : 0);
-
-  if (nr == 0 && FrameCounter < 2)
-    printf("::: %d [%d]\n", rnd, FrameCounter);
-
-#if 0
-  if (nr == 0 && FrameCounter < 2 && rnd == 8)
-    rnd /= 0;
-#endif
-
-  return rnd;
-}
-#endif
 
 
 /* ------------------------------------------------------------------------- */
@@ -539,8 +500,7 @@ char *getStringToLower(char *s)
 
 void setString(char **old_value, char *new_value)
 {
-  if (*old_value != NULL)
-    free(*old_value);
+  checked_free(*old_value);
 
   *old_value = getStringCopy(new_value);
 }
@@ -822,7 +782,7 @@ void Error(int mode, char *format, ...)
 
 
 /* ------------------------------------------------------------------------- */
-/* memory allocation functions                                               */
+/* checked memory allocation and freeing functions                           */
 /* ------------------------------------------------------------------------- */
 
 void *checked_malloc(unsigned long size)
@@ -859,6 +819,12 @@ void *checked_realloc(void *ptr, unsigned long size)
   return ptr;
 }
 
+void checked_free(void *ptr)
+{
+  if (ptr != NULL)     /* this check should be done by free() anyway */
+    free(ptr);
+}
+
 
 /* ------------------------------------------------------------------------- */
 /* various helper functions                                                  */
@@ -1518,8 +1484,7 @@ boolean fileHasPrefix(char *basename, char *prefix)
   static char *basename_lower = NULL;
   int basename_length, prefix_length;
 
-  if (basename_lower != NULL)
-    free(basename_lower);
+  checked_free(basename_lower);
 
   if (basename == NULL || prefix == NULL)
     return FALSE;
@@ -1541,8 +1506,7 @@ boolean fileHasSuffix(char *basename, char *suffix)
   static char *basename_lower = NULL;
   int basename_length, suffix_length;
 
-  if (basename_lower != NULL)
-    free(basename_lower);
+  checked_free(basename_lower);
 
   if (basename == NULL || suffix == NULL)
     return FALSE;
@@ -1843,7 +1807,7 @@ static boolean token_suffix_match(char *token, char *suffix, int start_pos)
   return FALSE;
 }
 
-#define KNOWN_TOKEN_VALUE      "[KNOWN_TOKEN]"
+#define KNOWN_TOKEN_VALUE      "[KNOWN_TOKEN_VALUE]"
 
 static void read_token_parameters(SetupFileHash *setup_file_hash,
                                  struct ConfigInfo *suffix_list,
@@ -1960,7 +1924,8 @@ static void LoadArtworkConfigFromFilename(struct ArtworkListInfo *artwork_info,
   int num_ext2_suffixes = artwork_info->num_ext2_suffixes;
   int num_ext3_suffixes = artwork_info->num_ext3_suffixes;
   int num_ignore_tokens = artwork_info->num_ignore_tokens;
-  SetupFileHash *setup_file_hash, *extra_file_hash;
+  SetupFileHash *setup_file_hash, *valid_file_hash;
+  SetupFileHash *extra_file_hash, *empty_file_hash;
   char *known_token_value = KNOWN_TOKEN_VALUE;
   int i, j, k, l;
 
@@ -1974,26 +1939,42 @@ static void LoadArtworkConfigFromFilename(struct ArtworkListInfo *artwork_info,
   if ((setup_file_hash = loadSetupFileHash(filename)) == NULL)
     return;
 
+  /* separate valid (defined) from empty (undefined) config token values */
+  valid_file_hash = newSetupFileHash();
+  empty_file_hash = newSetupFileHash();
+  BEGIN_HASH_ITERATION(setup_file_hash, itr)
+  {
+    char *value = HASH_ITERATION_VALUE(itr);
+
+    setHashEntry(*value ? valid_file_hash : empty_file_hash,
+                HASH_ITERATION_TOKEN(itr), value);
+  }
+  END_HASH_ITERATION(setup_file_hash, itr)
+
+  /* at this point, we do not need the setup file hash anymore -- free it */
+  freeSetupFileHash(setup_file_hash);
+
   /* read parameters for all known config file tokens */
   for (i = 0; i < num_file_list_entries; i++)
-    read_token_parameters(setup_file_hash, suffix_list, &file_list[i]);
+    read_token_parameters(valid_file_hash, suffix_list, &file_list[i]);
 
   /* set all tokens that can be ignored here to "known" keyword */
   for (i = 0; i < num_ignore_tokens; i++)
-    setHashEntry(setup_file_hash, ignore_tokens[i], known_token_value);
+    setHashEntry(valid_file_hash, ignore_tokens[i], known_token_value);
 
-  /* copy all unknown config file tokens to extra config list */
+  /* copy all unknown config file tokens to extra config hash */
   extra_file_hash = newSetupFileHash();
-  BEGIN_HASH_ITERATION(setup_file_hash, itr)
+  BEGIN_HASH_ITERATION(valid_file_hash, itr)
   {
-    if (strcmp(HASH_ITERATION_VALUE(itr), known_token_value) != 0)
-      setHashEntry(extra_file_hash,
-                  HASH_ITERATION_TOKEN(itr), HASH_ITERATION_VALUE(itr));
+    char *value = HASH_ITERATION_VALUE(itr);
+
+    if (strcmp(value, known_token_value) != 0)
+      setHashEntry(extra_file_hash, HASH_ITERATION_TOKEN(itr), value);
   }
-  END_HASH_ITERATION(setup_file_hash, itr)
+  END_HASH_ITERATION(valid_file_hash, itr)
 
-  /* at this point, we do not need the config file hash anymore -- free it */
-  freeSetupFileHash(setup_file_hash);
+  /* at this point, we do not need the valid file hash anymore -- free it */
+  freeSetupFileHash(valid_file_hash);
 
   /* now try to determine valid, dynamically defined config tokens */
 
@@ -2210,11 +2191,12 @@ static void LoadArtworkConfigFromFilename(struct ArtworkListInfo *artwork_info,
                     artwork_info->sizeof_artwork_list_entry);
   }
 
-  if (extra_file_hash != NULL && options.verbose && IS_PARENT_PROCESS())
+  if (options.verbose && IS_PARENT_PROCESS())
   {
     SetupFileList *setup_file_list, *list;
     boolean dynamic_tokens_found = FALSE;
     boolean unknown_tokens_found = FALSE;
+    boolean undefined_values_found = (hashtable_count(empty_file_hash) != 0);
 
     if ((setup_file_list = loadSetupFileList(filename)) == NULL)
       Error(ERR_EXIT, "loadSetupFileHash works, but loadSetupFileList fails");
@@ -2262,10 +2244,28 @@ static void LoadArtworkConfigFromFilename(struct ArtworkListInfo *artwork_info,
       Error(ERR_RETURN_LINE, "-");
     }
 
+    if (undefined_values_found)
+    {
+      Error(ERR_RETURN_LINE, "-");
+      Error(ERR_RETURN, "warning: undefined values found in config file:");
+      Error(ERR_RETURN, "- config file: '%s'", filename);
+
+      for (list = setup_file_list; list != NULL; list = list->next)
+      {
+       char *value = getHashEntry(empty_file_hash, list->token);
+
+       if (value != NULL)
+         Error(ERR_RETURN, "- undefined value for token: '%s'", list->token);
+      }
+
+      Error(ERR_RETURN_LINE, "-");
+    }
+
     freeSetupFileList(setup_file_list);
   }
 
   freeSetupFileHash(extra_file_hash);
+  freeSetupFileHash(empty_file_hash);
 
 #if 0
   for (i = 0; i < num_file_list_entries; i++)