~ubuntu-branches/ubuntu/natty/postgresql-8.4/natty-security

« back to all changes in this revision

Viewing changes to src/backend/utils/adt/formatting.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2009-07-11 16:59:35 UTC
  • mfrom: (5.1.1 karmic)
  • Revision ID: james.westby@ubuntu.com-20090711165935-jfwin6gfrxf0gfsi
Tags: 8.4.0-2
* debian/libpq-dev.install: Ship catalog/genbki.h. (Closes: #536139)
* debian/rules: Drop --enable-cassert for final release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -----------------------------------------------------------------------
2
2
 * formatting.c
3
3
 *
4
 
 * $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.156 2009/03/15 20:31:19 tgl Exp $
 
4
 * $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.158 2009/06/22 17:54:30 tgl Exp $
5
5
 *
6
6
 *
7
7
 *       Portions Copyright (c) 1999-2009, PostgreSQL Global Development Group
148
148
 */
149
149
typedef enum
150
150
{
151
 
        FROM_CHAR_DATE_NONE = 0,  /* Value does not affect date mode. */
152
 
        FROM_CHAR_DATE_GREGORIAN, /* Gregorian (day, month, year) style date */
153
 
        FROM_CHAR_DATE_ISOWEEK    /* ISO 8601 week date */
 
151
        FROM_CHAR_DATE_NONE = 0,        /* Value does not affect date mode. */
 
152
        FROM_CHAR_DATE_GREGORIAN,       /* Gregorian (day, month, year) style date */
 
153
        FROM_CHAR_DATE_ISOWEEK          /* ISO 8601 week date */
154
154
} FromCharDateMode;
155
155
 
156
156
typedef struct FormatNode FormatNode;
286
286
 * Flags & Options:
287
287
 * ----------
288
288
 */
289
 
#define ONE_UPPER               1       /* Name */
290
 
#define ALL_UPPER               2       /* NAME */
291
 
#define ALL_LOWER               3       /* name */
 
289
#define ONE_UPPER               1               /* Name */
 
290
#define ALL_UPPER               2               /* NAME */
 
291
#define ALL_LOWER               3               /* name */
292
292
 
293
293
#define FULL_SIZ                0
294
294
 
421
421
                                cc,
422
422
                                j,
423
423
                                us,
424
 
                                yysz,           /* is it YY or YYYY ? */
425
 
                                clock;          /* 12 or 24 hour clock? */
 
424
                                yysz,                   /* is it YY or YYYY ? */
 
425
                                clock;                  /* 12 or 24 hour clock? */
426
426
} TmFromChar;
427
427
 
428
428
#define ZERO_tmfc(_X) memset(_X, 0, sizeof(TmFromChar))
709
709
 */
