Skip to content

Commit

Permalink
locale.c: Use parallel array to simplify
Browse files Browse the repository at this point in the history
This allows the numeric fields returned by localeconv() to have the same
logic as the string fields, simplifying the code a bit.  They weren't
previously handled the same because one category doesn't have any
numeric fields.  But this is now handled by creating an array and making
its corresponding element NULL, so the strings and numeric fields are
handled in the same way.
  • Loading branch information
khwilliamson committed Nov 22, 2023
1 parent e37328d commit 8ec4ae0
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 30 deletions.
12 changes: 6 additions & 6 deletions embed.fnc
Expand Up @@ -4405,12 +4405,12 @@ Sf |char * |strftime_tm |NN const char *fmt \
|NN const struct tm *mytm
# if defined(HAS_LOCALECONV)
S |HV * |my_localeconv |const int item
S |void |populate_hash_from_localeconv \
|NN HV *hv \
|NN const char *locale \
|const PERL_UINT_FAST8_T which_mask \
|NN const lconv_offset_t *strings[2] \
|NULLOK const lconv_offset_t *integers
S |void |populate_hash_from_localeconv \
|NN HV *hv \
|NN const char *locale \
|const PERL_UINT_FAST8_T which_mask \
|NN const lconv_offset_t *strings[2] \
|NULLOK const lconv_offset_t *integers[2]
# endif
# if defined(USE_LOCALE)
S |const char *|calculate_LC_ALL_string \
Expand Down
51 changes: 28 additions & 23 deletions locale.c
Expand Up @@ -5452,6 +5452,13 @@ S_my_localeconv(pTHX_ const int item)
lconv_monetary_strings
};

/* The LC_MONETARY category also has some integer-valued fields, whose
* information is kept in a separate parallel array to 'strings' */
const lconv_offset_t * integers[2] = {
NULL,
lconv_integers
};

/* If we aren't paying attention to a given category, use LC_CTYPE instead;
* If not paying attention to that either, the code below should end up not
* using this. Make sure that things blow up if that avoidance gets lost,
Expand Down Expand Up @@ -5497,10 +5504,6 @@ S_my_localeconv(pTHX_ const int item)
* what we are working on at the moment */
const char * locale;

/* The LC_MONETARY category also has some integer-valued fields, whose
* information is kept in a separate list */
const lconv_offset_t * integers = lconv_integers;

# ifdef HAS_SOME_LANGINFO

/* If the only use-case for this is the full localeconv(), the 'item'
Expand Down Expand Up @@ -5566,7 +5569,6 @@ S_my_localeconv(pTHX_ const int item)
strings[NUMERIC_OFFSET] = thousands_sep_string;

numeric_common:
integers = NULL;
index_bits = OFFSET_TO_BIT(NUMERIC_OFFSET);
locale = numeric_locale = PL_numeric_name;
break;
Expand All @@ -5586,7 +5588,7 @@ S_my_localeconv(pTHX_ const int item)
}

strings[MONETARY_OFFSET] = CURRENCY_SYMBOL_ADDRESS;
integers = P_CS_PRECEDES_ADDRESS;
integers[MONETARY_OFFSET] = P_CS_PRECEDES_ADDRESS;

index_bits = OFFSET_TO_BIT(MONETARY_OFFSET);
break;
Expand Down Expand Up @@ -5652,10 +5654,7 @@ S_my_localeconv(pTHX_ const int item)
populate_hash_from_localeconv(hv,
numeric_locale,
OFFSET_TO_BIT(NUMERIC_OFFSET),
strings,
NULL /* There are no NUMERIC integer
fields */
);
strings, integers);
}

/* Here, the hash has been completely populated.
Expand Down Expand Up @@ -5725,12 +5724,14 @@ S_my_localeconv(pTHX_ const int item)
SvUTF8_on(*value);
}
}
} /* End of fixing up UTF8ness */

if (integers[i] == NULL) {
continue;
}

/* Examine each integer */
for (; integers; integers++) {
const char * name = integers->name;
/* And each integer */
for (const lconv_offset_t *intp = integers[i]; intp->name; intp++) {
const char * name = intp->name;

if (! name) { /* Reached the end */
break;
Expand All @@ -5745,6 +5746,7 @@ S_my_localeconv(pTHX_ const int item)
if (SvIV(*value) == CHAR_MAX) {
sv_setiv(*value, -1);
}
}
}

return hv;
Expand All @@ -5766,8 +5768,8 @@ S_populate_hash_from_localeconv(pTHX_ HV * hv,
* monetary */
const lconv_offset_t * strings[2],

/* And to the monetary integer fields */
const lconv_offset_t * integers)
/* And similarly the integer fields */
const lconv_offset_t * integers[2])
{
PERL_ARGS_ASSERT_POPULATE_HASH_FROM_LOCALECONV;
PERL_UNUSED_ARG(which_mask); /* Some configurations don't use this;
Expand Down Expand Up @@ -5916,14 +5918,17 @@ S_populate_hash_from_localeconv(pTHX_ HV * hv,
category_strings++;
}

/* Add any int fields to the HV* */
if (i == MONETARY_OFFSET && integers) {
while (integers->name) {
/* Add any int fields to the HV*. */
if (integers[i]) {
const lconv_offset_t * current = integers[i];
while (current->name) {
const char value = *((const char *)( lcbuf_as_string
+ integers->offset));
(void) hv_store(hv, integers->name,
strlen(integers->name), newSViv(value), 0);
integers++;
+ current->offset));
(void) hv_store(hv,
current->name, strlen(current->name),
newSViv(value),
0);
current++;
}
}
} /* End of loop through the fields */
Expand Down
2 changes: 1 addition & 1 deletion proto.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 8ec4ae0

Please sign in to comment.