Author: cazfi Date: Fri Dec 25 18:56:27 2015 New Revision: 31200 URL: http://svn.gna.org/viewcvs/freeciv?rev=31200&view=rev Log: Added support for floating point numbers in section files.
See patch #6723 Modified: trunk/client/options.c trunk/server/legacysave.c trunk/server/ruleset.c trunk/server/savecompat.c trunk/utility/inputfile.c trunk/utility/inputfile.h trunk/utility/registry_ini.c trunk/utility/registry_ini.h trunk/utility/section_file.c trunk/utility/shared.c trunk/utility/shared.h Modified: trunk/client/options.c URL: http://svn.gna.org/viewcvs/freeciv/trunk/client/options.c?rev=31200&r1=31199&r2=31200&view=diff ============================================================================== --- trunk/client/options.c (original) +++ trunk/client/options.c Fri Dec 25 18:56:27 2015 @@ -5223,6 +5223,10 @@ case ENTRY_STR: (void) entry_str_get(pentry, &string); break; + + case ENTRY_FLOAT: + /* Not supported yet */ + break; } if (NULL == string) { Modified: trunk/server/legacysave.c URL: http://svn.gna.org/viewcvs/freeciv/trunk/server/legacysave.c?rev=31200&r1=31199&r2=31200&view=diff ============================================================================== --- trunk/server/legacysave.c (original) +++ trunk/server/legacysave.c Fri Dec 25 18:56:27 2015 @@ -3258,6 +3258,7 @@ } break; case ENTRY_BOOL: + case ENTRY_FLOAT: break; } } Modified: trunk/server/ruleset.c URL: http://svn.gna.org/viewcvs/freeciv/trunk/server/ruleset.c?rev=31200&r1=31199&r2=31200&view=diff ============================================================================== --- trunk/server/ruleset.c (original) +++ trunk/server/ruleset.c Fri Dec 25 18:56:27 2015 @@ -324,8 +324,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; @@ -374,6 +374,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: trunk/server/savecompat.c URL: http://svn.gna.org/viewcvs/freeciv/trunk/server/savecompat.c?rev=31200&r1=31199&r2=31200&view=diff ============================================================================== --- trunk/server/savecompat.c (original) +++ trunk/server/savecompat.c Fri Dec 25 18:56:27 2015 @@ -1055,6 +1055,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: trunk/utility/inputfile.c URL: http://svn.gna.org/viewcvs/freeciv/trunk/utility/inputfile.c?rev=31200&r1=31199&r2=31200&view=diff ============================================================================== --- trunk/utility/inputfile.c (original) +++ trunk/utility/inputfile.c Fri Dec 25 18:56:27 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: trunk/utility/inputfile.h URL: http://svn.gna.org/viewcvs/freeciv/trunk/utility/inputfile.h?rev=31200&r1=31199&r2=31200&view=diff ============================================================================== --- trunk/utility/inputfile.h (original) +++ trunk/utility/inputfile.h Fri Dec 25 18:56:27 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: trunk/utility/registry_ini.c URL: http://svn.gna.org/viewcvs/freeciv/trunk/utility/registry_ini.c?rev=31200&r1=31199&r2=31200&view=diff ============================================================================== --- trunk/utility/registry_ini.c (original) +++ trunk/utility/registry_ini.c Fri Dec 25 18:56:27 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: trunk/utility/registry_ini.h URL: http://svn.gna.org/viewcvs/freeciv/trunk/utility/registry_ini.h?rev=31200&r1=31199&r2=31200&view=diff ============================================================================== --- trunk/utility/registry_ini.h (original) +++ trunk/utility/registry_ini.h Fri Dec 25 18:56:27 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: trunk/utility/section_file.c URL: http://svn.gna.org/viewcvs/freeciv/trunk/utility/section_file.c?rev=31200&r1=31199&r2=31200&view=diff ============================================================================== --- trunk/utility/section_file.c (original) +++ trunk/utility/section_file.c Fri Dec 25 18:56:27 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: trunk/utility/shared.c URL: http://svn.gna.org/viewcvs/freeciv/trunk/utility/shared.c?rev=31200&r1=31199&r2=31200&view=diff ============================================================================== --- trunk/utility/shared.c (original) +++ trunk/utility/shared.c Fri Dec 25 18:56:27 2015 @@ -694,8 +694,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) { @@ -724,6 +724,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: trunk/utility/shared.h URL: http://svn.gna.org/viewcvs/freeciv/trunk/utility/shared.h?rev=31200&r1=31199&r2=31200&view=diff ============================================================================== --- trunk/utility/shared.h (original) +++ trunk/utility/shared.h Fri Dec 25 18:56:27 2015 @@ -134,6 +134,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