710
710
static const KeyWord DCH_keywords[] = {
711
711
/*      name, len, id, is_digit, date_mode */
712
 
        {"A.D.", 4, DCH_A_D, FALSE, FROM_CHAR_DATE_NONE},               /* A */
 
712
        {"A.D.", 4, DCH_A_D, FALSE, FROM_CHAR_DATE_NONE},       /* A */
713
713
        {"A.M.", 4, DCH_A_M, FALSE, FROM_CHAR_DATE_NONE},
714
714
        {"AD", 2, DCH_AD, FALSE, FROM_CHAR_DATE_NONE},
715
715
        {"AM", 2, DCH_AM, FALSE, FROM_CHAR_DATE_NONE},
716
 
        {"B.C.", 4, DCH_B_C, FALSE, FROM_CHAR_DATE_NONE},               /* B */
 
716
        {"B.C.", 4, DCH_B_C, FALSE, FROM_CHAR_DATE_NONE},       /* B */
717
717
        {"BC", 2, DCH_BC, FALSE, FROM_CHAR_DATE_NONE},
718
 
        {"CC", 2, DCH_CC, TRUE, FROM_CHAR_DATE_NONE},                   /* C */
719
 
        {"DAY", 3, DCH_DAY, FALSE, FROM_CHAR_DATE_NONE},                /* D */
 
718
        {"CC", 2, DCH_CC, TRUE, FROM_CHAR_DATE_NONE},           /* C */
 
719
        {"DAY", 3, DCH_DAY, FALSE, FROM_CHAR_DATE_NONE},        /* D */
720
720
        {"DDD", 3, DCH_DDD, TRUE, FROM_CHAR_DATE_GREGORIAN},
721
721
        {"DD", 2, DCH_DD, TRUE, FROM_CHAR_DATE_GREGORIAN},
722
722
        {"DY", 2, DCH_DY, FALSE, FROM_CHAR_DATE_NONE},
723
723
        {"Day", 3, DCH_Day, FALSE, FROM_CHAR_DATE_NONE},
724
724
        {"Dy", 2, DCH_Dy, FALSE, FROM_CHAR_DATE_NONE},
725
725
        {"D", 1, DCH_D, TRUE, FROM_CHAR_DATE_GREGORIAN},
726
 
        {"FX", 2, DCH_FX, FALSE, FROM_CHAR_DATE_NONE},                  /* F */
727
 
        {"HH24", 4, DCH_HH24, TRUE, FROM_CHAR_DATE_NONE},               /* H */
 
726
        {"FX", 2, DCH_FX, FALSE, FROM_CHAR_DATE_NONE},          /* F */
 
727
        {"HH24", 4, DCH_HH24, TRUE, FROM_CHAR_DATE_NONE},       /* H */
728
728
        {"HH12", 4, DCH_HH12, TRUE, FROM_CHAR_DATE_NONE},
729
729
        {"HH", 2, DCH_HH, TRUE, FROM_CHAR_DATE_NONE},
730
 
        {"IDDD", 4, DCH_IDDD, TRUE, FROM_CHAR_DATE_ISOWEEK},    /* I */
 
730
        {"IDDD", 4, DCH_IDDD, TRUE, FROM_CHAR_DATE_ISOWEEK},            /* I */
731
731
        {"ID", 2, DCH_ID, TRUE, FROM_CHAR_DATE_ISOWEEK},
732
732
        {"IW", 2, DCH_IW, TRUE, FROM_CHAR_DATE_ISOWEEK},
733
733
        {"IYYY", 4, DCH_IYYY, TRUE, FROM_CHAR_DATE_ISOWEEK},
734
734
        {"IYY", 3, DCH_IYY, TRUE, FROM_CHAR_DATE_ISOWEEK},
735
735
        {"IY", 2, DCH_IY, TRUE, FROM_CHAR_DATE_ISOWEEK},
736
736
        {"I", 1, DCH_I, TRUE, FROM_CHAR_DATE_ISOWEEK},
737
 
        {"J", 1, DCH_J, TRUE, FROM_CHAR_DATE_NONE},                             /* J */
738
 
        {"MI", 2, DCH_MI, TRUE, FROM_CHAR_DATE_NONE},                   /* M */
 
737
        {"J", 1, DCH_J, TRUE, FROM_CHAR_DATE_NONE}, /* J */
 
738
        {"MI", 2, DCH_MI, TRUE, FROM_CHAR_DATE_NONE},           /* M */
739
739
        {"MM", 2, DCH_MM, TRUE, FROM_CHAR_DATE_GREGORIAN},
740
740
        {"MONTH", 5, DCH_MONTH, FALSE, FROM_CHAR_DATE_GREGORIAN},
741
741
        {"MON", 3, DCH_MON, FALSE, FROM_CHAR_DATE_GREGORIAN},
742
742
        {"MS", 2, DCH_MS, TRUE, FROM_CHAR_DATE_NONE},
743
743
        {"Month", 5, DCH_Month, FALSE, FROM_CHAR_DATE_GREGORIAN},
744
744
        {"Mon", 3, DCH_Mon, FALSE, FROM_CHAR_DATE_GREGORIAN},
745
 
        {"P.M.", 4, DCH_P_M, FALSE, FROM_CHAR_DATE_NONE},               /* P */
 
745
        {"P.M.", 4, DCH_P_M, FALSE, FROM_CHAR_DATE_NONE},       /* P */
746
746
        {"PM", 2, DCH_PM, FALSE, FROM_CHAR_DATE_NONE},
747
 
        {"Q", 1, DCH_Q, TRUE, FROM_CHAR_DATE_NONE},                             /* Q */
748
 
        {"RM", 2, DCH_RM, FALSE, FROM_CHAR_DATE_GREGORIAN},             /* R */
749
 
        {"SSSS", 4, DCH_SSSS, TRUE, FROM_CHAR_DATE_NONE},               /* S */
 
747
        {"Q", 1, DCH_Q, TRUE, FROM_CHAR_DATE_NONE}, /* Q */
 
748
        {"RM", 2, DCH_RM, FALSE, FROM_CHAR_DATE_GREGORIAN}, /* R */
 
749
        {"SSSS", 4, DCH_SSSS, TRUE, FROM_CHAR_DATE_NONE},       /* S */
750
750
        {"SS", 2, DCH_SS, TRUE, FROM_CHAR_DATE_NONE},
751
 
        {"TZ", 2, DCH_TZ, FALSE, FROM_CHAR_DATE_NONE},                  /* T */
752
 
        {"US", 2, DCH_US, TRUE, FROM_CHAR_DATE_NONE},                   /* U */
753
 
        {"WW", 2, DCH_WW, TRUE, FROM_CHAR_DATE_GREGORIAN},              /* W */
 
751
        {"TZ", 2, DCH_TZ, FALSE, FROM_CHAR_DATE_NONE},          /* T */
 
752
        {"US", 2, DCH_US, TRUE, FROM_CHAR_DATE_NONE},           /* U */
 
753
        {"WW", 2, DCH_WW, TRUE, FROM_CHAR_DATE_GREGORIAN},      /* W */
754
754
        {"W", 1, DCH_W, TRUE, FROM_CHAR_DATE_GREGORIAN},
755
 
        {"Y,YYY", 5, DCH_Y_YYY, TRUE, FROM_CHAR_DATE_GREGORIAN},/* Y */
 
755
        {"Y,YYY", 5, DCH_Y_YYY, TRUE, FROM_CHAR_DATE_GREGORIAN},        /* Y */
756
756
        {"YYYY", 4, DCH_YYYY, TRUE, FROM_CHAR_DATE_GREGORIAN},
757
757
        {"YYY", 3, DCH_YYY, TRUE, FROM_CHAR_DATE_GREGORIAN},
758
758
        {"YY", 2, DCH_YY, TRUE, FROM_CHAR_DATE_GREGORIAN},
759
759
        {"Y", 1, DCH_Y, TRUE, FROM_CHAR_DATE_GREGORIAN},
760
 
        {"a.d.", 4, DCH_a_d, FALSE, FROM_CHAR_DATE_NONE},               /* a */
 
760
        {"a.d.", 4, DCH_a_d, FALSE, FROM_CHAR_DATE_NONE},       /* a */
761
761
        {"a.m.", 4, DCH_a_m, FALSE, FROM_CHAR_DATE_NONE},
762
762
        {"ad", 2, DCH_ad, FALSE, FROM_CHAR_DATE_NONE},
763
763
        {"am", 2, DCH_am, FALSE, FROM_CHAR_DATE_NONE},
764
 
        {"b.c.", 4, DCH_b_c, FALSE, FROM_CHAR_DATE_NONE},               /* b */
 
764
        {"b.c.", 4, DCH_b_c, FALSE, FROM_CHAR_DATE_NONE},       /* b */
765
765
        {"bc", 2, DCH_bc, FALSE, FROM_CHAR_DATE_NONE},
766
 
        {"cc", 2, DCH_CC, TRUE, FROM_CHAR_DATE_NONE},                   /* c */
767
 
        {"day", 3, DCH_day, FALSE, FROM_CHAR_DATE_NONE},                /* d */
 
766
        {"cc", 2, DCH_CC, TRUE, FROM_CHAR_DATE_NONE},           /* c */
 
767
        {"day", 3, DCH_day, FALSE, FROM_CHAR_DATE_NONE},        /* d */
768
768
        {"ddd", 3, DCH_DDD, TRUE, FROM_CHAR_DATE_GREGORIAN},
769
769
        {"dd", 2, DCH_DD, TRUE, FROM_CHAR_DATE_GREGORIAN},
770
770
        {"dy", 2, DCH_dy, FALSE, FROM_CHAR_DATE_NONE},
771
771
        {"d", 1, DCH_D, TRUE, FROM_CHAR_DATE_GREGORIAN},
772
 
        {"fx", 2, DCH_FX, FALSE, FROM_CHAR_DATE_NONE},                  /* f */
773
 
        {"hh24", 4, DCH_HH24, TRUE, FROM_CHAR_DATE_NONE},               /* h */
 
772
        {"fx", 2, DCH_FX, FALSE, FROM_CHAR_DATE_NONE},          /* f */
 
773
        {"hh24", 4, DCH_HH24, TRUE, FROM_CHAR_DATE_NONE},       /* h */
774
774
        {"hh12", 4, DCH_HH12, TRUE, FROM_CHAR_DATE_NONE},
775
775
        {"hh", 2, DCH_HH, TRUE, FROM_CHAR_DATE_NONE},
776
 
        {"iddd", 4, DCH_IDDD, TRUE, FROM_CHAR_DATE_ISOWEEK},    /* i */
 
776
        {"iddd", 4, DCH_IDDD, TRUE, FROM_CHAR_DATE_ISOWEEK},            /* i */
777
777
        {"id", 2, DCH_ID, TRUE, FROM_CHAR_DATE_ISOWEEK},
778
778
        {"iw", 2, DCH_IW, TRUE, FROM_CHAR_DATE_ISOWEEK},
779
779
        {"iyyy", 4, DCH_IYYY, TRUE, FROM_CHAR_DATE_ISOWEEK},
780
780
        {"iyy", 3, DCH_IYY, TRUE, FROM_CHAR_DATE_ISOWEEK},
781
781
        {"iy", 2, DCH_IY, TRUE, FROM_CHAR_DATE_ISOWEEK},
782
782
        {"i", 1, DCH_I, TRUE, FROM_CHAR_DATE_ISOWEEK},
783
 
        {"j", 1, DCH_J, TRUE, FROM_CHAR_DATE_NONE},                             /* j */
784
 
        {"mi", 2, DCH_MI, TRUE, FROM_CHAR_DATE_NONE},                   /* m */
 
783
        {"j", 1, DCH_J, TRUE, FROM_CHAR_DATE_NONE}, /* j */
 
784
        {"mi", 2, DCH_MI, TRUE, FROM_CHAR_DATE_NONE},           /* m */
785
785
        {"mm", 2, DCH_MM, TRUE, FROM_CHAR_DATE_GREGORIAN},
786
786
        {"month", 5, DCH_month, FALSE, FROM_CHAR_DATE_GREGORIAN},
787
787
        {"mon", 3, DCH_mon, FALSE, FROM_CHAR_DATE_GREGORIAN},
788
788
        {"ms", 2, DCH_MS, TRUE, FROM_CHAR_DATE_NONE},
789
 
        {"p.m.", 4, DCH_p_m, FALSE, FROM_CHAR_DATE_NONE},               /* p */
 
789
        {"p.m.", 4, DCH_p_m, FALSE, FROM_CHAR_DATE_NONE},       /* p */
790
790
        {"pm", 2, DCH_pm, FALSE, FROM_CHAR_DATE_NONE},
791
 
        {"q", 1, DCH_Q, TRUE, FROM_CHAR_DATE_NONE},                             /* q */
792
 
        {"rm", 2, DCH_rm, FALSE, FROM_CHAR_DATE_GREGORIAN},             /* r */
793
 
        {"ssss", 4, DCH_SSSS, TRUE, FROM_CHAR_DATE_NONE},               /* s */
 
791
        {"q", 1, DCH_Q, TRUE, FROM_CHAR_DATE_NONE}, /* q */
 
792
        {"rm", 2, DCH_rm, FALSE, FROM_CHAR_DATE_GREGORIAN}, /* r */
 
793
        {"ssss", 4, DCH_SSSS, TRUE, FROM_CHAR_DATE_NONE},       /* s */
794
794
        {"ss", 2, DCH_SS, TRUE, FROM_CHAR_DATE_NONE},
795
 
        {"tz", 2, DCH_tz, FALSE, FROM_CHAR_DATE_NONE},                  /* t */
796
 
        {"us", 2, DCH_US, TRUE, FROM_CHAR_DATE_NONE},                   /* u */
797
 
        {"ww", 2, DCH_WW, TRUE, FROM_CHAR_DATE_GREGORIAN},              /* w */
 
795
        {"tz", 2, DCH_tz, FALSE, FROM_CHAR_DATE_NONE},          /* t */
 
796
        {"us", 2, DCH_US, TRUE, FROM_CHAR_DATE_NONE},           /* u */
 
797
        {"ww", 2, DCH_WW, TRUE, FROM_CHAR_DATE_GREGORIAN},      /* w */
798
798
        {"w", 1, DCH_W, TRUE, FROM_CHAR_DATE_GREGORIAN},
799
 
        {"y,yyy", 5, DCH_Y_YYY, TRUE, FROM_CHAR_DATE_GREGORIAN},/* y */
 
799
        {"y,yyy", 5, DCH_Y_YYY, TRUE, FROM_CHAR_DATE_GREGORIAN},        /* y */
800
800
        {"yyyy", 4, DCH_YYYY, TRUE, FROM_CHAR_DATE_GREGORIAN},
801
801
        {"yyy", 3, DCH_YYY, TRUE, FROM_CHAR_DATE_GREGORIAN},
802
802
        {"yy", 2, DCH_YY, TRUE, FROM_CHAR_DATE_GREGORIAN},
814
814
 */
815
815
static const KeyWord NUM_keywords[] = {
816
816
/*      name, len, id                   is in Index */
817
 
        {",", 1, NUM_COMMA},    /* , */
818
 
        {".", 1, NUM_DEC},              /* . */
819
 
        {"0", 1, NUM_0},                /* 0 */
820
 
        {"9", 1, NUM_9},                /* 9 */
821
 
        {"B", 1, NUM_B},                /* B */
822
 
        {"C", 1, NUM_C},                /* C */
823
 
        {"D", 1, NUM_D},                /* D */
824
 
        {"E", 1, NUM_E},                /* E */
825
 
        {"FM", 2, NUM_FM},              /* F */
826
 
        {"G", 1, NUM_G},                /* G */
827
 
        {"L", 1, NUM_L},                /* L */
828
 
        {"MI", 2, NUM_MI},              /* M */
829
 
        {"PL", 2, NUM_PL},              /* P */
 
817
        {",", 1, NUM_COMMA},            /* , */
 
818
        {".", 1, NUM_DEC},                      /* . */
 
819
        {"0", 1, NUM_0},                        /* 0 */
 
820
        {"9", 1, NUM_9},                        /* 9 */
 
821
        {"B", 1, NUM_B},                        /* B */
 
822
        {"C", 1, NUM_C},                        /* C */
 
823
        {"D", 1, NUM_D},                        /* D */
 
824
        {"E", 1, NUM_E},                        /* E */
 
825
        {"FM", 2, NUM_FM},                      /* F */
 
826
        {"G", 1, NUM_G},                        /* G */
 
827
        {"L", 1, NUM_L},                        /* L */
 
828
        {"MI", 2, NUM_MI},                      /* M */
 
829
        {"PL", 2, NUM_PL},                      /* P */
830
830
        {"PR", 2, NUM_PR},
831
 
        {"RN", 2, NUM_RN},              /* R */
832
 
        {"SG", 2, NUM_SG},              /* S */
 
831
        {"RN", 2, NUM_RN},                      /* R */
 
832
        {"SG", 2, NUM_SG},                      /* S */
833
833
        {"SP", 2, NUM_SP},
834
834
        {"S", 1, NUM_S},
835
 
        {"TH", 2, NUM_TH},              /* T */
836
 
        {"V", 1, NUM_V},                /* V */
837
 
        {"b", 1, NUM_B},                /* b */
838
 
        {"c", 1, NUM_C},                /* c */
839
 
        {"d", 1, NUM_D},                /* d */
840
 
        {"e", 1, NUM_E},                /* e */
841
 
        {"fm", 2, NUM_FM},              /* f */
842
 
        {"g", 1, NUM_G},                /* g */
843
 
        {"l", 1, NUM_L},                /* l */
844
 
        {"mi", 2, NUM_MI},              /* m */
845
 
        {"pl", 2, NUM_PL},              /* p */
 
835
        {"TH", 2, NUM_TH},                      /* T */
 
836
        {"V", 1, NUM_V},                        /* V */
 
837
        {"b", 1, NUM_B},                        /* b */
 
838
        {"c", 1, NUM_C},                        /* c */
 
839
        {"d", 1, NUM_D},                        /* d */
 
840
        {"e", 1, NUM_E},                        /* e */
 
841
        {"fm", 2, NUM_FM},                      /* f */
 
842
        {"g", 1, NUM_G},                        /* g */
 
843
        {"l", 1, NUM_L},                        /* l */
 
844
        {"mi", 2, NUM_MI},                      /* m */
 
845
        {"pl", 2, NUM_PL},                      /* p */
846
846
        {"pr", 2, NUM_PR},
847
 
        {"rn", 2, NUM_rn},              /* r */
848
 
        {"sg", 2, NUM_SG},              /* s */
 
847
        {"rn", 2, NUM_rn},                      /* r */
 
848
        {"sg", 2, NUM_SG},                      /* s */
849
849
        {"sp", 2, NUM_SP},
850
850
        {"s", 1, NUM_S},
851
 
        {"th", 2, NUM_th},              /* t */
852
 
        {"v", 1, NUM_V},                /* v */
 
851
        {"th", 2, NUM_th},                      /* t */
 
852
        {"v", 1, NUM_V},                        /* v */
853
853
 
854
854
        /* last */
855
855
        {NULL, 0, 0}
950
950
                         KeySuffix *suf, const int *index, int ver, NUMDesc *Num);
951
951
 
952
952
static void DCH_to_char(FormatNode *node, bool is_interval,
953
 
                                                TmToChar *in, char *out);
 
953
                        TmToChar *in, char *out);
