Skip to content

Commit

Permalink
Remove our dependency on popt by writing a custom popt-like parser. P…
Browse files Browse the repository at this point in the history
…atch 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
  • Loading branch information
buginator committed Oct 24, 2010
1 parent d82ee0b commit 2aca760
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 10 deletions.
6 changes: 1 addition & 5 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -349,8 +349,7 @@ fi
# check for nearbyint()
AC_CHECK_LIB(m, nearbyint, [MATH_LIB=""], AC_MSG_ERROR([nearbyint not found.]))

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

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

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

# Look for PhysicsFS
AC_CHECK_HEADER(physfs.h, , AC_MSG_ERROR([PhysicsFS header not found.]))
Expand Down
4 changes: 2 additions & 2 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
force-linker.cpp:
touch $@

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)
AM_CPPFLAGS = -DYY_NO_INPUT $(SDL_CFLAGS) $(PHYSFS_CFLAGS) $(PNG_CFLAGS) $(OGGVORBIS_CFLAGS) $(OPENAL_CFLAGS) $(OPENGLC_CFLAGS) $(OPENGL_CFLAGS) $(WZ_CPPFLAGS) $(GLee_CFLAGS)
AM_CFLAGS = $(WZ_CFLAGS)
AM_LFLAGS = $(FLEX_FLAGS)
AM_YFLAGS = -d
Expand Down Expand Up @@ -298,7 +298,7 @@ warzone2100_LDADD = \
$(top_builddir)/lib/iniparser/libiniparser.a \
$(top_builddir)/lib/exceptionhandler/libexceptionhandler.a

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)
warzone2100_LDADD += $(LTLIBINTL) $(SDL_LIBS) $(PHYSFS_LIBS) $(PNG_LIBS) $(OGGVORBIS_LIBS) $(THEORA_LIBS) $(OPENAL_LIBS) $(OPENGLC_LIBS) $(OPENGL_LIBS) $(X11_LIBS) $(GLee_LIBS)

if MINGW32
warzone2100_LDADD += $(top_builddir)/win32/warzone2100.o $(WIN32_LIBS)
Expand Down
169 changes: 166 additions & 3 deletions src/clparse.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
*
*/

#include <popt.h>

#include "lib/framework/frame.h"
#include "lib/netplay/netplay.h"

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

//////
// Our fine replacement for the popt abomination follows

#define POPT_ARG_STRING true
#define POPT_ARG_NONE false
#define POPT_ERROR_BADOPT -1
#define POPT_ARGFLAG_DOC_HIDDEN 0

struct poptOption
{
const char *string;
char short_form;
bool argument;
void *nullptr; // unused
int enumeration;
const char *descrip;
const char *argDescrip;
};

typedef struct _poptContext
{
int argc, current, size;
const char **argv;
const char *parameter;
const char *bad;
const struct poptOption *table;
} *poptContext;

static void poptPrintUsage(poptContext ctx, FILE *output, WZ_DECL_UNUSED int unused)
{
// TODO ?
}

static void poptPrintHelp(poptContext ctx, FILE *output, WZ_DECL_UNUSED int unused)
{
int i;

fprintf(output, "Usage: %s [OPTION...]\n", ctx->argv[0]);
for (i = 0; i < ctx->size; i++)
{
char txt[128];

if (ctx->table[i].short_form != '\0')
{
ssprintf(txt, " -%c, --%s", ctx->table[i].short_form, ctx->table[i].string);
}
else
{
ssprintf(txt, " --%s", ctx->table[i].string);
}

if (ctx->table[i].argument)
{
sstrcat(txt, "=");
sstrcat(txt, ctx->table[i].argDescrip);
}

fprintf(output, "%-40s", txt);
if (ctx->table[i].descrip)
{
fprintf(output, "%s", ctx->table[i].descrip);
}
fprintf(output, "\n");
}
}

static void poptFreeContext(WZ_DECL_UNUSED poptContext ctx)
{
// Nothing!
}

