Author: cazfi
Date: Fri Dec 25 18:56:35 2015
New Revision: 31201

URL: http://svn.gna.org/viewcvs/freeciv?rev=31201&view=rev
Log:
Added support for floating point numbers in section files.

See patch #6723

Modified:
    branches/S2_6/client/options.c
    branches/S2_6/server/ruleset.c
    branches/S2_6/server/savecompat.c
    branches/S2_6/server/savegame.c
    branches/S2_6/utility/inputfile.c
    branches/S2_6/utility/inputfile.h
    branches/S2_6/utility/registry_ini.c
    branches/S2_6/utility/registry_ini.h
    branches/S2_6/utility/section_file.c
    branches/S2_6/utility/shared.c
    branches/S2_6/utility/shared.h

Modified: branches/S2_6/client/options.c
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_6/client/options.c?rev=31201&r1=31200&r2=31201&view=diff
==============================================================================
--- branches/S2_6/client/options.c      (original)
+++ branches/S2_6/client/options.c      Fri Dec 25 18:56:35 2015
@@ -4964,6 +4964,10 @@
     case ENTRY_STR:
       (void) entry_str_get(pentry, &string);
       break;
+
+    case ENTRY_FLOAT:
+      /* Not supported yet */
+      break;
     }
 
     if (NULL == string) {

Modified: branches/S2_6/server/ruleset.c
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_6/server/ruleset.c?rev=31201&r1=31200&r2=31201&view=diff
==============================================================================
--- branches/S2_6/server/ruleset.c      (original)
+++ branches/S2_6/server/ruleset.c      Fri Dec 25 18:56:35 2015
@@ -344,8 +344,8 @@
   (callers need not worry about freeing anything).
 **************************************************************************/
 static struct requirement_vector *lookup_req_list(struct section_file *file,
-                                                 const char *sec,
-                                                 const char *sub,
+                                                  const char *sec,
+                                                  const char *sub,
                                                   const char *rfor)
 {
   const char *type, *name;
@@ -394,6 +394,12 @@
       break;
     case ENTRY_STR:
       (void) entry_str_get(pentry, &name);
+      break;
+    case ENTRY_FLOAT:
+      fc_assert(entry_type(pentry) != ENTRY_FLOAT);
+      ruleset_error(LOG_ERROR,
+                    "\"%s\": trying to have an floating point entry as a 
requirement name in '%s.%s%d'.",
+                    filename, sec, sub, j);
       break;
     }
     if (NULL == name) {

Modified: branches/S2_6/server/savecompat.c
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_6/server/savecompat.c?rev=31201&r1=31200&r2=31201&view=diff
==============================================================================
--- branches/S2_6/server/savecompat.c   (original)
+++ branches/S2_6/server/savecompat.c   Fri Dec 25 18:56:35 2015
@@ -1013,6 +1013,10 @@
                                i, entries[j].entry_name);
           }
           break;
+        case ENTRY_FLOAT:
+          sg_failure_ret(entries[j].entry_type != ENTRY_FLOAT,
+                         "Research related entry marked as float.");
+          break;
         }
       }
     }

Modified: branches/S2_6/server/savegame.c
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_6/server/savegame.c?rev=31201&r1=31200&r2=31201&view=diff
==============================================================================
--- branches/S2_6/server/savegame.c     (original)
+++ branches/S2_6/server/savegame.c     Fri Dec 25 18:56:35 2015
@@ -3225,6 +3225,7 @@
       }
       break;
     case ENTRY_BOOL:
+    case ENTRY_FLOAT:
       break;
     }
   }

Modified: branches/S2_6/utility/inputfile.c
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_6/utility/inputfile.c?rev=31201&r1=31200&r2=31201&view=diff
==============================================================================
--- branches/S2_6/utility/inputfile.c   (original)
+++ branches/S2_6/utility/inputfile.c   Fri Dec 25 18:56:35 2015
@@ -797,6 +797,13 @@
     while(*c != '\0' && fc_isdigit(*c)) {
       c++;
     }