954
954
static void DCH_from_char(FormatNode *node, char *in, TmFromChar *out);
955
955
 
956
956
#ifdef DEBUG_TO_FROM_CHAR
1474
1474
char *
1475
1475
str_tolower(const char *buff, size_t nbytes)
1476
1476
{
1477
 
        char            *result;
 
1477
        char       *result;
1478
1478
 
1479
1479
        if (!buff)
1480
1480
                return NULL;
1482
1482
#ifdef USE_WIDE_UPPER_LOWER
1483
1483
        if (pg_database_encoding_max_length() > 1 && !lc_ctype_is_c())
1484
1484
        {
1485
 
                wchar_t         *workspace;
 
1485
                wchar_t    *workspace;
1486
1486
                size_t          curr_char;
1487
1487
                size_t          result_size;
1488
1488
 
1508
1508
                pfree(workspace);
1509
1509
        }
1510
1510
        else
1511
 
#endif          /* USE_WIDE_UPPER_LOWER */
 
1511
#endif   /* USE_WIDE_UPPER_LOWER */
1512
1512
        {
1513
 
                char *p;
 
1513
                char       *p;
1514
1514
 
1515
1515
                result = pnstrdup(buff, nbytes);
1516
1516
 
1530
1530
char *
1531
1531
str_toupper(const char *buff, size_t nbytes)
1532
1532
{
1533
 
        char            *result;
 
1533
        char       *result;
1534
1534
 
1535
1535
        if (!buff)
1536
1536
                return NULL;
1538
1538
#ifdef USE_WIDE_UPPER_LOWER
1539
1539
        if (pg_database_encoding_max_length() > 1 && !lc_ctype_is_c())
1540
1540
        {
1541
 
                wchar_t         *workspace;
 
1541
                wchar_t    *workspace;
1542
1542
                size_t          curr_char;
1543
1543
                size_t          result_size;
1544
1544
 
1564
1564
                pfree(workspace);
1565
1565
        }
1566
1566
        else
1567
 
#endif          /* USE_WIDE_UPPER_LOWER */
 
1567
#endif   /* USE_WIDE_UPPER_LOWER */
1568
1568
        {
1569
 
                char *p;
 
1569
                char       *p;
1570
1570
 
1571
1571
                result = pnstrdup(buff, nbytes);
1572
1572
 
1586
1586
char *
1587
1587
str_initcap(const char *buff, size_t nbytes)
1588
1588
{
1589
 
        char            *result;
 
1589
        char       *result;
1590
1590
        int                     wasalnum = false;
1591
1591
 
1592
1592
        if (!buff)
1595
1595
#ifdef USE_WIDE_UPPER_LOWER
1596
1596
        if (pg_database_encoding_max_length() > 1 && !lc_ctype_is_c())
1597
1597
        {
1598
 
                wchar_t         *workspace;
 
1598
                wchar_t    *workspace;
1599
1599
                size_t          curr_char;
1600
1600
                size_t          result_size;
1601
1601
 
1627
1627
                pfree(workspace);
1628
1628
        }
1629
1629
        else
1630
 
#endif          /* USE_WIDE_UPPER_LOWER */
 
1630
#endif   /* USE_WIDE_UPPER_LOWER */
1631
1631
        {
1632
 
                char *p;
 
1632
                char       *p;
1633
1633
 
1634
1634
                result = pnstrdup(buff, nbytes);
1635
1635
 
1805
1805
        if (*dest != 0 && *dest != value)
1806
1806
                ereport(ERROR,
1807
1807
                                (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
1808
 
                                 errmsg("conflicting values for \"%s\" field in formatting string",
1809
 
                                            node->key->name),
 
1808
                   errmsg("conflicting values for \"%s\" field in formatting string",
 
1809
                                  node->key->name),
1810
1810
                                 errdetail("This value contradicts a previous setting for "
1811
1811
                                                   "the same field type.")));
1812
1812
        *dest = value;
1817
1817
 * 'dest'. If 'dest' is NULL, the result is discarded.
1818
1818
 *
1819
1819
 * In fixed-width mode (the node does not have the FM suffix), consume at most
1820
 
 * 'len' characters.
 
1820
 * 'len' characters.  However, any leading whitespace isn't counted in 'len'.
1821
1821
 *
1822
1822
 * We use strtol() to recover the integer value from the source string, in
1823
1823
 * accordance with the given FormatNode.
1840
1840
        char       *init = *src;
1841
1841
        int                     used;
1842
1842
 
 
1843
        /*
 
1844
         * Skip any whitespace before parsing the integer.
 
1845
         */
 
1846
        *src += strspace_len(*src);
 
1847
 
1843
1848
        Assert(len <= DCH_MAX_ITEM_SIZ);
1844
1849
        used = (int) strlcpy(copy, *src, len + 1);
1845
1850
 
1847
1852
        {
1848
1853
                /*
1849
1854
                 * This node is in Fill Mode, or the next node is known to be a
1850
 
                 * non-digit value, so we just slurp as many characters as we
1851
 
                 * can get.
 
1855
                 * non-digit value, so we just slurp as many characters as we can get.
1852
1856
                 */
1853
1857
                errno = 0;
1854
1858
                result = strtol(init, src, 10);
1859
1863
                 * We need to pull exactly the number of characters given in 'len' out
1860
1864
                 * of the string, and convert those.
1861
1865
                 */
1862
 
                char *last;
 
1866
                char       *last;
1863
1867
 
1864
1868
                if (used < len)
1865
1869
                        ereport(ERROR,
1866
1870
                                        (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
1867
 
                                         errmsg("source string too short for \"%s\" formatting field",
1868
 
                                                    node->key->name),
 
1871
                                errmsg("source string too short for \"%s\" formatting field",
 
1872
                                           node->key->name),
1869
1873
                                         errdetail("Field requires %d characters, but only %d "
1870
1874
                                                           "remain.",
1871
1875
                                                           len, used),
1879
1883
                if (used > 0 && used < len)
1880
1884
                        ereport(ERROR,
1881
1885
                                        (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
1882
 
                                         errmsg("invalid value \"%s\" for \"%s\"", 
1883
 
                                                        copy, node->key->name),
 
1886
                                         errmsg("invalid value \"%s\" for \"%s\"",
 
1887
                                                        copy, node->key->name),
1884
1888
                                         errdetail("Field requires %d characters, but only %d "
1885
 
                                                           "could be parsed.", len, used),
 
1889
                                                           "could be parsed.", len, used),
1886
1890
                                         errhint("If your source string is not fixed-width, try "
1887
 
                                                         "using the \"FM\" modifier.")));
 
1891
                                                         "using the \"FM\" modifier.")));
1888
1892
 
1889
1893
                *src += used;
1890
1894
        }
1893
1897
                ereport(ERROR,
1894
1898
                                (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
1895
1899
                                 errmsg("invalid value \"%s\" for \"%s\"",
1896
 
                                            copy, node->key->name),
 
1900
                                                copy, node->key->name),
1897
1901
                                 errdetail("Value must be an integer.")));
1898
1902
 
1899
1903
        if (errno == ERANGE || result < INT_MIN || result > INT_MAX)
1900
1904
                ereport(ERROR,
1901
1905
                                (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
1902
1906
                                 errmsg("value for \"%s\" in source string is out of range",
1903
 
                                            node->key->name),
 
1907
                                                node->key->name),
1904
1908
                                 errdetail("Value must be in the range %d to %d.",
1905
1909
                                                   INT_MIN, INT_MAX)));
1906
1910
 
1998
2002
 
1999
2003
/*
2000
2004
 * Perform a sequential search in 'array' for text matching the first 'max'
2001
 
 * characters of the source string.  
 
2005
 * characters of the source string.
2002
2006
 *
2003
2007
 * If a match is found, copy the array index of the match into the integer
2004
2008
 * pointed to by 'dest', advance 'src' to the end of the part of the string
2007
2011
 * If the string doesn't match, throw an error.
2008
2012
 */
2009
2013
static int
2010
 
from_char_seq_search(int *dest, char **src, char **array, int type, int max, 
 
2014
from_char_seq_search(int *dest, char **src, char **array, int type, int max,
2011
2015
                                         FormatNode *node)
2012
2016
{
2013
 
        int len;
 
2017
        int                     len;
2014
2018
 
2015
2019
        *dest = seq_search(*src, array, type, max, &len);
2016
2020
        if (len <= 0)
2017
2021
        {
2018
 
                char copy[DCH_MAX_ITEM_SIZ + 1];
 
2022
                char            copy[DCH_MAX_ITEM_SIZ + 1];
2019
2023
 
2020
2024
                Assert(max <= DCH_MAX_ITEM_SIZ);
2021
2025
                strlcpy(copy, *src, max + 1);
2023
2027
                ereport(ERROR,
2024
2028
                                (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
2025
2029
                                 errmsg("invalid value \"%s\" for \"%s\"",
2026
 
                                            copy, node->key->name),
 
2030
                                                copy, node->key->name),
2027
2031
                                 errdetail("The given value did not match any of the allowed "
2028
 
                                                   "values for this field.")));
 
2032
                                                   "values for this field.")));
2029
2033
        }
