Skip to content

Commit 2aca760

Browse files
committed
Remove our dependency on popt by writing a custom popt-like parser. Patch by me and i-NoD. Closes ticket:1659
git-svn-id: https://warzone2100.svn.sourceforge.net/svnroot/warzone2100/trunk@10186 4a71c877-e1ca-e34f-864e-861f7616d084 (cherry picked from commit 240bb91) Conflicts: configure.ac src/Makefile.am
1 parent d82ee0b commit 2aca760

3 files changed

Lines changed: 169 additions & 10 deletions

File tree

‎configure.ac‎

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -349,8 +349,7 @@ fi
349349
# check for nearbyint()
350350
AC_CHECK_LIB(m, nearbyint, [MATH_LIB=""], AC_MSG_ERROR([nearbyint not found.]))
351351

352-
# When (cross-)compiling for Windows (MinGW) we need to link in iberty for Popt
353-
# and the Dr. MinGW derived exception handler.
352+
# When (cross-)compiling for Windows (MinGW) we need to link in iberty for the Dr. MinGW derived exception handler.
354353
if test "x$host_os_mingw32" = "xyes" ; then
355354
AC_CHECK_LIB(iberty, main, AC_SUBST([IBERTY_LIBS], [-liberty]), AC_MSG_ERROR([libiberty not found.]))
356355

@@ -382,9 +381,6 @@ AS_IF([test "$enable_motif" != "no"],[
382381
])
383382
AM_CONDITIONAL([MOTIF_AVAILABLE], test -n "$MOTIF_LIBS")
384383

385-
# Look for Popt
386-
AC_CHECK_HEADER(popt.h, , AC_MSG_ERROR([Popt header not found.]))
387-
AC_CHECK_LIB(popt, poptGetContext, AC_SUBST([POPT_LIBS], [-lpopt]), AC_MSG_ERROR([Popt not found.]), [${WIN32_LIBS}])
388384

389385
# Look for PhysicsFS
390386
AC_CHECK_HEADER(physfs.h, , AC_MSG_ERROR([PhysicsFS header not found.]))

‎src/Makefile.am‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
force-linker.cpp:
99
touch $@
1010

11-
AM_CPPFLAGS = -DYY_NO_INPUT $(SDL_CFLAGS) $(PHYSFS_CFLAGS) $(PNG_CFLAGS) $(OGGVORBIS_CFLAGS) $(OPENAL_CFLAGS) $(OPENGLC_CFLAGS) $(OPENGL_CFLAGS) $(POPT_CFLAGS) $(WZ_CPPFLAGS) $(GLee_CFLAGS)
11+
AM_CPPFLAGS = -DYY_NO_INPUT $(SDL_CFLAGS) $(PHYSFS_CFLAGS) $(PNG_CFLAGS) $(OGGVORBIS_CFLAGS) $(OPENAL_CFLAGS) $(OPENGLC_CFLAGS) $(OPENGL_CFLAGS) $(WZ_CPPFLAGS) $(GLee_CFLAGS)
1212
AM_CFLAGS = $(WZ_CFLAGS)
1313
AM_LFLAGS = $(FLEX_FLAGS)
1414
AM_YFLAGS = -d
@@ -298,7 +298,7 @@ warzone2100_LDADD = \
298298
$(top_builddir)/lib/iniparser/libiniparser.a \
299299
$(top_builddir)/lib/exceptionhandler/libexceptionhandler.a
300300

301-
warzone2100_LDADD += $(LTLIBINTL) $(SDL_LIBS) $(PHYSFS_LIBS) $(PNG_LIBS) $(OGGVORBIS_LIBS) $(THEORA_LIBS) $(OPENAL_LIBS) $(OPENGLC_LIBS) $(OPENGL_LIBS) $(POPT_LIBS) $(MOTIF_LIBS) $(X11_LIBS) $(GLee_LIBS)
301+
warzone2100_LDADD += $(LTLIBINTL) $(SDL_LIBS) $(PHYSFS_LIBS) $(PNG_LIBS) $(OGGVORBIS_LIBS) $(THEORA_LIBS) $(OPENAL_LIBS) $(OPENGLC_LIBS) $(OPENGL_LIBS) $(X11_LIBS) $(GLee_LIBS)
302302

