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 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 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