diff options
author | Haru <haru@dotalux.com> | 2020-06-01 04:08:28 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-01 04:08:28 +0200 |
commit | 36aff97b92f9f42f9bc59911b7d06110a8e9aed5 (patch) | |
tree | 69d20dc9137da111ecda664a896bbf0abbead02e /3rdparty/libconfig/libconfig.c | |
parent | b9f7d1439c84b64facaf7d2875adc29110c65cf4 (diff) | |
parent | c66d467fb5816734851b7de6b20537ce7a08c861 (diff) | |
download | hercules-36aff97b92f9f42f9bc59911b7d06110a8e9aed5.tar.gz hercules-36aff97b92f9f42f9bc59911b7d06110a8e9aed5.tar.bz2 hercules-36aff97b92f9f42f9bc59911b7d06110a8e9aed5.tar.xz hercules-36aff97b92f9f42f9bc59911b7d06110a8e9aed5.zip |
Merge pull request #2671 from Helianthella/binliteral
add support for binary and octal number literals
Diffstat (limited to '3rdparty/libconfig/libconfig.c')
-rw-r--r-- | 3rdparty/libconfig/libconfig.c | 58 |
1 files changed, 53 insertions, 5 deletions
diff --git a/3rdparty/libconfig/libconfig.c b/3rdparty/libconfig/libconfig.c index 533145ac4..daf3ba42d 100644 --- a/3rdparty/libconfig/libconfig.c +++ b/3rdparty/libconfig/libconfig.c @@ -174,6 +174,31 @@ static void __config_indent(FILE *stream, int depth, unsigned short w) /* ------------------------------------------------------------------------- */ +/** + * converts an integer to a binary string (because itoa is not in C99) + * skips leading zeros, and does not prepend with a 0b prefix + * + * @param value - the integer to convert to a binary expression + * @param buffer - a pointer to the buffer used to build the string + * @returns the same buffer + */ +char *int_tobin(const unsigned long long value, char *buffer) { + const unsigned long long mask = 1; + unsigned char nonzero = 0; + + for (char bit = 63; bit >= 0; --bit) { + if ((value & (mask << bit)) == 1) { + nonzero = 1; + *buffer++ = '1'; + } else if (nonzero != 0) { + *buffer++ = '0'; + } + } + + *buffer = '\0'; + return buffer; +} + static void __config_write_value(const struct config_t *config, const union config_value_t *value, int type, int format, int depth, FILE *stream) @@ -195,6 +220,17 @@ static void __config_write_value(const struct config_t *config, fprintf(stream, "0x%X", (unsigned int)(value->ival)); break; + case CONFIG_FORMAT_BIN: + { + char buffer[33]; // 32 individual bits (char '0' and '1') represented as 32 bytes + null + fprintf(stream, "0b%s", int_tobin((unsigned int)(value->ival), buffer)); + break; + } + + case CONFIG_FORMAT_OCT: + fprintf(stream, "0o%o", (unsigned int)(value->ival)); + break; + case CONFIG_FORMAT_DEFAULT: default: fprintf(stream, "%d", value->ival); @@ -210,6 +246,17 @@ static void __config_write_value(const struct config_t *config, fprintf(stream, "0x" INT64_HEX_FMT "L", (unsigned long long)(value->llval)); break; + case CONFIG_FORMAT_BIN: + { + char buffer[65]; // 64 individual bits (char '0' and '1') represented as 64 bytes + null + fprintf(stream, "0b%s", int_tobin((unsigned long long)(value->llval), buffer)); + break; + } + + case CONFIG_FORMAT_OCT: + fprintf(stream, "0o" INT64_OCT_FMT "L", (unsigned long long)(value->llval)); + break; + case CONFIG_FORMAT_DEFAULT: default: fprintf(stream, INT64_FMT "L", value->llval); @@ -1174,14 +1221,15 @@ int config_setting_set_string(struct config_setting_t *setting, const char *valu int config_setting_set_format(struct config_setting_t *setting, short format) { - if(((setting->type != CONFIG_TYPE_INT) - && (setting->type != CONFIG_TYPE_INT64)) - || ((format != CONFIG_FORMAT_DEFAULT) && (format != CONFIG_FORMAT_HEX))) - return(CONFIG_FALSE); + if (((setting->type != CONFIG_TYPE_INT) && (setting->type != CONFIG_TYPE_INT64)) + || ((format != CONFIG_FORMAT_DEFAULT) && (format != CONFIG_FORMAT_HEX) + && (format != CONFIG_FORMAT_BIN) && (format != CONFIG_FORMAT_OCT))) { + return CONFIG_FALSE; + } setting->format = format; - return(CONFIG_TRUE); + return CONFIG_TRUE; } /* ------------------------------------------------------------------------- */ |