static const char *poptBadOption(poptContext ctx, WZ_DECL_UNUSED int unused)
{
return ctx->bad;
}

static const char *poptGetOptArg(poptContext ctx)
{
return ctx->parameter;
}

static int poptGetNextOpt(poptContext ctx)
{
static char match[PATH_MAX]; // static for bad function
static char parameter[PATH_MAX]; // static for arg function
char *pparam;
int i;

ctx->bad = NULL;
ctx->parameter = NULL;
parameter[0] = '\0';
match[0] = '\0';

if (ctx->current >= ctx->argc) // counts from 1
{
return 0;
}

sstrcpy(match, ctx->argv[ctx->current]);
ctx->current++;
pparam = strrchr(match, '=');
if (pparam) // option's got a parameter
{
*pparam++ = '\0'; // split option from parameter and increment past '='
if (pparam[0] == '"') // found scary quotes
{
pparam++; // skip start quote
sstrcpy(parameter, pparam); // copy first parameter
if (!strrchr(pparam, '"')) // if no end quote, then find it
{
while (!strrchr(parameter, '"') && ctx->current < ctx->argc)
{
sstrcat(parameter, " "); // insert space
sstrcat(parameter, ctx->argv[ctx->current]);
ctx->current++; // next part, please!
}
}
if (strrchr(parameter, '"')) // its not an else for above!
{
*strrchr(parameter, '"') = '\0'; // remove end qoute
}
}
else
{
sstrcpy(parameter, pparam); // copy parameter
}
}

for (i = 0; i < ctx->size; i++)
{
char sshort[3];
char slong[64];

ssprintf(sshort, "-%c", ctx->table[i].short_form);
ssprintf(slong, "--%s", ctx->table[i].string);
if ((strcmp(sshort, match) == 0 && ctx->table[i].short_form != '\0') || strcmp(slong, match) == 0)
{
if (ctx->table[i].argument && pparam)
{
ctx->parameter = parameter;
}
return ctx->table[i].enumeration;
}
}
ctx->bad = match;
ctx->current++;
return POPT_ERROR_BADOPT;
}

static poptContext poptGetContext(WZ_DECL_UNUSED void *unused, int argc, const char **argv, const struct poptOption *table, WZ_DECL_UNUSED int none)
{
static struct _poptContext ctx;

ctx.argc = argc;
ctx.argv = argv;
ctx.table = table;
ctx.current = 1;
ctx.parameter = NULL;

for (ctx.size = 0; table[ctx.size].string; ctx.size++) ; // count table size

return &ctx;
}


typedef enum
{
// We don't want to use zero, so start at one (1)
Expand Down Expand Up @@ -79,8 +242,8 @@ static const struct poptOption* getOptionsTable(void)
static const struct poptOption optionsTable[] =
{
{ "cheat", '\0', POPT_ARG_NONE, NULL, CLI_CHEAT, N_("Run in cheat mode"), NULL },
{ "datadir", '\0', POPT_ARG_STRING, NULL, CLI_DATADIR, N_("Set default data directory"), N_("data directory") },
{ "configdir", '\0', POPT_ARG_STRING, NULL, CLI_CONFIGDIR, N_("Set configuration directory"), N_("configuration directory") },
{ "datadir", '\0', POPT_ARG_STRING, NULL, CLI_DATADIR, N_("Set default data directory"), N_("data directory") },
{ "debug", '\0', POPT_ARG_STRING, NULL, CLI_DEBUG, N_("Show debug for given level"), N_("debug level") },
{ "debugfile", '\0', POPT_ARG_STRING, NULL, CLI_DEBUGFILE, N_("Log debug output to file"), N_("file") },
{ "flush-debug-stderr", '\0', POPT_ARG_NONE, NULL, CLI_FLUSHDEBUGSTDERR, N_("Flush all debug output written to stderr"), NULL },
Expand Down

0 comments on commit 2aca760

Please sign in to comment.