+/* Returns the number formatting style associated with the given
+ format TYPE. */
+const struct fmt_number_style *
+fmt_settings_get_style (const struct fmt_settings *settings,
+ enum fmt_type type)
+{
+ verify (FMT_F < 6);
+ verify (FMT_COMMA < 6);
+ verify (FMT_DOT < 6);
+ verify (FMT_DOLLAR < 6);
+ verify (FMT_PCT < 6);
+ verify (FMT_E < 6);
+
+#define OPPOSITE(C) ((C) == ',' ? '.' : ',')
+#define AFFIX(S) { .s = (char *) (S), .width = sizeof (S) - 1 }
+#define NS(PREFIX, SUFFIX, DECIMAL, GROUPING) { \
+ .neg_prefix = AFFIX ("-"), \
+ .prefix = AFFIX (PREFIX), \
+ .suffix = AFFIX (SUFFIX), \
+ .neg_suffix = AFFIX (""), \
+ .decimal = DECIMAL, \
+ .grouping = GROUPING, \
+ }
+#define ANS(DECIMAL, GROUPING) { \
+ [FMT_F] = NS( "", "", DECIMAL, 0), \
+ [FMT_E] = NS( "", "", DECIMAL, 0), \
+ [FMT_COMMA] = NS( "", "", DECIMAL, GROUPING), \
+ [FMT_DOT] = NS( "", "", GROUPING, DECIMAL), \
+ [FMT_DOLLAR] = NS("$", "", DECIMAL, GROUPING), \
+ [FMT_PCT] = NS( "", "%", DECIMAL, 0), \
+ }
+
+ static const struct fmt_number_style period_styles[6] = ANS ('.', ',');
+ static const struct fmt_number_style comma_styles[6] = ANS (',', '.');
+ static const struct fmt_number_style default_style = NS ("", "", '.', 0);
+
+ switch (type)
+ {
+ case FMT_F:
+ case FMT_COMMA:
+ case FMT_DOT:
+ case FMT_DOLLAR:
+ case FMT_PCT:
+ case FMT_E:
+ return (settings->decimal == '.'
+ ? &period_styles[type]
+ : &comma_styles[type]);
+
+ case FMT_CCA:
+ case FMT_CCB:
+ case FMT_CCC:
+ case FMT_CCD:
+ case FMT_CCE:
+ {
+ size_t idx = fmt_type_to_cc_index (type);
+ return settings->ccs[idx] ? settings->ccs[idx] : &default_style;
+ }
+
+ default:
+ return &default_style;
+ }
+}
+
+static int
+default_epoch (void)
+{
+ static int epoch = 0;
+ if (!epoch)
+ {
+ time_t t = time (0);
+ struct tm *tm = localtime (&t);
+ epoch = (tm != NULL ? tm->tm_year + 1900 : 2000) - 69;
+ }
+ return epoch;
+}
+
+int
+fmt_settings_get_epoch (const struct fmt_settings *settings)
+{
+ return !settings->epoch ? default_epoch () : settings->epoch;
+}