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 354