GCC Code Coverage Report


Directory: ./
File: panels/system/datetime/date-endian.c
Date: 2024-05-04 07:58:27
Exec Total Coverage
Lines: 0 85 0.0%
Functions: 0 4 0.0%
Branches: 0 69 0.0%

Line Branch Exec Source
1 /*
2 * Copyright (C) 2011 Red Hat, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
16 *
17 * Author: Bastien Nocera <hadess@hadess.net>
18 *
19 */
20
21 #include <errno.h>
22 #include <langinfo.h>
23 #include <locale.h>
24 #include <glib.h>
25 #include <string.h>
26
27 #include "date-endian.h"
28
29 /* We default to returning DATE_ENDIANESS_LITTLE because that's
30 * what 3.4 billion people use */
31 #define DEFAULT_ENDIANESS DATE_ENDIANESS_LITTLE
32
33 typedef enum {
34 ITEM_NONE = 0,
35 ITEM_DAY,
36 ITEM_MONTH,
37 ITEM_YEAR
38 } Item;
39
40 static gboolean
41 has_item (Item *items,
42 Item item)
43 {
44 guint i;
45
46 for (i = 0; i < 3; i++) {
47 if (items[i] == ITEM_NONE)
48 return FALSE;
49 if (items[i] == item)
50 return TRUE;
51 }
52 return FALSE;
53 }
54
55 DateEndianess
56 date_endian_get_default (gboolean verbose)
57 {
58 const char *fmt;
59 const char *p;
60 Item items[3];
61 guint i;
62
63 fmt = nl_langinfo (D_FMT);
64 g_return_val_if_fail (fmt != NULL, DEFAULT_ENDIANESS);
65
66 if (verbose)
67 g_print ("%s", fmt);
68
69 if (g_str_equal (fmt, "%F"))
70 return DATE_ENDIANESS_BIG;
71
72 i = 0;
73 memset (&items, 0, sizeof(items));
74
75 /* Assume ASCII only */
76 for (p = fmt; *p != '\0'; p++) {
77 char c;
78
79 /* Look for '%' */
80 if (*p != '%')
81 continue;
82
83 /* Only assert when we're sure we don't have another '%' */
84 if (i >= 4) {
85 g_warning ("Could not parse format '%s', too many formats", fmt);
86 return DEFAULT_ENDIANESS;
87 }
88
89 c = *(p + 1);
90 /* Ignore alternative formats */
91 if (c == 'O' || c == '-' || c == 'E')
92 c = *(p + 2);
93 if (c == '\0') {
94 g_warning ("Count not parse format '%s', unterminated '%%'", fmt);
95 return DEFAULT_ENDIANESS;
96 }
97 switch (c) {
98 case 'A':
99 case 'd':
100 case 'e':
101 if (has_item (items, ITEM_DAY) == FALSE) {
102 items[i] = ITEM_DAY;
103 i++;
104 }
105 break;
106 case 'm':
107 case 'b':
108 case 'B':
109 if (has_item (items, ITEM_MONTH) == FALSE) {
110 items[i] = ITEM_MONTH;
111 i++;
112 }
113 break;
114 case 'y':
115 case 'Y':
116 if (has_item (items, ITEM_YEAR) == FALSE) {
117 items[i] = ITEM_YEAR;
118 i++;
119 }
120 break;
121 case 'a':
122 /* Ignore */
123 ;
124 }
125 }
126
127 if (items[0] == ITEM_DAY &&
128 items[1] == ITEM_MONTH &&
129 items[2] == ITEM_YEAR)
130 return DATE_ENDIANESS_LITTLE;
131 if (items[0] == ITEM_YEAR &&
132 items[1] == ITEM_MONTH &&
133 items[2] == ITEM_DAY)
134 return DATE_ENDIANESS_BIG;
135 if (items[0] == ITEM_MONTH &&
136 items[1] == ITEM_DAY &&
137 items[2] == ITEM_YEAR)
138 return DATE_ENDIANESS_MIDDLE;
139 if (items[0] == ITEM_YEAR &&
140 items[1] == ITEM_DAY &&
141 items[2] == ITEM_MONTH)
142 return DATE_ENDIANESS_YDM;
143
144 g_warning ("Could not parse format '%s'", fmt);
145
146 return DEFAULT_ENDIANESS;
147 }
148
149 DateEndianess
150 date_endian_get_for_lang (const char *lang,
151 gboolean verbose)
152 {
153 locale_t locale;
154 locale_t old_locale;
155 DateEndianess endian;
156
157 locale = newlocale (LC_TIME_MASK, lang, (locale_t) 0);
158 if (locale == (locale_t) 0)
159 g_warning ("Failed to create locale %s: %s", lang, g_strerror (errno));
160 else
161 old_locale = uselocale (locale);
162
163 endian = date_endian_get_default (verbose);
164
165 if (locale != (locale_t) 0) {
166 uselocale (old_locale);
167 freelocale (locale);
168 }
169
170 return endian;
171 }
172
173 const char *
174 date_endian_to_string (DateEndianess endianess)
175 {
176 switch (endianess) {
177 case DATE_ENDIANESS_LITTLE:
178 return "Little (DD-MM-YYYY)";
179 case DATE_ENDIANESS_BIG:
180 return "Big (YYYY-MM-DD)";
181 case DATE_ENDIANESS_MIDDLE:
182 return "Middle (MM-DD-YYYY)";
183 case DATE_ENDIANESS_YDM:
184 return "YDM (YYYY-DD-MM)";
185 default:
186 g_assert_not_reached ();
187 }
188 }
189