303303
if MINGW32
304304
warzone2100_LDADD += $(top_builddir)/win32/warzone2100.o $(WIN32_LIBS)

‎src/clparse.c‎

Lines changed: 166 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@
2424
*
2525
*/
2626

27-
#include <popt.h>
28-
2927
#include "lib/framework/frame.h"
3028
#include "lib/netplay/netplay.h"
3129

@@ -43,6 +41,171 @@
4341
//! Let the end user into debug mode....
4442
BOOL bAllowDebugMode = false;
4543

44+
//////
45+
// Our fine replacement for the popt abomination follows
46+
47+
#define POPT_ARG_STRING true
48+
#define POPT_ARG_NONE false
49+
#define POPT_ERROR_BADOPT -1
50+
#define POPT_ARGFLAG_DOC_HIDDEN 0
51+
52+
struct poptOption
53+
{
54+
const char *string;
55+
char short_form;
56+
bool argument;
57+
void *nullptr; // unused
58+
int enumeration;
59+
const char *descrip;
60+
const char *argDescrip;
61+
};
62+
63+
typedef struct _poptContext
64+
{
65+
int argc, current, size;
66+
const char **argv;
67+
const char *parameter;
68+
const char *bad;
69+
const struct poptOption *table;
70+
} *poptContext;
71+
72+
static void poptPrintUsage(poptContext ctx, FILE *output, WZ_DECL_UNUSED int unused)
73+
{
74+
// TODO ?
75+
}
76+
77+
static void poptPrintHelp(poptContext ctx, FILE *output, WZ_DECL_UNUSED int unused)
78+
{
79+
int i;
80+
81+
fprintf(output, "Usage: %s [OPTION...]\n", ctx->argv[0]);
82+
for (i = 0; i < ctx->size; i++)
83+
{
84+
char txt[128];
85+
86+
if (ctx->table[i].short_form != '\0')
87+
{
88+
ssprintf(txt, " -%c, --%s", ctx->table[i].short_form, ctx->table[i].string);
89+
}
90+
else
91+
{
92+
ssprintf(txt, " --%s", ctx->table[i].string);
93+
}
94+
95+
if (ctx->table[i].argument)
96+
{
97+
sstrcat(txt, "=");
98+
sstrcat(txt, ctx->table[i].argDescrip);
99+
}
100+
101+
fprintf(output, "%-40s", txt);
102+
if (ctx->table[i].descrip)
103+
{
104+
fprintf(output, "%s", ctx->table[i].descrip);
105+
}
106+
fprintf(output, "\n");
107+
}
108+
}
109+
110+
static void poptFreeContext(WZ_DECL_UNUSED poptContext ctx)
111+
{
112+
// Nothing!
113+
}
114+
115+
static const char *poptBadOption(poptContext ctx, WZ_DECL_UNUSED int unused)
116+
{
117+
return ctx->bad;
118+
}
119+
120+
static const char *poptGetOptArg(poptContext ctx)
121+
{
122+
return ctx->parameter;
123+
}
124+
125+
static int poptGetNextOpt(poptContext ctx)
126+
{
127+
static char match[PATH_MAX]; // static for bad function
128+
static char parameter[PATH_MAX]; // static for arg function
129+
char *pparam;
130+
int i;
131+
132+
ctx->bad = NULL;
133+
ctx->parameter = NULL;
134+
parameter[0] = '\0';
135+
match[0] = '\0';
136+
137+
if (ctx->current >= ctx->argc) // counts from 1
138+
{
139+
return 0;
140+
}
141+
142+
sstrcpy(match, ctx->argv[ctx->current]);
143+
ctx->current++;
144+
pparam = strrchr(match, '=');
145+
if (pparam) // option's got a parameter
146+
{
147+
*pparam++ = '\0'; // split option from parameter and increment past '='
148+
if (pparam[0] == '"') // found scary quotes
149+
{
150+
pparam++; // skip start quote
151+
sstrcpy(parameter, pparam); // copy first parameter
152+
if (!strrchr(pparam, '"')) // if no end quote, then find it
153+
{
154+
while (!strrchr(parameter, '"') && ctx->current < ctx->argc)
155+
{
156+
sstrcat(parameter, " "); // insert space
157+
sstrcat(parameter, ctx->argv[ctx->current]);
158+
ctx->current++; // next part, please!
159+
}
160+
}
161+
if (strrchr(parameter, '"')) // its not an else for above!
162+
{
163+
*strrchr(parameter, '"') = '\0'; // remove end qoute
164+
}
165+
}
166+
else
167+
{
168+
sstrcpy(parameter, pparam); // copy parameter
169+
}
170+
}
171+
172+
for (i = 0; i < ctx->size; i++)
173+
{
174+
char sshort[3];
175+
char slong[64];
176+
177+
ssprintf(sshort, "-%c", ctx->table[i].short_form);
178+
ssprintf(slong, "--%s", ctx->table[i].string);
179+
if ((strcmp(sshort, match) == 0 && ctx->table[i].short_form != '\0') || strcmp(slong, match) == 0)
180+
{
181+
if (ctx->table[i].argument && pparam)
182+
{
183+
ctx->parameter = parameter;
184+
}
185+
return ctx->table[i].enumeration;
186+
}
187+
}
188+
ctx->bad = match;
189+
ctx->current++;
190+
return POPT_ERROR_BADOPT;
191+
}
192+
193+
static poptContext poptGetContext(WZ_DECL_UNUSED void *unused, int argc, const char **argv, const struct poptOption *table, WZ_DECL_UNUSED int none)
194+
{
195+
static struct _poptContext ctx;
196+
197+
ctx.argc = argc;
198+
ctx.argv = argv;
199+
ctx.table = table;
200+
ctx.current = 1;
201+
ctx.parameter = NULL;
202+
203+
for (ctx.size = 0; table[ctx.size].string; ctx.size++) ; // count table size
204+
205+
return &ctx;
206+
}
207+
208+
46209
typedef enum
47210
{
48211
// We don't want to use zero, so start at one (1)
@@ -79,8 +242,8 @@ static const struct poptOption* getOptionsTable(void)
79242
static const struct poptOption optionsTable[] =
80243
{
81244
{ "cheat", '\0', POPT_ARG_NONE, NULL, CLI_CHEAT, N_("Run in cheat mode"), NULL },
82-
{ "datadir", '\0', POPT_ARG_STRING, NULL, CLI_DATADIR, N_("Set default data directory"), N_("data directory") },
83245
{ "configdir", '\0', POPT_ARG_STRING, NULL, CLI_CONFIGDIR, N_("Set configuration directory"), N_("configuration directory") },
246+
{ "datadir", '\0', POPT_ARG_STRING, NULL, CLI_DATADIR, N_("Set default data directory"), N_("data directory") },
84247
{ "debug", '\0', POPT_ARG_STRING, NULL, CLI_DEBUG, N_("Show debug for given level"), N_("debug level") },
85248
{ "debugfile", '\0', POPT_ARG_STRING, NULL, CLI_DEBUGFILE, N_("Log debug output to file"), N_("file") },
86249
{ "flush-debug-stderr", '\0', POPT_ARG_NONE, NULL, CLI_FLUSHDEBUGSTDERR, N_("Flush all debug output written to stderr"), NULL },

0 commit comments

Comments
 (0)