1 /*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 2020 The DragonFly Project. All rights reserved.
5 * Copyright (c) 1989, 1993, 1994
6 * The Regents of the University of California. All rights reserved.
7 *
8 * This code is derived from software contributed to The DragonFly Project
9 * by Aaron LI <aly@aaronly.me>
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36 #include <ctype.h>
37 #include <err.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <time.h>
42
43 #include "calendar.h"
44 #include "nnames.h"
45 #include "utils.h"
46
47
48 #define NNAME_INIT0 \
49 { 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0 }
50 #define NNAME_INIT1(val, name) \
51 { (val), name, sizeof(name)-1, NULL, 0, NULL, 0, NULL, 0 }
52 #define NNAME_INIT2(val, name, f_name) \
53 { (val), name, sizeof(name)-1, f_name, sizeof(f_name)-1, \
54 NULL, 0, NULL, 0 }
55
56 /* names of every day of week */
57 struct nname dow_names[NDOWS+1] = {
58 NNAME_INIT2(0, "Sun", "Sunday"),
59 NNAME_INIT2(1, "Mon", "Monday"),
60 NNAME_INIT2(2, "Tue", "Tuesday"),
61 NNAME_INIT2(3, "Wed", "Wednesday"),
62 NNAME_INIT2(4, "Thu", "Thursday"),
63 NNAME_INIT2(5, "Fri", "Friday"),
64 NNAME_INIT2(6, "Sat", "Saturday"),
65 NNAME_INIT0,
66 };
67
68 /* names of every month */
69 struct nname month_names[NMONTHS+1] = {
70 NNAME_INIT2(1, "Jan", "January"),
71 NNAME_INIT2(2, "Feb", "February"),
72 NNAME_INIT2(3, "Mar", "March"),
73 NNAME_INIT2(4, "Apr", "April"),
74 NNAME_INIT2(5, "May", "May"),
75 NNAME_INIT2(6, "Jun", "June"),
76 NNAME_INIT2(7, "Jul", "July"),
77 NNAME_INIT2(8, "Aug", "August"),
78 NNAME_INIT2(9, "Sep", "September"),
79 NNAME_INIT2(10, "Oct", "October"),
80 NNAME_INIT2(11, "Nov", "November"),
81 NNAME_INIT2(12, "Dec", "December"),
82 NNAME_INIT0,
83 };
84
85 /* names of every sequence */
86 struct nname sequence_names[NSEQUENCES+1] = {
87 NNAME_INIT1(1, "First"),
88 NNAME_INIT1(2, "Second"),
89 NNAME_INIT1(3, "Third"),
90 NNAME_INIT1(4, "Fourth"),
91 NNAME_INIT1(5, "Fifth"),
92 NNAME_INIT1(-1, "Last"),
93 NNAME_INIT0,
94 };
95
96
97 void
set_nnames(void)98 set_nnames(void)
99 {
100 char buf[64];
101 struct tm tm;
102 struct nname *nname;
103
104 memset(&tm, 0, sizeof(tm));
105 for (int i = 0; i < NDOWS; i++) {
106 nname = &dow_names[i];
107 tm.tm_wday = i;
108
109 strftime(buf, sizeof(buf), "%a", &tm);
110 free(nname->n_name);
111 nname->n_name = xstrdup(buf);
112 nname->n_len = strlen(nname->n_name);
113
114 strftime(buf, sizeof(buf), "%A", &tm);
115 free(nname->fn_name);
116 nname->fn_name = xstrdup(buf);
117 nname->fn_len = strlen(nname->fn_name);
118
119 DPRINTF2("%s: dow[%d]: %s, %s, %s, %s\n", __func__,
120 nname->value, nname->name, nname->f_name,
121 nname->n_name, nname->fn_name);
122 }
123
124 memset(&tm, 0, sizeof(tm));
125 for (int i = 0; i < NMONTHS; i++) {
126 nname = &month_names[i];
127 tm.tm_mon = i;
128
129 strftime(buf, sizeof(buf), "%b", &tm);
130 free(nname->n_name);
131 /* The month may have a leading blank (e.g., on *BSD) */
132 nname->n_name = xstrdup(triml(buf));
133 nname->n_len = strlen(nname->n_name);
134
135 strftime(buf, sizeof(buf), "%B", &tm);
136 free(nname->fn_name);
137 nname->fn_name = xstrdup(triml(buf));
138 nname->fn_len = strlen(nname->fn_name);
139
140 DPRINTF2("%s: month[%02d]: %s, %s, %s, %s\n", __func__,
141 nname->value, nname->name, nname->f_name,
142 nname->n_name, nname->fn_name);
143 }
144 }
145
146 void
set_nsequences(const char * seq)147 set_nsequences(const char *seq)
148 {
149 struct nname *nname;
150 const char *p = seq;
151 size_t len;
152
153 if (count_char(seq, ' ') != NSEQUENCES - 1) {
154 warnx("Invalid SEQUENCE: |%s|", seq);
155 return;
156 }
157
158 for (int i = 0; i < NSEQUENCES; i++) {
159 while (*p != ' ' && *p != '\0')
160 p++;
161
162 len = (size_t)(p - seq);
163 nname = &sequence_names[i];
164 free(nname->n_name);
165 nname->n_name = xcalloc(1, len + 1);
166 strncpy(nname->n_name, seq, len);
167 nname->n_len = strlen(nname->n_name);
168 DPRINTF2("%s: sequence[%d]: %s, %s, %s, %s\n", __func__,
169 nname->value, nname->name, nname->f_name,
170 nname->n_name, nname->fn_name);
171
172 seq = ++p;
173 }
174 }
175