]> git.pond.sub.org Git - empserver/blob - src/lib/common/keyword.c
Indented with src/scripts/indent-emp.
[empserver] / src / lib / common / keyword.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2000, Dave Pare, Jeff Bailey, Thomas Ruschak,
4  *                           Ken Stevens, Steve McClure
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  *  ---
21  *
22  *  See the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the
23  *  related information and legal notices. It is expected that any future
24  *  projects/authors will amend these files as needed.
25  *
26  *  ---
27  *
28  *  keyword.c: Find keywords in a file
29  * 
30  *  Known contributors to this file:
31  *     
32  */
33
34 #include "misc.h"
35 #include "keyword.h"
36 #include "gen.h"
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <ctype.h>
40 #include "common.h"
41
42 struct kwtab {
43     struct kwtab *next;
44     s_char *name;
45     s_char *text;
46 };
47
48 struct kwtab *kw_list;
49
50 int
51 kw_read(FILE * fp)
52 {
53     register struct kwtab *kw;
54     register struct kwtab *next;
55     s_char buf[255];
56     s_char *p;
57     int n;
58
59     for (kw = kw_list; kw != 0; kw = next) {
60         next = kw->next;
61         free(kw->name);
62         free(kw->text);
63         free(kw);
64     }
65     kw_list = 0;
66     for (n = 0; fgets(buf, sizeof(buf), fp) != 0; n++) {
67         /* Allow for comments.. any line starting with # */
68         if (buf[0] == '#')
69             continue;
70         p = rindex(buf, '\n');
71         if (p != 0)
72             *p = 0;
73         if ((p = index(buf, ':')) == 0) {
74             logerror("kw_read: Bad keyword line #%d\n", n);
75             return 0;
76         }
77         *p++ = 0;
78         while (*p && isspace(*p))
79             p++;
80         kw = (struct kwtab *)malloc(sizeof(*kw));
81         kw->name = strcpy(malloc(strlen(buf) + 1), buf);
82         kw->text = strcpy(malloc(strlen(p) + 1), p);
83         kw->next = kw_list;
84         kw_list = kw;
85     }
86     return n;
87 }
88
89 s_char *
90 kw_find(s_char *name)
91 {
92     register struct kwtab *kw;
93
94     for (kw = kw_list; kw != 0; kw = kw->next) {
95         if (strcmp(kw->name, name) == 0)
96             return kw->text;
97     }
98     return 0;
99 }
100
101 #define CF_VALUE        1
102 #define CF_TIME         2
103 #define CF_TIMERANGE    3
104 #define CF_WEEKDAY      4
105
106 /*
107  * destructive parse
108  */
109 s_char *
110 kw_parse(int type, s_char *text, int *data)
111 {
112     s_char *get_time(s_char *ptr, int *data);
113     s_char *weekday(s_char *ptr, int *data);
114     s_char *next;
115
116     while (isspace(*text))
117         text++;
118     switch (type) {
119     case CF_VALUE:
120         *data = atoip(&text);
121         break;
122     case CF_TIME:
123         text = get_time(text, &data[0]);
124         break;
125     case CF_TIMERANGE:
126         if ((next = index(text, '-')) == 0)
127             return 0;
128         next++;
129         if ((text = get_time(text, &data[0])) == 0)
130             return 0;
131         text = get_time(next, &data[1]);
132         break;
133     case CF_WEEKDAY:
134         text = weekday(text, &data[0]);
135         break;
136     default:
137         text = 0;
138         break;
139     }
140     return text;
141 }
142
143 struct day {
144     s_char *string;
145     int day[7];
146 } day[] = {
147     {
148         "smtwtfs", {
149     -1, 0, -1, 2, -1, 4, -1}}, {
150         "uouehra", {
151     0, 1, 2, 3, 4, 5, 6}}
152 };
153
154 s_char *
155 weekday(s_char *ptr, int *data)
156 {
157     register s_char *string;
158     register int c;
159     register int n;
160
161     c = *ptr++;
162     if (isupper(c))
163         c = tolower(c);
164     string = day[0].string;
165     for (n = 0; n < 7; n++) {
166         if (string[n] != c)
167             continue;
168         if (day[0].day[n] >= 0)
169             break;
170         if (day[1].string[n] == *ptr)
171             break;
172     }
173     if (n == 7)
174         return 0;
175     *data = day[1].day[n];
176     while (*ptr && !isspace(*ptr))
177         ptr++;
178     return ptr;
179 }
180
181
182 s_char *
183 get_time(s_char *ptr, int *data)
184 {
185     int hour;
186     int minute;
187
188     if (!isdigit(*ptr))
189         return 0;
190     hour = atoip(&ptr);
191     minute = 0;
192     if (*ptr) {
193         if (*ptr != ':')
194             return 0;
195         ptr++;
196         if (!isdigit(*ptr))
197             return 0;
198         minute = atoip(&ptr);
199     }
200     *data = (hour * 60) + minute;
201     return ptr;
202 }