]> git.pond.sub.org Git - empserver/blob - src/lib/common/keyword.c
Import of Empire 4.2.12
[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         { "smtwtfs", { -1, 0, -1, 2, -1, 4, -1  } },
148         { "uouehra", {  0,  1, 2,  3, 4,  5,  6 } }
149 };
150
151 s_char *
152 weekday(s_char *ptr, int *data)
153 {
154         register s_char *string;
155         register int c;
156         register int n;
157
158         c = *ptr++;
159         if (isupper(c))
160                 c = tolower(c);
161         string = day[0].string;
162         for (n=0; n<7; n++) {
163                 if (string[n] != c)
164                         continue;
165                 if (day[0].day[n] >= 0)
166                         break;
167                 if (day[1].string[n] == *ptr)
168                         break;
169         }
170         if (n == 7)
171                 return 0;
172         *data = day[1].day[n];
173         while (*ptr && !isspace(*ptr))
174                 ptr++;
175         return ptr;
176 }
177
178
179 s_char *
180 get_time(s_char *ptr, int *data)
181 {
182         int     hour;
183         int     minute;
184
185         if (!isdigit(*ptr))
186                 return 0;
187         hour = atoip(&ptr);
188         minute = 0;
189         if (*ptr) {
190                 if (*ptr != ':')
191                         return 0;
192                 ptr++;
193                 if (!isdigit(*ptr))
194                         return 0;
195                 minute = atoip(&ptr);
196         }
197         *data = (hour * 60) + minute;
198         return ptr;
199 }