2030
2034
        *src += len;
2031
2035
        return len;
2111
2115
                                        str_numth(s, s, S_TH_TYPE(n->suffix));
2112
2116
                                s += strlen(s);
2113
2117
                                break;
2114
 
                        case DCH_MS:                    /* millisecond */
 
2118
                        case DCH_MS:            /* millisecond */
2115
2119
#ifdef HAVE_INT64_TIMESTAMP
2116
2120
                                sprintf(s, "%03d", (int) (in->fsec / INT64CONST(1000)));
2117
2121
#else
2122
2126
                                        str_numth(s, s, S_TH_TYPE(n->suffix));
2123
2127
                                s += strlen(s);
2124
2128
                                break;
2125
 
                        case DCH_US:                    /* microsecond */
 
2129
                        case DCH_US:            /* microsecond */
2126
2130
#ifdef HAVE_INT64_TIMESTAMP
2127
2131
                                sprintf(s, "%06d", (int) in->fsec);
2128
2132
#else
2263
2267
                                        strcpy(s, str_toupper_z(localized_full_days[tm->tm_wday]));
2264
2268
                                else
2265
2269
                                        sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -9,
2266
 
                                                                str_toupper_z(days[tm->tm_wday]));
 
2270
                                                        str_toupper_z(days[tm->tm_wday]));
