time/tst-strftime2.c: Make the file easier to maintain
[platform/upstream/glibc.git] / time / tst-strftime2.c
1 /* Verify the behavior of strftime on alternative representation for
2    year.
3
4    Copyright (C) 2019 Free Software Foundation, Inc.
5    This file is part of the GNU C Library.
6
7    The GNU C Library is free software; you can redistribute it and/or
8    modify it under the terms of the GNU Lesser General Public
9    License as published by the Free Software Foundation; either
10    version 2.1 of the License, or (at your option) any later version.
11
12    The GNU C Library is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    Lesser General Public License for more details.
16
17    You should have received a copy of the GNU Lesser General Public
18    License along with the GNU C Library; if not, see
19    <http://www.gnu.org/licenses/>.  */
20
21 #include <array_length.h>
22 #include <stdbool.h>
23 #include <support/check.h>
24 #include <stdlib.h>
25 #include <locale.h>
26 #include <time.h>
27 #include <stdio.h>
28 #include <string.h>
29
30 static const char *locales[] =
31 {
32   "ja_JP.UTF-8", "lo_LA.UTF-8", "th_TH.UTF-8"
33 };
34
35 /* Must match locale index into locales array.  */
36 enum
37 {
38   ja_JP, lo_LA, th_TH
39 };
40
41 static const char *formats[] = { "%EY", "%_EY", "%-EY" };
42
43 typedef struct
44 {
45   const int d, m, y;
46 } date_t;
47
48 static const date_t dates[] =
49 {
50   {  1,  4, 1988 },
51   {  7,  1, 1989 },
52   {  8,  1, 1989 },
53   {  1,  4, 1990 },
54   {  1,  4, 1997 },
55   {  1,  4, 1998 }
56 };
57
58 static char ref[array_length (locales)][array_length (formats)]
59                [array_length (dates)][100];
60
61 static bool
62 is_before (const int i, const int d, const int m, const int y)
63 {
64   if (dates[i].y < y)
65     return true;
66   else if (dates[i].y > y)
67     return false;
68   else if (dates[i].m < m)
69     return true;
70   else if (dates[i].m > m)
71     return false;
72   else
73     return dates[i].d < d;
74 }
75
76 static void
77 mkreftable (void)
78 {
79   int i, j, k, yr;
80   const char *era, *sfx;
81   /* Japanese era year to be checked.  */
82   static const int yrj[] =
83   {
84     63, 64, 1, 2, 9, 10
85   };
86   /* Buddhist calendar year to be checked.  */
87   static const int yrb[] =
88   {
89     2531, 2532, 2532, 2533, 2540, 2541
90   };
91
92   for (i = 0; i < array_length (locales); i++)
93     for (j = 0; j < array_length (formats); j++)
94       for (k = 0; k < array_length (dates); k++)
95         {
96           if (i == ja_JP)
97             {
98               era = (is_before (k, 8, 1, 1989)) ? "\u662d\u548c"
99                                                 : "\u5e73\u6210";
100               yr = yrj[k], sfx = "\u5e74";
101             }
102           else if (i == lo_LA)
103             era = "\u0e9e.\u0eaa. ", yr = yrb[k], sfx = "";
104           else if (i == th_TH)
105             era = "\u0e1e.\u0e28. ", yr = yrb[k], sfx = "";
106           else
107             FAIL_EXIT1 ("Invalid table index!");
108           if (yr == 1)
109             sprintf (ref[i][j][k], "%s\u5143%s", era, sfx);
110           else if (j == 0)
111             sprintf (ref[i][j][k], "%s%02d%s", era, abs (yr), sfx);
112           else if (j == 1)
113             sprintf (ref[i][j][k], "%s%2d%s", era, abs (yr), sfx);
114           else if (j == 2)
115             sprintf (ref[i][j][k], "%s%d%s", era, abs (yr), sfx);
116           else
117             FAIL_EXIT1 ("Invalid table index!");
118         }
119 }
120
121 static int
122 do_test (void)
123 {
124   int i, j, k, result = 0;
125   struct tm ttm;
126   char date[11], buf[100];
127   size_t r, e;
128
129   mkreftable ();
130   for (i = 0; i < array_length (locales); i++)
131     {
132       if (setlocale (LC_ALL, locales[i]) == NULL)
133         {
134           printf ("locale %s does not exist, skipping...\n", locales[i]);
135           continue;
136         }
137       printf ("[%s]\n", locales[i]);
138       for (j = 0; j < array_length (formats); j++)
139         {
140           for (k = 0; k < array_length (dates); k++)
141             {
142               ttm.tm_mday = dates[k].d;
143               ttm.tm_mon  = dates[k].m - 1;
144               ttm.tm_year = dates[k].y - 1900;
145               strftime (date, sizeof (date), "%F", &ttm);
146               r = strftime (buf, sizeof (buf), formats[j], &ttm);
147               e = strlen (ref[i][j][k]);
148               printf ("%s\t\"%s\"\t\"%s\"", date, formats[j], buf);
149               if (strcmp (buf, ref[i][j][k]) != 0)
150                 {
151                   printf ("\tshould be \"%s\"", ref[i][j][k]);
152                   if (r != e)
153                     printf ("\tgot: %zu, expected: %zu", r, e);
154                   result = 1;
155                 }
156               else
157                 printf ("\tOK");
158               putchar ('\n');
159             }
160           putchar ('\n');
161         }
162     }
163   return result;
164 }
165
166 #include <support/test-driver.c>