2 * Empire - A multi-player, client/server Internet based war game.
3 * Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
4 * Ken Stevens, Steve McClure
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.
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.
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
22 * See files README, COPYING and CREDITS in the root of the source
23 * tree for related information and legal notices. It is expected
24 * that future projects/authors will amend these files as needed.
28 * xdump.c: Extended dumps
30 * Known contributors to this file:
31 * Markus Armbruster, 2008
35 * Dump everything under the sun
37 * Static game data (configuration):
38 * - Item characteristics: ichr[]
39 * - Land unit characteristics: lchr[]
40 * - Nuke characteristics: nchr[]
41 * - Plane characteristics: plchr[]
42 * - Product characteristics: pchr[]
43 * - Sector designation characteristics: dchr[]
44 * - Sector infrastructure characteristics: intrchr[]
45 * - Ship characteristics: mchr[]
46 * - News item characteristics: rpt[]
47 * - News page headings: page_headings[]
48 * - Commands: player_coms[] (TODO)
49 * - Update schedule: update_time[] (not really static)
50 * - Configuration: configkeys[]
53 * - Sectors: EF_SECTOR (superseding dump)
54 * - Land units: EF_LAND (superseding ldump)
55 * - Lost: EF_LOST (superseding lost)
56 * - Nukes: EF_NUKE (superseding ndump)
57 * - Planes: EF_PLANE (superseding pdump)
58 * - Ships: EF_SHIP (superseding sdump)
60 * - Treaties: EF_TREATY
61 * - Power: EF_POWER (TODO)
62 * - Nations: EF_NATION
64 * - Map: EF_MAP (TODO)
65 * - Bmap: EF_BMAP (TODO)
70 * See doc/xdump for motivation, syntax, semantics, and rationale.
71 * Make sure to keep it up-to-date!
74 /* TODO don't dump stuff that's useless due to options */
85 * Initialize XD to dump for country CNUM.
86 * If HUMAN, dump in human-readable format.
87 * Dump is to be delivered through callback PR.
91 xdinit(struct xdstr *xd, natid cnum, int human, void (*pr)(char *fmt, ...))
94 xd->divine = getnatp(cnum)->nat_stat == STAT_GOD;
101 * Evaluate a attribute of an object into VAL, return VAL.
102 * XD is the xdump descriptor.
103 * TYPE is the attribute's type.
104 * PTR points to the context object.
105 * The attribute is stored there at offset OFF + IDX * S, where S is
107 * LEN is the #array elements if it is an array, else zero.
110 xdeval(struct valstr *val, struct xdstr *xd,
111 nsc_type type, void *ptr, ptrdiff_t off, int idx, int len)
113 val->val_type = type;
114 val->val_cat = NSC_OFF;
115 val->val_as.sym.off = off;
116 val->val_as.sym.len = len;
117 val->val_as.sym.idx = idx;
118 nstr_exec_val(val, xd->cnum, ptr, NSC_NOTYPE);
119 return val; /* FIXME nstr_exec_val() should return VAL */
123 * Dump string STR to XD with funny characters escaped.
124 * Dump at most N characters.
127 xdpresc(struct xdstr *xd, char *str, size_t n)
129 unsigned char *s, *e, *l;
131 s = (unsigned char *)str;
135 e < l && *e != '"' && *e != '\\' && isgraph(*e);
138 xd->pr("%.*s", (int)(e-s), s);
140 xd->pr("\\%03o", *e++);
147 /* Dump VAL in machine readable format, prefixed with SEP, return " ". */
149 xdprval_nosym(struct xdstr *xd, struct valstr *val, char *sep)
151 switch (val->val_type) {
153 xd->pr("%s%ld", sep, val->val_as.lng);
156 #if 0 /* TODO have %a */
157 xd->pr("%s%a", sep, val->val_as.dbl);
159 xd->pr("%s%#g", sep, val->val_as.dbl);
163 if (val->val_as.str.base) {
165 xdpresc(xd, val->val_as.str.base, val->val_as.str.maxsz);
168 xd->pr("%snil", sep);
178 * Dump symbol with value KEY from symbol table TYPE to XD.
179 * Prefix with SEP, return " ".
182 xdprsym(struct xdstr *xd, int key, int type, char *sep)
184 char *sym = symbol_by_value(key, ef_ptr(type, 0));
186 if (CANT_HAPPEN(!sym))
187 xd->pr("%s%ld", sep, key);
190 xdpresc(xd, sym, INT_MAX);
196 * Dump VAL prefixed with SEP, return " ".
197 * CA describes the field from which the value was fetched.
200 xdprval_sym(struct xdstr *xd, struct valstr *val, struct castr *ca, char *sep)
203 struct castr *ca_sym;
206 if (xd->human && val->val_type == NSC_LONG && ca->ca_table != EF_BAD) {
207 ca_sym = ef_cadef(ca->ca_table);
208 if (ca_sym != symbol_ca)
210 else if (ca->ca_flags & NSC_BITS) {
213 for (bit = 1; bit; bit <<= 1) {
214 if (bit & val->val_as.lng)
215 sep = xdprsym(xd, bit, ca->ca_table, sep);
220 return xdprsym(xd, val->val_as.lng, ca->ca_table, sep);
223 return xdprval_nosym(xd, val, sep);
227 * Dump VAL prefixed with SEP, return " ".
228 * XD must not be human-readable.
231 xdprval(struct xdstr *xd, struct valstr *val, char *sep)
233 CANT_HAPPEN(xd->human);
234 return xdprval_nosym(xd, val, sep);
238 * Dump field values of a context object to XD.
239 * CA[] describes fields.
240 * PTR points to context object.
243 xdflds(struct xdstr *xd, struct castr ca[], void *ptr)
249 for (i = 0; ca[i].ca_name; ++i) {
250 if (ca[i].ca_flags & NSC_DEITY && !xd->divine)
252 if (ca[i].ca_flags & NSC_EXTRA)
254 n = ca[i].ca_type != NSC_STRINGY ? ca[i].ca_len : 0;
258 ca[i].ca_type, ptr, ca[i].ca_off, j, ca[i].ca_len);
259 sep = xdprval_sym(xd, &val, &ca[i], sep);
265 * Dump header for dump NAME to XD.
266 * If META, it's for the meta-data dump rather than the data dump.
269 xdhdr(struct xdstr *xd, char *name, int meta)
272 xd->pr("config %s\n", name);
274 xd->pr("XDUMP %s%s %ld\n",
275 meta ? "meta " : "", name, (long)time(NULL));
279 * Dump column header to XD.
280 * CA[] describes fields.
281 * Does nothing unless XD is human-readable.
284 xdcolhdr(struct xdstr *xd, struct castr ca[])
292 for (i = 0; ca[i].ca_name; ++i) {
293 if (ca[i].ca_flags & NSC_DEITY && !xd->divine)
295 if (ca[i].ca_flags & NSC_EXTRA)
297 n = ca[i].ca_type != NSC_STRINGY ? ca[i].ca_len : 0;
299 for (j = 0; j < n; j++) {
300 xd->pr("%s%s(%d)",sep, ca[i].ca_name, j);
304 xd->pr("%s%s", sep, ca[i].ca_name);
311 /* Dump footer for a dump that dumped N objects to XD. */
313 xdftr(struct xdstr *xd, int n)
322 * Dump meta-data for items of type TYPE to XD.
326 xdmeta(struct xdstr *xd, int type)
328 struct castr *ca = ef_cadef(type);
335 xdhdr(xd, ef_nameof(type), 1);
338 for (i = 0; ca[i].ca_name; i++) {
339 if (ca[i].ca_flags & NSC_DEITY && !xd->divine)
341 if (ca[i].ca_flags & NSC_EXTRA)
343 xdflds(xd, mdchr_ca, &ca[i]);