]> git.pond.sub.org Git - empserver/blob - src/lib/subs/nstr.c
Import of Empire 4.2.12
[empserver] / src / lib / subs / nstr.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  *  nstr.c: compile and execute the item selections on sectors
29  * 
30  *  Known contributors to this file:
31  *     Dave Pare, 1989
32  *     Steve McClure, 1997
33  */
34
35 #include <ctype.h>
36 #include "struct.h"
37 #include "misc.h"
38 #include "var.h"
39 #include "xy.h"
40 #include "sect.h"
41 #include "nsc.h"
42 #include "nat.h"
43 #include "match.h"
44 #include "file.h"
45 #include "player.h"
46 #include "prototypes.h"
47
48 static int legal_val(s_char *str, int val);
49
50 /*
51  * Compiles and adds "str" to the list of conditionals.
52  * type is the EF typename of the item type we're selecting.
53  * returns amount of "str" used by nstr_comp (i.e. how far
54  * the pointer was advanced).  The last is only meaningful
55  * if several conditionals are expected in one string.
56  */
57 s_char *
58 nstr_comp(struct nscstr *np, int *size, int type, s_char *str)
59 {
60         register s_char *bp;
61         register s_char *cp;
62         register int c;
63         s_char  ident[80];
64         s_char  arg[255];
65         int op;
66         int val;
67
68         strncpy(arg, str, sizeof(arg)-1);
69         arg[sizeof(arg)-1] = 0;
70         cp = arg;
71         bp = ident;
72         while ((c = *cp++) && bp < &ident[sizeof(ident)-1]) {
73                 if (c == '<' || c == '=' || c == '>' || c == '#')
74                         break;
75                 *bp++ = c;
76         }
77         *bp = 0;
78         if (c == 0) {
79                 pr("'%s'? -- meaningless condition?\n", arg);
80                 return 0;
81         }
82         op = c;
83         np[*size].oper = op;
84         if ((val = encode(ident, &np[*size].fld1, type)) < 0)
85                 return 0;
86         if (val == 2)
87             np[*size].oper += 255;
88         bp = ident;
89         while ((c = *cp++) && bp < &ident[sizeof(ident)-1]) {
90                 if (c == '&')
91                         break;
92                 *bp++ = c;
93         }
94         *bp = 0;
95         if ((val = encode(ident, &np[*size].fld2, type)) < 0)
96                 return 0;
97         if (val == 2)
98             np[*size].oper += 65535;
99         if (c == 0)
100                 cp--;
101         (*size)++;
102         return str + (cp - arg);
103 }
104
105 int
106 encode(register s_char *str, long int *val, int type)
107 {
108         register int i;
109         struct  castr *cap;
110
111         if (str == 0) {
112                 *val = 0;
113                 return 0;
114         }
115         if (isdigit(*str) || ((*str == '-') && isdigit(str[1]))) {
116 #ifdef BIT16ONLY
117                 /* XXX silently truncate to 16 bit int */
118                 *val = atoi(str) & 0xffff;
119 #else
120                 *val = atoi(str);
121 #endif /* BIT16ONLY */
122                 return 2;
123         }
124         if ((i = typematch(str, type)) >= 0) {
125                 *val = i;
126                 return 1;
127         }
128         if ((cap = ef_cadef(type)) != 0) {
129                 i = stmtch(str, (caddr_t)cap, fldoff(castr, ca_name),
130                         sizeof(struct castr));
131                 if (i >= 0) {
132                         *val = cap[i].ca_code|NSC_OFF;
133                         *val &= ~NSC_ROUND;
134                         return legal_val(str, *val);
135                 }
136                 if (i == M_NOTUNIQUE) {
137                         pr("%s -- ambiguous type selector\n", str);
138                         return 0;
139                 }
140         }
141         /*
142          * Only check for commodity selectors on objects which
143          * are allowed to have commodities.
144          */
145         if (ef_flags(type) & EFF_COM) {
146                 i = stmtch(str, (caddr_t)var_ca, fldoff(castr, ca_name),
147                         sizeof(struct castr));
148                 if (i >= 0) {
149                         *val = var_ca[i].ca_code & ~NSC_ROUND;
150                         return legal_val(str, *val);
151                         return 1;
152                 }
153                 if (i == M_NOTUNIQUE) {
154                         pr("%s -- ambiguous commodity selector\n", str);
155                         return 0;
156                 }
157         }
158         pr("%s -- not a valid selector\n", str);
159         return 0;
160 }
161
162 static int
163 legal_val(s_char *str, int val)
164 {
165         if (val & NSC_DEITY && !player->god) {
166                 pr("%s -- permission denied\n", str);
167                 return -1;
168         }
169         return 1;
170 }
171
172
173 /*
174  * The rest of this stuff has been moved to libcommon
175  * so it can be used elsewhere (emp_update, mostly)
176  */