Skip to content

Commit

Permalink
config: introduce git_config_double()
Browse files Browse the repository at this point in the history
Future commits will want to parse a double-precision floating point
value from configuration, but we have no way to parse such a value prior
to this patch.

The core of the routine is implemented in git_parse_double(). Unlike
git_parse_unsigned() and git_parse_signed(), however, the function
implemented here only works on type "double", and not related types like
"float", or "long double".

This is because "float" and "long double" use different functions to
convert from ASCII strings to floating point values (strtof() and
strtold(), respectively). Likewise, there is no pointer type that can
assign to any of these values (except for "void *"), so the only way to
define this trio of functions would be with a macro expansion that is
parameterized over the floating point type and conversion function.

That is all doable, but likely to be overkill given our current needs,
which is only to parse double-precision floats.

Signed-off-by: Taylor Blau <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
  • Loading branch information
ttaylorr authored and gitster committed May 24, 2024
1 parent c059c87 commit 5831f8a
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 0 deletions.
9 changes: 9 additions & 0 deletions config.c
Original file line number Diff line number Diff line change
Expand Up @@ -1243,6 +1243,15 @@ ssize_t git_config_ssize_t(const char *name, const char *value,
return ret;
}

double git_config_double(const char *name, const char *value,
const struct key_value_info *kvi)
{
double ret;
if (!git_parse_double(value, &ret))
die_bad_number(name, value, kvi);
return ret;
}

static const struct fsync_component_name {
const char *name;
enum fsync_component component_bits;
Expand Down
7 changes: 7 additions & 0 deletions config.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,13 @@ unsigned long git_config_ulong(const char *, const char *,
ssize_t git_config_ssize_t(const char *, const char *,
const struct key_value_info *);

/**
* Identically to `git_config_double`, but for double-precision floating point
* values.
*/
double git_config_double(const char *, const char *,
const struct key_value_info *);

/**
* Same as `git_config_bool`, except that integers are returned as-is, and
* an `is_bool` flag is unset.
Expand Down
29 changes: 29 additions & 0 deletions parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,35 @@ int git_parse_ssize_t(const char *value, ssize_t *ret)
return 1;
}

int git_parse_double(const char *value, double *ret)
{
char *end;
double val;
uintmax_t factor;

if (!value || !*value) {
errno = EINVAL;
return 0;
}

errno = 0;
val = strtod(value, &end);
if (errno == ERANGE)
return 0;
if (end == value) {
errno = EINVAL;
return 0;
}
factor = get_unit_factor(end);
if (!factor) {
errno = EINVAL;
return 0;
}
val *= factor;
*ret = val;
return 1;
}

int git_parse_maybe_bool_text(const char *value)
{
if (!value)
Expand Down
1 change: 1 addition & 0 deletions parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ int git_parse_ssize_t(const char *, ssize_t *);
int git_parse_ulong(const char *, unsigned long *);
int git_parse_int(const char *value, int *ret);
int git_parse_int64(const char *value, int64_t *ret);
int git_parse_double(const char *value, double *ret);

/**
* Same as `git_config_bool`, except that it returns -1 on error rather
Expand Down

0 comments on commit 5831f8a

Please sign in to comment.