2267
2271
                                s += strlen(s);
2268
2272
                                break;
2269
2273
                        case DCH_Day:
2317
2321
                                sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : 3,
2318
2322
                                                (n->key->id == DCH_DDD) ?
2319
2323
                                                tm->tm_yday :
2320
 
                                                date2isoyearday(tm->tm_year, tm->tm_mon, tm->tm_mday));
 
2324
                                          date2isoyearday(tm->tm_year, tm->tm_mon, tm->tm_mday));
2321
2325
                                if (S_THth(n->suffix))
2322
2326
                                        str_numth(s, s, S_TH_TYPE(n->suffix));
2323
2327
                                s += strlen(s);
2365
2369
                                s += strlen(s);
2366
2370
                                break;
2367
2371
                        case DCH_CC:
2368
 
                                if (is_interval)                        /* straight calculation */
 
2372
                                if (is_interval)        /* straight calculation */
2369
2373
                                        i = tm->tm_year / 100;
2370
 
                                else                                            /* century 21 starts in 2001 */
 
2374
                                else    /* century 21 starts in 2001 */
2371
2375
                                        i = (tm->tm_year - 1) / 100 + 1;
2372
2376
                                if (i <= 99 && i >= -99)
2373
2377
                                        sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : 2, i);
2556
2560
                                from_char_parse_int(&out->ss, &s, n);
