* ---
*
* empdump.c: Export/import Empire game state
- *
+ *
* Known contributors to this file:
* Markus Armbruster, 2008
*/
#include <unistd.h>
#include "file.h"
#include "optlist.h"
+#include "nat.h"
#include "prototypes.h"
#include "version.h"
#include "xdump.h"
+static void exit_bad_arg(char *, ...)
+ ATTRIBUTE((noreturn, format (printf, 1, 2)));
static void dump_table(int, int);
-static void pln_fixup(void);
-static void lnd_fixup(void);
-static void nuk_fixup(void);
int
main(int argc, char *argv[])
FILE *impf = NULL;
int dirty[EF_MAX];
- while ((opt = getopt(argc, argv, "e:mtxhv")) != EOF) {
+ while ((opt = getopt(argc, argv, "e:i:mnxhv")) != EOF) {
switch (opt) {
case 'e':
config_file = optarg;
break;
+ case 'i':
+ import = optarg;
+ break;
+ case 'm':
+ human = 0;
+ break;
+ case 'n':
+ private = EFF_PRIVATE;
+ break;
+ case 'x':
+ export = 1;
+ break;
case 'h':
- printf("Usage: %s [OPTION]... [DUMP-FILE]\n"
+ printf("Usage: %s [OPTION]...\n"
" -e CONFIG-FILE configuration file\n"
" (default %s)\n"
+ " -i DUMP-FILE import from DUMP-FILE\n"
" -m use machine-readable format\n"
- " -t test import, don't update game state\n"
+ " -n dry run, don't update game state\n"
" -x export to standard output\n"
" -h display this help and exit\n"
" -v display version information and exit\n",
argv[0], dflt_econfig);
exit(0);
- case 'm':
- human = 0;
- break;
- case 't':
- private = EFF_PRIVATE;
- break;
- case 'x':
- export = 1;
- break;
case 'v':
printf("%s\n\n%s", version, legal);
exit(0);
default:
- fprintf(stderr, "Try -h for help.\n");
- exit(1);
+ exit_bad_arg(NULL);
}
}
if (argv[optind])
- import = argv[optind++];
+ exit_bad_arg("%s: extra operand %s\n", argv[0], argv[optind]);
+
+ if (!import && !export)
+ exit_bad_arg("%s: nothing to do!\n", argv[0]);
if (import) {
impf = fopen(import, "r");
if (!impf) {
- fprintf(stderr, "Cant open %s for reading (%s)\n",
- import, strerror(errno));
+ fprintf(stderr, "%s: Can't open %s for reading (%s)\n",
+ argv[0], import, strerror(errno));
exit(1);
}
} else
if (read_custom_tables() < 0)
exit(1);
if (chdir(gamedir)) {
- fprintf(stderr, "Can't chdir to %s (%s)\n",
- gamedir, strerror(errno));
+ fprintf(stderr, "%s: Can't chdir to %s (%s)\n",
+ argv[0], gamedir, strerror(errno));
exit(1);
}
global_init();
for (i = 0; i < EF_MAX; i++) {
if (!EF_IS_GAME_STATE(i))
continue;
- if (!ef_open(i, EFF_MEM | private))
+ if (!ef_open(i, EFF_MEM | private, -1))
exit(1);
}
dirty[type] = 1;
if (type == EF_BAD)
exit(1);
- pln_fixup();
- lnd_fixup();
- nuk_fixup();
}
if (ef_verify() < 0)
continue;
dump_table(i, human);
}
+ if (fclose(stdout) != 0) {
+ fprintf(stderr, "%s: error writing export (%s)\n",
+ argv[0], strerror(errno));
+ exit(1);
+ }
}
/* write out imported data */
return 0;
}
+static void
+exit_bad_arg(char *complaint, ...)
+{
+ va_list ap;
+
+ if (complaint) {
+ va_start(ap, complaint);
+ vfprintf(stderr, complaint, ap);
+ va_end(ap);
+ }
+ fprintf(stderr, "Try -h for help.\n");
+ exit(1);
+}
+
static void
printf_wrapper(char *fmt, ...)
{
if (!ca)
return;
- xdinit(&xd, 0, human, printf_wrapper);
+ xdinit(&xd, NATID_BAD, human, printf_wrapper);
xdhdr(&xd, ef_nameof(type), 0);
xdcolhdr(&xd, ca);
for (i = 0; (p = ef_ptr(type, i)); i++) {
}
xdftr(&xd, i);
}
-
-
-/* TODO remove need for this */
-
-#include <math.h>
-#include "ship.h"
-#include "plane.h"
-#include "land.h"
-#include "nuke.h"
-
-static int fit_plane_on_ship(struct plnstr *, struct shpstr *);
-static int fit_plane_on_land(struct plnstr *, struct lndstr *);
-
-static void
-pln_fixup(void)
-{
- int i;
- struct plnstr *pp;
- struct shpstr *csp;
- struct lndstr *clp;
-
- for (i = 0; (pp = ef_ptr(EF_PLANE, i)); i++) {
- if (!pp->pln_own)
- continue;
- csp = ef_ptr(EF_SHIP, pp->pln_ship);
- clp = ef_ptr(EF_LAND, pp->pln_land);
- if (csp)
- fit_plane_on_ship(pp, csp);
- else if (clp)
- fit_plane_on_land(pp, clp);
- }
-}
-
-static void
-lnd_fixup(void)
-{
- int i;
- struct lndstr *lp;
- struct shpstr *csp;
- struct lndstr *clp;
-
- for (i = 0; (lp = ef_ptr(EF_LAND, i)); i++) {
- if (!lp->lnd_own)
- continue;
- csp = ef_ptr(EF_SHIP, lp->lnd_ship);
- clp = ef_ptr(EF_LAND, lp->lnd_land);
- if (csp)
- csp->shp_nland++;
- else if (clp)
- clp->lnd_nland++;
- }
-}
-
-static void
-nuk_fixup(void)
-{
- int i;
- struct nukstr *np;
- struct plnstr *cpp;
-
- for (i = 0; (np = ef_ptr(EF_NUKE, i)); i++) {
- if (!np->nuk_own)
- continue;
- cpp = ef_ptr(EF_PLANE, np->nuk_plane);
- if (cpp)
- cpp->pln_nuketype = np->nuk_type;
- }
-}
-
-/* Temporarily copied from src/lib/subs/???sub.c */
-
-/*
- * Fit a plane of PP's type on ship SP.
- * Adjust SP's plane counters.
- * Updating the plane accordingly is the caller's job.
- * Return whether it fits.
- */
-static int
-fit_plane_on_ship(struct plnstr *pp, struct shpstr *sp)
-{
- struct plchrstr *pcp = plchr + pp->pln_type;
- struct mchrstr *mcp = mchr + sp->shp_type;
- int wanted;
-
- if (pcp->pl_flags & P_K) {
- /* chopper, try chopper slot first */
- if (sp->shp_nchoppers < mcp->m_nchoppers)
- return ++sp->shp_nchoppers;
- /* else try plane slot */
- wanted = M_FLY;
- } else if (pcp->pl_flags & P_E) {
- /* x-light, try x-light slot first */
- if (sp->shp_nxlight < mcp->m_nxlight)
- return ++sp->shp_nxlight;
- /* else try plane slot */
- wanted = M_MSL | M_FLY;
- } else if (!(pcp->pl_flags & P_L)) {
- /* not light, no go */
- wanted = 0;
- } else if (pcp->pl_flags & P_M) {
- /* missile, use plane slot */
- wanted = M_MSL | M_FLY;
- } else {
- /* fixed-wing plane, use plane slot */
- wanted = M_FLY;
- }
-
- if ((mcp->m_flags & wanted) == 0)
- return 0; /* ship not capable */
-
- if (sp->shp_nplane < mcp->m_nplanes)
- return ++sp->shp_nplane;
-
- return 0;
-}
-
-/*
- * Fit a plane of PP's type on land unit LP.
- * Adjust LP's plane counters.
- * Updating the plane accordingly is the caller's job.
- * Return whether it fits.
- */
-static int
-fit_plane_on_land(struct plnstr *pp, struct lndstr *lp)
-{
- struct plchrstr *pcp = plchr + pp->pln_type;
- struct lchrstr *lcp = lchr + lp->lnd_type;
-
- if ((pcp->pl_flags & P_E) && lp->lnd_nxlight < lcp->l_nxlight)
- return ++lp->lnd_nxlight;
-
- return 0;
-}