+    if (*c == '.') {
+      /* Float maybe */
+      c++;
+      while(*c != '\0' && fc_isdigit(*c)) {
+        c++;
+      }
+    }
     /* check that the trailing stuff is ok: */
     if (!(*c == '\0' || *c == ',' || fc_isspace(*c) || is_comment(*c))) {
       return NULL;

Modified: branches/S2_6/utility/inputfile.h
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_6/utility/inputfile.h?rev=31201&r1=31200&r2=31201&view=diff
==============================================================================
--- branches/S2_6/utility/inputfile.h   (original)
+++ branches/S2_6/utility/inputfile.h   Fri Dec 25 18:56:35 2015
@@ -23,6 +23,7 @@
 extern "C" {
 #endif /* __cplusplus */
 
+/* utility */
 #include "ioz.h"
 #include "log.h"                /* enum log_level */
 #include "support.h"            /* bool type and fc__attribute */
@@ -32,9 +33,9 @@
 typedef const char *(*datafilename_fn_t)(const char *filename);
 
 struct inputfile *inf_from_file(const char *filename,
-                               datafilename_fn_t datafn);
+                                datafilename_fn_t datafn);
 struct inputfile *inf_from_stream(fz_FILE * stream,
-                                 datafilename_fn_t datafn);
+                                  datafilename_fn_t datafn);
 void inf_close(struct inputfile *inf);
 bool inf_at_eof(struct inputfile *inf);
 