2557
2561
                                s += SKIP_THth(n->suffix);
2558
2562
                                break;
2559
 
                        case DCH_MS:                    /* millisecond */
 
2563
                        case DCH_MS:            /* millisecond */
2560
2564
                                len = from_char_parse_int_len(&out->ms, &s, 3, n);
2561
2565
 
2562
2566
                                /*
2567
2571
 
2568
2572
                                s += SKIP_THth(n->suffix);
2569
2573
                                break;
2570
 
                        case DCH_US:                    /* microsecond */
 
2574
                        case DCH_US:            /* microsecond */
2571
2575
                                len = from_char_parse_int_len(&out->us, &s, 6, n);
2572
2576
 
2573
2577
                                out->us *= len == 1 ? 100000 :
2662
2666
                                s += SKIP_THth(n->suffix);
2663
2667
                                break;
2664
2668
                        case DCH_Q:
 
2669
 
2665
2670
                                /*
2666
2671
                                 * We ignore Q when converting to date because it is not
2667
2672
                                 * normative.
2678
2683
                                break;
2679
2684
                        case DCH_Y_YYY:
2680
2685
                                {
2681
 
                                        int matched, years, millenia;
 
2686
                                        int                     matched,
 
2687
                                                                years,
 
2688
                                                                millenia;
2682
2689
 
2683
2690
                                        matched = sscanf(s, "%d,%03d", &millenia, &years);
2684
2691
                                        if (matched != 2)
2685
2692
                                                ereport(ERROR,
2686
2693
                                                                (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
2687
 
                                                                 errmsg("invalid input string for \"Y,YYY\"")));
 
2694
                                                          errmsg("invalid input string for \"Y,YYY\"")));
2688
2695
                                        years += (millenia * 1000);
2689
2696
                                        from_char_set_int(&out->year, years, n);
2690
2697
                                        out->yysz = 4;
2739
2746
                                s += SKIP_THth(n->suffix);
2740
2747
                                break;
2741
2748
                        case DCH_RM:
2742
 
                                from_char_seq_search(&value, &s, rm_months_upper, 
 
2749
                                from_char_seq_search(&value, &s, rm_months_upper,
2743
2750
                                                                         ALL_UPPER, MAX_RM_LEN, n);
2744
2751
                                from_char_set_int(&out->mm, 12 - value, n);
2745
2752
                                break;
2746
2753
                        case DCH_rm:
2747
 
                                from_char_seq_search(&value, &s, rm_months_lower, 
 
2754
                                from_char_seq_search(&value, &s, rm_months_lower,
2748
2755
                                                                         ALL_LOWER, MAX_RM_LEN, n);
2749
2756
                                from_char_set_int(&out->mm, 12 - value, n);
2750
2757
                                break;
3276
3283
        if (tmfc.ddd && (tm->tm_mon <= 1 || tm->tm_mday <= 1))
3277
3284
        {
3278
3285
                /*
3279
 
                 * The month and day field have not been set, so we use the day-of-year
3280
 
                 * field to populate them.  Depending on the date mode, this field may
3281
 
                 * be interpreted as a Gregorian day-of-year, or an ISO week date
3282
 
                 * day-of-year.
 
3286
                 * The month and day field have not been set, so we use the
 
3287
                 * day-of-year field to populate them.  Depending on the date mode,
 
3288
                 * this field may be interpreted as a Gregorian day-of-year, or an ISO
 
3289
                 * week date day-of-year.
3283
3290
                 */
