mirror of
https://github.com/irssi/irssi.git
synced 2024-11-03 04:27:19 -05:00
Remove popt and use glib GOption commandline option parser
(glib-2.6 is now the minimum required version). git-svn-id: http://svn.irssi.org/repos/irssi/trunk@4700 dbcabf3a-b0e7-0310-adc4-f8d773084564
This commit is contained in:
parent
c403b70de4
commit
ab8da71d29
2
TODO
2
TODO
@ -269,8 +269,6 @@
|
|||||||
- irssi crashes at quit if perl is loaded as module
|
- irssi crashes at quit if perl is loaded as module
|
||||||
- #1 0x68cc7 in module_file_deinit_gmodule (file=0x110e20) at modules-load.c:356
|
- #1 0x68cc7 in module_file_deinit_gmodule (file=0x110e20) at modules-load.c:356
|
||||||
- <dg> i've managed to reproduce the bug, if i make three split windows (/window show 3..5), then set the windows to not be sticky and go to one of the windows, then alt+number to another window then go back the other window the display prints two windows in the same window
|
- <dg> i've managed to reproduce the bug, if i make three split windows (/window show 3..5), then set the windows to not be sticky and go to one of the windows, then alt+number to another window then go back the other window the display prints two windows in the same window
|
||||||
- irssi -cserver -nnick -> crashes - lib-popt is buggy!
|
|
||||||
- bug as well but not crash: --config=foo --home=bar -c server
|
|
||||||
- /SB CLEAR still crashing sometimes?
|
- /SB CLEAR still crashing sometimes?
|
||||||
- make sure irssi works with 0x0 sized terminal. 1x1 sized terminal
|
- make sure irssi works with 0x0 sized terminal. 1x1 sized terminal
|
||||||
doesn't work if we use recreate_windows()
|
doesn't work if we use recreate_windows()
|
||||||
|
@ -276,7 +276,7 @@ for try in 1 2; do
|
|||||||
echo "*** trying without -lgmodule"
|
echo "*** trying without -lgmodule"
|
||||||
glib_modules=
|
glib_modules=
|
||||||
fi
|
fi
|
||||||
AM_PATH_GLIB_2_0(2.0.0,,, $glib_modules)
|
AM_PATH_GLIB_2_0(2.6.0,,, $glib_modules)
|
||||||
if test "$GLIB_LIBS"; then
|
if test "$GLIB_LIBS"; then
|
||||||
if test $glib_modules = gmodule; then
|
if test $glib_modules = gmodule; then
|
||||||
AC_DEFINE(HAVE_GMODULE)
|
AC_DEFINE(HAVE_GMODULE)
|
||||||
@ -648,7 +648,7 @@ dnl ****************************************
|
|||||||
AC_SUBST(CHAT_MODULES)
|
AC_SUBST(CHAT_MODULES)
|
||||||
AC_SUBST(irc_MODULES)
|
AC_SUBST(irc_MODULES)
|
||||||
|
|
||||||
CORE_LIBS="../core/libcore.a ../lib-config/libirssi_config.a ../lib-popt/libpopt.a"
|
CORE_LIBS="../core/libcore.a ../lib-config/libirssi_config.a"
|
||||||
FE_COMMON_LIBS=""
|
FE_COMMON_LIBS=""
|
||||||
|
|
||||||
CHAT_LIBS=""
|
CHAT_LIBS=""
|
||||||
@ -753,7 +753,6 @@ src/fe-common/irc/notifylist/Makefile
|
|||||||
src/fe-none/Makefile
|
src/fe-none/Makefile
|
||||||
src/fe-text/Makefile
|
src/fe-text/Makefile
|
||||||
src/lib-config/Makefile
|
src/lib-config/Makefile
|
||||||
src/lib-popt/Makefile
|
|
||||||
src/perl/Makefile
|
src/perl/Makefile
|
||||||
src/perl/common/Makefile.PL
|
src/perl/common/Makefile.PL
|
||||||
src/perl/irc/Makefile.PL
|
src/perl/irc/Makefile.PL
|
||||||
|
@ -22,8 +22,8 @@
|
|||||||
|____|_____|_____|____|
|
|____|_____|_____|____|
|
||||||
|
|
|
|
||||||
CORE
|
CORE
|
||||||
/ \
|
/
|
||||||
lib-config lib-popt
|
lib-config
|
||||||
|
|
||||||
|
|
||||||
(IRC, ICQ, xxx and yyy are chat protocols ..)
|
(IRC, ICQ, xxx and yyy are chat protocols ..)
|
||||||
@ -75,12 +75,6 @@
|
|||||||
signals.txt for a list of signals.
|
signals.txt for a list of signals.
|
||||||
|
|
||||||
|
|
||||||
** lib-popt
|
|
||||||
|
|
||||||
CORE depends on this for command line parameter handling.
|
|
||||||
(distributed with irssi)
|
|
||||||
|
|
||||||
|
|
||||||
** lib-config
|
** lib-config
|
||||||
|
|
||||||
Irssi depends on this for reading and saving configuration.
|
Irssi depends on this for reading and saving configuration.
|
||||||
|
@ -14,4 +14,4 @@ pkginc_srcdir=$(pkgincludedir)/src
|
|||||||
pkginc_src_HEADERS = \
|
pkginc_src_HEADERS = \
|
||||||
common.h
|
common.h
|
||||||
|
|
||||||
SUBDIRS = lib-popt lib-config core irc fe-common $(PERLDIR) $(TEXTUI) $(BOTUI)
|
SUBDIRS = lib-config core irc fe-common $(PERLDIR) $(TEXTUI) $(BOTUI)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
args.c : small frontend to libPopt command line argument parser
|
args.c : small frontend to GOption command line argument parser
|
||||||
|
|
||||||
Copyright (C) 1999-2001 Timo Sirainen
|
Copyright (C) 1999-2001 Timo Sirainen
|
||||||
|
|
||||||
@ -21,46 +21,32 @@
|
|||||||
#include "module.h"
|
#include "module.h"
|
||||||
#include "args.h"
|
#include "args.h"
|
||||||
|
|
||||||
static GArray *iopt_tables = NULL;
|
static GOptionContext *context = NULL;
|
||||||
|
|
||||||
void args_register(struct poptOption *options)
|
void args_register(GOptionEntry *options)
|
||||||
{
|
{
|
||||||
if (iopt_tables == NULL) {
|
if (context == NULL)
|
||||||
iopt_tables = g_array_new(TRUE, TRUE,
|
context = g_option_context_new("");
|
||||||
sizeof(struct poptOption));
|
|
||||||
}
|
|
||||||
|
|
||||||
while (options->longName != NULL || options->shortName != '\0' ||
|
g_option_context_add_main_entries(context, options, PACKAGE_TARNAME);
|
||||||
options->arg != NULL) {
|
|
||||||
g_array_append_val(iopt_tables, *options);
|
|
||||||
options = options+1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void args_execute(int argc, char *argv[])
|
void args_execute(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
poptContext con;
|
GError* error = NULL;
|
||||||
int nextopt;
|
|
||||||
|
|
||||||
if (iopt_tables == NULL)
|
if (context == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
con = poptGetContext(PACKAGE_TARNAME, argc, argv,
|
g_option_context_parse(context, &argc, &argv, &error);
|
||||||
(struct poptOption *) (iopt_tables->data), 0);
|
g_option_context_free(context);
|
||||||
poptReadDefaultConfig(con, TRUE);
|
context = NULL;
|
||||||
|
|
||||||
while ((nextopt = poptGetNextOpt(con)) > 0) ;
|
if (error != NULL) {
|
||||||
|
printf("%s\n"
|
||||||
if (nextopt != -1) {
|
|
||||||
printf("Error on option %s: %s.\n"
|
|
||||||
"Run '%s --help' to see a full list of "
|
"Run '%s --help' to see a full list of "
|
||||||
"available command line options.\n",
|
"available command line options.\n",
|
||||||
poptBadOption(con, 0), poptStrerror(nextopt), argv[0]);
|
error->message, argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_array_free(iopt_tables, TRUE);
|
|
||||||
iopt_tables = NULL;
|
|
||||||
|
|
||||||
poptFreeContext(con);
|
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,7 @@
|
|||||||
#ifndef __ARGS_H
|
#ifndef __ARGS_H
|
||||||
#define __ARGS_H
|
#define __ARGS_H
|
||||||
|
|
||||||
#ifdef HAVE_POPT_H
|
void args_register(GOptionEntry *options);
|
||||||
# include <popt.h>
|
|
||||||
#else
|
|
||||||
# include "lib-popt/popt.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void args_register(struct poptOption *options);
|
|
||||||
void args_execute(int argc, char *argv[]);
|
void args_execute(int argc, char *argv[]);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -167,10 +167,10 @@ static char *fix_path(const char *str)
|
|||||||
|
|
||||||
void core_register_options(void)
|
void core_register_options(void)
|
||||||
{
|
{
|
||||||
static struct poptOption options[] = {
|
static GOptionEntry options[] = {
|
||||||
{ "config", 0, POPT_ARG_STRING, &irssi_config_file, 0, "Configuration file location (~/.irssi/config)", "PATH" },
|
{ "config", 0, 0, G_OPTION_ARG_STRING, &irssi_config_file, "Configuration file location (~/.irssi/config)", "PATH" },
|
||||||
{ "home", 0, POPT_ARG_STRING, &irssi_dir, 0, "Irssi home dir location (~/.irssi)", "PATH" },
|
{ "home", 0, 0, G_OPTION_ARG_STRING, &irssi_dir, "Irssi home dir location (~/.irssi)", "PATH" },
|
||||||
{ NULL, '\0', 0, NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
args_register(options);
|
args_register(options);
|
||||||
@ -192,6 +192,7 @@ void core_preinit(const char *path)
|
|||||||
} else {
|
} else {
|
||||||
str = irssi_dir;
|
str = irssi_dir;
|
||||||
irssi_dir = fix_path(str);
|
irssi_dir = fix_path(str);
|
||||||
|
g_free(str);
|
||||||
len = strlen(irssi_dir);
|
len = strlen(irssi_dir);
|
||||||
if (irssi_dir[len-1] == G_DIR_SEPARATOR)
|
if (irssi_dir[len-1] == G_DIR_SEPARATOR)
|
||||||
irssi_dir[len-1] = '\0';
|
irssi_dir[len-1] = '\0';
|
||||||
@ -201,6 +202,7 @@ void core_preinit(const char *path)
|
|||||||
else {
|
else {
|
||||||
str = irssi_config_file;
|
str = irssi_config_file;
|
||||||
irssi_config_file = fix_path(str);
|
irssi_config_file = fix_path(str);
|
||||||
|
g_free(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
session_set_binary(path);
|
session_set_binary(path);
|
||||||
|
@ -329,14 +329,13 @@ static void sig_init_finished(void)
|
|||||||
config_close(session);
|
config_close(session);
|
||||||
|
|
||||||
unlink(session_file);
|
unlink(session_file);
|
||||||
session_file = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void session_register_options(void)
|
void session_register_options(void)
|
||||||
{
|
{
|
||||||
static struct poptOption options[] = {
|
static GOptionEntry options[] = {
|
||||||
{ "session", 0, POPT_ARG_STRING | POPT_ARGFLAG_DOC_HIDDEN, &session_file, 0, "Used by /UPGRADE command", "PATH" },
|
{ "session", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &session_file, "Used by /UPGRADE command", "PATH" },
|
||||||
{ NULL, '\0', 0, NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
session_file = NULL;
|
session_file = NULL;
|
||||||
|
@ -124,15 +124,14 @@ static void sig_channel_destroyed(CHANNEL_REC *channel)
|
|||||||
|
|
||||||
void fe_common_core_register_options(void)
|
void fe_common_core_register_options(void)
|
||||||
{
|
{
|
||||||
static struct poptOption options[] = {
|
static GOptionEntry options[] = {
|
||||||
POPT_AUTOHELP
|
{ "connect", 'c', 0, G_OPTION_ARG_STRING, &autocon_server, "Automatically connect to server/network", "SERVER" },
|
||||||
{ "connect", 'c', POPT_ARG_STRING, &autocon_server, 0, "Automatically connect to server/network", "SERVER" },
|
{ "password", 'w', 0, G_OPTION_ARG_STRING, &autocon_password, "Autoconnect password", "PASSWORD" },
|
||||||
{ "password", 'w', POPT_ARG_STRING, &autocon_password, 0, "Autoconnect password", "PASSWORD" },
|
{ "port", 'p', 0, G_OPTION_ARG_INT, &autocon_port, "Autoconnect port", "PORT" },
|
||||||
{ "port", 'p', POPT_ARG_INT, &autocon_port, 0, "Autoconnect port", "PORT" },
|
{ "noconnect", '!', 0, G_OPTION_ARG_NONE, &no_autoconnect, "Disable autoconnecting", NULL },
|
||||||
{ "noconnect", '!', POPT_ARG_NONE, &no_autoconnect, 0, "Disable autoconnecting", NULL },
|
{ "nick", 'n', 0, G_OPTION_ARG_STRING, &cmdline_nick, "Specify nick to use", NULL },
|
||||||
{ "nick", 'n', POPT_ARG_STRING, &cmdline_nick, 0, "Specify nick to use", NULL },
|
{ "hostname", 'h', 0, G_OPTION_ARG_STRING, &cmdline_hostname, "Specify host name to use", NULL },
|
||||||
{ "hostname", 'h', POPT_ARG_STRING, &cmdline_hostname, 0, "Specify host name to use", NULL },
|
{ NULL }
|
||||||
{ NULL, '\0', 0, NULL }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
autocon_server = NULL;
|
autocon_server = NULL;
|
||||||
|
@ -81,10 +81,9 @@ void noui_deinit(void)
|
|||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
static struct poptOption options[] = {
|
static GOptionEntry options[] = {
|
||||||
POPT_AUTOHELP
|
{ "load", 'l', 0, G_OPTION_ARG_STRING, &autoload_module, "Module to load (default = bot)", "MODULE" },
|
||||||
{ "load", 'l', POPT_ARG_STRING, &autoload_module, 0, "Module to load (default = bot)", "MODULE" },
|
{ NULL }
|
||||||
{ NULL, '\0', 0, NULL }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
autoload_module = NULL;
|
autoload_module = NULL;
|
||||||
|
@ -329,10 +329,10 @@ GMemVTable gc_mem_table = {
|
|||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
static int version = 0;
|
static int version = 0;
|
||||||
static struct poptOption options[] = {
|
static GOptionEntry options[] = {
|
||||||
{ "dummy", 'd', POPT_ARG_NONE, &dummy, 0, "Use the dummy terminal mode", NULL },
|
{ "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, "Use the dummy terminal mode", NULL },
|
||||||
{ "version", 'v', POPT_ARG_NONE, &version, 0, "Display irssi version", NULL },
|
{ "version", 'v', 0, G_OPTION_ARG_NONE, &version, "Display irssi version", NULL },
|
||||||
{ NULL, '\0', 0, NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
core_register_options();
|
core_register_options();
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
noinst_LIBRARIES = libpopt.a
|
|
||||||
|
|
||||||
INCLUDES = \
|
|
||||||
-I$(top_srcdir)/src \
|
|
||||||
$(GLIB_CFLAGS)
|
|
||||||
|
|
||||||
libpopt_a_SOURCES = \
|
|
||||||
findme.c popt.c poptconfig.c popthelp.c poptparse.c
|
|
||||||
|
|
||||||
pkginc_libpoptdir=$(pkgincludedir)/src/lib-popt
|
|
||||||
pkginc_libpopt_HEADERS = \
|
|
||||||
findme.h popt.h poptint.h
|
|
@ -1,54 +0,0 @@
|
|||||||
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
|
|
||||||
file accompanying popt source distributions, available from
|
|
||||||
ftp://ftp.redhat.com/pub/code/popt */
|
|
||||||
|
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
#ifdef __NeXT
|
|
||||||
/* access macros are not declared in non posix mode in unistd.h -
|
|
||||||
don't try to use posix on NeXTstep 3.3 ! */
|
|
||||||
#include <libc.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "findme.h"
|
|
||||||
|
|
||||||
char * findProgramPath(char * argv0) {
|
|
||||||
char * path = getenv("PATH");
|
|
||||||
char * pathbuf;
|
|
||||||
char * start, * chptr;
|
|
||||||
char * buf;
|
|
||||||
|
|
||||||
/* If there is a / in the argv[0], it has to be an absolute
|
|
||||||
path */
|
|
||||||
if (strchr(argv0, '/'))
|
|
||||||
return g_strdup(argv0);
|
|
||||||
|
|
||||||
if (!path) return NULL;
|
|
||||||
|
|
||||||
start = pathbuf = g_strdup(path);
|
|
||||||
buf = g_malloc(strlen(path) + strlen(argv0) + 2);
|
|
||||||
|
|
||||||
chptr = NULL;
|
|
||||||
do {
|
|
||||||
if ((chptr = strchr(start, ':')))
|
|
||||||
*chptr = '\0';
|
|
||||||
sprintf(buf, "%s/%s", start, argv0);
|
|
||||||
|
|
||||||
#ifndef WIN32
|
|
||||||
if (!access(buf, X_OK)) {
|
|
||||||
g_free(pathbuf);
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (chptr)
|
|
||||||
start = chptr + 1;
|
|
||||||
else
|
|
||||||
start = NULL;
|
|
||||||
} while (start && *start);
|
|
||||||
|
|
||||||
g_free(pathbuf);
|
|
||||||
free(buf);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
|
|
||||||
file accompanying popt source distributions, available from
|
|
||||||
ftp://ftp.redhat.com/pub/code/popt */
|
|
||||||
|
|
||||||
#ifndef H_FINDME
|
|
||||||
#define H_FINDME
|
|
||||||
|
|
||||||
char * findProgramPath(char * argv0);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,594 +0,0 @@
|
|||||||
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
|
|
||||||
file accompanying popt source distributions, available from
|
|
||||||
ftp://ftp.redhat.com/pub/code/popt */
|
|
||||||
|
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
#include "findme.h"
|
|
||||||
#include "popt.h"
|
|
||||||
#include "poptint.h"
|
|
||||||
|
|
||||||
void poptSetExecPath(poptContext con, const char * path, int allowAbsolute) {
|
|
||||||
if (con->execPath) free(con->execPath);
|
|
||||||
con->execPath = g_strdup(path);
|
|
||||||
con->execAbsolute = allowAbsolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void invokeCallbacks(poptContext con, const struct poptOption * table,
|
|
||||||
int post) {
|
|
||||||
const struct poptOption * opt = table;
|
|
||||||
poptCallbackType cb;
|
|
||||||
|
|
||||||
while (opt->longName || opt->shortName || opt->arg) {
|
|
||||||
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
|
|
||||||
invokeCallbacks(con, opt->arg, post);
|
|
||||||
} else if (((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_CALLBACK) &&
|
|
||||||
((!post && (opt->argInfo & POPT_CBFLAG_PRE)) ||
|
|
||||||
( post && (opt->argInfo & POPT_CBFLAG_POST)))) {
|
|
||||||
cb = (poptCallbackType)opt->arg;
|
|
||||||
cb(con, post ? POPT_CALLBACK_REASON_POST : POPT_CALLBACK_REASON_PRE,
|
|
||||||
NULL, NULL, opt->descrip);
|
|
||||||
}
|
|
||||||
opt++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
poptContext poptGetContext(char * name, int argc, char ** argv,
|
|
||||||
const struct poptOption * options, int flags) {
|
|
||||||
poptContext con = malloc(sizeof(*con));
|
|
||||||
|
|
||||||
memset(con, 0, sizeof(*con));
|
|
||||||
|
|
||||||
con->os = con->optionStack;
|
|
||||||
con->os->argc = argc;
|
|
||||||
con->os->argv = argv;
|
|
||||||
|
|
||||||
if (!(flags & POPT_CONTEXT_KEEP_FIRST))
|
|
||||||
con->os->next = 1; /* skip argv[0] */
|
|
||||||
|
|
||||||
con->leftovers = malloc(sizeof(char *) * (argc + 1));
|
|
||||||
con->options = options;
|
|
||||||
con->finalArgv = malloc(sizeof(*con->finalArgv) * (argc * 2));
|
|
||||||
con->finalArgvAlloced = argc * 2;
|
|
||||||
con->flags = flags;
|
|
||||||
con->execAbsolute = 1;
|
|
||||||
|
|
||||||
if (getenv("POSIXLY_CORRECT") || getenv("POSIX_ME_HARDER"))
|
|
||||||
con->flags |= POPT_CONTEXT_POSIXMEHARDER;
|
|
||||||
|
|
||||||
if (name)
|
|
||||||
con->appName = strcpy(malloc(strlen(name) + 1), name);
|
|
||||||
|
|
||||||
invokeCallbacks(con, con->options, 0);
|
|
||||||
|
|
||||||
return con;
|
|
||||||
}
|
|
||||||
|
|
||||||
void poptResetContext(poptContext con) {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
con->os = con->optionStack;
|
|
||||||
con->os->currAlias = NULL;
|
|
||||||
con->os->nextCharArg = NULL;
|
|
||||||
con->os->nextArg = NULL;
|
|
||||||
con->os->next = 1; /* skip argv[0] */
|
|
||||||
|
|
||||||
con->numLeftovers = 0;
|
|
||||||
con->nextLeftover = 0;
|
|
||||||
con->restLeftover = 0;
|
|
||||||
con->doExec = NULL;
|
|
||||||
|
|
||||||
for (i = 0; i < con->finalArgvCount; i++)
|
|
||||||
free(con->finalArgv[i]);
|
|
||||||
|
|
||||||
con->finalArgvCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Only one of longName, shortName may be set at a time */
|
|
||||||
static int handleExec(poptContext con, char * longName, char shortName) {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
i = con->numExecs - 1;
|
|
||||||
if (longName) {
|
|
||||||
while (i >= 0 && (!con->execs[i].longName ||
|
|
||||||
strcmp(con->execs[i].longName, longName))) i--;
|
|
||||||
} else {
|
|
||||||
while (i >= 0 &&
|
|
||||||
con->execs[i].shortName != shortName) i--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i < 0) return 0;
|
|
||||||
|
|
||||||
if (con->flags & POPT_CONTEXT_NO_EXEC)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (!con->doExec) {
|
|
||||||
con->doExec = con->execs + i;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We already have an exec to do; remember this option for next
|
|
||||||
time 'round */
|
|
||||||
if ((con->finalArgvCount + 1) >= (con->finalArgvAlloced)) {
|
|
||||||
con->finalArgvAlloced += 10;
|
|
||||||
con->finalArgv = realloc(con->finalArgv,
|
|
||||||
sizeof(*con->finalArgv) * con->finalArgvAlloced);
|
|
||||||
}
|
|
||||||
|
|
||||||
i = con->finalArgvCount++;
|
|
||||||
con->finalArgv[i] = malloc((longName ? strlen(longName) : 0) + 3);
|
|
||||||
if (longName)
|
|
||||||
sprintf(con->finalArgv[i], "--%s", longName);
|
|
||||||
else
|
|
||||||
sprintf(con->finalArgv[i], "-%c", shortName);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Only one of longName, shortName may be set at a time */
|
|
||||||
static int handleAlias(poptContext con, char * longName, char shortName,
|
|
||||||
char * nextCharArg) {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (con->os->currAlias && con->os->currAlias->longName && longName &&
|
|
||||||
!strcmp(con->os->currAlias->longName, longName))
|
|
||||||
return 0;
|
|
||||||
if (con->os->currAlias && shortName &&
|
|
||||||
shortName == con->os->currAlias->shortName)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
i = con->numAliases - 1;
|
|
||||||
if (longName) {
|
|
||||||
while (i >= 0 && (!con->aliases[i].longName ||
|
|
||||||
strcmp(con->aliases[i].longName, longName))) i--;
|
|
||||||
} else {
|
|
||||||
while (i >= 0 &&
|
|
||||||
con->aliases[i].shortName != shortName) i--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i < 0) return 0;
|
|
||||||
|
|
||||||
if ((con->os - con->optionStack + 1)
|
|
||||||
== POPT_OPTION_DEPTH)
|
|
||||||
return POPT_ERROR_OPTSTOODEEP;
|
|
||||||
|
|
||||||
if (nextCharArg && *nextCharArg)
|
|
||||||
con->os->nextCharArg = nextCharArg;
|
|
||||||
|
|
||||||
con->os++;
|
|
||||||
con->os->next = 0;
|
|
||||||
con->os->stuffed = 0;
|
|
||||||
con->os->nextArg = con->os->nextCharArg = NULL;
|
|
||||||
con->os->currAlias = con->aliases + i;
|
|
||||||
con->os->argc = con->os->currAlias->argc;
|
|
||||||
con->os->argv = con->os->currAlias->argv;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void execCommand(poptContext con) {
|
|
||||||
char ** argv;
|
|
||||||
int pos = 0;
|
|
||||||
char * script = con->doExec->script;
|
|
||||||
|
|
||||||
argv = malloc(sizeof(*argv) *
|
|
||||||
(6 + con->numLeftovers + con->finalArgvCount));
|
|
||||||
|
|
||||||
if (!con->execAbsolute && strchr(script, '/')) return;
|
|
||||||
|
|
||||||
if (!strchr(script, '/') && con->execPath) {
|
|
||||||
argv[pos] = g_strdup_printf("%s/%s", con->execPath, script);
|
|
||||||
} else {
|
|
||||||
argv[pos] = script;
|
|
||||||
}
|
|
||||||
pos++;
|
|
||||||
|
|
||||||
argv[pos] = findProgramPath(con->os->argv[0]);
|
|
||||||
if (argv[pos]) pos++;
|
|
||||||
argv[pos++] = ";";
|
|
||||||
|
|
||||||
memcpy(argv + pos, con->finalArgv, sizeof(*argv) * con->finalArgvCount);
|
|
||||||
pos += con->finalArgvCount;
|
|
||||||
|
|
||||||
if (con->numLeftovers) {
|
|
||||||
argv[pos++] = "--";
|
|
||||||
memcpy(argv + pos, con->leftovers, sizeof(*argv) * con->numLeftovers);
|
|
||||||
pos += con->numLeftovers;
|
|
||||||
}
|
|
||||||
|
|
||||||
argv[pos++] = NULL;
|
|
||||||
|
|
||||||
#ifdef __hpux
|
|
||||||
setresuid(getuid(), getuid(),-1);
|
|
||||||
#else
|
|
||||||
/*
|
|
||||||
* XXX " ... on BSD systems setuid() should be preferred over setreuid()"
|
|
||||||
* XXX sez' Timur Bakeyev <mc@bat.ru>
|
|
||||||
* XXX from Norbert Warmuth <nwarmuth@privat.circular.de>
|
|
||||||
*/
|
|
||||||
#if defined(HAVE_SETUID)
|
|
||||||
setuid(getuid());
|
|
||||||
#elif defined (HAVE_SETREUID)
|
|
||||||
setreuid(getuid(), getuid()); /*hlauer: not portable to hpux9.01 */
|
|
||||||
#else
|
|
||||||
; /* Can't drop privileges */
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
execvp(argv[0], argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct poptOption * findOption(const struct poptOption * table,
|
|
||||||
const char * longName,
|
|
||||||
char shortName,
|
|
||||||
poptCallbackType * callback,
|
|
||||||
void ** callbackData,
|
|
||||||
int singleDash) {
|
|
||||||
const struct poptOption * opt = table;
|
|
||||||
const struct poptOption * opt2;
|
|
||||||
const struct poptOption * cb = NULL;
|
|
||||||
|
|
||||||
/* This happens when a single - is given */
|
|
||||||
if (singleDash && !shortName && !*longName)
|
|
||||||
shortName = '-';
|
|
||||||
|
|
||||||
while (opt->longName || opt->shortName || opt->arg) {
|
|
||||||
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
|
|
||||||
opt2 = findOption(opt->arg, longName, shortName, callback,
|
|
||||||
callbackData, singleDash);
|
|
||||||
if (opt2) {
|
|
||||||
if (*callback && !*callbackData)
|
|
||||||
*callbackData = opt->descrip;
|
|
||||||
return opt2;
|
|
||||||
}
|
|
||||||
} else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_CALLBACK) {
|
|
||||||
cb = opt;
|
|
||||||
} else if (longName && opt->longName &&
|
|
||||||
(!singleDash || (opt->argInfo & POPT_ARGFLAG_ONEDASH)) &&
|
|
||||||
!strcmp(longName, opt->longName)) {
|
|
||||||
break;
|
|
||||||
} else if (shortName && shortName == opt->shortName) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
opt++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!opt->longName && !opt->shortName) return NULL;
|
|
||||||
*callbackData = NULL;
|
|
||||||
*callback = NULL;
|
|
||||||
if (cb) {
|
|
||||||
*callback = (poptCallbackType)cb->arg;
|
|
||||||
if (!(cb->argInfo & POPT_CBFLAG_INC_DATA))
|
|
||||||
*callbackData = cb->descrip;
|
|
||||||
}
|
|
||||||
|
|
||||||
return opt;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* returns 'val' element, -1 on last item, POPT_ERROR_* on error */
|
|
||||||
int poptGetNextOpt(poptContext con) {
|
|
||||||
char * optString, * chptr, * localOptString;
|
|
||||||
char * longArg = NULL;
|
|
||||||
char * origOptString, *dup;
|
|
||||||
long aLong;
|
|
||||||
char * end;
|
|
||||||
const struct poptOption * opt = NULL;
|
|
||||||
int done = 0;
|
|
||||||
int i;
|
|
||||||
poptCallbackType cb;
|
|
||||||
void * cbData;
|
|
||||||
int singleDash;
|
|
||||||
|
|
||||||
dup = NULL;
|
|
||||||
while (!done) {
|
|
||||||
if (dup) {
|
|
||||||
g_free(dup);
|
|
||||||
dup = NULL;
|
|
||||||
}
|
|
||||||
while (!con->os->nextCharArg && con->os->next == con->os->argc
|
|
||||||
&& con->os > con->optionStack)
|
|
||||||
con->os--;
|
|
||||||
if (!con->os->nextCharArg && con->os->next == con->os->argc) {
|
|
||||||
invokeCallbacks(con, con->options, 1);
|
|
||||||
if (con->doExec) execCommand(con);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!con->os->nextCharArg) {
|
|
||||||
|
|
||||||
origOptString = con->os->argv[con->os->next++];
|
|
||||||
|
|
||||||
if (con->restLeftover || *origOptString != '-') {
|
|
||||||
con->leftovers[con->numLeftovers++] = origOptString;
|
|
||||||
if (con->flags & POPT_CONTEXT_POSIXMEHARDER)
|
|
||||||
con->restLeftover = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make a copy we can hack at */
|
|
||||||
dup = localOptString = optString =
|
|
||||||
g_strdup(origOptString);
|
|
||||||
|
|
||||||
if (!optString[0]) {
|
|
||||||
g_free(dup);
|
|
||||||
return POPT_ERROR_BADOPT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (optString[1] == '-' && !optString[2]) {
|
|
||||||
con->restLeftover = 1;
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
optString++;
|
|
||||||
if (*optString == '-')
|
|
||||||
singleDash = 0, optString++;
|
|
||||||
else
|
|
||||||
singleDash = 1;
|
|
||||||
|
|
||||||
if (handleAlias(con, optString, '\0', NULL))
|
|
||||||
continue;
|
|
||||||
if (handleExec(con, optString, '\0'))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
chptr = optString;
|
|
||||||
while (*chptr && *chptr != '=') chptr++;
|
|
||||||
if (*chptr == '=') {
|
|
||||||
longArg = origOptString + (chptr - localOptString) + 1;
|
|
||||||
*chptr = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
opt = findOption(con->options, optString, '\0', &cb, &cbData,
|
|
||||||
singleDash);
|
|
||||||
if (!opt && !singleDash) {
|
|
||||||
g_free(dup);
|
|
||||||
return POPT_ERROR_BADOPT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!opt)
|
|
||||||
con->os->nextCharArg = origOptString + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (con->os->nextCharArg) {
|
|
||||||
origOptString = con->os->nextCharArg;
|
|
||||||
|
|
||||||
con->os->nextCharArg = NULL;
|
|
||||||
|
|
||||||
if (handleAlias(con, NULL, *origOptString,
|
|
||||||
origOptString + 1)) {
|
|
||||||
origOptString++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (handleExec(con, NULL, *origOptString))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
opt = findOption(con->options, NULL, *origOptString, &cb,
|
|
||||||
&cbData, 0);
|
|
||||||
if (!opt) {
|
|
||||||
g_free(dup);
|
|
||||||
return POPT_ERROR_BADOPT;
|
|
||||||
}
|
|
||||||
origOptString++;
|
|
||||||
if (*origOptString)
|
|
||||||
con->os->nextCharArg = origOptString;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opt->arg && (opt->argInfo & POPT_ARG_MASK) == POPT_ARG_NONE) {
|
|
||||||
*((int *)opt->arg) = 1;
|
|
||||||
} else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_VAL) {
|
|
||||||
if (opt->arg) *((int *) opt->arg) = opt->val;
|
|
||||||
} else if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_NONE) {
|
|
||||||
if (longArg) {
|
|
||||||
con->os->nextArg = longArg;
|
|
||||||
} else if (con->os->nextCharArg) {
|
|
||||||
con->os->nextArg = con->os->nextCharArg;
|
|
||||||
con->os->nextCharArg = NULL;
|
|
||||||
} else {
|
|
||||||
while (con->os->next == con->os->argc &&
|
|
||||||
con->os > con->optionStack)
|
|
||||||
con->os--;
|
|
||||||
if (con->os->next == con->os->argc) {
|
|
||||||
g_free(dup);
|
|
||||||
return POPT_ERROR_NOARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
con->os->nextArg = con->os->argv[con->os->next++];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opt->arg) {
|
|
||||||
switch (opt->argInfo & POPT_ARG_MASK) {
|
|
||||||
case POPT_ARG_STRING:
|
|
||||||
*((char **) opt->arg) = con->os->nextArg;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case POPT_ARG_INT:
|
|
||||||
case POPT_ARG_LONG:
|
|
||||||
aLong = strtol(con->os->nextArg, &end, 0);
|
|
||||||
if (!(end && *end == '\0')) {
|
|
||||||
g_free(dup);
|
|
||||||
return POPT_ERROR_BADNUMBER;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aLong == LONG_MIN || aLong == LONG_MAX) {
|
|
||||||
g_free(dup);
|
|
||||||
return POPT_ERROR_OVERFLOW;
|
|
||||||
}
|
|
||||||
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_LONG) {
|
|
||||||
*((long *) opt->arg) = aLong;
|
|
||||||
} else {
|
|
||||||
if (aLong > INT_MAX || aLong < INT_MIN) {
|
|
||||||
g_free(dup);
|
|
||||||
return POPT_ERROR_OVERFLOW;
|
|
||||||
}
|
|
||||||
*((int *) opt->arg) =aLong;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
fprintf(stdout, POPT_("option type (%d) not implemented in popt\n"),
|
|
||||||
opt->argInfo & POPT_ARG_MASK);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cb)
|
|
||||||
cb(con, POPT_CALLBACK_REASON_OPTION, opt, con->os->nextArg, cbData);
|
|
||||||
else if (opt->val && ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_VAL))
|
|
||||||
done = 1;
|
|
||||||
|
|
||||||
if ((con->finalArgvCount + 2) >= (con->finalArgvAlloced)) {
|
|
||||||
con->finalArgvAlloced += 10;
|
|
||||||
con->finalArgv = realloc(con->finalArgv,
|
|
||||||
sizeof(*con->finalArgv) * con->finalArgvAlloced);
|
|
||||||
}
|
|
||||||
|
|
||||||
i = con->finalArgvCount++;
|
|
||||||
con->finalArgv[i] =
|
|
||||||
malloc((opt->longName ? strlen(opt->longName) : 0) + 3);
|
|
||||||
if (opt->longName)
|
|
||||||
sprintf(con->finalArgv[i], "--%s", opt->longName);
|
|
||||||
else
|
|
||||||
sprintf(con->finalArgv[i], "-%c", opt->shortName);
|
|
||||||
|
|
||||||
if (opt->arg && (opt->argInfo & POPT_ARG_MASK) != POPT_ARG_NONE
|
|
||||||
&& (opt->argInfo & POPT_ARG_MASK) != POPT_ARG_VAL)
|
|
||||||
con->finalArgv[con->finalArgvCount++] =
|
|
||||||
strcpy(malloc(strlen(con->os->nextArg)+1), con->os->nextArg);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dup) g_free(dup);
|
|
||||||
return opt->val;
|
|
||||||
}
|
|
||||||
|
|
||||||
char * poptGetOptArg(poptContext con) {
|
|
||||||
char * ret = con->os->nextArg;
|
|
||||||
con->os->nextArg = NULL;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
char * poptGetArg(poptContext con) {
|
|
||||||
if (con->numLeftovers == con->nextLeftover) return NULL;
|
|
||||||
return (con->leftovers[con->nextLeftover++]);
|
|
||||||
}
|
|
||||||
|
|
||||||
char * poptPeekArg(poptContext con) {
|
|
||||||
if (con->numLeftovers == con->nextLeftover) return NULL;
|
|
||||||
return (con->leftovers[con->nextLeftover]);
|
|
||||||
}
|
|
||||||
|
|
||||||
char ** poptGetArgs(poptContext con) {
|
|
||||||
if (con->numLeftovers == con->nextLeftover) return NULL;
|
|
||||||
|
|
||||||
/* some apps like [like RPM ;-) ] need this NULL terminated */
|
|
||||||
con->leftovers[con->numLeftovers] = NULL;
|
|
||||||
|
|
||||||
return (con->leftovers + con->nextLeftover);
|
|
||||||
}
|
|
||||||
|
|
||||||
void poptFreeContext(poptContext con) {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < con->numAliases; i++) {
|
|
||||||
if (con->aliases[i].longName) free(con->aliases[i].longName);
|
|
||||||
free(con->aliases[i].argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < con->numExecs; i++) {
|
|
||||||
if (con->execs[i].longName) free(con->execs[i].longName);
|
|
||||||
free(con->execs[i].script);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < con->finalArgvCount; i++)
|
|
||||||
free(con->finalArgv[i]);
|
|
||||||
|
|
||||||
free(con->leftovers);
|
|
||||||
free(con->finalArgv);
|
|
||||||
if (con->appName) free(con->appName);
|
|
||||||
if (con->aliases) free(con->aliases);
|
|
||||||
if (con->otherHelp) free(con->otherHelp);
|
|
||||||
if (con->execPath) free(con->execPath);
|
|
||||||
free(con);
|
|
||||||
}
|
|
||||||
|
|
||||||
int poptAddAlias(poptContext con, struct poptAlias newAlias, int flags) {
|
|
||||||
int aliasNum = con->numAliases++;
|
|
||||||
struct poptAlias * alias;
|
|
||||||
|
|
||||||
/* SunOS won't realloc(NULL, ...) */
|
|
||||||
if (!con->aliases)
|
|
||||||
con->aliases = malloc(sizeof(newAlias) * con->numAliases);
|
|
||||||
else
|
|
||||||
con->aliases = realloc(con->aliases,
|
|
||||||
sizeof(newAlias) * con->numAliases);
|
|
||||||
alias = con->aliases + aliasNum;
|
|
||||||
|
|
||||||
*alias = newAlias;
|
|
||||||
if (alias->longName)
|
|
||||||
alias->longName = strcpy(malloc(strlen(alias->longName) + 1),
|
|
||||||
alias->longName);
|
|
||||||
else
|
|
||||||
alias->longName = NULL;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
char * poptBadOption(poptContext con, int flags) {
|
|
||||||
struct optionStackEntry * os;
|
|
||||||
|
|
||||||
if (flags & POPT_BADOPTION_NOALIAS)
|
|
||||||
os = con->optionStack;
|
|
||||||
else
|
|
||||||
os = con->os;
|
|
||||||
|
|
||||||
return os->argv[os->next - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
#define POPT_ERROR_NOARG -10
|
|
||||||
#define POPT_ERROR_BADOPT -11
|
|
||||||
#define POPT_ERROR_OPTSTOODEEP -13
|
|
||||||
#define POPT_ERROR_BADQUOTE -15 /* only from poptParseArgString() */
|
|
||||||
#define POPT_ERROR_ERRNO -16 /* only from poptParseArgString() */
|
|
||||||
|
|
||||||
const char * poptStrerror(const int error) {
|
|
||||||
switch (error) {
|
|
||||||
case POPT_ERROR_NOARG:
|
|
||||||
return POPT_("missing argument");
|
|
||||||
case POPT_ERROR_BADOPT:
|
|
||||||
return POPT_("unknown option");
|
|
||||||
case POPT_ERROR_OPTSTOODEEP:
|
|
||||||
return POPT_("aliases nested too deeply");
|
|
||||||
case POPT_ERROR_BADQUOTE:
|
|
||||||
return POPT_("error in paramter quoting");
|
|
||||||
case POPT_ERROR_BADNUMBER:
|
|
||||||
return POPT_("invalid numeric value");
|
|
||||||
case POPT_ERROR_OVERFLOW:
|
|
||||||
return POPT_("number too large or too small");
|
|
||||||
case POPT_ERROR_ERRNO:
|
|
||||||
return strerror(errno);
|
|
||||||
default:
|
|
||||||
return POPT_("unknown error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int poptStuffArgs(poptContext con, char ** argv) {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if ((con->os - con->optionStack) == POPT_OPTION_DEPTH)
|
|
||||||
return POPT_ERROR_OPTSTOODEEP;
|
|
||||||
|
|
||||||
for (i = 0; argv[i]; i++);
|
|
||||||
|
|
||||||
con->os++;
|
|
||||||
con->os->next = 0;
|
|
||||||
con->os->nextArg = con->os->nextCharArg = NULL;
|
|
||||||
con->os->currAlias = NULL;
|
|
||||||
con->os->argc = i;
|
|
||||||
con->os->argv = argv;
|
|
||||||
con->os->stuffed = 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char * poptGetInvocationName(poptContext con) {
|
|
||||||
return con->os->argv[0];
|
|
||||||
}
|
|
@ -1,123 +0,0 @@
|
|||||||
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
|
|
||||||
file accompanying popt source distributions, available from
|
|
||||||
ftp://ftp.redhat.com/pub/code/popt */
|
|
||||||
|
|
||||||
#ifndef H_POPT
|
|
||||||
#define H_POPT
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdio.h> /* for FILE * */
|
|
||||||
|
|
||||||
#define POPT_OPTION_DEPTH 10
|
|
||||||
|
|
||||||
#define POPT_ARG_NONE 0
|
|
||||||
#define POPT_ARG_STRING 1
|
|
||||||
#define POPT_ARG_INT 2
|
|
||||||
#define POPT_ARG_LONG 3
|
|
||||||
#define POPT_ARG_INCLUDE_TABLE 4 /* arg points to table */
|
|
||||||
#define POPT_ARG_CALLBACK 5 /* table-wide callback... must be
|
|
||||||
set first in table; arg points
|
|
||||||
to callback, descrip points to
|
|
||||||
callback data to pass */
|
|
||||||
#define POPT_ARG_INTL_DOMAIN 6 /* set the translation domain
|
|
||||||
for this table and any
|
|
||||||
included tables; arg points
|
|
||||||
to the domain string */
|
|
||||||
#define POPT_ARG_VAL 7 /* arg should take value val */
|
|
||||||
#define POPT_ARG_MASK 0x0000FFFF
|
|
||||||
#define POPT_ARGFLAG_ONEDASH 0x80000000 /* allow -longoption */
|
|
||||||
#define POPT_ARGFLAG_DOC_HIDDEN 0x40000000 /* don't show in help/usage */
|
|
||||||
#define POPT_CBFLAG_PRE 0x80000000 /* call the callback before parse */
|
|
||||||
#define POPT_CBFLAG_POST 0x40000000 /* call the callback after parse */
|
|
||||||
#define POPT_CBFLAG_INC_DATA 0x20000000 /* use data from the include line,
|
|
||||||
not the subtable */
|
|
||||||
|
|
||||||
#define POPT_ERROR_NOARG -10
|
|
||||||
#define POPT_ERROR_BADOPT -11
|
|
||||||
#define POPT_ERROR_OPTSTOODEEP -13
|
|
||||||
#define POPT_ERROR_BADQUOTE -15 /* only from poptParseArgString() */
|
|
||||||
#define POPT_ERROR_ERRNO -16 /* only from poptParseArgString() */
|
|
||||||
#define POPT_ERROR_BADNUMBER -17
|
|
||||||
#define POPT_ERROR_OVERFLOW -18
|
|
||||||
|
|
||||||
/* poptBadOption() flags */
|
|
||||||
#define POPT_BADOPTION_NOALIAS (1 << 0) /* don't go into an alias */
|
|
||||||
|
|
||||||
/* poptGetContext() flags */
|
|
||||||
#define POPT_CONTEXT_NO_EXEC (1 << 0) /* ignore exec expansions */
|
|
||||||
#define POPT_CONTEXT_KEEP_FIRST (1 << 1) /* pay attention to argv[0] */
|
|
||||||
#define POPT_CONTEXT_POSIXMEHARDER (1 << 2) /* options can't follow args */
|
|
||||||
|
|
||||||
struct poptOption {
|
|
||||||
const char * longName; /* may be NULL */
|
|
||||||
char shortName; /* may be '\0' */
|
|
||||||
int argInfo;
|
|
||||||
void * arg; /* depends on argInfo */
|
|
||||||
int val; /* 0 means don't return, just update flag */
|
|
||||||
char * descrip; /* description for autohelp -- may be NULL */
|
|
||||||
char * argDescrip; /* argument description for autohelp */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct poptAlias {
|
|
||||||
char * longName; /* may be NULL */
|
|
||||||
char shortName; /* may be '\0' */
|
|
||||||
int argc;
|
|
||||||
char ** argv; /* must be free()able */
|
|
||||||
};
|
|
||||||
|
|
||||||
extern struct poptOption poptHelpOptions[];
|
|
||||||
#define POPT_AUTOHELP { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptHelpOptions, \
|
|
||||||
0, "Help options", NULL },
|
|
||||||
|
|
||||||
typedef struct poptContext_s * poptContext;
|
|
||||||
#ifndef __cplusplus
|
|
||||||
typedef struct poptOption * poptOption;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
enum poptCallbackReason { POPT_CALLBACK_REASON_PRE,
|
|
||||||
POPT_CALLBACK_REASON_POST,
|
|
||||||
POPT_CALLBACK_REASON_OPTION };
|
|
||||||
typedef void (*poptCallbackType)(poptContext con,
|
|
||||||
enum poptCallbackReason reason,
|
|
||||||
const struct poptOption * opt,
|
|
||||||
const char * arg, void * data);
|
|
||||||
|
|
||||||
poptContext poptGetContext(char * name, int argc, char ** argv,
|
|
||||||
const struct poptOption * options, int flags);
|
|
||||||
void poptResetContext(poptContext con);
|
|
||||||
|
|
||||||
/* returns 'val' element, -1 on last item, POPT_ERROR_* on error */
|
|
||||||
int poptGetNextOpt(poptContext con);
|
|
||||||
/* returns NULL if no argument is available */
|
|
||||||
char * poptGetOptArg(poptContext con);
|
|
||||||
/* returns NULL if no more options are available */
|
|
||||||
char * poptGetArg(poptContext con);
|
|
||||||
char * poptPeekArg(poptContext con);
|
|
||||||
char ** poptGetArgs(poptContext con);
|
|
||||||
/* returns the option which caused the most recent error */
|
|
||||||
char * poptBadOption(poptContext con, int flags);
|
|
||||||
void poptFreeContext(poptContext con);
|
|
||||||
int poptStuffArgs(poptContext con, char ** argv);
|
|
||||||
int poptAddAlias(poptContext con, struct poptAlias alias, int flags);
|
|
||||||
int poptReadConfigFile(poptContext con, char * fn);
|
|
||||||
/* like above, but reads /etc/popt and $HOME/.popt along with environment
|
|
||||||
vars */
|
|
||||||
int poptReadDefaultConfig(poptContext con, int useEnv);
|
|
||||||
/* argv should be freed -- this allows ', ", and \ quoting, but ' is treated
|
|
||||||
the same as " and both may include \ quotes */
|
|
||||||
int poptParseArgvString(const char * s, int * argcPtr, char *** argvPtr);
|
|
||||||
const char * poptStrerror(const int error);
|
|
||||||
void poptSetExecPath(poptContext con, const char * path, int allowAbsolute);
|
|
||||||
void poptPrintHelp(poptContext con, FILE * f, int flags);
|
|
||||||
void poptPrintUsage(poptContext con, FILE * f, int flags);
|
|
||||||
void poptSetOtherOptionHelp(poptContext con, const char * text);
|
|
||||||
const char * poptGetInvocationName(poptContext con);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,144 +0,0 @@
|
|||||||
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
|
|
||||||
file accompanying popt source distributions, available from
|
|
||||||
ftp://ftp.redhat.com/pub/code/popt */
|
|
||||||
|
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
#include "popt.h"
|
|
||||||
#include "poptint.h"
|
|
||||||
|
|
||||||
static void configLine(poptContext con, char * line) {
|
|
||||||
int nameLength = strlen(con->appName);
|
|
||||||
char * opt;
|
|
||||||
struct poptAlias alias;
|
|
||||||
char * entryType;
|
|
||||||
char * longName = NULL;
|
|
||||||
char shortName = '\0';
|
|
||||||
|
|
||||||
if (strncmp(line, con->appName, nameLength)) return;
|
|
||||||
line += nameLength;
|
|
||||||
if (!*line || !i_isspace(*line)) return;
|
|
||||||
while (*line && i_isspace(*line)) line++;
|
|
||||||
entryType = line;
|
|
||||||
|
|
||||||
while (!*line || !i_isspace(*line)) line++;
|
|
||||||
*line++ = '\0';
|
|
||||||
while (*line && i_isspace(*line)) line++;
|
|
||||||
if (!*line) return;
|
|
||||||
opt = line;
|
|
||||||
|
|
||||||
while (!*line || !i_isspace(*line)) line++;
|
|
||||||
*line++ = '\0';
|
|
||||||
while (*line && i_isspace(*line)) line++;
|
|
||||||
if (!*line) return;
|
|
||||||
|
|
||||||
if (opt[0] == '-' && opt[1] == '-')
|
|
||||||
longName = opt + 2;
|
|
||||||
else if (opt[0] == '-' && !opt[2])
|
|
||||||
shortName = opt[1];
|
|
||||||
|
|
||||||
if (!strcmp(entryType, "alias")) {
|
|
||||||
if (poptParseArgvString(line, &alias.argc, &alias.argv)) return;
|
|
||||||
alias.longName = longName, alias.shortName = shortName;
|
|
||||||
poptAddAlias(con, alias, 0);
|
|
||||||
} else if (!strcmp(entryType, "exec")) {
|
|
||||||
con->execs = realloc(con->execs,
|
|
||||||
sizeof(*con->execs) * (con->numExecs + 1));
|
|
||||||
if (longName)
|
|
||||||
con->execs[con->numExecs].longName = g_strdup(longName);
|
|
||||||
else
|
|
||||||
con->execs[con->numExecs].longName = NULL;
|
|
||||||
|
|
||||||
con->execs[con->numExecs].shortName = shortName;
|
|
||||||
con->execs[con->numExecs].script = g_strdup(line);
|
|
||||||
|
|
||||||
con->numExecs++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int poptReadConfigFile(poptContext con, char * fn) {
|
|
||||||
char * file, * chptr, * end;
|
|
||||||
char * buf, * dst;
|
|
||||||
int fd, rc;
|
|
||||||
int fileLength;
|
|
||||||
|
|
||||||
fd = open(fn, O_RDONLY);
|
|
||||||
if (fd < 0) {
|
|
||||||
if (errno == ENOENT)
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return POPT_ERROR_ERRNO;
|
|
||||||
}
|
|
||||||
|
|
||||||
fileLength = lseek(fd, 0, SEEK_END);
|
|
||||||
lseek(fd, 0, 0);
|
|
||||||
|
|
||||||
file = malloc(fileLength + 1);
|
|
||||||
if (read(fd, file, fileLength) != fileLength) {
|
|
||||||
rc = errno;
|
|
||||||
close(fd);
|
|
||||||
errno = rc;
|
|
||||||
free(file);
|
|
||||||
return POPT_ERROR_ERRNO;
|
|
||||||
}
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
dst = buf = malloc(fileLength + 1);
|
|
||||||
|
|
||||||
chptr = file;
|
|
||||||
end = (file + fileLength);
|
|
||||||
while (chptr < end) {
|
|
||||||
switch (*chptr) {
|
|
||||||
case '\n':
|
|
||||||
*dst = '\0';
|
|
||||||
dst = buf;
|
|
||||||
while (*dst && i_isspace(*dst)) dst++;
|
|
||||||
if (*dst && *dst != '#') {
|
|
||||||
configLine(con, dst);
|
|
||||||
}
|
|
||||||
chptr++;
|
|
||||||
break;
|
|
||||||
case '\\':
|
|
||||||
*dst++ = *chptr++;
|
|
||||||
if (chptr < end) {
|
|
||||||
if (*chptr == '\n')
|
|
||||||
dst--, chptr++;
|
|
||||||
/* \ at the end of a line does not insert a \n */
|
|
||||||
else
|
|
||||||
*dst++ = *chptr++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
*dst++ = *chptr++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(buf);
|
|
||||||
free(file);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int poptReadDefaultConfig(poptContext con, int useEnv) {
|
|
||||||
char * fn, * home;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
if (!con->appName) return 0;
|
|
||||||
|
|
||||||
rc = poptReadConfigFile(con, "/etc/popt");
|
|
||||||
if (rc) return rc;
|
|
||||||
#ifndef WIN32
|
|
||||||
if (getuid() != geteuid()) return 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ((home = getenv("HOME"))) {
|
|
||||||
fn = malloc(strlen(home) + 20);
|
|
||||||
strcpy(fn, home);
|
|
||||||
strcat(fn, "/.popt");
|
|
||||||
rc = poptReadConfigFile(con, fn);
|
|
||||||
free(fn);
|
|
||||||
if (rc) return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@ -1,301 +0,0 @@
|
|||||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
|
||||||
|
|
||||||
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
|
|
||||||
file accompanying popt source distributions, available from
|
|
||||||
ftp://ftp.redhat.com/pub/code/popt */
|
|
||||||
|
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
#include "popt.h"
|
|
||||||
#include "poptint.h"
|
|
||||||
|
|
||||||
static void displayArgs(poptContext con, enum poptCallbackReason foo,
|
|
||||||
struct poptOption * key,
|
|
||||||
const char * arg, void * data) {
|
|
||||||
if (key->shortName== '?')
|
|
||||||
poptPrintHelp(con, stdout, 0);
|
|
||||||
else
|
|
||||||
poptPrintUsage(con, stdout, 0);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct poptOption poptHelpOptions[] = {
|
|
||||||
{ NULL, '\0', POPT_ARG_CALLBACK, (void *)&displayArgs, '\0', NULL },
|
|
||||||
{ "help", '?', 0, NULL, '?', "Show this help message" },
|
|
||||||
{ "usage", '\0', 0, NULL, 'u', "Display brief usage message" },
|
|
||||||
{ NULL, '\0', 0, NULL, 0 }
|
|
||||||
} ;
|
|
||||||
|
|
||||||
|
|
||||||
static const char *
|
|
||||||
getTableTranslationDomain(const struct poptOption *table)
|
|
||||||
{
|
|
||||||
const struct poptOption *opt;
|
|
||||||
|
|
||||||
for(opt = table;
|
|
||||||
opt->longName || opt->shortName || opt->arg;
|
|
||||||
opt++) {
|
|
||||||
if(opt->argInfo == POPT_ARG_INTL_DOMAIN)
|
|
||||||
return opt->arg;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char * getArgDescrip(const struct poptOption * opt,
|
|
||||||
const char *translation_domain) {
|
|
||||||
if (!(opt->argInfo & POPT_ARG_MASK)) return NULL;
|
|
||||||
|
|
||||||
if (opt == (poptHelpOptions + 1) || opt == (poptHelpOptions + 2))
|
|
||||||
if (opt->argDescrip) return POPT_(opt->argDescrip);
|
|
||||||
|
|
||||||
if (opt->argDescrip) return D_(translation_domain, opt->argDescrip);
|
|
||||||
return POPT_("ARG");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void singleOptionHelp(FILE * f, int maxLeftCol,
|
|
||||||
const struct poptOption * opt,
|
|
||||||
const char *translation_domain) {
|
|
||||||
int indentLength = maxLeftCol + 5;
|
|
||||||
int lineLength = 79 - indentLength;
|
|
||||||
const char * help = D_(translation_domain, opt->descrip);
|
|
||||||
int helpLength;
|
|
||||||
const char * ch;
|
|
||||||
char format[10];
|
|
||||||
char * left = malloc(maxLeftCol + 1);
|
|
||||||
const char * argDescrip = getArgDescrip(opt, translation_domain);
|
|
||||||
|
|
||||||
*left = '\0';
|
|
||||||
if (opt->longName && opt->shortName)
|
|
||||||
sprintf(left, "-%c, --%s", opt->shortName, opt->longName);
|
|
||||||
else if (opt->shortName)
|
|
||||||
sprintf(left, "-%c", opt->shortName);
|
|
||||||
else if (opt->longName)
|
|
||||||
sprintf(left, "--%s", opt->longName);
|
|
||||||
if (!*left) {
|
|
||||||
free(left);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (argDescrip) {
|
|
||||||
strcat(left, "=");
|
|
||||||
strcat(left, argDescrip);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (help)
|
|
||||||
fprintf(f," %-*s ", maxLeftCol, left);
|
|
||||||
else {
|
|
||||||
fprintf(f," %s\n", left);
|
|
||||||
free(left);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(left);
|
|
||||||
|
|
||||||
helpLength = strlen(help);
|
|
||||||
while (helpLength > lineLength) {
|
|
||||||
ch = help + lineLength - 1;
|
|
||||||
while (ch > help && !i_isspace(*ch)) ch--;
|
|
||||||
if (ch == help) break; /* give up */
|
|
||||||
while (ch > (help + 1) && i_isspace(*ch)) ch--;
|
|
||||||
ch++;
|
|
||||||
|
|
||||||
sprintf(format, "%%.%ds\n%%%ds", (int) (ch - help), indentLength);
|
|
||||||
fprintf(f, format, help, " ");
|
|
||||||
help = ch;
|
|
||||||
while (i_isspace(*help) && *help) help++;
|
|
||||||
helpLength = strlen(help);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (helpLength) fprintf(f, "%s\n", help);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int maxArgWidth(const struct poptOption * opt,
|
|
||||||
const char * translation_domain) {
|
|
||||||
int max = 0;
|
|
||||||
int this;
|
|
||||||
const char * s;
|
|
||||||
|
|
||||||
while (opt->longName || opt->shortName || opt->arg) {
|
|
||||||
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
|
|
||||||
this = maxArgWidth(opt->arg, translation_domain);
|
|
||||||
if (this > max) max = this;
|
|
||||||
} else if (!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) {
|
|
||||||
this = opt->shortName ? 2 : 0;
|
|
||||||
if (opt->longName) {
|
|
||||||
if (this) this += 2;
|
|
||||||
this += strlen(opt->longName) + 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
s = getArgDescrip(opt, translation_domain);
|
|
||||||
if (s)
|
|
||||||
this += strlen(s) + 1;
|
|
||||||
if (this > max) max = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
opt++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return max;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void singleTableHelp(FILE * f, const struct poptOption * table,
|
|
||||||
int left,
|
|
||||||
const char *translation_domain) {
|
|
||||||
const struct poptOption * opt;
|
|
||||||
const char *sub_transdom;
|
|
||||||
|
|
||||||
opt = table;
|
|
||||||
while (opt->longName || opt->shortName || opt->arg) {
|
|
||||||
if ((opt->longName || opt->shortName) &&
|
|
||||||
!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN))
|
|
||||||
singleOptionHelp(f, left, opt, translation_domain);
|
|
||||||
opt++;
|
|
||||||
}
|
|
||||||
|
|
||||||
opt = table;
|
|
||||||
while (opt->longName || opt->shortName || opt->arg) {
|
|
||||||
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
|
|
||||||
sub_transdom = getTableTranslationDomain(opt->arg);
|
|
||||||
if(!sub_transdom)
|
|
||||||
sub_transdom = translation_domain;
|
|
||||||
|
|
||||||
if (opt->descrip)
|
|
||||||
fprintf(f, "\n%s\n", D_(sub_transdom, opt->descrip));
|
|
||||||
|
|
||||||
singleTableHelp(f, opt->arg, left, sub_transdom);
|
|
||||||
}
|
|
||||||
opt++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int showHelpIntro(poptContext con, FILE * f) {
|
|
||||||
int len = 6;
|
|
||||||
char * fn;
|
|
||||||
|
|
||||||
fprintf(f, POPT_("Usage:"));
|
|
||||||
if (!(con->flags & POPT_CONTEXT_KEEP_FIRST)) {
|
|
||||||
fn = con->optionStack->argv[0];
|
|
||||||
if (strrchr(fn, '/')) fn = strrchr(fn, '/') + 1;
|
|
||||||
fprintf(f, " %s", fn);
|
|
||||||
len += strlen(fn) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
void poptPrintHelp(poptContext con, FILE * f, int flags) {
|
|
||||||
int leftColWidth;
|
|
||||||
|
|
||||||
showHelpIntro(con, f);
|
|
||||||
if (con->otherHelp)
|
|
||||||
fprintf(f, " %s\n", con->otherHelp);
|
|
||||||
else
|
|
||||||
fprintf(f, " %s\n", POPT_("[OPTION...]"));
|
|
||||||
|
|
||||||
leftColWidth = maxArgWidth(con->options, NULL);
|
|
||||||
singleTableHelp(f, con->options, leftColWidth, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int singleOptionUsage(FILE * f, int cursor,
|
|
||||||
const struct poptOption * opt,
|
|
||||||
const char *translation_domain) {
|
|
||||||
int len = 3;
|
|
||||||
char shortStr[2];
|
|
||||||
const char * item = shortStr;
|
|
||||||
const char * argDescrip = getArgDescrip(opt, translation_domain);
|
|
||||||
|
|
||||||
if (opt->shortName) {
|
|
||||||
if (!(opt->argInfo & POPT_ARG_MASK))
|
|
||||||
return cursor; /* we did these already */
|
|
||||||
len++;
|
|
||||||
*shortStr = opt->shortName;
|
|
||||||
shortStr[1] = '\0';
|
|
||||||
} else if (opt->longName) {
|
|
||||||
len += 1 + strlen(opt->longName);
|
|
||||||
item = opt->longName;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (len == 3) return cursor;
|
|
||||||
|
|
||||||
if (argDescrip)
|
|
||||||
len += strlen(argDescrip) + 1;
|
|
||||||
|
|
||||||
if ((cursor + len) > 79) {
|
|
||||||
fprintf(f, "\n ");
|
|
||||||
cursor = 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(f, " [-%s%s%s%s]", opt->shortName ? "" : "-", item,
|
|
||||||
argDescrip ? (opt->shortName ? " " : "=") : "",
|
|
||||||
argDescrip ? argDescrip : "");
|
|
||||||
|
|
||||||
return cursor + len + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int singleTableUsage(FILE * f, int cursor, const struct poptOption * table,
|
|
||||||
const char *translation_domain) {
|
|
||||||
const struct poptOption * opt;
|
|
||||||
|
|
||||||
opt = table;
|
|
||||||
while (opt->longName || opt->shortName || opt->arg) {
|
|
||||||
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INTL_DOMAIN)
|
|
||||||
translation_domain = (const char *)opt->arg;
|
|
||||||
else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE)
|
|
||||||
cursor = singleTableUsage(f, cursor, opt->arg,
|
|
||||||
translation_domain);
|
|
||||||
else if ((opt->longName || opt->shortName) &&
|
|
||||||
!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN))
|
|
||||||
cursor = singleOptionUsage(f, cursor, opt, translation_domain);
|
|
||||||
|
|
||||||
opt++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cursor;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int showShortOptions(const struct poptOption * opt, FILE * f,
|
|
||||||
char * str) {
|
|
||||||
char s[300]; /* this is larger then the ascii set, so
|
|
||||||
it should do just fine */
|
|
||||||
|
|
||||||
if (!str) {
|
|
||||||
str = s;
|
|
||||||
memset(str, 0, sizeof(s));
|
|
||||||
}
|
|
||||||
|
|
||||||
while (opt->longName || opt->shortName || opt->arg) {
|
|
||||||
if (opt->shortName && !(opt->argInfo & POPT_ARG_MASK))
|
|
||||||
str[strlen(str)] = opt->shortName;
|
|
||||||
else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE)
|
|
||||||
showShortOptions(opt->arg, f, str);
|
|
||||||
|
|
||||||
opt++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s != str || !*s)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
fprintf(f, " [-%s]", s);
|
|
||||||
return strlen(s) + 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
void poptPrintUsage(poptContext con, FILE * f, int flags) {
|
|
||||||
int cursor;
|
|
||||||
|
|
||||||
cursor = showHelpIntro(con, f);
|
|
||||||
cursor += showShortOptions(con->options, f, NULL);
|
|
||||||
singleTableUsage(f, cursor, con->options, NULL);
|
|
||||||
|
|
||||||
if (con->otherHelp) {
|
|
||||||
cursor += strlen(con->otherHelp) + 1;
|
|
||||||
if (cursor > 79) fprintf(f, "\n ");
|
|
||||||
fprintf(f, " %s", con->otherHelp);
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(f, "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void poptSetOtherOptionHelp(poptContext con, const char * text) {
|
|
||||||
if (con->otherHelp) free(con->otherHelp);
|
|
||||||
con->otherHelp = g_strdup(text);
|
|
||||||
}
|
|
@ -1,54 +0,0 @@
|
|||||||
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
|
|
||||||
file accompanying popt source distributions, available from
|
|
||||||
ftp://ftp.redhat.com/pub/code/popt */
|
|
||||||
|
|
||||||
#ifndef H_POPTINT
|
|
||||||
#define H_POPTINT
|
|
||||||
|
|
||||||
struct optionStackEntry {
|
|
||||||
int argc;
|
|
||||||
char ** argv;
|
|
||||||
int next;
|
|
||||||
char * nextArg;
|
|
||||||
char * nextCharArg;
|
|
||||||
struct poptAlias * currAlias;
|
|
||||||
int stuffed;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct execEntry {
|
|
||||||
char * longName;
|
|
||||||
char shortName;
|
|
||||||
char * script;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct poptContext_s {
|
|
||||||
struct optionStackEntry optionStack[POPT_OPTION_DEPTH], * os;
|
|
||||||
char ** leftovers;
|
|
||||||
int numLeftovers;
|
|
||||||
int nextLeftover;
|
|
||||||
const struct poptOption * options;
|
|
||||||
int restLeftover;
|
|
||||||
char * appName;
|
|
||||||
struct poptAlias * aliases;
|
|
||||||
int numAliases;
|
|
||||||
int flags;
|
|
||||||
struct execEntry * execs;
|
|
||||||
int numExecs;
|
|
||||||
char ** finalArgv;
|
|
||||||
int finalArgvCount;
|
|
||||||
int finalArgvAlloced;
|
|
||||||
struct execEntry * doExec;
|
|
||||||
char * execPath;
|
|
||||||
int execAbsolute;
|
|
||||||
char * otherHelp;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef HAVE_DGETTEXT
|
|
||||||
#define D_(dom, str) dgettext(dom, str)
|
|
||||||
#define POPT_(foo) D_("popt", foo)
|
|
||||||
#else
|
|
||||||
#define POPT_(foo) (foo)
|
|
||||||
#define D_(dom, str) (str)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,98 +0,0 @@
|
|||||||
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
|
|
||||||
file accompanying popt source distributions, available from
|
|
||||||
ftp://ftp.redhat.com/pub/code/popt */
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "popt.h"
|
|
||||||
|
|
||||||
static const int poptArgvArrayGrowDelta = 5;
|
|
||||||
|
|
||||||
int poptParseArgvString(const char * s, int * argcPtr, char *** argvPtr) {
|
|
||||||
char * buf, * bufStart, * dst;
|
|
||||||
const char * src;
|
|
||||||
char quote = '\0';
|
|
||||||
int argvAlloced = poptArgvArrayGrowDelta;
|
|
||||||
char ** argv = malloc(sizeof(*argv) * argvAlloced);
|
|
||||||
char ** argv2;
|
|
||||||
int argc = 0;
|
|
||||||
int i, buflen;
|
|
||||||
|
|
||||||
buflen = strlen(s) + 1;
|
|
||||||
bufStart = buf = malloc(buflen);
|
|
||||||
memset(buf, '\0', buflen);
|
|
||||||
|
|
||||||
src = s;
|
|
||||||
argv[argc] = buf;
|
|
||||||
|
|
||||||
while (*src) {
|
|
||||||
if (quote == *src) {
|
|
||||||
quote = '\0';
|
|
||||||
} else if (quote) {
|
|
||||||
if (*src == '\\') {
|
|
||||||
src++;
|
|
||||||
if (!*src) {
|
|
||||||
free(argv);
|
|
||||||
free(bufStart);
|
|
||||||
return POPT_ERROR_BADQUOTE;
|
|
||||||
}
|
|
||||||
if (*src != quote) *buf++ = '\\';
|
|
||||||
}
|
|
||||||
*buf++ = *src;
|
|
||||||
} else if (isspace((int) (unsigned char) *src)) {
|
|
||||||
if (*argv[argc]) {
|
|
||||||
buf++, argc++;
|
|
||||||
if (argc == argvAlloced) {
|
|
||||||
argvAlloced += poptArgvArrayGrowDelta;
|
|
||||||
argv = realloc(argv, sizeof(*argv) * argvAlloced);
|
|
||||||
}
|
|
||||||
argv[argc] = buf;
|
|
||||||
}
|
|
||||||
} else switch (*src) {
|
|
||||||
case '"':
|
|
||||||
case '\'':
|
|
||||||
quote = *src;
|
|
||||||
break;
|
|
||||||
case '\\':
|
|
||||||
src++;
|
|
||||||
if (!*src) {
|
|
||||||
free(argv);
|
|
||||||
free(bufStart);
|
|
||||||
return POPT_ERROR_BADQUOTE;
|
|
||||||
}
|
|
||||||
/* fallthrough */
|
|
||||||
default:
|
|
||||||
*buf++ = *src;
|
|
||||||
}
|
|
||||||
|
|
||||||
src++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strlen(argv[argc])) {
|
|
||||||
argc++, buf++;
|
|
||||||
}
|
|
||||||
|
|
||||||
dst = malloc(argc * sizeof(*argv) + (buf - bufStart));
|
|
||||||
argv2 = (void *) dst;
|
|
||||||
dst += argc * sizeof(*argv);
|
|
||||||
memcpy(argv2, argv, argc * sizeof(*argv));
|
|
||||||
memcpy(dst, bufStart, buf - bufStart);
|
|
||||||
|
|
||||||
for (i = 0; i < argc; i++) {
|
|
||||||
argv2[i] = dst + (argv[i] - bufStart);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(argv);
|
|
||||||
|
|
||||||
*argvPtr = argv2;
|
|
||||||
*argcPtr = argc;
|
|
||||||
|
|
||||||
free(bufStart);
|
|
||||||
return 0;
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user