Modified: branches/S2_6/utility/registry_ini.c
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_6/utility/registry_ini.c?rev=31201&r1=31200&r2=31201&view=diff
==============================================================================
--- branches/S2_6/utility/registry_ini.c        (original)
+++ branches/S2_6/utility/registry_ini.c        Fri Dec 25 18:56:35 2015
@@ -1097,6 +1097,56 @@
 }
 
 /**************************************************************************
+  Insert a floating entry.
+**************************************************************************/
+struct entry *secfile_insert_float_full(struct section_file *secfile,
+                                        float value, const char *comment,
+                                        bool allow_replace,
+                                        const char *path, ...)
+{
+  char fullpath[MAX_LEN_SECPATH];
+  const char *ent_name;
+  struct section *psection;
+  struct entry *pentry = NULL;
+  va_list args;
+
+  SECFILE_RETURN_VAL_IF_FAIL(secfile, NULL, NULL != secfile, NULL);
+
+  va_start(args, path);
+  fc_vsnprintf(fullpath, sizeof(fullpath), path, args);
+  va_end(args);
+
+  psection = secfile_insert_base(secfile, fullpath, &ent_name);
+  if (!psection) {
+    return NULL;
+  }
+
+  if (allow_replace) {
+    pentry = section_entry_by_name(psection, ent_name);
+    if (NULL != pentry) {
+      if (ENTRY_FLOAT == entry_type(pentry)) {
+        if (!entry_float_set(pentry, value)) {
+          return NULL;
+        }
+      } else {
+        entry_destroy(pentry);
+        pentry = NULL;
+      }
+    }
+  }
+
+  if (NULL == pentry) {
+    pentry = section_entry_float_new(psection, ent_name, value);
+  }
+
+  if (NULL != pentry && NULL != comment) {
+    entry_set_comment(pentry, comment);
+  }
+
+  return pentry;
+}
+
+/**************************************************************************
   Insert a include entry.
 **************************************************************************/
 struct section *secfile_insert_include(struct section_file *secfile,
@@ -2851,6 +2901,10 @@
     struct {
       int value;
     } integer;
+    /* ENTRY_FLOAT */
+    struct {
+      float value;
+    } floating;
     /* ENTRY_STR */
     struct {
       char *value;              /* Malloced string. */
@@ -2938,6 +2992,22 @@
 }
 
 /**************************************************************************
+  Returns a new entry of type ENTRY_FLOAT.
+**************************************************************************/
+struct entry *section_entry_float_new(struct section *psection,
+                                      const char *name, float value)
+{
+  struct entry *pentry = entry_new(psection, name);
+
+  if (NULL != pentry) {
+    pentry->type = ENTRY_FLOAT;
+    pentry->floating.value = value;
+  }
+
+  return pentry;
+}
+
+/**************************************************************************
   Returns a new entry of type ENTRY_STR.
 **************************************************************************/
 struct entry *section_entry_str_new(struct section *psection,
@@ -2985,6 +3055,7 @@
   switch (pentry->type) {
   case ENTRY_BOOL:
   case ENTRY_INT:
+  case ENTRY_FLOAT:
     break;
 
   case ENTRY_STR:
@@ -3163,6 +3234,36 @@
 }
 
 /**************************************************************************
+  Gets an floating value. Returns TRUE on success.
+**************************************************************************/
+bool entry_float_get(const struct entry *pentry, float *value)
+{
+  SECFILE_RETURN_VAL_IF_FAIL(NULL, NULL, NULL != pentry, FALSE);
+  SECFILE_RETURN_VAL_IF_FAIL(pentry->psection->secfile, pentry->psection,
+                             ENTRY_FLOAT == pentry->type, FALSE);
+
+  if (NULL != value) {
+    *value = pentry->floating.value;
+  }
+
+  return TRUE;
+}
+
+/**************************************************************************
+  Sets an floating value. Returns TRUE on success.
+**************************************************************************/
+bool entry_float_set(struct entry *pentry, float value)
+{
+  SECFILE_RETURN_VAL_IF_FAIL(NULL, NULL, NULL != pentry, FALSE);
+  SECFILE_RETURN_VAL_IF_FAIL(pentry->psection->secfile, pentry->psection,
+                             ENTRY_FLOAT == pentry->type, FALSE);
+
+  pentry->floating.value = value;
+
+  return TRUE;
+}
+
+/**************************************************************************
   Gets an integer value.  Returns TRUE on success.
 **************************************************************************/
 bool entry_int_get(const struct entry *pentry, int *value)
@@ -3264,6 +3365,8 @@
 static void entry_to_file(const struct entry *pentry, fz_FILE *fs)
 {
   static char buf[8192];
+  char *dot = NULL;
+  int i;
 
   switch (pentry->type) {
   case ENTRY_BOOL:
@@ -3271,6 +3374,22 @@
     break;
   case ENTRY_INT:
     fz_fprintf(fs, "%d", pentry->integer.value);
+    break;
+  case ENTRY_FLOAT:
+    snprintf(buf, sizeof(buf), "%f", pentry->floating.value);
+    for (i = 0; buf[i] != '\0' ; i++) {
+      if (buf[i] == '.') {
+        dot = &(buf[i]);
+        break;
+      }
+    }
+    if (dot == NULL) {
+      /* There's no '.' so it would seem like a integer value when loaded.
+       * Force it not to look like an integer by adding ".0" */
+      fz_fprintf(fs, "%s.0", buf);
+    } else {
+      fz_fprintf(fs, "%s", buf);
+    }
     break;
   case ENTRY_STR:
     if (pentry->string.escaped) {

Modified: branches/S2_6/utility/registry_ini.h
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_6/utility/registry_ini.h?rev=31201&r1=31200&r2=31201&view=diff
==============================================================================
--- branches/S2_6/utility/registry_ini.h        (original)
+++ branches/S2_6/utility/registry_ini.h        Fri Dec 25 18:56:35 2015
@@ -141,6 +141,15 @@
                                         comment, path, ...)                 \
   secfile_insert_int_vec_full(secfile, values, dim, comment, TRUE,          \
                               path, ## __VA_ARGS__)
+
+struct entry *secfile_insert_float_full(struct section_file *secfile,
+                                        float value, const char *comment,
+                                        bool allow_replace,
+                                        const char *path, ...)
+                                        fc__attribute((__format__ (__printf__, 
5, 6)));
+#define secfile_insert_float(secfile, value, path, ...)                     \
+  secfile_insert_float_full(secfile, value, NULL, FALSE,                    \
+                            path, ## __VA_ARGS__)
 
 struct section *secfile_insert_include(struct section_file *secfile,
                                        const char *filename);
@@ -579,6 +588,9 @@
 struct entry *section_entry_bool_new(struct section *psection,
                                      const char *entry_name,
                                      bool value);
+struct entry *section_entry_float_new(struct section *psection,
+                                      const char *entry_name,
+                                      float value);
 struct entry *section_entry_str_new(struct section *psection,
                                     const char *entry_name,
                                     const char *value, bool escaped);
@@ -587,6 +599,7 @@
 enum entry_type {
   ENTRY_BOOL,
   ENTRY_INT,
+  ENTRY_FLOAT,
   ENTRY_STR
 };
 
@@ -607,6 +620,9 @@
 
 bool entry_bool_get(const struct entry *pentry, bool *value);
 bool entry_bool_set(struct entry *pentry, bool value);
+
+bool entry_float_get(const struct entry *pentry, float *value);
+bool entry_float_set(struct entry *pentry, float value);
 
 bool entry_str_get(const struct entry *pentry, const char **value);
 bool entry_str_set(struct entry *pentry, const char *value);

Modified: branches/S2_6/utility/section_file.c
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_6/utility/section_file.c?rev=31201&r1=31200&r2=31201&view=diff
==============================================================================
--- branches/S2_6/utility/section_file.c        (original)
+++ branches/S2_6/utility/section_file.c        Fri Dec 25 18:56:35 2015
@@ -186,12 +186,22 @@
   }
 
   if (fc_isdigit(tok[0]) || ('-' == tok[0] && fc_isdigit(tok[1]))) {
-    int value;
-
-    if (str_to_int(tok, &value)) {
-      (void) section_entry_int_new(psection, name, value);
-      DEBUG_ENTRIES("entry %s %d", name, value);
+    float fvalue;
+
+    if (str_to_float(tok, &fvalue)) {
+      (void) section_entry_float_new(psection, name, fvalue);
+      DEBUG_ENTRIES("entry %s %d", name, fvalue);
+
       return TRUE;
+    } else {
+      int ivalue;
+
+      if (str_to_int(tok, &ivalue)) {
+        (void) section_entry_int_new(psection, name, ivalue);
+        DEBUG_ENTRIES("entry %s %d", name, ivalue);
+
+        return TRUE;
+      }
     }
   }
 

Modified: branches/S2_6/utility/shared.c
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_6/utility/shared.c?rev=31201&r1=31200&r2=31201&view=diff
==============================================================================
--- branches/S2_6/utility/shared.c      (original)
+++ branches/S2_6/utility/shared.c      Fri Dec 25 18:56:35 2015
@@ -707,8 +707,8 @@
 }
 
 /****************************************************************************
-  Convert 'str' to it's string reprentation if possible. 'pint' can be NULL,
-  then it will only test 'str' only contains a number.
+  Convert 'str' to it's int reprentation if possible. 'pint' can be NULL,
+  then it will only test 'str' only contains an integer number.
 ****************************************************************************/
 bool str_to_int(const char *str, int *pint)
 {
@@ -737,6 +737,54 @@
   }
 
   return ('\0' == *str && (NULL == pint || 1 == sscanf(start, "%d", pint)));
+}
+
+/****************************************************************************
+  Convert 'str' to it's float reprentation if possible. 'pfloat' can be NULL,
+  then it will only test 'str' only contains a floating point number.
+****************************************************************************/
+bool str_to_float(const char *str, float *pfloat)
+{
+  bool dot;
+  const char *start;
+
+  fc_assert_ret_val(NULL != str, FALSE);
+
+  while (fc_isspace(*str)) {
+    /* Skip leading spaces. */
+    str++;
+  }
+
+  start = str;
+
+  if ('-' == *str || '+' == *str) {
+    /* Handle sign. */
+    str++;
+  }
+  while (fc_isdigit(*str)) {
+    /* Digits. */
+    str++;
+  }
+
+  if (*str == '.') {
+    dot = TRUE;
+    str++;
+
+    while (fc_isdigit(*str)) {
+      /* Digits. */
+      str++;
+    }
+  } else {
+    dot = FALSE;
+  }
+
+  while (fc_isspace(*str)) {
+    /* Ignore trailing spaces. */
+    str++;
+  }
+
+  return ('\0' == *str && dot
+          && (NULL == pfloat || 1 == sscanf(start, "%f", pfloat)));
 }
 
 /***************************************************************************

Modified: branches/S2_6/utility/shared.h
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_6/utility/shared.h?rev=31201&r1=31200&r2=31201&view=diff
==============================================================================
--- branches/S2_6/utility/shared.h      (original)
+++ branches/S2_6/utility/shared.h      Fri Dec 25 18:56:35 2015
@@ -135,6 +135,7 @@
 char *end_of_strn(char *str, int *nleft);
 
 bool str_to_int(const char *str, int *pint);
+bool str_to_float(const char *str, float *pfloat);
 
 /**************************************************************************
 ...


_______________________________________________
Freeciv-commits mailing list
Freeciv-commits@gna.org
https://mail.gna.org/listinfo/freeciv-commits

Reply via email to