3284
3291
 
3285
3292
                if (!tm->tm_year && !tmfc.bc)
3286
3293
                        ereport(ERROR,
3287
3294
                                        (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
3288
 
                                         errmsg("cannot calculate day of year without year information")));
 
3295
                        errmsg("cannot calculate day of year without year information")));
3289
3296
 
3290
3297
                if (tmfc.mode == FROM_CHAR_DATE_ISOWEEK)
3291
3298
                {
3302
3309
 
3303
3310
                        static const int ysum[2][13] = {
3304
3311
                                {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365},
3305
 
                                {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}};
 
3312
                        {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}};
3306
3313
 
3307
3314
                        y = ysum[isleap(tm->tm_year)];
3308
3315
 
3388
3395
                for (ent = NUMCache; ent <= (NUMCache + NUM_CACHE_FIELDS); ent++)
3389
3396
                {
3390
3397
                        /*
3391
 
                         * entry removed via NUM_cache_remove() can be used here,
3392
 
                         * which is why it's worth scanning first entry again
 
3398
                         * entry removed via NUM_cache_remove() can be used here, which is
 
3399
                         * why it's worth scanning first entry again
3393
3400
                         */
3394
3401
                        if (ent->str[0] == '\0')
3395
3402
                        {
3621
3628
                 */
3622
3629
                if (lconv->decimal_point && *lconv->decimal_point)
3623
3630
                        Np->decimal = lconv->decimal_point;
 
3631
 
3624
3632
                else
3625
3633
                        Np->decimal = ".";
3626
3634
 
3637
3645
                if (lconv->thousands_sep && *lconv->thousands_sep)
3638
3646
                        Np->L_thousands_sep = lconv->thousands_sep;
3639
3647
                /* Make sure thousands separator doesn't match decimal point symbol. */
3640
 
                else if (strcmp(Np->decimal, ",") != 0)
 
3648
                else if (strcmp(Np->decimal, ",") !=0)
3641
3649
                        Np->L_thousands_sep = ",";
3642
3650
                else
3643
3651
                        Np->L_thousands_sep = ".";