client: Unbreak standalone build
[empserver] / include / nsc.h
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2021, Dave Pare, Jeff Bailey, Thomas Ruschak,
4  *                Ken Stevens, Steve McClure, Markus Armbruster
5  *
6  *  Empire 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 3 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, see <http://www.gnu.org/licenses/>.
18  *
19  *  ---
20  *
21  *  See files README, COPYING and CREDITS in the root of the source
22  *  tree for related information and legal notices.  It is expected
23  *  that future projects/authors will amend these files as needed.
24  *
25  *  ---
26  *
27  *  nsc.h: Definitions for Empire conditionals
28  *
29  *  Known contributors to this file:
30  *     Dave Pare, 1989
31  *     Markus Armbruster, 2004-2020
32  */
33
34 #ifndef NSC_H
35 #define NSC_H
36
37 #include <stddef.h>
38 #include "misc.h"
39 #include "xy.h"
40
41 #define NS_LSIZE        128
42 #define NS_NCOND        16
43
44 /* Value type */
45 enum nsc_type {
46     NSC_NOTYPE,
47     /* promoted types */
48     NSC_LONG,                   /* long */
49     NSC_DOUBLE,                 /* double */
50     NSC_STRING,                 /* character string */
51     /* unpromoted types */
52     NSC_CHAR,                   /* signed char */
53     NSC_UCHAR,                  /* unsigned char */
54     NSC_SHORT,                  /* short */
55     NSC_USHORT,                 /* unsigned short */
56     NSC_INT,                    /* int */
57     NSC_XCOORD,                 /* coord that needs x conversion */
58     NSC_YCOORD,                 /* coord that needs y conversion */
59     NSC_TIME,                   /* time_t */
60     NSC_FLOAT,                  /* float */
61     NSC_STRINGY,                /* char[] */
62     /* aliases, must match typedefs */
63     NSC_NATID = NSC_UCHAR       /* nation ID */
64 };
65
66 /* Is TYPE a promoted value type? */
67 #define NSC_IS_PROMOTED(type) (NSC_LONG <= (type) && (type) <= NSC_STRING)
68
69 /* Return nsc_type for a signed integer with the same size as TYPE. */
70 #define NSC_SITYPE(type) \
71     (BUILD_ASSERT_ONE(NSC_SITYPE_(type) != NSC_NOTYPE) * NSC_SITYPE_(type))
72 #define NSC_SITYPE_(type)                               \
73     (sizeof(type) == 1 ? NSC_CHAR                       \
74      : sizeof(type) == sizeof(short) ? NSC_SHORT        \
75      : sizeof(type) == sizeof(int) ? NSC_INT            \
76      : sizeof(type) == sizeof(long) ? NSC_LONG          \
77      : NSC_NOTYPE)
78
79 /* Value category */
80 enum nsc_cat {
81     NSC_NOCAT,
82     NSC_VAL,                    /* evaluated value */
83     NSC_OFF,                    /* symbolic value: at offset in object */
84     NSC_ID                      /* unresolved identifier (internal use) */
85 };
86
87 /*
88  * Value, possibly symbolic
89  *
90  * If type is NSC_NOTYPE, it's an error value.
91  * If category is NSC_VAL, the value is in @val_as, and the type is a
92  * promoted type.
93  * If category is NSC_OFF, the value is in a context object, and
94  * @val_as.sym specifies how to get it, as follows.
95  * If sym.get is null, and type is NSC_STRINGY, the value is a string
96  * stored in sym.len characters starting at sym.offs in the context
97  * object.  sym.idx must be zero.  Ugly wart: if sym.len is one, the
98  * terminating null character may be omitted.
99  * Else if sym.get is null, and sym.len is zero, the value is in the
100  * context object at offset sym.off.  sym.idx must be zero.
101  * Else if sym.get is null, sym.len is non-zero, and the value has
102  * index sym.idx in an array of sym.len elements at offset sym.off in
103  * in the context object.  I.e. the value is at sym.off + sym.idx *
104  * SZ, where SZ is the size of the value.
105  * If sym.get is not null, you obtain the value by calling get() like
106  * VAL->get(VAL, NP, CTXO), where NP points to the country to use for
107  * coordinate translation and access control (null for none), and CTXO
108  * is the context object.  get() either returns a null pointer and
109  * sets VAL->val_as to the value, as appropriate for the type.  Or it
110  * returns another context object and sets VAL->val_as.sym for it.
111  */
112 struct valstr {
113     enum nsc_type val_type;     /* type of value */
114     enum nsc_cat val_cat;       /* category of value */
115     union {
116         struct {                /* cat NSC_OFF */
117             ptrdiff_t off;
118             int len;
119             int idx;
120             void *(*get)(struct valstr *, struct natstr *, void *);
121             int hidden;
122         } sym;
123         double dbl;             /* cat NSC_VAL, type NSC_DOUBLE */
124         struct {                /* cat NSC_VAL, type NSC_STRING, cat NSC_ID */
125             char *base;
126             size_t maxsz;
127         } str;
128         long lng;               /* cat NSC_VAL, type NSC_LONG */
129     } val_as;
130 };
131
132 /* Compiled condition */
133 struct nscstr {
134     char operator;              /* '<', '=', '>', '#' */
135     enum nsc_type optype;       /* operator type */
136     struct valstr lft;          /* left operand */
137     struct valstr rgt;          /* right operand */
138 };
139
140 /* Selection type */
141 enum ns_seltype {
142     NS_UNDEF,                   /* error value */
143     NS_LIST,                    /* list of IDs */
144     NS_DIST,                    /* circular area */
145     NS_AREA,                    /* rectangular area */
146     NS_ALL,                     /* everything */
147     NS_XY,                      /* one sector area */
148     NS_GROUP,                   /* group, i.e. fleet, wing, army */
149     NS_CARGO                    /* loaded on the same carrier */
150 };
151
152 /* Sector iterator */
153 struct nstr_sect {
154     coord x, y;                 /* current x-y */
155     coord dx, dy;               /* accumulated x,y travel */
156     int id;                     /* return value of sctoff */
157     enum ns_seltype type;       /* selection type: NS_AREA or NS_DIST */
158     int curdist;                /* NS_DIST: current range */
159     struct range range;         /* area of coverage */
160     int dist;                   /* NS_DIST: range */
161     coord cx, cy;               /* NS_DIST: center x-y */
162     int ncond;                  /* # of selection conditions */
163     struct nscstr cond[NS_NCOND]; /* selection conditions */
164 };
165
166 /* Item iterator */
167 struct nstr_item {
168     int cur;                    /* current item */
169     enum ns_seltype sel;        /* selection type, any but NS_UNDEF */
170     int type;                   /* item type being selected */
171     int curdist;                /* if NS_DIST, current item's dist */
172     struct range range;         /* NS_AREA/NS_DIST: range selector */
173     int dist;                   /* NS_DIST: distance selector */
174     coord cx, cy;               /* NS_DIST: center x-y, NS_XY: xy */
175     char group;                 /* NS_GROUP: fleet/wing match */
176     int next;                   /* NS_CARGO: next item */
177     int size;                   /* NS_LIST: size of list */
178     int index;                  /* NS_LIST: index */
179     int list[NS_LSIZE];         /* NS_LIST: item list */
180     int ncond;                  /* # of selection conditions */
181     struct nscstr cond[NS_NCOND]; /* selection conditions */
182 };
183
184 /*
185  * Symbol binding: associate @name with @value.
186  */
187 struct symbol {
188     int value;
189     char *name;
190 };
191
192 /* Selector flags */
193 enum {
194     NSC_DEITY = bit(0),         /* access restricted to deity */
195     NSC_BITS = bit(3),          /* value consists of flag bits */
196     NSC_HIDDEN = bit(4)         /* visibility depends on contact */
197 };
198
199 /* Selector use by xdump and xundump */
200 enum ca_dump {
201     /* order is relevant */
202     CA_DUMP,                    /* xdump and xundump normally */
203     CA_DUMP_CONST,              /* same, but value can't be changed  */
204     CA_DUMP_ONLY,               /* only in xdump command */
205     CA_DUMP_NONE                /* do not xdump or xundump */
206 };
207
208 /*
209  * Selector descriptor
210  *
211  * A selector describes an attribute of some context object.
212  * A selector with @ca_type NSC_NOTYPE is invalid.
213  * If @ca_get is null, the selector describes a datum of type @ca_type
214  * at offset @ca_offs in the context object.
215  * A datum of type NSC_STRINGY is a string stored in an array of
216  * @ca_len characters.  Ugly wart: if @ca_len is one, the terminating
217  * null character may be omitted.
218  * A datum of any other type is either a scalar of that type (if
219  * @ca_len is zero), or an array of @ca_len elements of that type.
220  * If @ca_get is not null, the selector is virtual.  Values can be
221  * obtained by calling @ca_get(VAL, NP, CTXO), where VAL has been
222  * initialized from the selector and an index by nstr_mksymval(),
223  * NP points to the country to use for coordinate translation and
224  * access control (null for none), and CTXO is the context object.
225  * See struct valstr for details.
226  * Because virtual selectors don't have a setter method, xundump must
227  * be made to ignore them, by setting @ca_dump to CA_DUMP_NONE.
228  * If @ca_table is not EF_BAD, the datum refers to that Empire table;
229  * @ca_type must be an integer type.
230  * If NSC_BITS is set in @ca_flags, the datum consists of flag bits,
231  * and the referred table must be a symbol table defining those bits.
232  * If NSC_DEITY is set in @ca_flags, only deities can use this
233  * selector.
234  * If NSC_HIDDEN is set in @ca_flags, the selector must be an array of
235  * MAXNOC elements, indexed by country number.  Array elements are
236  * masked for contact when opt_HIDDEN is on.  Only implemented for
237  * integer types and context object EF_RELAT.
238  * @ca_dump specifies how xdump and xundump are to use the selector.
239  */
240 struct castr {
241     char *ca_name;
242     ptrdiff_t ca_off;
243     enum nsc_type ca_type;
244     unsigned short ca_len;
245     void *(*ca_get)(struct valstr *, struct natstr *, void *);
246     int ca_table;
247     int ca_flags;
248     enum ca_dump ca_dump;
249 };
250
251 /* Is CA an array? */
252 #define CA_IS_ARRAY(ca) ((ca)->ca_type != NSC_STRINGY && (ca)->ca_len != 0)
253
254 /* If CA is an array, return its length, else zero */
255 #define CA_ARRAY_LEN(ca) ((ca)->ca_type != NSC_STRINGY ? (ca)->ca_len : 0)
256
257 extern struct castr ichr_ca[];
258 extern struct castr pchr_ca[];
259 extern struct castr sect_ca[];
260 extern struct castr dchr_ca[];
261 extern struct castr ship_ca[];
262 extern struct castr mchr_ca[];
263 extern struct castr plane_ca[];
264 extern struct castr plchr_ca[];
265 extern struct castr land_ca[];
266 extern struct castr lchr_ca[];
267 extern struct castr nuke_ca[];
268 extern struct castr nchr_ca[];
269 extern struct castr loan_ca[];
270 extern struct castr news_ca[];
271 extern struct castr lost_ca[];
272 extern struct castr commodity_ca[];
273 extern struct castr trade_ca[];
274 extern struct castr nat_ca[];
275 extern struct castr cou_ca[];
276 extern struct castr relat_ca[];
277 extern struct castr contact_ca[];
278 extern struct castr reject_ca[];
279 extern struct castr realm_ca[];
280 extern struct castr game_ca[];
281 extern struct castr intrchr_ca[];
282 extern struct castr rpt_ca[];
283 extern struct castr update_ca[];
284 extern struct castr empfile_ca[];
285 extern struct castr symbol_ca[];
286 extern struct symbol ship_chr_flags[];
287 extern struct symbol plane_chr_flags[];
288 extern struct symbol land_chr_flags[];
289 extern struct symbol nuke_chr_flags[];
290 extern struct castr mdchr_ca[];
291 extern struct symbol meta_type[];
292 extern struct symbol meta_flags[];
293 extern struct symbol missions[];
294 extern struct symbol plane_flags[];
295 extern struct symbol retreat_flags[];
296 extern struct symbol nation_status[];
297 extern struct symbol nation_flags[];
298 extern struct symbol nation_rejects[];
299 extern struct symbol nation_relations[];
300 extern struct symbol level[];
301 extern struct symbol agreement_statuses[];
302 extern struct symbol plague_stages[];
303 extern struct symbol packing[];
304 extern struct symbol resources[];
305 extern struct symbol sect_chr_flags[];
306 extern struct symbol sector_navigation[];
307
308 /* src/lib/common/nstreval.c */
309 extern struct valstr *nstr_mksymval(struct valstr *, struct castr *, int);
310 extern struct valstr *nstr_eval(struct valstr *, natid, void *,
311                                 enum nsc_type);
312 extern int nstr_promote(int);
313 extern char *symbol_by_value(int, struct symbol *);
314 extern int symbol_set_fmt(char *, size_t, int, struct symbol *,
315                           char *, int);
316 /* src/lib/global/nsc.c */
317 extern void nsc_init(void);
318 /* src/lib/subs/nxtitem.c */
319 extern int nxtitem(struct nstr_item *, void *);
320 /* src/lib/subs/nxtsct.c */
321 extern int nxtsct(struct nstr_sect *, struct sctstr *);
322 /* src/lib/subs/sarg.c */
323 extern enum ns_seltype sarg_type(char *);
324 extern int sarg_xy(char *, coord *, coord *);
325 extern int sarg_area(char *, struct range *);
326 extern int sarg_range(char *, coord *, coord *, int *);
327 extern int sarg_list(char *, int *, int);
328 /* src/lib/subs/snxtitem.c */
329 extern int snxtitem(struct nstr_item *, int, char *, char *);
330 extern void snxtitem_area(struct nstr_item *, int, struct range *);
331 extern void snxtitem_dist(struct nstr_item *, int, int, int, int);
332 extern void snxtitem_xy(struct nstr_item *, int, coord, coord);
333 extern void snxtitem_all(struct nstr_item *, int);
334 extern void snxtitem_group(struct nstr_item *, int, char);
335 extern void snxtitem_rewind(struct nstr_item *);
336 extern int snxtitem_list(struct nstr_item *, int, int *, int);
337 extern void snxtitem_cargo(struct nstr_item *, int, int, int);
338 extern int snxtitem_use_condarg(struct nstr_item *);
339 /* src/lib/subs/snxtsct.c */
340 extern int snxtsct(struct nstr_sect *, char *);
341 extern void snxtsct_area(struct nstr_sect *, struct range *);
342 extern void snxtsct_all(struct nstr_sect *);
343 extern void snxtsct_rewind(struct nstr_sect *);
344 extern void snxtsct_dist(struct nstr_sect *, coord, coord, int);
345 extern int snxtsct_use_condarg(struct nstr_sect *);
346 /* src/lib/subs/nstr.c */
347 extern int nstr_comp(struct nscstr *np, int len, int type, char *str);
348 extern char *nstr_comp_val(char *, struct valstr *, int);
349 extern int nstr_exec(struct nscstr *, int, void *);
350 /* src/lib/update/nxtitemp.c */
351 extern void *nxtitemp(struct nstr_item *);
352
353 #endif