aboutsummaryrefslogtreecommitdiff
path: root/time
diff options
context:
space:
mode:
Diffstat (limited to 'time')
-rw-r--r--time/strptime_l.c104
1 files changed, 76 insertions, 28 deletions
diff --git a/time/strptime_l.c b/time/strptime_l.c
index b95f0982e8..9eb8181313 100644
--- a/time/strptime_l.c
+++ b/time/strptime_l.c
@@ -20,6 +20,7 @@
# include <config.h>
#endif
+#include <assert.h>
#include <ctype.h>
#include <langinfo.h>
#include <limits.h>
@@ -732,30 +733,26 @@ __strptime_internal (rp, fmt, tm, decided, era_cnt LOCALE_PARAM)
else
return NULL;
}
- else
+
+ num_eras = _NL_CURRENT_WORD (LC_TIME,
+ _NL_TIME_ERA_NUM_ENTRIES);
+ for (era_cnt = 0; era_cnt < (int) num_eras;
+ ++era_cnt, rp = rp_backup)
{
- num_eras = _NL_CURRENT_WORD (LC_TIME,
- _NL_TIME_ERA_NUM_ENTRIES);
- for (era_cnt = 0; era_cnt < (int) num_eras;
- ++era_cnt, rp = rp_backup)
- {
- era = _nl_select_era_entry (era_cnt
- HELPER_LOCALE_ARG);
- if (era != NULL && match_string (era->era_name, rp))
- {
- *decided = loc;
- break;
- }
- }
- if (era_cnt == (int) num_eras)
+ era = _nl_select_era_entry (era_cnt
+ HELPER_LOCALE_ARG);
+ if (era != NULL && match_string (era->era_name, rp))
{
- era_cnt = -1;
- if (*decided == loc)
- return NULL;
+ *decided = loc;
+ break;
}
- else
- break;
}
+ if (era_cnt != (int) num_eras)
+ break;
+
+ era_cnt = -1;
+ if (*decided == loc)
+ return NULL;
*decided = raw;
}
@@ -763,15 +760,66 @@ __strptime_internal (rp, fmt, tm, decided, era_cnt LOCALE_PARAM)
normal representation. */
goto match_century;
case 'y':
- if (*decided == raw)
- goto match_year_in_century;
+ if (*decided != raw)
+ {
+ get_number(0, 9999, 4);
+ tm->tm_year = val;
+ want_era = 1;
+ want_xday = 1;
+ want_century = 1;
- get_number(0, 9999, 4);
- tm->tm_year = val;
- want_era = 1;
- want_xday = 1;
- want_century = 1;
- break;
+ if (era_cnt >= 0)
+ {
+ assert (*decided == loc);
+
+ era = _nl_select_era_entry (era_cnt HELPER_LOCALE_ARG);
+ bool match = false;
+ if (era != NULL)
+ {
+ int delta = ((tm->tm_year - era->offset)
+ * era->absolute_direction);
+ match = (delta >= 0
+ && delta < (((int64_t) era->stop_date[0]
+ - (int64_t) era->start_date[0])
+ * era->absolute_direction));
+ }
+ if (! match)
+ return NULL;
+
+ break;
+ }
+
+ num_eras = _NL_CURRENT_WORD (LC_TIME,
+ _NL_TIME_ERA_NUM_ENTRIES);
+ for (era_cnt = 0; era_cnt < (int) num_eras; ++era_cnt)
+ {
+ era = _nl_select_era_entry (era_cnt
+ HELPER_LOCALE_ARG);
+ if (era != NULL)
+ {
+ int delta = ((tm->tm_year - era->offset)
+ * era->absolute_direction);
+ if (delta >= 0
+ && delta < (((int64_t) era->stop_date[0]
+ - (int64_t) era->start_date[0])
+ * era->absolute_direction))
+ {
+ *decided = loc;
+ break;
+ }
+ }
+ }
+ if (era_cnt != (int) num_eras)
+ break;
+
+ era_cnt = -1;
+ if (*decided == loc)
+ return NULL;
+
+ *decided = raw;
+ }
+
+ goto match_year_in_century;
case 'Y':
if (*decided != raw)
{