Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
liblongpath-rsync
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
liblongpath
liblongpath-rsync
Commits
cc248aae
Commit
cc248aae
authored
Jul 27, 2002
by
Wayne Davison
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Updated to version 1.6.4.
parent
ca23c51a
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
1837 additions
and
649 deletions
+1837
-649
CHANGES
popt/CHANGES
+4
-1
README
popt/README
+1
-1
README.rsync
popt/README.rsync
+4
-5
findme.c
popt/findme.c
+17
-13
findme.h
popt/findme.h
+13
-3
popt.c
popt/popt.c
+728
-304
popt.h
popt/popt.h
+400
-84
poptconfig.c
popt/poptconfig.c
+107
-66
popthelp.c
popt/popthelp.c
+473
-118
poptint.h
popt/poptint.h
+41
-32
poptparse.c
popt/poptparse.c
+37
-21
system.h
popt/system.h
+12
-1
No files found.
popt/CHANGES
View file @
cc248aae
1.3 ->
1.5 -> 1.6
- add ability to perform callbacks for every, not just first, match.
1.3 -> 1.5
- heavy dose of const's
- poptParseArgvString() now NULL terminates the list
...
...
popt/README
View file @
cc248aae
...
...
@@ -5,7 +5,7 @@ to getopt(3), it contains a number of enhancements, including:
2) popt can parse arbitrary argv[] style arrays while
getopt(2) makes this quite difficult
3) popt allows users to alias command line arguments
4) popt provides convience functions for pars
t
ing strings
4) popt provides convience functions for parsing strings
into argv[] style arrays
popt is used by rpm, the Red Hat install program, and many other Red Hat
...
...
popt/README.rsync
View file @
cc248aae
Unlike zlib, this is a perfectly ordinary copy of libpopt. It's only
used on platforms that don't have a sufficiently up-to-date copy of
their own. If you build rsync on a platform which has popt, this
directory should not be used. (You can control that using
--with-included-popt.)
This is a perfectly ordinary copy of libpopt. It is only used on platforms
that do not have a sufficiently up-to-date copy of their own. If you build
rsync on a platform which has popt, this directory should not be used. (You
can control that using the --with-included-popt configure flag.)
popt/findme.c
View file @
cc248aae
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
/** \ingroup popt
* \file popt/findme.c
*/
/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
file accompanying popt source distributions, available from
ftp://ftp.r
edhat.com/pub/code/popt
*/
ftp://ftp.r
pm.org/pub/rpm/dist.
*/
#include "system.h"
#include "findme.h"
...
...
@@ -9,38 +13,38 @@ const char * findProgramPath(const char * argv0) {
char
*
path
=
getenv
(
"PATH"
);
char
*
pathbuf
;
char
*
start
,
*
chptr
;
char
*
buf
,
*
local
=
NULL
;
char
*
buf
;
/* If there is a / in the argv[0], it has to be an absolute
path */
if
(
argv0
==
NULL
)
return
NULL
;
/* XXX can't happen */
/* If there is a / in the argv[0], it has to be an absolute
path */
if
(
strchr
(
argv0
,
'/'
))
return
xstrdup
(
argv0
);
if
(
!
path
)
return
NULL
;
if
(
path
==
NULL
)
return
NULL
;
local
=
start
=
pathbuf
=
malloc
(
strlen
(
path
)
+
1
);
buf
=
malloc
(
strlen
(
path
)
+
strlen
(
argv0
)
+
2
);
start
=
pathbuf
=
alloca
(
strlen
(
path
)
+
1
);
buf
=
malloc
(
strlen
(
path
)
+
strlen
(
argv0
)
+
sizeof
(
"/"
));
if
(
buf
==
NULL
)
return
NULL
;
/* XXX can't happen */
strcpy
(
pathbuf
,
path
);
chptr
=
NULL
;
/*@-branchstate@*/
do
{
if
((
chptr
=
strchr
(
start
,
':'
)))
*
chptr
=
'\0'
;
sprintf
(
buf
,
"%s/%s"
,
start
,
argv0
);
if
(
!
access
(
buf
,
X_OK
))
{
if
(
local
)
free
(
local
);
return
buf
;
}
if
(
!
access
(
buf
,
X_OK
))
return
buf
;
if
(
chptr
)
start
=
chptr
+
1
;
else
start
=
NULL
;
}
while
(
start
&&
*
start
);
/*@=branchstate@*/
free
(
buf
);
if
(
local
)
free
(
local
);
return
NULL
;
}
popt/findme.h
View file @
cc248aae
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
/** \ingroup popt
* \file popt/findme.h
*/
/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
file accompanying popt source distributions, available from
ftp://ftp.r
edhat.com/pub/code/popt
*/
ftp://ftp.r
pm.org/pub/rpm/dist.
*/
#ifndef H_FINDME
#define H_FINDME
const
char
*
findProgramPath
(
const
char
*
argv0
);
/**
* Return absolute path to executable by searching PATH.
* @param argv0 name of executable
* @return (malloc'd) absolute path to executable (or NULL)
*/
/*@null@*/
const
char
*
findProgramPath
(
/*@null@*/
const
char
*
argv0
)
/*@*/
;
#endif
popt/popt.c
View file @
cc248aae
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
/** \ingroup popt
* \file popt/popt.c
*/
/* (C) 19982000 Red Hat, Inc. -- Licensing details are in the COPYING
file accompanying popt source distributions, available from
ftp://ftp.redhat.com/pub/code/popt */
ftp://ftp.rpm.org/pub/rpm/dist */
#undef MYDEBUG
#include "system.h"
#if HAVE_FLOAT_H
#include <float.h>
#endif
#include <math.h>
#include "findme.h"
#include "poptint.h"
...
...
@@ -18,47 +30,143 @@ static char * strerror(int errno) {
}
#endif
void
poptSetExecPath
(
poptContext
con
,
const
char
*
path
,
int
allowAbsolute
)
{
if
(
con
->
execPath
)
xfree
(
con
->
execPath
);
#ifdef MYDEBUG
/*@unused@*/
static
void
prtcon
(
const
char
*
msg
,
poptContext
con
)
{
if
(
msg
)
fprintf
(
stderr
,
"%s"
,
msg
);
fprintf
(
stderr
,
"
\t
con %p os %p nextCharArg
\"
%s
\"
nextArg
\"
%s
\"
argv[%d]
\"
%s
\"\n
"
,
con
,
con
->
os
,
(
con
->
os
->
nextCharArg
?
con
->
os
->
nextCharArg
:
""
),
(
con
->
os
->
nextArg
?
con
->
os
->
nextArg
:
""
),
con
->
os
->
next
,
(
con
->
os
->
argv
&&
con
->
os
->
argv
[
con
->
os
->
next
]
?
con
->
os
->
argv
[
con
->
os
->
next
]
:
""
));
}
#endif
void
poptSetExecPath
(
poptContext
con
,
const
char
*
path
,
int
allowAbsolute
)
{
con
->
execPath
=
_free
(
con
->
execPath
);
con
->
execPath
=
xstrdup
(
path
);
con
->
execAbsolute
=
allowAbsolute
;
/*@-nullstate@*/
/* LCL: con->execPath can be NULL? */
return
;
/*@=nullstate@*/
}
static
void
invokeCallbacks
(
poptContext
con
,
const
struct
poptOption
*
table
,
int
post
)
{
const
struct
poptOption
*
opt
=
table
;
poptCallbackType
cb
;
static
void
invokeCallbacksPRE
(
poptContext
con
,
const
struct
poptOption
*
opt
)
/*@globals internalState@*/
/*@modifies internalState@*/
{
if
(
opt
!=
NULL
)
for
(;
opt
->
longName
||
opt
->
shortName
||
opt
->
arg
;
opt
++
)
{
if
(
opt
->
arg
==
NULL
)
continue
;
/* XXX program error. */
if
((
opt
->
argInfo
&
POPT_ARG_MASK
)
==
POPT_ARG_INCLUDE_TABLE
)
{
/* Recurse on included sub-tables. */
invokeCallbacksPRE
(
con
,
opt
->
arg
);
}
else
if
((
opt
->
argInfo
&
POPT_ARG_MASK
)
==
POPT_ARG_CALLBACK
&&
(
opt
->
argInfo
&
POPT_CBFLAG_PRE
))
{
/*@-castfcnptr@*/
poptCallbackType
cb
=
(
poptCallbackType
)
opt
->
arg
;
/*@=castfcnptr@*/
/* Perform callback. */
/*@-moduncon -noeffectuncon @*/
cb
(
con
,
POPT_CALLBACK_REASON_PRE
,
NULL
,
NULL
,
opt
->
descrip
);
/*@=moduncon =noeffectuncon @*/
}
}
}
while
(
opt
->
longName
||
opt
->
shortName
||
opt
->
arg
)
{
static
void
invokeCallbacksPOST
(
poptContext
con
,
const
struct
poptOption
*
opt
)
/*@globals internalState@*/
/*@modifies internalState@*/
{
if
(
opt
!=
NULL
)
for
(;
opt
->
longName
||
opt
->
shortName
||
opt
->
arg
;
opt
++
)
{
if
(
opt
->
arg
==
NULL
)
continue
;
/* XXX program error. */
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
);
/* Recurse on included sub-tables. */
invokeCallbacksPOST
(
con
,
opt
->
arg
);
}
else
if
((
opt
->
argInfo
&
POPT_ARG_MASK
)
==
POPT_ARG_CALLBACK
&&
(
opt
->
argInfo
&
POPT_CBFLAG_POST
))
{
/*@-castfcnptr@*/
poptCallbackType
cb
=
(
poptCallbackType
)
opt
->
arg
;
/*@=castfcnptr@*/
/* Perform callback. */
/*@-moduncon -noeffectuncon @*/
cb
(
con
,
POPT_CALLBACK_REASON_POST
,
NULL
,
NULL
,
opt
->
descrip
);
/*@=moduncon =noeffectuncon @*/
}
}
}
static
void
invokeCallbacksOPTION
(
poptContext
con
,
const
struct
poptOption
*
opt
,
const
struct
poptOption
*
myOpt
,
/*@null@*/
const
void
*
myData
,
int
shorty
)
/*@globals internalState@*/
/*@modifies internalState@*/
{
const
struct
poptOption
*
cbopt
=
NULL
;
if
(
opt
!=
NULL
)
for
(;
opt
->
longName
||
opt
->
shortName
||
opt
->
arg
;
opt
++
)
{
if
((
opt
->
argInfo
&
POPT_ARG_MASK
)
==
POPT_ARG_INCLUDE_TABLE
)
{
/* Recurse on included sub-tables. */
if
(
opt
->
arg
!=
NULL
)
/* XXX program error */
invokeCallbacksOPTION
(
con
,
opt
->
arg
,
myOpt
,
myData
,
shorty
);
}
else
if
((
opt
->
argInfo
&
POPT_ARG_MASK
)
==
POPT_ARG_CALLBACK
&&
!
(
opt
->
argInfo
&
POPT_CBFLAG_SKIPOPTION
))
{
/* Save callback info. */
cbopt
=
opt
;
}
else
if
(
cbopt
!=
NULL
&&
((
myOpt
->
shortName
&&
opt
->
shortName
&&
shorty
&&
myOpt
->
shortName
==
opt
->
shortName
)
||
(
myOpt
->
longName
&&
opt
->
longName
&&
/*@-nullpass@*/
/* LCL: opt->longName != NULL */
!
strcmp
(
myOpt
->
longName
,
opt
->
longName
)))
/*@=nullpass@*/
)
{
/*@-castfcnptr@*/
poptCallbackType
cb
=
(
poptCallbackType
)
cbopt
->
arg
;
/*@=castfcnptr@*/
const
void
*
cbData
=
(
cbopt
->
descrip
?
cbopt
->
descrip
:
myData
);
/* Perform callback. */
if
(
cb
!=
NULL
)
{
/* XXX program error */
/*@-moduncon -noeffectuncon @*/
cb
(
con
,
POPT_CALLBACK_REASON_OPTION
,
myOpt
,
con
->
os
->
nextArg
,
cbData
);
/*@=moduncon =noeffectuncon @*/
}
/* Terminate (unless explcitly continuing). */
if
(
!
(
cbopt
->
argInfo
&
POPT_CBFLAG_CONTINUE
))
return
;
}
opt
++
;
}
}
poptContext
poptGetContext
(
const
char
*
name
,
int
argc
,
const
char
**
argv
,
const
struct
poptOption
*
options
,
int
flags
)
{
const
struct
poptOption
*
options
,
int
flags
)
{
poptContext
con
=
malloc
(
sizeof
(
*
con
));
if
(
con
==
NULL
)
return
NULL
;
/* XXX can't happen */
memset
(
con
,
0
,
sizeof
(
*
con
));
con
->
os
=
con
->
optionStack
;
con
->
os
->
argc
=
argc
;
/*@-dependenttrans -assignexpose@*/
/* FIX: W2DO? */
con
->
os
->
argv
=
argv
;
/*@=dependenttrans =assignexpose@*/
con
->
os
->
argb
=
NULL
;
if
(
!
(
flags
&
POPT_CONTEXT_KEEP_FIRST
))
con
->
os
->
next
=
1
;
/* skip argv[0] */
con
->
leftovers
=
calloc
(
(
argc
+
1
),
sizeof
(
char
*
)
);
con
->
leftovers
=
calloc
(
(
argc
+
1
),
sizeof
(
*
con
->
leftovers
)
);
/*@-dependenttrans -assignexpose@*/
/* FIX: W2DO? */
con
->
options
=
options
;
/*@=dependenttrans =assignexpose@*/
con
->
aliases
=
NULL
;
con
->
numAliases
=
0
;
con
->
flags
=
flags
;
...
...
@@ -72,40 +180,37 @@ poptContext poptGetContext(const char * name, int argc, const char ** argv,
if
(
getenv
(
"POSIXLY_CORRECT"
)
||
getenv
(
"POSIX_ME_HARDER"
))
con
->
flags
|=
POPT_CONTEXT_POSIXMEHARDER
;
if
(
name
)
con
->
appName
=
strcpy
(
malloc
(
strlen
(
name
)
+
1
),
name
);
if
(
name
)
{
char
*
t
=
malloc
(
strlen
(
name
)
+
1
);
if
(
t
)
con
->
appName
=
strcpy
(
t
,
name
);
}
invokeCallbacks
(
con
,
con
->
options
,
0
);
/*@-internalglobs@*/
invokeCallbacksPRE
(
con
,
con
->
options
);
/*@=internalglobs@*/
return
con
;
}
static
void
cleanOSE
(
struct
optionStackEntry
*
os
)
static
void
cleanOSE
(
/*@special@*/
struct
optionStackEntry
*
os
)
/*@uses os @*/
/*@releases os->nextArg, os->argv, os->argb @*/
/*@modifies os @*/
{
if
(
os
->
nextArg
)
{
xfree
(
os
->
nextArg
);
os
->
nextArg
=
NULL
;
}
if
(
os
->
argv
)
{
xfree
(
os
->
argv
);
os
->
argv
=
NULL
;
}
if
(
os
->
argb
)
{
PBM_FREE
(
os
->
argb
);
os
->
argb
=
NULL
;
}
os
->
nextArg
=
_free
(
os
->
nextArg
);
os
->
argv
=
_free
(
os
->
argv
);
os
->
argb
=
PBM_FREE
(
os
->
argb
);
}
void
poptResetContext
(
poptContext
con
)
{
void
poptResetContext
(
poptContext
con
)
{
int
i
;
if
(
con
==
NULL
)
return
;
while
(
con
->
os
>
con
->
optionStack
)
{
cleanOSE
(
con
->
os
--
);
}
if
(
con
->
os
->
argb
)
{
PBM_FREE
(
con
->
os
->
argb
);
con
->
os
->
argb
=
NULL
;
}
con
->
os
->
argb
=
PBM_FREE
(
con
->
os
->
argb
);
con
->
os
->
currAlias
=
NULL
;
con
->
os
->
nextCharArg
=
NULL
;
con
->
os
->
nextArg
=
NULL
;
...
...
@@ -116,36 +221,44 @@ void poptResetContext(poptContext con) {
con
->
restLeftover
=
0
;
con
->
doExec
=
NULL
;
for
(
i
=
0
;
i
<
con
->
finalArgvCount
;
i
++
)
{
if
(
con
->
finalArgv
[
i
])
{
xfree
(
con
->
finalArgv
[
i
]);
con
->
finalArgv
[
i
]
=
NULL
;
}
}
if
(
con
->
finalArgv
!=
NULL
)
for
(
i
=
0
;
i
<
con
->
finalArgvCount
;
i
++
)
/*@-unqualifiedtrans@*/
/* FIX: typedef double indirection. */
con
->
finalArgv
[
i
]
=
_free
(
con
->
finalArgv
[
i
]);
/*@=unqualifiedtrans@*/
con
->
finalArgvCount
=
0
;
if
(
con
->
arg_strip
)
{
PBM_FREE
(
con
->
arg_strip
);
con
->
arg_strip
=
NULL
;
}
con
->
arg_strip
=
PBM_FREE
(
con
->
arg_strip
);
/*@-nullstate@*/
/* FIX: con->finalArgv != NULL */
return
;
/*@=nullstate@*/
}
/* Only one of longName, shortName may be set at a time */
static
int
handleExec
(
poptContext
con
,
char
*
longName
,
char
shortName
)
{
/* Only one of longName, shortName should be set, not both. */
static
int
handleExec
(
/*@special@*/
poptContext
con
,
/*@null@*/
const
char
*
longName
,
char
shortName
)
/*@uses con->execs, con->numExecs, con->flags, con->doExec,
con->finalArgv, con->finalArgvAlloced, con->finalArgvCount @*/
/*@modifies con @*/
{
poptItem
item
;
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
(
con
->
execs
==
NULL
||
con
->
numExecs
<=
0
)
/* XXX can't happen */
return
0
;
for
(
i
=
con
->
numExecs
-
1
;
i
>=
0
;
i
--
)
{
item
=
con
->
execs
+
i
;
if
(
longName
&&
!
(
item
->
option
.
longName
&&
!
strcmp
(
longName
,
item
->
option
.
longName
)))
continue
;
else
if
(
shortName
!=
item
->
option
.
shortName
)
continue
;
break
;
}
if
(
i
<
0
)
return
0
;
if
(
con
->
flags
&
POPT_CONTEXT_NO_EXEC
)
return
1
;
...
...
@@ -163,38 +276,55 @@ static int handleExec(poptContext con, char * longName, char shortName) {
}
i
=
con
->
finalArgvCount
++
;
if
(
con
->
finalArgv
!=
NULL
)
/* XXX can't happen */
{
char
*
s
=
malloc
((
longName
?
strlen
(
longName
)
:
0
)
+
3
);
if
(
longName
)
sprintf
(
s
,
"--%s"
,
longName
);
else
sprintf
(
s
,
"-%c"
,
shortName
);
con
->
finalArgv
[
i
]
=
s
;
if
(
s
!=
NULL
)
{
/* XXX can't happen */
if
(
longName
)
sprintf
(
s
,
"--%s"
,
longName
);
else
sprintf
(
s
,
"-%c"
,
shortName
);
con
->
finalArgv
[
i
]
=
s
;
}
else
con
->
finalArgv
[
i
]
=
NULL
;
}
/*@-nullstate@*/
/* FIX: con->finalArgv[] == NULL */
return
1
;
/*@=nullstate@*/
}
/* Only one of longName, shortName may be set at a time */
static
int
handleAlias
(
poptContext
con
,
const
char
*
longName
,
char
shortName
,
/*@keep@*/
const
char
*
nextCharArg
)
{
static
int
handleAlias
(
/*@special@*/
poptContext
con
,
/*@null@*/
const
char
*
longName
,
char
shortName
,
/*@keep@*/
/*@null@*/
const
char
*
nextCharArg
)
/*@uses con->aliases, con->numAliases, con->optionStack, con->os,
con->os->currAlias, con->os->currAlias->option.longName @*/
/*@modifies con @*/
{
poptItem
item
=
con
->
os
->
currAlias
;
int
rc
;
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
)
if
(
item
)
{
if
(
longName
&&
(
item
->
option
.
longName
&&
!
strcmp
(
longName
,
item
->
option
.
longName
)))
return
0
;
if
(
shortName
&&
shortName
==
item
->
option
.
shortName
)
return
0
;
}
if
(
con
->
aliases
==
NULL
||
con
->
numAliases
<=
0
)
/* XXX can't happen */
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
--
;
for
(
i
=
con
->
numAliases
-
1
;
i
>=
0
;
i
--
)
{
item
=
con
->
aliases
+
i
;
if
(
longName
&&
!
(
item
->
option
.
longName
&&
!
strcmp
(
longName
,
item
->
option
.
longName
)))
continue
;
else
if
(
shortName
!=
item
->
option
.
shortName
)
continue
;
break
;
}
if
(
i
<
0
)
return
0
;
if
((
con
->
os
-
con
->
optionStack
+
1
)
==
POPT_OPTION_DEPTH
)
...
...
@@ -209,49 +339,65 @@ static int handleAlias(poptContext con, const char * longName, char shortName,
con
->
os
->
nextArg
=
NULL
;
con
->
os
->
nextCharArg
=
NULL
;
con
->
os
->
currAlias
=
con
->
aliases
+
i
;
poptDupArgv
(
con
->
os
->
currAlias
->
argc
,
con
->
os
->
currAlias
->
argv
,
rc
=
poptDupArgv
(
con
->
os
->
currAlias
->
argc
,
con
->
os
->
currAlias
->
argv
,
&
con
->
os
->
argc
,
&
con
->
os
->
argv
);
con
->
os
->
argb
=
NULL
;
return
1
;
return
(
rc
?
rc
:
1
)
;
}
static
void
execCommand
(
poptContext
con
)
{
static
int
execCommand
(
poptContext
con
)
/*@*/
{
poptItem
item
=
con
->
doExec
;
const
char
**
argv
;
int
pos
=
0
;
const
char
*
script
=
con
->
doExec
->
script
;
int
argc
=
0
;
int
rc
;
argv
=
malloc
(
sizeof
(
*
argv
)
*
(
6
+
con
->
numLeftovers
+
con
->
finalArgvCount
))
;
if
(
item
==
NULL
)
/*XXX can't happen*/
return
POPT_ERROR_NOARG
;
if
(
!
con
->
execAbsolute
&&
strchr
(
script
,
'/'
))
return
;
if
(
item
->
argv
==
NULL
||
item
->
argc
<
1
||
(
!
con
->
execAbsolute
&&
strchr
(
item
->
argv
[
0
],
'/'
)))
return
POPT_ERROR_NOARG
;
argv
=
malloc
(
sizeof
(
*
argv
)
*
(
6
+
item
->
argc
+
con
->
numLeftovers
+
con
->
finalArgvCount
));
if
(
argv
==
NULL
)
return
POPT_ERROR_MALLOC
;
/* XXX can't happen */
if
(
!
strchr
(
script
,
'/'
)
&&
con
->
execPath
)
{
char
*
s
=
malloc
(
strlen
(
con
->
execPath
)
+
strlen
(
script
)
+
2
);
sprintf
(
s
,
"%s/%s"
,
con
->
execPath
,
script
);
argv
[
pos
]
=
s
;
if
(
!
strchr
(
item
->
argv
[
0
]
,
'/'
)
&&
con
->
execPath
)
{
char
*
s
=
alloca
(
strlen
(
con
->
execPath
)
+
strlen
(
item
->
argv
[
0
])
+
sizeof
(
"/"
)
);
sprintf
(
s
,
"%s/%s"
,
con
->
execPath
,
item
->
argv
[
0
]
);
argv
[
argc
]
=
s
;
}
else
{
argv
[
pos
]
=
script
;
argv
[
argc
]
=
findProgramPath
(
item
->
argv
[
0
])
;
}
pos
++
;
if
(
argv
[
argc
++
]
==
NULL
)
return
POPT_ERROR_NOARG
;
argv
[
pos
]
=
findProgramPath
(
con
->
os
->
argv
[
0
]);
if
(
argv
[
pos
])
pos
++
;
argv
[
pos
++
]
=
";"
;
if
(
item
->
argc
>
1
)
{
memcpy
(
argv
+
argc
,
item
->
argv
+
1
,
sizeof
(
*
argv
)
*
(
item
->
argc
-
1
));
argc
+=
(
item
->
argc
-
1
);
}
memcpy
(
argv
+
pos
,
con
->
finalArgv
,
sizeof
(
*
argv
)
*
con
->
finalArgvCount
);
pos
+=
con
->
finalArgvCount
;
if
(
con
->
finalArgv
!=
NULL
&&
con
->
finalArgvCount
>
0
)
{
memcpy
(
argv
+
argc
,
con
->
finalArgv
,
sizeof
(
*
argv
)
*
con
->
finalArgvCount
);
argc
+=
con
->
finalArgvCount
;
}
if
(
con
->
numLeftovers
)
{
argv
[
pos
++
]
=
"--"
;
memcpy
(
argv
+
pos
,
con
->
leftovers
,
sizeof
(
*
argv
)
*
con
->
numLeftovers
);
pos
+=
con
->
numLeftovers
;
if
(
con
->
leftovers
!=
NULL
&&
con
->
numLeftovers
>
0
)
{
#if 0
argv[argc++] = "--";
#endif
memcpy
(
argv
+
argc
,
con
->
leftovers
,
sizeof
(
*
argv
)
*
con
->
numLeftovers
);
argc
+=
con
->
numLeftovers
;
}
argv
[
pos
++
]
=
NULL
;
argv
[
argc
]
=
NULL
;
#ifdef __hpux
setresuid
(
getuid
(),
getuid
(),
-
1
);
rc
=
setresuid
(
getuid
(),
getuid
(),
-
1
);
if
(
rc
)
return
POPT_ERROR_ERRNO
;
#else
/*
* XXX " ... on BSD systems setuid() should be preferred over setreuid()"
...
...
@@ -259,65 +405,103 @@ static void execCommand(poptContext con) {
* XXX from Norbert Warmuth <nwarmuth@privat.circular.de>
*/
#if defined(HAVE_SETUID)
setuid
(
getuid
());
rc
=
setuid
(
getuid
());
if
(
rc
)
return
POPT_ERROR_ERRNO
;
#elif defined (HAVE_SETREUID)
setreuid
(
getuid
(),
getuid
());
/*hlauer: not portable to hpux9.01 */
rc
=
setreuid
(
getuid
(),
getuid
());
/*hlauer: not portable to hpux9.01 */
if
(
rc
)
return
POPT_ERROR_ERRNO
;
#else
;
/* Can't drop privileges */
#endif
#endif
execvp
(
argv
[
0
],
(
char
*
const
*
)
argv
);
if
(
argv
[
0
]
==
NULL
)
return
POPT_ERROR_NOARG
;
#ifdef MYDEBUG
{
const
char
**
avp
;
fprintf
(
stderr
,
"==> execvp(%s) argv[%d]:"
,
argv
[
0
],
argc
);
for
(
avp
=
argv
;
*
avp
;
avp
++
)
fprintf
(
stderr
,
" '%s'"
,
*
avp
);
fprintf
(
stderr
,
"
\n
"
);
}
#endif
rc
=
execvp
(
argv
[
0
],
(
char
*
const
*
)
argv
);
return
POPT_ERROR_ERRNO
;
}
/*@observer@*/
static
const
struct
poptOption
*
findOption
(
const
struct
poptOption
*
table
,
const
char
*
longName
,
char
shortName
,
/*@out@*/
poptCallbackType
*
callback
,
/*@out@*/
const
void
**
callbackData
,
int
singleDash
)
/*@observer@*/
/*@null@*/
static
const
struct
poptOption
*
findOption
(
const
struct
poptOption
*
opt
,
/*@null@*/
const
char
*
longName
,
char
shortName
,
/*@null@*/
/*@out@*/
poptCallbackType
*
callback
,
/*@null@*/
/*@out@*/
const
void
**
callbackData
,
int
singleDash
)
/*@modifies *callback, *callbackData */
{
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
)
if
(
singleDash
&&
!
shortName
&&
(
longName
&&
*
longName
==
'\0'
)
)
shortName
=
'-'
;
while
(
opt
->
longName
||
opt
->
shortName
||
opt
->
arg
)
{
for
(;
opt
->
longName
||
opt
->
shortName
||
opt
->
arg
;
opt
++
)
{
if
((
opt
->
argInfo
&
POPT_ARG_MASK
)
==
POPT_ARG_INCLUDE_TABLE
)
{
const
struct
poptOption
*
opt2
;
/* Recurse on included sub-tables. */
if
(
opt
->
arg
==
NULL
)
continue
;
/* XXX program error */
opt2
=
findOption
(
opt
->
arg
,
longName
,
shortName
,
callback
,
callbackData
,
singleDash
);
if
(
opt2
)
{
if
(
*
callback
&&
!*
callbackData
)
*
callbackData
=
opt
->
descrip
;
return
opt2
;
}
if
(
opt2
==
NULL
)
continue
;
/* Sub-table data will be inheirited if no data yet. */
if
(
!
(
callback
&&
*
callback
))
return
opt2
;
if
(
!
(
callbackData
&&
*
callbackData
==
NULL
))
return
opt2
;
/*@-observertrans -dependenttrans @*/
*
callbackData
=
opt
->
descrip
;
/*@=observertrans =dependenttrans @*/
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
))
{
/*@-nullpass@*/
/* LCL: opt->longName != NULL */
!
strcmp
(
longName
,
opt
->
longName
))
/*@=nullpass@*/
{
break
;
}
else
if
(
shortName
&&
shortName
==
opt
->
shortName
)
{
break
;
}
opt
++
;
}
if
(
!
opt
->
longName
&&
!
opt
->
shortName
)
return
NULL
;
*
callbackData
=
NULL
;
*
callback
=
NULL
;
if
(
!
opt
->
longName
&&
!
opt
->
shortName
)
return
NULL
;
/*@-modobserver -mods @*/
if
(
callback
)
*
callback
=
NULL
;
if
(
callbackData
)
*
callbackData
=
NULL
;
if
(
cb
)
{
*
callback
=
(
poptCallbackType
)
cb
->
arg
;
if
(
!
(
cb
->
argInfo
&
POPT_CBFLAG_INC_DATA
))
*
callbackData
=
cb
->
descrip
;
if
(
callback
)
/*@-castfcnptr@*/
*
callback
=
(
poptCallbackType
)
cb
->
arg
;
/*@=castfcnptr@*/
if
(
!
(
cb
->
argInfo
&
POPT_CBFLAG_INC_DATA
))
{
if
(
callbackData
)
/*@-observertrans@*/
/* FIX: typedef double indirection. */
*
callbackData
=
cb
->
descrip
;
/*@=observertrans@*/
}
}
/*@=modobserver =mods @*/
return
opt
;
}
static
const
char
*
findNextArg
(
poptContext
con
,
unsigned
argx
,
int
delete
)
static
const
char
*
findNextArg
(
/*@special@*/
poptContext
con
,
unsigned
argx
,
int
delete_arg
)
/*@uses con->optionStack, con->os,
con->os->next, con->os->argb, con->os->argc, con->os->argv @*/
/*@modifies con @*/
{
struct
optionStackEntry
*
os
=
con
->
os
;
const
char
*
arg
;
...
...
@@ -327,43 +511,58 @@ static const char *findNextArg(poptContext con, unsigned argx, int delete)
arg
=
NULL
;
while
(
os
->
next
==
os
->
argc
&&
os
>
con
->
optionStack
)
os
--
;
if
(
os
->
next
==
os
->
argc
&&
os
==
con
->
optionStack
)
break
;
if
(
os
->
argv
!=
NULL
)
for
(
i
=
os
->
next
;
i
<
os
->
argc
;
i
++
)
{
if
(
os
->
argb
&&
PBM_ISSET
(
i
,
os
->
argb
))
continue
;
if
(
*
os
->
argv
[
i
]
==
'-'
)
continue
;
if
(
--
argx
>
0
)
continue
;
/*@-sizeoftype@*/
if
(
os
->
argb
&&
PBM_ISSET
(
i
,
os
->
argb
))
/*@innercontinue@*/
continue
;
if
(
*
os
->
argv
[
i
]
==
'-'
)
/*@innercontinue@*/
continue
;
if
(
--
argx
>
0
)
/*@innercontinue@*/
continue
;
arg
=
os
->
argv
[
i
];
if
(
delete
)
{
if
(
delete
_arg
)
{
if
(
os
->
argb
==
NULL
)
os
->
argb
=
PBM_ALLOC
(
os
->
argc
);
if
(
os
->
argb
!=
NULL
)
/* XXX can't happen */
PBM_SET
(
i
,
os
->
argb
);
}
break
;
/*@innerbreak@*/
break
;
/*@=sizeoftype@*/
}
if
(
os
>
con
->
optionStack
)
os
--
;
}
while
(
arg
==
NULL
);
return
arg
;
}
static
/*@only@*/
const
char
*
expandNextArg
(
poptContext
con
,
const
char
*
s
)
static
/*@only@*/
/*@null@*/
const
char
*
expandNextArg
(
/*@special@*/
poptContext
con
,
const
char
*
s
)
/*@uses con->optionStack, con->os,
con->os->next, con->os->argb, con->os->argc, con->os->argv @*/
/*@modifies con @*/
{
const
char
*
a
;
const
char
*
a
=
NULL
;
size_t
alen
;
char
*
t
,
*
te
;
size_t
tn
=
strlen
(
s
)
+
1
;
char
c
;
te
=
t
=
malloc
(
tn
);;
if
(
t
==
NULL
)
return
NULL
;
/* XXX can't happen */
while
((
c
=
*
s
++
)
!=
'\0'
)
{
switch
(
c
)
{
#if 0 /* XXX can't do this */
case '\\': /* escape */
c = *s++;
break;
/*@switchbreak@*/
break;
#endif
case
'!'
:
if
(
!
(
s
[
0
]
==
'#'
&&
s
[
1
]
==
':'
&&
s
[
2
]
==
'+'
))
break
;
if
((
a
=
findNextArg
(
con
,
1
,
1
))
==
NULL
)
break
;
/*@switchbreak@*/
break
;
/* XXX Make sure that findNextArg deletes only next arg. */
if
(
a
==
NULL
)
{
if
((
a
=
findNextArg
(
con
,
1
,
1
))
==
NULL
)
/*@switchbreak@*/
break
;
}
s
+=
3
;
alen
=
strlen
(
a
);
...
...
@@ -373,23 +572,87 @@ static /*@only@*/ const char * expandNextArg(poptContext con, const char * s)
te
=
t
+
strlen
(
t
);
strncpy
(
te
,
a
,
alen
);
te
+=
alen
;
continue
;
/*@notreached@*/
break
;
/*@notreached@*/
/*@switchbreak@*/
break
;
default
:
break
;
/*@switchbreak@*/
break
;
}
*
te
++
=
c
;
}
*
te
=
'\0'
;
t
=
realloc
(
t
,
strlen
(
t
)
+
1
);
/* XXX memory leak, hard to plug */
t
=
realloc
(
t
,
strlen
(
t
)
+
1
);
/* XXX memory leak, hard to plug */
return
t
;
}
static
void
poptStripArg
(
poptContext
con
,
int
which
)
static
void
poptStripArg
(
/*@special@*/
poptContext
con
,
int
which
)
/*@uses con->arg_strip, con->optionStack @*/
/*@defines con->arg_strip @*/
/*@modifies con @*/
{
if
(
con
->
arg_strip
==
NULL
)
{
/*@-sizeoftype@*/
if
(
con
->
arg_strip
==
NULL
)
con
->
arg_strip
=
PBM_ALLOC
(
con
->
optionStack
[
0
].
argc
);
}
if
(
con
->
arg_strip
!=
NULL
)
/* XXX can't happen */
PBM_SET
(
which
,
con
->
arg_strip
);
/*@=sizeoftype@*/
/*@-compdef@*/
/* LCL: con->arg_strip udefined? */
return
;
/*@=compdef@*/
}
static
int
poptSaveLong
(
const
struct
poptOption
*
opt
,
long
aLong
)
/*@modifies opt->arg @*/
{
if
(
opt
->
arg
==
NULL
)
return
POPT_ERROR_NULLARG
;
if
(
opt
->
argInfo
&
POPT_ARGFLAG_NOT
)
aLong
=
~
aLong
;
switch
(
opt
->
argInfo
&
POPT_ARGFLAG_LOGICALOPS
)
{
case
0
:
*
((
long
*
)
opt
->
arg
)
=
aLong
;
break
;
case
POPT_ARGFLAG_OR
:
*
((
long
*
)
opt
->
arg
)
|=
aLong
;
break
;
case
POPT_ARGFLAG_AND
:
*
((
long
*
)
opt
->
arg
)
&=
aLong
;
break
;
case
POPT_ARGFLAG_XOR
:
*
((
long
*
)
opt
->
arg
)
^=
aLong
;
break
;
default
:
return
POPT_ERROR_BADOPERATION
;
/*@notreached@*/
break
;
}
return
0
;
}
static
int
poptSaveInt
(
const
struct
poptOption
*
opt
,
long
aLong
)
/*@modifies opt->arg @*/
{
if
(
opt
->
arg
==
NULL
)
return
POPT_ERROR_NULLARG
;
if
(
opt
->
argInfo
&
POPT_ARGFLAG_NOT
)
aLong
=
~
aLong
;
switch
(
opt
->
argInfo
&
POPT_ARGFLAG_LOGICALOPS
)
{
case
0
:
*
((
int
*
)
opt
->
arg
)
=
aLong
;
break
;
case
POPT_ARGFLAG_OR
:
*
((
int
*
)
opt
->
arg
)
|=
aLong
;
break
;
case
POPT_ARGFLAG_AND
:
*
((
int
*
)
opt
->
arg
)
&=
aLong
;
break
;
case
POPT_ARGFLAG_XOR
:
*
((
int
*
)
opt
->
arg
)
^=
aLong
;
break
;
default
:
return
POPT_ERROR_BADOPERATION
;
/*@notreached@*/
break
;
}
return
0
;
}
/* returns 'val' element, -1 on last item, POPT_ERROR_* on error */
...
...
@@ -398,28 +661,25 @@ int poptGetNextOpt(poptContext con)
const
struct
poptOption
*
opt
=
NULL
;
int
done
=
0
;
/* looks a bit tricky to get rid of alloca properly in this fn */
#if HAVE_ALLOCA_H
#define ALLOCA(x) alloca(x)
#else
#define ALLOCA(x) malloc(x)
#endif
if
(
con
==
NULL
)
return
-
1
;
while
(
!
done
)
{
const
char
*
origOptString
=
NULL
;
poptCallbackType
cb
=
NULL
;
const
void
*
cbData
=
NULL
;
const
char
*
longArg
=
NULL
;
int
canstrip
=
0
;
int
shorty
=
0
;
while
(
!
con
->
os
->
nextCharArg
&&
con
->
os
->
next
==
con
->
os
->
argc
&&
con
->
os
>
con
->
optionStack
)
{
cleanOSE
(
con
->
os
--
);
}
if
(
!
con
->
os
->
nextCharArg
&&
con
->
os
->
next
==
con
->
os
->
argc
)
{
invokeCallbacks
(
con
,
con
->
options
,
1
);
if
(
con
->
doExec
)
execCommand
(
con
);
/*@-internalglobs@*/
invokeCallbacksPOST
(
con
,
con
->
options
);
/*@=internalglobs@*/
if
(
con
->
doExec
)
return
execCommand
(
con
);
return
-
1
;
}
...
...
@@ -428,26 +688,36 @@ int poptGetNextOpt(poptContext con)
char
*
localOptString
,
*
optString
;
int
thisopt
;
/*@-sizeoftype@*/
if
(
con
->
os
->
argb
&&
PBM_ISSET
(
con
->
os
->
next
,
con
->
os
->
argb
))
{
con
->
os
->
next
++
;
continue
;
}
thisopt
=
con
->
os
->
next
;
/*@=sizeoftype@*/
thisopt
=
con
->
os
->
next
;
if
(
con
->
os
->
argv
!=
NULL
)
/* XXX can't happen */
origOptString
=
con
->
os
->
argv
[
con
->
os
->
next
++
];
if
(
origOptString
==
NULL
)
/* XXX can't happen */
return
POPT_ERROR_BADOPT
;
if
(
con
->
restLeftover
||
*
origOptString
!=
'-'
)
{
con
->
leftovers
[
con
->
numLeftovers
++
]
=
origOptString
;
if
(
con
->
flags
&
POPT_CONTEXT_POSIXMEHARDER
)
con
->
restLeftover
=
1
;
if
(
con
->
flags
&
POPT_CONTEXT_ARG_OPTS
)
{
con
->
os
->
nextArg
=
xstrdup
(
origOptString
);
return
0
;
}
if
(
con
->
leftovers
!=
NULL
)
/* XXX can't happen */
con
->
leftovers
[
con
->
numLeftovers
++
]
=
origOptString
;
continue
;
}
/* Make a copy we can hack at */
localOptString
=
optString
=
strcpy
(
ALLOCA
(
strlen
(
origOptString
)
+
1
),
origOptString
);
strcpy
(
alloca
(
strlen
(
origOptString
)
+
1
),
origOptString
);
if
(
!
optString
[
0
]
)
if
(
optString
[
0
]
==
'\0'
)
return
POPT_ERROR_BADOPT
;
if
(
optString
[
1
]
==
'-'
&&
!
optString
[
2
])
{
...
...
@@ -466,12 +736,13 @@ int poptGetNextOpt(poptContext con)
/* XXX aliases with arg substitution need "--alias=arg" */
if
(
handleAlias
(
con
,
optString
,
'\0'
,
NULL
))
continue
;
if
(
handleExec
(
con
,
optString
,
'\0'
))
continue
;
/* Check for "--long=arg" option. */
for
(
oe
=
optString
;
*
oe
&&
*
oe
!=
'='
;
oe
++
)
;
{}
;
if
(
*
oe
==
'='
)
{
*
oe
++
=
'\0'
;
/* XXX longArg is mapped back to persistent storage. */
...
...
@@ -487,110 +758,175 @@ int poptGetNextOpt(poptContext con)
if
(
!
opt
)
{
con
->
os
->
nextCharArg
=
origOptString
+
1
;
}
else
{
if
(
con
->
os
==
con
->
optionStack
&&
opt
->
argInfo
&
POPT_ARGFLAG_STRIP
)
{
if
(
con
->
os
==
con
->
optionStack
&&
opt
->
argInfo
&
POPT_ARGFLAG_STRIP
)
{
canstrip
=
1
;
poptStripArg
(
con
,
thisopt
);
}
shorty
=
0
;
}
}
/* Process next short option */
/*@-branchstate@*/
/* FIX: W2DO? */
if
(
con
->
os
->
nextCharArg
)
{
origOptString
=
con
->
os
->
nextCharArg
;
con
->
os
->
nextCharArg
=
NULL
;
if
(
handleAlias
(
con
,
NULL
,
*
origOptString
,
origOptString
+
1
))
{
if
(
handleAlias
(
con
,
NULL
,
*
origOptString
,
origOptString
+
1
))
continue
;
if
(
handleExec
(
con
,
NULL
,
*
origOptString
))
{
/* Restore rest of short options for further processing */
origOptString
++
;
if
(
*
origOptString
!=
'\0'
)
con
->
os
->
nextCharArg
=
origOptString
;
continue
;
}
if
(
handleExec
(
con
,
NULL
,
*
origOptString
))
continue
;
opt
=
findOption
(
con
->
options
,
NULL
,
*
origOptString
,
&
cb
,
&
cbData
,
0
);
if
(
!
opt
)
return
POPT_ERROR_BADOPT
;
shorty
=
1
;
origOptString
++
;
if
(
*
origOptString
)
if
(
*
origOptString
!=
'\0'
)
con
->
os
->
nextCharArg
=
origOptString
;
}
/*@=branchstate@*/
if
(
opt
==
NULL
)
return
POPT_ERROR_BADOPT
;
/* XXX can't happen */
if
(
opt
->
arg
&&
(
opt
->
argInfo
&
POPT_ARG_MASK
)
==
POPT_ARG_NONE
)
{
*
((
int
*
)
opt
->
arg
)
=
1
;
if
(
poptSaveInt
(
opt
,
1L
))
return
POPT_ERROR_BADOPERATION
;
}
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
(
con
->
os
->
nextArg
)
{
xfree
(
con
->
os
->
nextArg
);
con
->
os
->
nextArg
=
NULL
;
if
(
opt
->
arg
)
{
if
(
poptSaveInt
(
opt
,
(
long
)
opt
->
val
))
return
POPT_ERROR_BADOPERATION
;
}
}
else
if
((
opt
->
argInfo
&
POPT_ARG_MASK
)
!=
POPT_ARG_NONE
)
{
con
->
os
->
nextArg
=
_free
(
con
->
os
->
nextArg
);
/*@-usedef@*/
/* FIX: W2DO? */
if
(
longArg
)
{
con
->
os
->
nextArg
=
expandNextArg
(
con
,
longArg
);
/*@=usedef@*/
longArg
=
expandNextArg
(
con
,
longArg
);
con
->
os
->
nextArg
=
longArg
;
}
else
if
(
con
->
os
->
nextCharArg
)
{
con
->
os
->
nextArg
=
expandNextArg
(
con
,
con
->
os
->
nextCharArg
);
longArg
=
expandNextArg
(
con
,
con
->
os
->
nextCharArg
);
con
->
os
->
nextArg
=
longArg
;
con
->
os
->
nextCharArg
=
NULL
;
}
else
{
while
(
con
->
os
->
next
==
con
->
os
->
argc
&&
con
->
os
>
con
->
optionStack
)
{
cleanOSE
(
con
->
os
--
);
}
if
(
con
->
os
->
next
==
con
->
os
->
argc
)
return
POPT_ERROR_NOARG
;
/* make sure this isn't part of a short arg or the
result of an alias expansion */
if
(
con
->
os
==
con
->
optionStack
&&
opt
->
argInfo
&
POPT_ARGFLAG_STRIP
&&
canstrip
)
{
poptStripArg
(
con
,
con
->
os
->
next
);
}
if
(
con
->
os
->
next
==
con
->
os
->
argc
)
{
if
(
!
(
opt
->
argInfo
&
POPT_ARGFLAG_OPTIONAL
))
/*@-compdef@*/
/* FIX: con->os->argv not defined */
return
POPT_ERROR_NOARG
;
/*@=compdef@*/
con
->
os
->
nextArg
=
NULL
;
}
else
{
/*
* Make sure this isn't part of a short arg or the
* result of an alias expansion.
*/
if
(
con
->
os
==
con
->
optionStack
&&
(
opt
->
argInfo
&
POPT_ARGFLAG_STRIP
)
&&
canstrip
)
{
poptStripArg
(
con
,
con
->
os
->
next
);
}
con
->
os
->
nextArg
=
expandNextArg
(
con
,
con
->
os
->
argv
[
con
->
os
->
next
++
]);
if
(
con
->
os
->
argv
!=
NULL
)
{
/* XXX can't happen */
/* XXX watchout: subtle side-effects live here. */
longArg
=
con
->
os
->
argv
[
con
->
os
->
next
++
];
longArg
=
expandNextArg
(
con
,
longArg
);
con
->
os
->
nextArg
=
longArg
;
}
}
}
longArg
=
NULL
;
if
(
opt
->
arg
)
{
long
aLong
;
char
*
end
;
switch
(
opt
->
argInfo
&
POPT_ARG_MASK
)
{
case
POPT_ARG_STRING
:
case
POPT_ARG_STRING
:
/* XXX memory leak, hard to plug */
*
((
const
char
**
)
opt
->
arg
)
=
xstrdup
(
con
->
os
->
nextArg
);
break
;
case
POPT_ARG_INT
:
case
POPT_ARG_LONG
:
aLong
=
strtol
(
con
->
os
->
nextArg
,
&
end
,
0
);
if
(
!
(
end
&&
*
end
==
'\0'
))
return
POPT_ERROR_BADNUMBER
;
*
((
const
char
**
)
opt
->
arg
)
=
(
con
->
os
->
nextArg
)
?
xstrdup
(
con
->
os
->
nextArg
)
:
NULL
;
/*@switchbreak@*/
break
;
case
POPT_ARG_INT
:
case
POPT_ARG_LONG
:
{
long
aLong
=
0
;
char
*
end
;
if
(
con
->
os
->
nextArg
)
{
aLong
=
strtol
(
con
->
os
->
nextArg
,
&
end
,
0
);
if
(
!
(
end
&&
*
end
==
'\0'
))
return
POPT_ERROR_BADNUMBER
;
}
if
(
aLong
==
LONG_MIN
||
aLong
==
LONG_MAX
)
return
POPT_ERROR_OVERFLOW
;
if
((
opt
->
argInfo
&
POPT_ARG_MASK
)
==
POPT_ARG_LONG
)
{
*
((
long
*
)
opt
->
arg
)
=
aLong
;
if
(
aLong
==
LONG_MIN
||
aLong
==
LONG_MAX
)
return
POPT_ERROR_OVERFLOW
;
if
(
poptSaveLong
(
opt
,
aLong
))
return
POPT_ERROR_BADOPERATION
;
}
else
{
if
(
aLong
>
INT_MAX
||
aLong
<
INT_MIN
)
return
POPT_ERROR_OVERFLOW
;
*
((
int
*
)
opt
->
arg
)
=
aLong
;
if
(
poptSaveInt
(
opt
,
aLong
))
return
POPT_ERROR_BADOPERATION
;
}
}
/*@switchbreak@*/
break
;
case
POPT_ARG_FLOAT
:
case
POPT_ARG_DOUBLE
:
{
double
aDouble
=
0
.
0
;
char
*
end
;
if
(
con
->
os
->
nextArg
)
{
/*@-mods@*/
int
saveerrno
=
errno
;
errno
=
0
;
aDouble
=
strtod
(
con
->
os
->
nextArg
,
&
end
);
if
(
errno
==
ERANGE
)
return
POPT_ERROR_OVERFLOW
;
errno
=
saveerrno
;
/*@=mods@*/
if
(
*
end
!=
'\0'
)
return
POPT_ERROR_BADNUMBER
;
}
break
;
default
:
fprintf
(
stdout
,
POPT_
(
"option type (%d) not implemented in popt
\n
"
),
opt
->
argInfo
&
POPT_ARG_MASK
);
if
((
opt
->
argInfo
&
POPT_ARG_MASK
)
==
POPT_ARG_DOUBLE
)
{
*
((
double
*
)
opt
->
arg
)
=
aDouble
;
}
else
{
#define _ABS(a) ((((a) - 0.0) < DBL_EPSILON) ? -(a) : (a))
if
((
_ABS
(
aDouble
)
-
FLT_MAX
)
>
DBL_EPSILON
)
return
POPT_ERROR_OVERFLOW
;
if
((
FLT_MIN
-
_ABS
(
aDouble
))
>
DBL_EPSILON
)
return
POPT_ERROR_OVERFLOW
;
*
((
float
*
)
opt
->
arg
)
=
aDouble
;
}
}
/*@switchbreak@*/
break
;
default
:
fprintf
(
stdout
,
POPT_
(
"option type (%d) not implemented in popt
\n
"
),
(
opt
->
argInfo
&
POPT_ARG_MASK
));
exit
(
EXIT_FAILURE
);
/*@notreached@*/
/*@switchbreak@*/
break
;
}
}
}
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
))
if
(
cb
)
{
/*@-internalglobs@*/
invokeCallbacksOPTION
(
con
,
con
->
options
,
opt
,
cbData
,
shorty
);
/*@=internalglobs@*/
}
else
if
(
opt
->
val
&&
((
opt
->
argInfo
&
POPT_ARG_MASK
)
!=
POPT_ARG_VAL
))
done
=
1
;
if
((
con
->
finalArgvCount
+
2
)
>=
(
con
->
finalArgvAlloced
))
{
...
...
@@ -599,131 +935,217 @@ int poptGetNextOpt(poptContext con)
sizeof
(
*
con
->
finalArgv
)
*
con
->
finalArgvAlloced
);
}
{
char
*
s
=
malloc
((
opt
->
longName
?
strlen
(
opt
->
longName
)
:
0
)
+
3
);
if
(
opt
->
longName
)
sprintf
(
s
,
"--%s"
,
opt
->
longName
);
else
sprintf
(
s
,
"-%c"
,
opt
->
shortName
);
con
->
finalArgv
[
con
->
finalArgvCount
++
]
=
s
;
if
(
con
->
finalArgv
!=
NULL
)
{
char
*
s
=
malloc
((
opt
->
longName
?
strlen
(
opt
->
longName
)
:
0
)
+
3
);
if
(
s
!=
NULL
)
{
/* XXX can't happen */
if
(
opt
->
longName
)
sprintf
(
s
,
"%s%s"
,
((
opt
->
argInfo
&
POPT_ARGFLAG_ONEDASH
)
?
"-"
:
"--"
),
opt
->
longName
);
else
sprintf
(
s
,
"-%c"
,
opt
->
shortName
);
con
->
finalArgv
[
con
->
finalArgvCount
++
]
=
s
;
}
else
con
->
finalArgv
[
con
->
finalArgvCount
++
]
=
NULL
;
}
if
(
opt
->
arg
&&
(
opt
->
argInfo
&
POPT_ARG_MASK
)
!=
POPT_ARG_NONE
&&
(
opt
->
argInfo
&
POPT_ARG_MASK
)
!=
POPT_ARG_VAL
)
{
con
->
finalArgv
[
con
->
finalArgvCount
++
]
=
xstrdup
(
con
->
os
->
nextArg
);
if
(
opt
->
arg
&&
(
opt
->
argInfo
&
POPT_ARG_MASK
)
==
POPT_ARG_NONE
)
/*@-ifempty@*/
;
/*@=ifempty@*/
else
if
((
opt
->
argInfo
&
POPT_ARG_MASK
)
==
POPT_ARG_VAL
)
/*@-ifempty@*/
;
/*@=ifempty@*/
else
if
((
opt
->
argInfo
&
POPT_ARG_MASK
)
!=
POPT_ARG_NONE
)
{
if
(
con
->
finalArgv
!=
NULL
&&
con
->
os
->
nextArg
)
con
->
finalArgv
[
con
->
finalArgvCount
++
]
=
/*@-nullpass@*/
/* LCL: con->os->nextArg != NULL */
xstrdup
(
con
->
os
->
nextArg
);
/*@=nullpass@*/
}
}
return
opt
->
val
;
return
(
opt
?
opt
->
val
:
-
1
);
/* XXX can't happen */
}
const
char
*
poptGetOptArg
(
poptContext
con
)
{
const
char
*
ret
=
con
->
os
->
nextArg
;
con
->
os
->
nextArg
=
NULL
;
const
char
*
poptGetOptArg
(
poptContext
con
)
{
const
char
*
ret
=
NULL
;
/*@-branchstate@*/
if
(
con
)
{
ret
=
con
->
os
->
nextArg
;
con
->
os
->
nextArg
=
NULL
;
}
/*@=branchstate@*/
return
ret
;
}
const
char
*
poptGetArg
(
poptContext
con
)
{
if
(
con
->
numLeftovers
==
con
->
nextLeftover
)
return
NULL
;
return
con
->
leftovers
[
con
->
nextLeftover
++
];
const
char
*
poptGetArg
(
poptContext
con
)
{
const
char
*
ret
=
NULL
;
if
(
con
&&
con
->
leftovers
!=
NULL
&&
con
->
nextLeftover
<
con
->
numLeftovers
)
ret
=
con
->
leftovers
[
con
->
nextLeftover
++
];
return
ret
;
}
const
char
*
poptPeekArg
(
poptContext
con
)
{
if
(
con
->
numLeftovers
==
con
->
nextLeftover
)
return
NULL
;
return
con
->
leftovers
[
con
->
nextLeftover
];
const
char
*
poptPeekArg
(
poptContext
con
)
{
const
char
*
ret
=
NULL
;
if
(
con
&&
con
->
leftovers
!=
NULL
&&
con
->
nextLeftover
<
con
->
numLeftovers
)
ret
=
con
->
leftovers
[
con
->
nextLeftover
];
return
ret
;
}
const
char
**
poptGetArgs
(
poptContext
con
)
{
if
(
con
->
numLeftovers
==
con
->
nextLeftover
)
return
NULL
;
const
char
**
poptGetArgs
(
poptContext
con
)
{
if
(
con
==
NULL
||
con
->
leftovers
==
NULL
||
con
->
numLeftovers
==
con
->
nextLeftover
)
return
NULL
;
/* some apps like [like RPM ;-) ] need this NULL terminated */
con
->
leftovers
[
con
->
numLeftovers
]
=
NULL
;
/*@-nullret -nullstate @*/
/* FIX: typedef double indirection. */
return
(
con
->
leftovers
+
con
->
nextLeftover
);
/*@=nullret =nullstate @*/
}
void
poptFreeContext
(
poptContext
con
)
{
poptContext
poptFreeContext
(
poptContext
con
)
{
poptItem
item
;
int
i
;
if
(
con
==
NULL
)
return
con
;
poptResetContext
(
con
);
if
(
con
->
os
->
argb
)
free
(
con
->
os
->
argb
);
con
->
os
->
argb
=
_
free
(
con
->
os
->
argb
);
if
(
con
->
aliases
!=
NULL
)
for
(
i
=
0
;
i
<
con
->
numAliases
;
i
++
)
{
if
(
con
->
aliases
[
i
].
longName
)
xfree
(
con
->
aliases
[
i
].
longName
);
free
(
con
->
aliases
[
i
].
argv
);
item
=
con
->
aliases
+
i
;
/*@-modobserver -observertrans -dependenttrans@*/
item
->
option
.
longName
=
_free
(
item
->
option
.
longName
);
item
->
option
.
descrip
=
_free
(
item
->
option
.
descrip
);
item
->
option
.
argDescrip
=
_free
(
item
->
option
.
argDescrip
);
/*@=modobserver =observertrans =dependenttrans@*/
item
->
argv
=
_free
(
item
->
argv
);
}
con
->
aliases
=
_free
(
con
->
aliases
);
if
(
con
->
execs
!=
NULL
)
for
(
i
=
0
;
i
<
con
->
numExecs
;
i
++
)
{
if
(
con
->
execs
[
i
].
longName
)
xfree
(
con
->
execs
[
i
].
longName
);
xfree
(
con
->
execs
[
i
].
script
);
item
=
con
->
execs
+
i
;
/*@-modobserver -observertrans -dependenttrans@*/
item
->
option
.
longName
=
_free
(
item
->
option
.
longName
);
item
->
option
.
descrip
=
_free
(
item
->
option
.
descrip
);
item
->
option
.
argDescrip
=
_free
(
item
->
option
.
argDescrip
);
/*@=modobserver =observertrans =dependenttrans@*/
item
->
argv
=
_free
(
item
->
argv
);
}
if
(
con
->
execs
)
xfree
(
con
->
execs
);
free
(
con
->
leftovers
);
free
(
con
->
finalArgv
);
if
(
con
->
appName
)
xfree
(
con
->
appName
);
if
(
con
->
aliases
)
free
(
con
->
aliases
);
if
(
con
->
otherHelp
)
xfree
(
con
->
otherHelp
);
if
(
con
->
execPath
)
xfree
(
con
->
execPath
);
if
(
con
->
arg_strip
)
PBM_FREE
(
con
->
arg_strip
);
con
->
execs
=
_free
(
con
->
execs
);
con
->
leftovers
=
_free
(
con
->
leftovers
);
con
->
finalArgv
=
_free
(
con
->
finalArgv
);
con
->
appName
=
_free
(
con
->
appName
);
con
->
otherHelp
=
_free
(
con
->
otherHelp
);
con
->
execPath
=
_free
(
con
->
execPath
);
con
->
arg_strip
=
PBM_FREE
(
con
->
arg_strip
);
free
(
con
);
con
=
_free
(
con
);
return
con
;
}
int
poptAddAlias
(
poptContext
con
,
struct
poptAlias
newA
lias
,
int
poptAddAlias
(
poptContext
con
,
struct
poptAlias
a
lias
,
/*@unused@*/
int
flags
)
{
int
aliasNum
=
con
->
numAliases
++
;
struct
poptAlias
*
alias
;
poptItem
item
=
alloca
(
sizeof
(
*
item
));
memset
(
item
,
0
,
sizeof
(
*
item
));
item
->
option
.
longName
=
alias
.
longName
;
item
->
option
.
shortName
=
alias
.
shortName
;
item
->
option
.
argInfo
=
POPT_ARGFLAG_DOC_HIDDEN
;
item
->
option
.
arg
=
0
;
item
->
option
.
val
=
0
;
item
->
option
.
descrip
=
NULL
;
item
->
option
.
argDescrip
=
NULL
;
item
->
argc
=
alias
.
argc
;
item
->
argv
=
alias
.
argv
;
return
poptAddItem
(
con
,
item
,
0
);
}
/* 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
;
/*@-mustmod@*/
/* LCL: con not modified? */
int
poptAddItem
(
poptContext
con
,
poptItem
newItem
,
int
flags
)
{
poptItem
*
items
,
item
;
int
*
nitems
;
switch
(
flags
)
{
case
1
:
items
=
&
con
->
execs
;
nitems
=
&
con
->
numExecs
;
break
;
case
0
:
items
=
&
con
->
aliases
;
nitems
=
&
con
->
numAliases
;
break
;
default
:
return
1
;
/*@notreached@*/
break
;
}
*
items
=
realloc
((
*
items
),
((
*
nitems
)
+
1
)
*
sizeof
(
**
items
));
if
((
*
items
)
==
NULL
)
return
1
;
item
=
(
*
items
)
+
(
*
nitems
);
alias
->
longName
=
(
newAlias
.
longName
)
?
strcpy
(
malloc
(
strlen
(
newAlias
.
longName
)
+
1
),
newAlias
.
longName
)
:
NULL
;
alias
->
shortName
=
newAlias
.
shortName
;
alias
->
argc
=
newAlias
.
argc
;
alias
->
argv
=
newAlias
.
argv
;
item
->
option
.
longName
=
(
newItem
->
option
.
longName
?
xstrdup
(
newItem
->
option
.
longName
)
:
NULL
);
item
->
option
.
shortName
=
newItem
->
option
.
shortName
;
item
->
option
.
argInfo
=
newItem
->
option
.
argInfo
;
item
->
option
.
arg
=
newItem
->
option
.
arg
;
item
->
option
.
val
=
newItem
->
option
.
val
;
item
->
option
.
descrip
=
(
newItem
->
option
.
descrip
?
xstrdup
(
newItem
->
option
.
descrip
)
:
NULL
);
item
->
option
.
argDescrip
=
(
newItem
->
option
.
argDescrip
?
xstrdup
(
newItem
->
option
.
argDescrip
)
:
NULL
);
item
->
argc
=
newItem
->
argc
;
item
->
argv
=
newItem
->
argv
;
(
*
nitems
)
++
;
return
0
;
}
/*@=mustmod@*/
const
char
*
poptBadOption
(
poptContext
con
,
int
flags
)
{
struct
optionStackEntry
*
os
;
const
char
*
poptBadOption
(
poptContext
con
,
int
flags
)
{
struct
optionStackEntry
*
os
=
NULL
;
if
(
flags
&
POPT_BADOPTION_NOALIAS
)
os
=
con
->
optionStack
;
else
os
=
con
->
os
;
if
(
con
!=
NULL
)
os
=
(
flags
&
POPT_BADOPTION_NOALIAS
)
?
con
->
optionStack
:
con
->
os
;
return
os
->
argv
[
os
->
next
-
1
];
/*@-nullderef@*/
/* LCL: os->argv != NULL */
return
(
os
&&
os
->
argv
?
os
->
argv
[
os
->
next
-
1
]
:
NULL
);
/*@=nullderef@*/
}
#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
*
const
poptStrerror
(
const
int
error
)
{
const
char
*
const
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_BADOPERATION
:
return
POPT_
(
"mutually exclusive logical operations requested"
);
case
POPT_ERROR_NULLARG
:
return
POPT_
(
"opt->arg should not be NULL"
);
case
POPT_ERROR_OPTSTOODEEP
:
return
POPT_
(
"aliases nested too deeply"
);
case
POPT_ERROR_BADQUOTE
:
return
POPT_
(
"error in paramter quoting"
);
return
POPT_
(
"error in param
e
ter 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_MALLOC
:
return
POPT_
(
"memory allocation failed"
);
case
POPT_ERROR_ERRNO
:
return
strerror
(
errno
);
default
:
...
...
@@ -731,52 +1153,54 @@ const char *const poptStrerror(const int error) {
}
}
int
poptStuffArgs
(
poptContext
con
,
const
char
**
argv
)
{
int
poptStuffArgs
(
poptContext
con
,
const
char
**
argv
)
{
int
argc
;
int
rc
;
if
((
con
->
os
-
con
->
optionStack
)
==
POPT_OPTION_DEPTH
)
return
POPT_ERROR_OPTSTOODEEP
;
for
(
argc
=
0
;
argv
[
argc
];
argc
++
)
;
{}
;
con
->
os
++
;
con
->
os
->
next
=
0
;
con
->
os
->
nextArg
=
NULL
;
con
->
os
->
nextCharArg
=
NULL
;
con
->
os
->
currAlias
=
NULL
;
poptDupArgv
(
argc
,
argv
,
&
con
->
os
->
argc
,
&
con
->
os
->
argv
);
rc
=
poptDupArgv
(
argc
,
argv
,
&
con
->
os
->
argc
,
&
con
->
os
->
argv
);
con
->
os
->
argb
=
NULL
;
con
->
os
->
stuffed
=
1
;
return
0
;
return
rc
;
}
const
char
*
poptGetInvocationName
(
poptContext
con
)
{
return
con
->
os
->
argv
[
0
];
const
char
*
poptGetInvocationName
(
poptContext
con
)
{
return
(
con
->
os
->
argv
?
con
->
os
->
argv
[
0
]
:
""
);
}
int
poptStrippedArgv
(
poptContext
con
,
int
argc
,
char
**
argv
)
int
poptStrippedArgv
(
poptContext
con
,
int
argc
,
char
**
argv
)
{
int
i
,
j
=
1
,
numargs
=
argc
;
int
numargs
=
argc
;
int
j
=
1
;
int
i
;
for
(
i
=
1
;
i
<
argc
;
i
++
)
{
if
(
PBM_ISSET
(
i
,
con
->
arg_strip
))
{
/*@-sizeoftype@*/
if
(
con
->
arg_strip
)
for
(
i
=
1
;
i
<
argc
;
i
++
)
{
if
(
PBM_ISSET
(
i
,
con
->
arg_strip
))
numargs
--
;
}
}
for
(
i
=
1
;
i
<
argc
;
i
++
)
{
if
(
PBM_ISSET
(
i
,
con
->
arg_strip
))
{
for
(
i
=
1
;
i
<
argc
;
i
++
)
{
if
(
con
->
arg_strip
&&
PBM_ISSET
(
i
,
con
->
arg_strip
))
continue
;
}
else
{
if
(
j
<
numargs
)
{
argv
[
j
++
]
=
argv
[
i
];
}
else
{
argv
[
j
++
]
=
'\0'
;
}
}
argv
[
j
]
=
(
j
<
numargs
)
?
argv
[
i
]
:
NULL
;
j
++
;
}
/*@=sizeoftype@*/
return
(
numargs
)
;
return
numargs
;
}
popt/popt.h
View file @
cc248aae
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
/** \file popt/popt.h
* \ingroup popt
*/
/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
file accompanying popt source distributions, available from
ftp://ftp.r
edhat.com/pub/code/popt
*/
ftp://ftp.r
pm.org/pub/rpm/dist.
*/
#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
/** \ingroup popt
* \name Arg type identifiers
*/
/*@{*/
#define POPT_ARG_NONE 0
/*!< no arg */
#define POPT_ARG_STRING 1
/*!< arg will be saved as string */
#define POPT_ARG_INT 2
/*!< arg will be converted to int */
#define POPT_ARG_LONG 3
/*!< arg will be converted to long */
#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
#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_VAL 7
/*!< arg should take value val */
#define POPT_ARG_FLOAT 8
/*!< arg will be converted to float */
#define POPT_ARG_DOUBLE 9
/*!< arg will be converted to double */
#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_ARGFLAG_STRIP 0x20000000
/* strip this arg from argv (only applies to long args) */
#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,
/*@}*/
/** \ingroup popt
* \name Arg modifiers
*/
/*@{*/
#define POPT_ARGFLAG_ONEDASH 0x80000000
/*!< allow -longoption */
#define POPT_ARGFLAG_DOC_HIDDEN 0x40000000
/*!< don't show in help/usage */
#define POPT_ARGFLAG_STRIP 0x20000000
/*!< strip this arg from argv(only applies to long args) */
#define POPT_ARGFLAG_OPTIONAL 0x10000000
/*!< arg may be missing */
#define POPT_ARGFLAG_OR 0x08000000
/*!< arg will be or'ed */
#define POPT_ARGFLAG_NOR 0x09000000
/*!< arg will be nor'ed */
#define POPT_ARGFLAG_AND 0x04000000
/*!< arg will be and'ed */
#define POPT_ARGFLAG_NAND 0x05000000
/*!< arg will be nand'ed */
#define POPT_ARGFLAG_XOR 0x02000000
/*!< arg will be xor'ed */
#define POPT_ARGFLAG_NOT 0x01000000
/*!< arg will be negated */
#define POPT_ARGFLAG_LOGICALOPS \
(POPT_ARGFLAG_OR|POPT_ARGFLAG_AND|POPT_ARGFLAG_XOR)
#define POPT_BIT_SET (POPT_ARG_VAL|POPT_ARGFLAG_OR)
/*!< set arg bit(s) */
#define POPT_BIT_CLR (POPT_ARG_VAL|POPT_ARGFLAG_NAND)
/*!< clear arg bit(s) */
#define POPT_ARGFLAG_SHOW_DEFAULT 0x00800000
/*!< show default value in --help */
/*@}*/
/** \ingroup popt
* \name Callback modifiers
*/
/*@{*/
#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_CBFLAG_SKIPOPTION 0x10000000
/*!< don't callback with option */
#define POPT_CBFLAG_CONTINUE 0x08000000
/*!< continue callbacks with option */
/*@}*/
#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
/** \ingroup popt
* \name Error return values
*/
/*@{*/
#define POPT_ERROR_NOARG -10
/*!< missing argument */
#define POPT_ERROR_BADOPT -11
/*!< unknown option */
#define POPT_ERROR_OPTSTOODEEP -13
/*!< aliases nested too deeply */
#define POPT_ERROR_BADQUOTE -15
/*!< error in paramter quoting */
#define POPT_ERROR_ERRNO -16
/*!< errno set, use strerror(errno) */
#define POPT_ERROR_BADNUMBER -17
/*!< invalid numeric value */
#define POPT_ERROR_OVERFLOW -18
/*!< number too large or too small */
#define POPT_ERROR_BADOPERATION -19
/*!< mutually exclusive logical operations requested */
#define POPT_ERROR_NULLARG -20
/*!< opt->arg should not be NULL */
#define POPT_ERROR_MALLOC -21
/*!< memory allocation failed */
/*@}*/
/* poptBadOption() flags */
#define POPT_BADOPTION_NOALIAS (1 << 0)
/* don't go into an alias */
/** \ingroup popt
* \name 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 */
/** \ingroup popt
* \name 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 */
#define POPT_CONTEXT_ARG_OPTS (1 << 4)
/*!< return args as options with value 0 */
/*@}*/
/** \ingroup popt
*/
struct
poptOption
{
/*@observer@*/
/*@null@*/
const
char
*
longName
;
/*
may be NULL */
char
shortName
;
/*
may be '\0' */
/*@observer@*/
/*@null@*/
const
char
*
longName
;
/*!<
may be NULL */
char
shortName
;
/*!<
may be '\0' */
int
argInfo
;
/*@shared@*/
/*@null@*/
void
*
arg
;
/*
depends on argInfo */
int
val
;
/* 0 means don't return, just update flag */
/*@shared@*/
/*@null@*/
const
char
*
descrip
;
/*
description for autohelp -- may be NULL */
/*@shared@*/
/*@null@*/
const
char
*
argDescrip
;
/*
argument description for autohelp */
/*@shared@*/
/*@null@*/
void
*
arg
;
/*!<
depends on argInfo */
int
val
;
/*
!<
0 means don't return, just update flag */
/*@observer@*/
/*@null@*/
const
char
*
descrip
;
/*!<
description for autohelp -- may be NULL */
/*@observer@*/
/*@null@*/
const
char
*
argDescrip
;
/*!<
argument description for autohelp */
};
/** \ingroup popt
* A popt alias argument for poptAddAlias().
*/
struct
poptAlias
{
/*@owned@*/
/*@null@*/
const
char
*
longName
;
/*
may be NULL */
char
shortName
;
/* may be '\0' */
/*@owned@*/
/*@null@*/
const
char
*
longName
;
/*!<
may be NULL */
char
shortName
;
/*
!<
may be '\0' */
int
argc
;
/*@owned@*/
const
char
**
argv
;
/*
must be free()able */
/*@owned@*/
const
char
**
argv
;
/*!<
must be free()able */
};
/** \ingroup popt
* A popt alias or exec argument for poptAddItem().
*/
typedef
struct
poptItem_s
{
struct
poptOption
option
;
/*!< alias/exec name(s) and description. */
int
argc
;
/*!< (alias) no. of args. */
/*@owned@*/
const
char
**
argv
;
/*!< (alias) args, must be free()able. */
}
*
poptItem
;
/** \ingroup popt
* \name Auto-generated help/usage
*/
/*@{*/
/**
* Empty table marker to enable displaying popt alias/exec options.
*/
/*@observer@*/
/*@checked@*/
extern
struct
poptOption
poptAliasOptions
[];
#define POPT_AUTOALIAS { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptAliasOptions, \
0, "Options implemented via popt alias/exec:", NULL },
/**
* Auto help table options.
*/
/*@observer@*/
/*@checked@*/
extern
struct
poptOption
poptHelpOptions
[];
#define POPT_AUTOHELP { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptHelpOptions, \
0, "Help options", NULL },
0, "Help options
:
", NULL },
typedef
struct
poptContext_s
*
poptContext
;
#define POPT_TABLEEND { NULL, '\0', 0, 0, 0, NULL, NULL }
/*@}*/
/** \ingroup popt
*/
typedef
/*@abstract@*/
struct
poptContext_s
*
poptContext
;
/** \ingroup popt
*/
#ifndef __cplusplus
/*@-typeuse@*/
typedef
struct
poptOption
*
poptOption
;
/*@=typeuse@*/
#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
,
const
void
*
data
);
/*@only@*/
poptContext
poptGetContext
(
/*@keep@*/
const
char
*
name
,
int
argc
,
/*@keep@*/
const
char
**
argv
,
/*@keep@*/
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 */
/*@observer@*/
/*@null@*/
const
char
*
poptGetOptArg
(
poptContext
con
);
/* returns NULL if no more options are available */
/*@observer@*/
/*@null@*/
const
char
*
poptGetArg
(
poptContext
con
);
/*@observer@*/
/*@null@*/
const
char
*
poptPeekArg
(
poptContext
con
);
/*@observer@*/
/*@null@*/
const
char
**
poptGetArgs
(
poptContext
con
);
/* returns the option which caused the most recent error */
/*@observer@*/
const
char
*
poptBadOption
(
poptContext
con
,
int
flags
);
void
poptFreeContext
(
/*@only@*/
poptContext
con
);
int
poptStuffArgs
(
poptContext
con
,
/*@keep@*/
const
char
**
argv
);
int
poptAddAlias
(
poptContext
con
,
struct
poptAlias
alias
,
int
flags
);
int
poptReadConfigFile
(
poptContext
con
,
const
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
poptDupArgv
(
int
argc
,
const
char
**
argv
,
/*@out@*/
int
*
argcPtr
,
/*@out@*/
const
char
***
argvPtr
);
#ifdef __cplusplus
extern
"C"
{
#endif
/*@-type@*/
/** \ingroup popt
* Table callback prototype.
* @param con context
* @param reason reason for callback
* @param opt option that triggered callback
* @param arg @todo Document.
* @param data @todo Document.
*/
typedef
void
(
*
poptCallbackType
)
(
poptContext
con
,
enum
poptCallbackReason
reason
,
/*@null@*/
const
struct
poptOption
*
opt
,
/*@null@*/
const
char
*
arg
,
/*@null@*/
const
void
*
data
)
/*@*/
;
/** \ingroup popt
* Initialize popt context.
* @param name
* @param argc no. of arguments
* @param argv argument array
* @param options address of popt option table
* @param flags or'd POPT_CONTEXT_* bits
* @return initialized popt context
*/
/*@only@*/
/*@null@*/
poptContext
poptGetContext
(
/*@dependent@*/
/*@keep@*/
const
char
*
name
,
int
argc
,
/*@dependent@*/
/*@keep@*/
const
char
**
argv
,
/*@dependent@*/
/*@keep@*/
const
struct
poptOption
*
options
,
int
flags
)
/*@*/
;
/** \ingroup popt
* Reinitialize popt context.
* @param con context
*/
void
poptResetContext
(
/*@null@*/
poptContext
con
)
/*@modifies con @*/
;
/** \ingroup popt
* Return value of next option found.
* @param con context
* @return next option val, -1 on last item, POPT_ERROR_* on error
*/
int
poptGetNextOpt
(
/*@null@*/
poptContext
con
)
/*@globals fileSystem@*/
/*@modifies con, fileSystem @*/
;
/*@-redecl@*/
/** \ingroup popt
* Return next option argument (if any).
* @param con context
* @return option argument, NULL if no more options are available
*/
/*@observer@*/
/*@null@*/
const
char
*
poptGetOptArg
(
/*@null@*/
poptContext
con
)
/*@modifies con @*/
;
/** \ingroup popt
* Return current option's argument.
* @param con context
* @return option argument, NULL if no more options are available
*/
/*@observer@*/
/*@null@*/
const
char
*
poptGetArg
(
/*@null@*/
poptContext
con
)
/*@modifies con @*/
;
/** \ingroup popt
* Peek at current option's argument.
* @param con context
* @return option argument
*/
/*@observer@*/
/*@null@*/
const
char
*
poptPeekArg
(
/*@null@*/
poptContext
con
)
/*@*/
;
/** \ingroup popt
* Return remaining arguments.
* @param con context
* @return argument array, terminated with NULL
*/
/*@observer@*/
/*@null@*/
const
char
**
poptGetArgs
(
/*@null@*/
poptContext
con
)
/*@modifies con @*/
;
/** \ingroup popt
* Return the option which caused the most recent error.
* @param con context
* @return offending option
*/
/*@observer@*/
const
char
*
poptBadOption
(
/*@null@*/
poptContext
con
,
int
flags
)
/*@*/
;
/*@=redecl@*/
/** \ingroup popt
* Destroy context.
* @param con context
* @return NULL always
*/
/*@null@*/
poptContext
poptFreeContext
(
/*@only@*/
/*@null@*/
poptContext
con
)
/*@modifies con @*/
;
/** \ingroup popt
* Add arguments to context.
* @param con context
* @param argv argument array, NULL terminated
* @return 0 on success, POPT_ERROR_OPTSTOODEEP on failure
*/
int
poptStuffArgs
(
poptContext
con
,
/*@keep@*/
const
char
**
argv
)
/*@modifies con @*/
;
/** \ingroup popt
* Add alias to context.
* @todo Pass alias by reference, not value.
* @deprecated Use poptAddItem instead.
* @param con context
* @param alias alias to add
* @param flags (unused)
* @return 0 on success
*/
/*@unused@*/
int
poptAddAlias
(
poptContext
con
,
struct
poptAlias
alias
,
int
flags
)
/*@modifies con @*/
;
/** \ingroup popt
* Add alias/exec item to context.
* @param con context
* @param item alias/exec item to add
* @param flags 0 for alias, 1 for exec
* @return 0 on success
*/
int
poptAddItem
(
poptContext
con
,
poptItem
newItem
,
int
flags
)
/*@modifies con @*/
;
/** \ingroup popt
* Read configuration file.
* @param con context
* @param fn file name to read
* @return 0 on success, POPT_ERROR_ERRNO on failure
*/
int
poptReadConfigFile
(
poptContext
con
,
const
char
*
fn
)
/*@globals fileSystem@*/
/*@modifies fileSystem,
con->execs, con->numExecs @*/
;
/** \ingroup popt
* Read default configuration from /etc/popt and $HOME/.popt.
* @param con context
* @param useEnv (unused)
* @return 0 on success, POPT_ERROR_ERRNO on failure
*/
int
poptReadDefaultConfig
(
poptContext
con
,
/*@unused@*/
int
useEnv
)
/*@globals fileSystem@*/
/*@modifies fileSystem,
con->execs, con->numExecs @*/
;
/** \ingroup popt
* Duplicate an argument array.
* @note: The argument array is malloc'd as a single area, so only argv must
* be free'd.
*
* @param argc no. of arguments
* @param argv argument array
* @retval argcPtr address of returned no. of arguments
* @retval argvPtr address of returned argument array
* @return 0 on success, POPT_ERROR_NOARG on failure
*/
int
poptDupArgv
(
int
argc
,
/*@null@*/
const
char
**
argv
,
/*@null@*/
/*@out@*/
int
*
argcPtr
,
/*@null@*/
/*@out@*/
const
char
***
argvPtr
)
/*@modifies *argcPtr, *argvPtr @*/
;
/** \ingroup popt
* Parse a string into an argument array.
* The parse allows ', ", and \ quoting, but ' is treated the same as " and
* both may include \ quotes.
* @note: The argument array is malloc'd as a single area, so only argv must
* be free'd.
*
* @param s string to parse
* @retval argcPtr address of returned no. of arguments
* @retval argvPtr address of returned argument array
*/
int
poptParseArgvString
(
const
char
*
s
,
/*@out@*/
int
*
argcPtr
,
/*@out@*/
const
char
***
argvPtr
);
/*@observer@*/
const
char
*
const
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
);
/*@observer@*/
const
char
*
poptGetInvocationName
(
poptContext
con
);
/* shuffles argv pointers to remove stripped args, returns new argc */
int
poptStrippedArgv
(
poptContext
con
,
int
argc
,
char
**
argv
);
/*@out@*/
int
*
argcPtr
,
/*@out@*/
const
char
***
argvPtr
)
/*@modifies *argcPtr, *argvPtr @*/
;
/** \ingroup popt
* Return formatted error string for popt failure.
* @param error popt error
* @return error string
*/
/*@-redecl@*/
/*@observer@*/
const
char
*
const
poptStrerror
(
const
int
error
)
/*@*/
;
/*@=redecl@*/
/** \ingroup popt
* Limit search for executables.
* @param con context
* @param path single path to search for executables
* @param allowAbsolute absolute paths only?
*/
void
poptSetExecPath
(
poptContext
con
,
const
char
*
path
,
int
allowAbsolute
)
/*@modifies con @*/
;
/** \ingroup popt
* Print detailed description of options.
* @param con context
* @param fp ouput file handle
* @param flags (unused)
*/
void
poptPrintHelp
(
poptContext
con
,
FILE
*
fp
,
/*@unused@*/
int
flags
)
/*@globals fileSystem @*/
/*@modifies *fp, fileSystem @*/
;
/** \ingroup popt
* Print terse description of options.
* @param con context
* @param fp ouput file handle
* @param flags (unused)
*/
void
poptPrintUsage
(
poptContext
con
,
FILE
*
fp
,
/*@unused@*/
int
flags
)
/*@globals fileSystem @*/
/*@modifies *fp, fileSystem @*/
;
/** \ingroup popt
* Provide text to replace default "[OPTION...]" in help/usage output.
* @param con context
* @param text replacement text
*/
/*@-fcnuse@*/
void
poptSetOtherOptionHelp
(
poptContext
con
,
const
char
*
text
)
/*@modifies con @*/
;
/*@=fcnuse@*/
/** \ingroup popt
* Return argv[0] from context.
* @param con context
* @return argv[0]
*/
/*@-redecl -fcnuse@*/
/*@observer@*/
const
char
*
poptGetInvocationName
(
poptContext
con
)
/*@*/
;
/*@=redecl =fcnuse@*/
/** \ingroup popt
* Shuffle argv pointers to remove stripped args, returns new argc.
* @param con context
* @param argc no. of args
* @param argv arg vector
* @return new argc
*/
/*@-fcnuse@*/
int
poptStrippedArgv
(
poptContext
con
,
int
argc
,
char
**
argv
)
/*@modifies *argv @*/
;
/*@=fcnuse@*/
/*@=type@*/
#ifdef __cplusplus
}
#endif
...
...
popt/poptconfig.c
View file @
cc248aae
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
/** \ingroup popt
* \file popt/poptconfig.c
*/
/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
file accompanying popt source distributions, available from
ftp://ftp.r
edhat.com/pub/code/popt
*/
ftp://ftp.r
pm.org/pub/rpm/dist.
*/
#include "system.h"
#include "poptint.h"
static
void
configLine
(
poptContext
con
,
char
*
line
)
{
/*@-compmempass@*/
/* FIX: item->option.longName kept, not dependent. */
static
void
configLine
(
poptContext
con
,
char
*
line
)
/*@modifies con @*/
{
/*@-type@*/
int
nameLength
=
strlen
(
con
->
appName
);
char
*
opt
;
struct
poptAlias
alias
;
c
har
*
entryType
;
char
*
longName
=
NULL
;
char
shortName
=
'\0'
;
/*@=type@*/
const
char
*
entryType
;
c
onst
char
*
opt
;
poptItem
item
=
alloca
(
sizeof
(
*
item
))
;
int
i
,
j
;
memset
(
item
,
0
,
sizeof
(
*
item
));
/*@-type@*/
if
(
strncmp
(
line
,
con
->
appName
,
nameLength
))
return
;
/*@=type@*/
line
+=
nameLength
;
if
(
!*
line
||
!
isspace
(
*
line
))
return
;
while
(
*
line
&&
isspace
(
*
line
))
line
++
;
entryType
=
line
;
if
(
*
line
==
'\0'
||
!
isspace
(
*
line
))
return
;
while
(
!*
line
||
!
isspace
(
*
line
))
line
++
;
while
(
*
line
!=
'\0'
&&
isspace
(
*
line
))
line
++
;
entryType
=
line
;
while
(
*
line
==
'\0'
||
!
isspace
(
*
line
))
line
++
;
*
line
++
=
'\0'
;
while
(
*
line
&&
isspace
(
*
line
))
line
++
;
if
(
!*
line
)
return
;
opt
=
line
;
while
(
!*
line
||
!
isspace
(
*
line
))
line
++
;
while
(
*
line
!=
'\0'
&&
isspace
(
*
line
))
line
++
;
if
(
*
line
==
'\0'
)
return
;
opt
=
line
;
while
(
*
line
==
'\0'
||
!
isspace
(
*
line
))
line
++
;
*
line
++
=
'\0'
;
while
(
*
line
&&
isspace
(
*
line
))
line
++
;
if
(
!*
line
)
return
;
while
(
*
line
!=
'\0'
&&
isspace
(
*
line
))
line
++
;
if
(
*
line
==
'\0'
)
return
;
/*@-temptrans@*/
/* FIX: line alias is saved */
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
=
xstrdup
(
longName
);
else
con
->
execs
[
con
->
numExecs
].
longName
=
NULL
;
con
->
execs
[
con
->
numExecs
].
shortName
=
shortName
;
con
->
execs
[
con
->
numExecs
].
script
=
xstrdup
(
line
);
con
->
numExecs
++
;
item
->
option
.
longName
=
opt
+
2
;
else
if
(
opt
[
0
]
==
'-'
&&
opt
[
2
]
==
'\0'
)
item
->
option
.
shortName
=
opt
[
1
];
/*@=temptrans@*/
if
(
poptParseArgvString
(
line
,
&
item
->
argc
,
&
item
->
argv
))
return
;
/*@-modobserver@*/
item
->
option
.
argInfo
=
POPT_ARGFLAG_DOC_HIDDEN
;
for
(
i
=
0
,
j
=
0
;
i
<
item
->
argc
;
i
++
,
j
++
)
{
const
char
*
f
;
if
(
!
strncmp
(
item
->
argv
[
i
],
"--POPTdesc="
,
sizeof
(
"--POPTdesc="
)
-
1
))
{
f
=
item
->
argv
[
i
]
+
sizeof
(
"--POPTdesc="
);
if
(
f
[
0
]
==
'$'
&&
f
[
1
]
==
'"'
)
f
++
;
item
->
option
.
descrip
=
f
;
item
->
option
.
argInfo
&=
~
POPT_ARGFLAG_DOC_HIDDEN
;
j
--
;
}
else
if
(
!
strncmp
(
item
->
argv
[
i
],
"--POPTargs="
,
sizeof
(
"--POPTargs="
)
-
1
))
{
f
=
item
->
argv
[
i
]
+
sizeof
(
"--POPTargs="
);
if
(
f
[
0
]
==
'$'
&&
f
[
1
]
==
'"'
)
f
++
;
item
->
option
.
argDescrip
=
f
;
item
->
option
.
argInfo
&=
~
POPT_ARGFLAG_DOC_HIDDEN
;
item
->
option
.
argInfo
|=
POPT_ARG_STRING
;
j
--
;
}
else
if
(
j
!=
i
)
item
->
argv
[
j
]
=
item
->
argv
[
i
];
}
if
(
j
!=
i
)
{
item
->
argv
[
j
]
=
NULL
;
item
->
argc
=
j
;
}
/*@=modobserver@*/
/*@-nullstate@*/
/* FIX: item->argv[] may be NULL */
if
(
!
strcmp
(
entryType
,
"alias"
))
(
void
)
poptAddItem
(
con
,
item
,
0
);
else
if
(
!
strcmp
(
entryType
,
"exec"
))
(
void
)
poptAddItem
(
con
,
item
,
1
);
/*@=nullstate@*/
}
/*@=compmempass@*/
int
poptReadConfigFile
(
poptContext
con
,
const
char
*
fn
)
{
char
*
file
=
NULL
,
*
chptr
,
*
end
;
char
*
buf
=
NULL
,
*
dst
;
int
poptReadConfigFile
(
poptContext
con
,
const
char
*
fn
)
{
const
char
*
file
,
*
chptr
,
*
end
;
char
*
buf
;
/*@dependent@*/
char
*
dst
;
int
fd
,
rc
;
in
t
fileLength
;
off_
t
fileLength
;
fd
=
open
(
fn
,
O_RDONLY
);
if
(
fd
<
0
)
{
if
(
errno
==
ENOENT
)
return
0
;
else
return
POPT_ERROR_ERRNO
;
}
if
(
fd
<
0
)
return
(
errno
==
ENOENT
?
0
:
POPT_ERROR_ERRNO
);
fileLength
=
lseek
(
fd
,
0
,
SEEK_END
);
(
void
)
lseek
(
fd
,
0
,
0
);
if
(
fileLength
==
-
1
||
lseek
(
fd
,
0
,
0
)
==
-
1
)
{
rc
=
errno
;
(
void
)
close
(
fd
);
/*@-mods@*/
errno
=
rc
;
/*@=mods@*/
return
POPT_ERROR_ERRNO
;
}
file
=
malloc
(
fileLength
+
1
);
if
(
read
(
fd
,
file
,
fileLength
)
!=
fileLength
)
{
file
=
alloca
(
fileLength
+
1
);
if
(
read
(
fd
,
(
char
*
)
file
,
fileLength
)
!=
fileLength
)
{
rc
=
errno
;
close
(
fd
);
(
void
)
close
(
fd
);
/*@-mods@*/
errno
=
rc
;
if
(
file
)
free
(
file
);
/*@=mods@*/
return
POPT_ERROR_ERRNO
;
}
close
(
fd
);
if
(
close
(
fd
)
==
-
1
)
return
POPT_ERROR_ERRNO
;
dst
=
buf
=
malloc
(
fileLength
+
1
);
dst
=
buf
=
alloca
(
fileLength
+
1
);
chptr
=
file
;
end
=
(
file
+
fileLength
);
/*@-infloops@*/
/* LCL: can't detect chptr++ */
while
(
chptr
<
end
)
{
switch
(
*
chptr
)
{
case
'\n'
:
*
dst
=
'\0'
;
dst
=
buf
;
while
(
*
dst
&&
isspace
(
*
dst
))
dst
++
;
if
(
*
dst
&&
*
dst
!=
'#'
)
{
if
(
*
dst
&&
*
dst
!=
'#'
)
configLine
(
con
,
dst
);
}
chptr
++
;
break
;
/*@switchbreak@*/
break
;
case
'\\'
:
*
dst
++
=
*
chptr
++
;
if
(
chptr
<
end
)
{
...
...
@@ -105,15 +148,13 @@ int poptReadConfigFile(poptContext con, const char * fn) {
else
*
dst
++
=
*
chptr
++
;
}
break
;
/*@switchbreak@*/
break
;
default:
*
dst
++
=
*
chptr
++
;
break
;
/*@switchbreak@*/
break
;
}
}
free
(
file
);
free
(
buf
);
/*@=infloops@*/
return
0
;
}
...
...
@@ -122,21 +163,21 @@ int poptReadDefaultConfig(poptContext con, /*@unused@*/ int useEnv) {
char
*
fn
,
*
home
;
int
rc
;
/*@-type@*/
if
(
!
con
->
appName
)
return
0
;
/*@=type@*/
rc
=
poptReadConfigFile
(
con
,
"/etc/popt"
);
if
(
rc
)
return
rc
;
if
(
getuid
()
!=
geteuid
())
return
0
;
if
((
home
=
getenv
(
"HOME"
)))
{
fn
=
malloc
(
strlen
(
home
)
+
20
);
fn
=
alloca
(
strlen
(
home
)
+
20
);
strcpy
(
fn
,
home
);
strcat
(
fn
,
"/.popt"
);
rc
=
poptReadConfigFile
(
con
,
fn
);
free
(
fn
);
if
(
rc
)
return
rc
;
}
return
0
;
}
popt/popthelp.c
View file @
cc248aae
/* -*- 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
/*@-type@*/
/** \ingroup popt
* \file popt/popthelp.c
*/
/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
file accompanying popt source distributions, available from
ftp://ftp.r
edhat.com/pub/code/popt
*/
ftp://ftp.r
pm.org/pub/rpm/dist.
*/
#include "system.h"
#include "poptint.h"
/**
* @param con context
* @param key option(s)
*/
static
void
displayArgs
(
poptContext
con
,
/*@unused@*/
enum
poptCallbackReason
foo
,
struct
poptOption
*
key
,
/*@unused@*/
const
char
*
arg
,
/*@unused@*/
void
*
data
)
{
if
(
key
->
shortName
==
'?'
)
/*@unused@*/
const
char
*
arg
,
/*@unused@*/
void
*
data
)
/*@globals fileSystem@*/
/*@modifies fileSystem@*/
{
if
(
key
->
shortName
==
'?'
)
poptPrintHelp
(
con
,
stdout
,
0
);
else
poptPrintUsage
(
con
,
stdout
,
0
);
exit
(
0
);
}
#ifdef NOTYET
/*@unchecked@*/
static
int
show_option_defaults
=
0
;
#endif
/**
* Empty table marker to enable displaying popt alias/exec options.
*/
/*@observer@*/
/*@unchecked@*/
struct
poptOption
poptAliasOptions
[]
=
{
POPT_TABLEEND
};
/**
* Auto help table options.
*/
/*@-castfcnptr@*/
/*@observer@*/
/*@unchecked@*/
struct
poptOption
poptHelpOptions
[]
=
{
{
NULL
,
'\0'
,
POPT_ARG_CALLBACK
,
(
void
*
)
&
displayArgs
,
'\0'
,
NULL
,
NULL
},
{
"help"
,
'?'
,
0
,
NULL
,
'?'
,
N_
(
"Show this help message"
),
NULL
},
{
"usage"
,
'\0'
,
0
,
NULL
,
'u'
,
N_
(
"Display brief usage message"
),
NULL
},
{
NULL
,
'\0'
,
0
,
NULL
,
0
,
NULL
,
NULL
}
{
NULL
,
'\0'
,
POPT_ARG_CALLBACK
,
(
void
*
)
&
displayArgs
,
'\0'
,
NULL
,
NULL
},
{
"help"
,
'?'
,
0
,
NULL
,
'?'
,
N_
(
"Show this help message"
),
NULL
},
{
"usage"
,
'\0'
,
0
,
NULL
,
'u'
,
N_
(
"Display brief usage message"
),
NULL
},
#ifdef NOTYET
{
"defaults"
,
'\0'
,
POPT_ARG_NONE
,
&
show_option_defaults
,
0
,
N_
(
"Display option defaults in message"
),
NULL
},
#endif
POPT_TABLEEND
}
;
/*@=castfcnptr@*/
/**
* @param table option(s)
*/
/*@observer@*/
/*@null@*/
static
const
char
*
const
getTableTranslationDomain
(
const
struct
poptOption
*
table
)
getTableTranslationDomain
(
/*@null@*/
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
;
}
const
struct
poptOption
*
opt
;
return
NULL
;
if
(
table
!=
NULL
)
for
(
opt
=
table
;
opt
->
longName
||
opt
->
shortName
||
opt
->
arg
;
opt
++
)
{
if
(
opt
->
argInfo
==
POPT_ARG_INTL_DOMAIN
)
return
opt
->
arg
;
}
return
NULL
;
}
/**
* @param opt option(s)
* @param translation_domain translation domain
*/
/*@observer@*/
/*@null@*/
static
const
char
*
const
getArgDescrip
(
const
struct
poptOption
*
opt
,
const
char
*
translation_domain
)
getArgDescrip
(
const
struct
poptOption
*
opt
,
/*@-paramuse@*/
/* FIX: wazzup? */
/*@null@*/
const
char
*
translation_domain
)
/*@=paramuse@*/
/*@*/
{
if
(
!
(
opt
->
argInfo
&
POPT_ARG_MASK
))
return
NULL
;
...
...
@@ -50,45 +94,224 @@ getArgDescrip(const struct poptOption * opt, const char *translation_domain)
if
(
opt
->
argDescrip
)
return
POPT_
(
opt
->
argDescrip
);
if
(
opt
->
argDescrip
)
return
D_
(
translation_domain
,
opt
->
argDescrip
);
return
POPT_
(
"ARG"
);
switch
(
opt
->
argInfo
&
POPT_ARG_MASK
)
{
case
POPT_ARG_NONE
:
return
POPT_
(
"NONE"
);
case
POPT_ARG_VAL
:
return
POPT_
(
"VAL"
);
case
POPT_ARG_INT
:
return
POPT_
(
"INT"
);
case
POPT_ARG_LONG
:
return
POPT_
(
"LONG"
);
case
POPT_ARG_STRING
:
return
POPT_
(
"STRING"
);
case
POPT_ARG_FLOAT
:
return
POPT_
(
"FLOAT"
);
case
POPT_ARG_DOUBLE
:
return
POPT_
(
"DOUBLE"
);
default:
return
POPT_
(
"ARG"
);
}
}
/**
* @param opt option(s)
* @param translation_domain translation domain
*/
static
/*@only@*/
/*@null@*/
char
*
singleOptionDefaultValue
(
int
lineLength
,
const
struct
poptOption
*
opt
,
/*@-paramuse@*/
/* FIX: i18n macros disable with lclint */
/*@null@*/
const
char
*
translation_domain
)
/*@=paramuse@*/
/*@*/
{
const
char
*
defstr
=
D_
(
translation_domain
,
"default"
);
char
*
le
=
malloc
(
4
*
lineLength
+
1
);
char
*
l
=
le
;
if
(
le
==
NULL
)
return
NULL
;
/* XXX can't happen */
*
le
=
'\0'
;
*
le
++
=
'('
;
strcpy
(
le
,
defstr
);
le
+=
strlen
(
le
);
*
le
++
=
':'
;
*
le
++
=
' '
;
if
(
opt
->
arg
)
/* XXX programmer error */
switch
(
opt
->
argInfo
&
POPT_ARG_MASK
)
{
case
POPT_ARG_VAL
:
case
POPT_ARG_INT
:
{
long
aLong
=
*
((
int
*
)
opt
->
arg
);
le
+=
sprintf
(
le
,
"%ld"
,
aLong
);
}
break
;
case
POPT_ARG_LONG
:
{
long
aLong
=
*
((
long
*
)
opt
->
arg
);
le
+=
sprintf
(
le
,
"%ld"
,
aLong
);
}
break
;
case
POPT_ARG_FLOAT
:
{
double
aDouble
=
*
((
float
*
)
opt
->
arg
);
le
+=
sprintf
(
le
,
"%g"
,
aDouble
);
}
break
;
case
POPT_ARG_DOUBLE
:
{
double
aDouble
=
*
((
double
*
)
opt
->
arg
);
le
+=
sprintf
(
le
,
"%g"
,
aDouble
);
}
break
;
case
POPT_ARG_STRING
:
{
const
char
*
s
=
*
(
const
char
**
)
opt
->
arg
;
if
(
s
==
NULL
)
{
strcpy
(
le
,
"null"
);
le
+=
strlen
(
le
);
}
else
{
size_t
slen
=
4
*
lineLength
-
(
le
-
l
)
-
sizeof
(
"
\"
...
\"
)"
);
*
le
++
=
'"'
;
strncpy
(
le
,
s
,
slen
);
le
[
slen
]
=
'\0'
;
le
+=
strlen
(
le
);
if
(
slen
<
strlen
(
s
))
{
strcpy
(
le
,
"..."
);
le
+=
strlen
(
le
);
}
*
le
++
=
'"'
;
}
}
break
;
case
POPT_ARG_NONE
:
default
:
l
=
_free
(
l
);
return
NULL
;
/*@notreached@*/
break
;
}
*
le
++
=
')'
;
*
le
=
'\0'
;
return
l
;
}
static
void
singleOptionHelp
(
FILE
*
f
,
int
maxLeftCol
,
const
struct
poptOption
*
opt
,
const
char
*
translation_domain
)
{
/**
* @param fp output file handle
* @param opt option(s)
* @param translation_domain translation domain
*/
static
void
singleOptionHelp
(
FILE
*
fp
,
int
maxLeftCol
,
const
struct
poptOption
*
opt
,
/*@null@*/
const
char
*
translation_domain
)
/*@globals fileSystem @*/
/*@modifies *fp, fileSystem @*/
{
int
indentLength
=
maxLeftCol
+
5
;
int
lineLength
=
79
-
indentLength
;
const
char
*
help
=
D_
(
translation_domain
,
opt
->
descrip
);
const
char
*
argDescrip
=
getArgDescrip
(
opt
,
translation_domain
);
int
helpLength
;
const
char
*
ch
;
char
format
[
10
];
char
*
defs
=
NULL
;
char
*
left
;
const
char
*
argDescrip
=
getArgDescrip
(
opt
,
translation_domain
);
int
nb
=
maxLeftCol
+
1
;
/* Make sure there's more than enough room in target buffer. */
if
(
opt
->
longName
)
nb
+=
strlen
(
opt
->
longName
);
if
(
argDescrip
)
nb
+=
strlen
(
argDescrip
);
left
=
malloc
(
maxLeftCol
+
1
);
*
left
=
'\0'
;
left
=
malloc
(
nb
);
if
(
left
==
NULL
)
return
;
/* XXX can't happen */
left
[
0
]
=
'\0'
;
left
[
maxLeftCol
]
=
'\0'
;
if
(
opt
->
longName
&&
opt
->
shortName
)
sprintf
(
left
,
"-%c, --%s"
,
opt
->
shortName
,
opt
->
longName
);
else
if
(
opt
->
shortName
)
sprintf
(
left
,
"-%c, %s%s"
,
opt
->
shortName
,
((
opt
->
argInfo
&
POPT_ARGFLAG_ONEDASH
)
?
"-"
:
"--"
),
opt
->
longName
);
else
if
(
opt
->
shortName
!=
'\0'
)
sprintf
(
left
,
"-%c"
,
opt
->
shortName
);
else
if
(
opt
->
longName
)
sprintf
(
left
,
"--%s"
,
opt
->
longName
);
if
(
!*
left
)
return
;
sprintf
(
left
,
"%s%s"
,
((
opt
->
argInfo
&
POPT_ARGFLAG_ONEDASH
)
?
"-"
:
"--"
),
opt
->
longName
);
if
(
!*
left
)
goto
out
;
if
(
argDescrip
)
{
strcat
(
left
,
"="
);
strcat
(
left
,
argDescrip
);
char
*
le
=
left
+
strlen
(
left
);
if
(
opt
->
argInfo
&
POPT_ARGFLAG_OPTIONAL
)
*
le
++
=
'['
;
/* Choose type of output */
/*@-branchstate@*/
if
(
opt
->
argInfo
&
POPT_ARGFLAG_SHOW_DEFAULT
)
{
defs
=
singleOptionDefaultValue
(
lineLength
,
opt
,
translation_domain
);
if
(
defs
)
{
char
*
t
=
malloc
((
help
?
strlen
(
help
)
:
0
)
+
strlen
(
defs
)
+
sizeof
(
" "
));
if
(
t
)
{
char
*
te
=
t
;
*
te
=
'\0'
;
if
(
help
)
{
strcpy
(
te
,
help
);
te
+=
strlen
(
te
);
}
*
te
++
=
' '
;
strcpy
(
te
,
defs
);
defs
=
_free
(
defs
);
}
defs
=
t
;
}
}
/*@=branchstate@*/
if
(
opt
->
argDescrip
==
NULL
)
{
switch
(
opt
->
argInfo
&
POPT_ARG_MASK
)
{
case
POPT_ARG_NONE
:
break
;
case
POPT_ARG_VAL
:
{
long
aLong
=
opt
->
val
;
int
ops
=
(
opt
->
argInfo
&
POPT_ARGFLAG_LOGICALOPS
);
int
negate
=
(
opt
->
argInfo
&
POPT_ARGFLAG_NOT
);
/* Don't bother displaying typical values */
if
(
!
ops
&&
(
aLong
==
0L
||
aLong
==
1L
||
aLong
==
-
1L
))
break
;
*
le
++
=
'['
;
switch
(
ops
)
{
case
POPT_ARGFLAG_OR
:
*
le
++
=
'|'
;
/*@innerbreak@*/
break
;
case
POPT_ARGFLAG_AND
:
*
le
++
=
'&'
;
/*@innerbreak@*/
break
;
case
POPT_ARGFLAG_XOR
:
*
le
++
=
'^'
;
/*@innerbreak@*/
break
;
default
:
/*@innerbreak@*/
break
;
}
*
le
++
=
'='
;
if
(
negate
)
*
le
++
=
'~'
;
/*@-formatconst@*/
le
+=
sprintf
(
le
,
(
ops
?
"0x%lx"
:
"%ld"
),
aLong
);
/*@=formatconst@*/
*
le
++
=
']'
;
}
break
;
case
POPT_ARG_INT
:
case
POPT_ARG_LONG
:
case
POPT_ARG_FLOAT
:
case
POPT_ARG_DOUBLE
:
case
POPT_ARG_STRING
:
*
le
++
=
'='
;
strcpy
(
le
,
argDescrip
);
le
+=
strlen
(
le
);
break
;
default
:
break
;
}
}
else
{
*
le
++
=
'='
;
strcpy
(
le
,
argDescrip
);
le
+=
strlen
(
le
);
}
if
(
opt
->
argInfo
&
POPT_ARGFLAG_OPTIONAL
)
*
le
++
=
']'
;
*
le
=
'\0'
;
}
if
(
help
)
fprintf
(
f
,
" %-*s "
,
maxLeftCol
,
left
);
fprintf
(
f
p
,
" %-*s "
,
maxLeftCol
,
left
);
else
{
fprintf
(
f
,
" %s
\n
"
,
left
);
fprintf
(
f
p
,
" %s
\n
"
,
left
);
goto
out
;
}
left
=
_free
(
left
);
if
(
defs
)
{
help
=
defs
;
defs
=
NULL
;
}
helpLength
=
strlen
(
help
);
while
(
helpLength
>
lineLength
)
{
const
char
*
ch
;
char
format
[
10
];
ch
=
help
+
lineLength
-
1
;
while
(
ch
>
help
&&
!
isspace
(
*
ch
))
ch
--
;
if
(
ch
==
help
)
break
;
/* give up */
...
...
@@ -96,39 +319,56 @@ static void singleOptionHelp(FILE * f, int maxLeftCol,
ch
++
;
sprintf
(
format
,
"%%.%ds
\n
%%%ds"
,
(
int
)
(
ch
-
help
),
indentLength
);
fprintf
(
f
,
format
,
help
,
" "
);
/*@-formatconst@*/
fprintf
(
fp
,
format
,
help
,
" "
);
/*@=formatconst@*/
help
=
ch
;
while
(
isspace
(
*
help
)
&&
*
help
)
help
++
;
helpLength
=
strlen
(
help
);
}
if
(
helpLength
)
fprintf
(
f
,
"%s
\n
"
,
help
);
if
(
helpLength
)
fprintf
(
f
p
,
"%s
\n
"
,
help
);
out
:
free
(
left
);
/*@-dependenttrans@*/
defs
=
_free
(
defs
);
/*@=dependenttrans@*/
left
=
_free
(
left
);
}
/**
* @param opt option(s)
* @param translation_domain translation domain
*/
static
int
maxArgWidth
(
const
struct
poptOption
*
opt
,
const
char
*
translation_domain
)
{
/*@null@*/
const
char
*
translation_domain
)
/*@*/
{
int
max
=
0
;
int
this
;
int
len
=
0
;
const
char
*
s
;
if
(
opt
!=
NULL
)
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
;
if
(
opt
->
arg
)
/* XXX program error */
len
=
maxArgWidth
(
opt
->
arg
,
translation_domain
);
if
(
len
>
max
)
max
=
len
;
}
else
if
(
!
(
opt
->
argInfo
&
POPT_ARGFLAG_DOC_HIDDEN
))
{
this
=
opt
->
shortName
?
2
:
0
;
len
=
sizeof
(
" "
)
-
1
;
if
(
opt
->
shortName
!=
'\0'
)
len
+=
sizeof
(
"-X"
)
-
1
;
if
(
opt
->
shortName
!=
'\0'
&&
opt
->
longName
)
len
+=
sizeof
(
", "
)
-
1
;
if
(
opt
->
longName
)
{
if
(
this
)
this
+=
2
;
this
+=
strlen
(
opt
->
longName
)
+
2
;
len
+=
((
opt
->
argInfo
&
POPT_ARGFLAG_ONEDASH
)
?
sizeof
(
"-"
)
-
1
:
sizeof
(
"--"
)
-
1
);
len
+=
strlen
(
opt
->
longName
);
}
s
=
getArgDescrip
(
opt
,
translation_domain
);
if
(
s
)
this
+=
strlen
(
s
)
+
1
;
if
(
this
>
max
)
max
=
this
;
len
+=
sizeof
(
"="
)
-
1
+
strlen
(
s
);
if
(
opt
->
argInfo
&
POPT_ARGFLAG_OPTIONAL
)
len
+=
sizeof
(
"[]"
)
-
1
;
if
(
len
>
max
)
max
=
len
;
}
opt
++
;
...
...
@@ -137,77 +377,134 @@ static int maxArgWidth(const struct poptOption * opt,
return
max
;
}
static
void
singleTableHelp
(
FILE
*
f
,
const
struct
poptOption
*
table
,
int
left
,
const
char
*
translation_domain
)
{
/**
* Display popt alias and exec help.
* @param fp output file handle
* @param items alias/exec array
* @param nitems no. of alias/exec entries
* @param translation_domain translation domain
*/
static
void
itemHelp
(
FILE
*
fp
,
/*@null@*/
poptItem
items
,
int
nitems
,
int
left
,
/*@null@*/
const
char
*
translation_domain
)
/*@globals fileSystem @*/
/*@modifies *fp, fileSystem @*/
{
poptItem
item
;
int
i
;
if
(
items
!=
NULL
)
for
(
i
=
0
,
item
=
items
;
i
<
nitems
;
i
++
,
item
++
)
{
const
struct
poptOption
*
opt
;
opt
=
&
item
->
option
;
if
((
opt
->
longName
||
opt
->
shortName
)
&&
!
(
opt
->
argInfo
&
POPT_ARGFLAG_DOC_HIDDEN
))
singleOptionHelp
(
fp
,
left
,
opt
,
translation_domain
);
}
}
/**
* @param fp output file handle
* @param table option(s)
* @param translation_domain translation domain
*/
static
void
singleTableHelp
(
poptContext
con
,
FILE
*
fp
,
/*@null@*/
const
struct
poptOption
*
table
,
int
left
,
/*@null@*/
const
char
*
translation_domain
)
/*@globals fileSystem @*/
/*@modifies *fp, fileSystem @*/
{
const
struct
poptOption
*
opt
;
const
char
*
sub_transdom
;
opt
=
table
;
while
(
opt
->
longName
||
opt
->
shortName
||
opt
->
arg
)
{
if
(
table
==
poptAliasOptions
)
{
itemHelp
(
fp
,
con
->
aliases
,
con
->
numAliases
,
left
,
NULL
);
itemHelp
(
fp
,
con
->
execs
,
con
->
numExecs
,
left
,
NULL
);
return
;
}
if
(
table
!=
NULL
)
for
(
opt
=
table
;
(
opt
->
longName
||
opt
->
shortName
||
opt
->
arg
);
opt
++
)
{
if
((
opt
->
longName
||
opt
->
shortName
)
&&
!
(
opt
->
argInfo
&
POPT_ARGFLAG_DOC_HIDDEN
))
singleOptionHelp
(
f
,
left
,
opt
,
translation_domain
);
opt
++
;
singleOptionHelp
(
fp
,
left
,
opt
,
translation_domain
);
}
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
(
table
!=
NULL
)
for
(
opt
=
table
;
(
opt
->
longName
||
opt
->
shortName
||
opt
->
arg
);
opt
++
)
{
if
((
opt
->
argInfo
&
POPT_ARG_MASK
)
!=
POPT_ARG_INCLUDE_TABLE
)
continue
;
sub_transdom
=
getTableTranslationDomain
(
opt
->
arg
);
if
(
sub_transdom
==
NULL
)
sub_transdom
=
translation_domain
;
if
(
opt
->
descrip
)
fprintf
(
f
,
"
\n
%s
\n
"
,
D_
(
sub_transdom
,
opt
->
descrip
));
if
(
opt
->
descrip
)
fprintf
(
fp
,
"
\n
%s
\n
"
,
D_
(
sub_transdom
,
opt
->
descrip
));
singleTableHelp
(
f
,
opt
->
arg
,
left
,
sub_transdom
);
}
opt
++
;
singleTableHelp
(
con
,
fp
,
opt
->
arg
,
left
,
sub_transdom
);
}
}
static
int
showHelpIntro
(
poptContext
con
,
FILE
*
f
)
{
/**
* @param con context
* @param fp output file handle
*/
static
int
showHelpIntro
(
poptContext
con
,
FILE
*
fp
)
/*@globals fileSystem @*/
/*@modifies *fp, fileSystem @*/
{
int
len
=
6
;
const
char
*
fn
;
fprintf
(
f
,
POPT_
(
"Usage:"
));
fprintf
(
f
p
,
POPT_
(
"Usage:"
));
if
(
!
(
con
->
flags
&
POPT_CONTEXT_KEEP_FIRST
))
{
/*@-nullderef@*/
/* LCL: wazzup? */
fn
=
con
->
optionStack
->
argv
[
0
];
if
(
strchr
(
fn
,
'/'
))
fn
=
strchr
(
fn
,
'/'
)
+
1
;
fprintf
(
f
,
" %s"
,
fn
);
/*@=nullderef@*/
if
(
fn
==
NULL
)
return
len
;
if
(
strchr
(
fn
,
'/'
))
fn
=
strrchr
(
fn
,
'/'
)
+
1
;
fprintf
(
fp
,
" %s"
,
fn
);
len
+=
strlen
(
fn
)
+
1
;
}
return
len
;
}
void
poptPrintHelp
(
poptContext
con
,
FILE
*
f
,
/*@unused@*/
int
flags
)
{
void
poptPrintHelp
(
poptContext
con
,
FILE
*
fp
,
/*@unused@*/
int
flags
)
{
int
leftColWidth
;
showHelpIntro
(
con
,
f
);
(
void
)
showHelpIntro
(
con
,
fp
);
if
(
con
->
otherHelp
)
fprintf
(
f
,
" %s
\n
"
,
con
->
otherHelp
);
fprintf
(
f
p
,
" %s
\n
"
,
con
->
otherHelp
);
else
fprintf
(
f
,
" %s
\n
"
,
POPT_
(
"[OPTION...]"
));
fprintf
(
f
p
,
" %s
\n
"
,
POPT_
(
"[OPTION...]"
));
leftColWidth
=
maxArgWidth
(
con
->
options
,
NULL
);
singleTableHelp
(
f
,
con
->
options
,
leftColWidth
,
NULL
);
singleTableHelp
(
con
,
fp
,
con
->
options
,
leftColWidth
,
NULL
);
}
static
int
singleOptionUsage
(
FILE
*
f
,
int
cursor
,
const
struct
poptOption
*
opt
,
const
char
*
translation_domain
)
{
/**
* @param fp output file handle
* @param opt option(s)
* @param translation_domain translation domain
*/
static
int
singleOptionUsage
(
FILE
*
fp
,
int
cursor
,
const
struct
poptOption
*
opt
,
/*@null@*/
const
char
*
translation_domain
)
/*@globals fileSystem @*/
/*@modifies *fp, fileSystem @*/
{
int
len
=
3
;
char
shortStr
[
2
]
=
{
'\0'
,
'\0'
};
const
char
*
item
=
shortStr
;
const
char
*
argDescrip
=
getArgDescrip
(
opt
,
translation_domain
);
if
(
opt
->
shortName
)
{
if
(
opt
->
shortName
!=
'\0'
)
{
if
(
!
(
opt
->
argInfo
&
POPT_ARG_MASK
))
return
cursor
;
/* we did these already */
len
++
;
*
shortStr
=
opt
->
shortName
;
shortStr
[
0
]
=
opt
->
shortName
;
shortStr
[
1
]
=
'\0'
;
}
else
if
(
opt
->
longName
)
{
len
+=
1
+
strlen
(
opt
->
longName
);
...
...
@@ -220,82 +517,140 @@ static int singleOptionUsage(FILE * f, int cursor,
len
+=
strlen
(
argDescrip
)
+
1
;
if
((
cursor
+
len
)
>
79
)
{
fprintf
(
f
,
"
\n
"
);
fprintf
(
f
p
,
"
\n
"
);
cursor
=
7
;
}
fprintf
(
f
,
" [-%s%s%s%s]"
,
opt
->
shortName
?
""
:
"-"
,
item
,
argDescrip
?
(
opt
->
shortName
?
" "
:
"="
)
:
""
,
argDescrip
?
argDescrip
:
""
);
fprintf
(
fp
,
" [-%s%s%s%s]"
,
((
opt
->
shortName
||
(
opt
->
argInfo
&
POPT_ARGFLAG_ONEDASH
))
?
""
:
"-"
),
item
,
(
argDescrip
?
(
opt
->
shortName
!=
'\0'
?
" "
:
"="
)
:
""
),
(
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
)
/**
* Display popt alias and exec usage.
* @param fp output file handle
* @param item alias/exec array
* @param nitems no. of ara/exec entries
* @param translation_domain translation domain
*/
static
int
itemUsage
(
FILE
*
fp
,
int
cursor
,
poptItem
item
,
int
nitems
,
/*@null@*/
const
char
*
translation_domain
)
/*@globals fileSystem @*/
/*@modifies *fp, fileSystem @*/
{
int
i
;
/*@-branchstate@*/
/* FIX: W2DO? */
if
(
item
!=
NULL
)
for
(
i
=
0
;
i
<
nitems
;
i
++
,
item
++
)
{
const
struct
poptOption
*
opt
;
opt
=
&
item
->
option
;
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
);
}
else
if
((
opt
->
longName
||
opt
->
shortName
)
&&
!
(
opt
->
argInfo
&
POPT_ARGFLAG_DOC_HIDDEN
))
{
cursor
=
singleOptionUsage
(
fp
,
cursor
,
opt
,
translation_domain
);
}
}
/*@=branchstate@*/
opt
++
;
return
cursor
;
}
/**
* @param fp output file handle
* @param opt option(s)
* @param translation_domain translation domain
*/
static
int
singleTableUsage
(
poptContext
con
,
FILE
*
fp
,
int
cursor
,
const
struct
poptOption
*
opt
,
/*@null@*/
const
char
*
translation_domain
)
/*@globals fileSystem @*/
/*@modifies *fp, fileSystem @*/
{
/*@-branchstate@*/
/* FIX: W2DO? */
if
(
opt
!=
NULL
)
for
(;
(
opt
->
longName
||
opt
->
shortName
||
opt
->
arg
)
;
opt
++
)
{
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
)
{
if
(
opt
->
arg
)
/* XXX program error */
cursor
=
singleTableUsage
(
con
,
fp
,
cursor
,
opt
->
arg
,
translation_domain
);
}
else
if
((
opt
->
longName
||
opt
->
shortName
)
&&
!
(
opt
->
argInfo
&
POPT_ARGFLAG_DOC_HIDDEN
))
{
cursor
=
singleOptionUsage
(
fp
,
cursor
,
opt
,
translation_domain
);
}
}
/*@=branchstate@*/
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 */
/**
* Return concatenated short options for display.
* @param opt option(s)
* @param fp output file handle
* @retval str concatenation of short options
* @return length of display string
*/
static
int
showShortOptions
(
const
struct
poptOption
*
opt
,
FILE
*
fp
,
/*@null@*/
char
*
str
)
/*@globals fileSystem @*/
/*@modifies *str, *fp, fileSystem @*/
{
char
*
s
=
alloca
(
300
);
/* larger then the ascii set */
s
[
0
]
=
'\0'
;
/*@-branchstate@*/
/* FIX: W2DO? */
if
(
str
==
NULL
)
{
memset
(
s
,
0
,
sizeof
(
s
));
str
=
s
;
}
/*@=branchstate@*/
while
(
opt
->
longName
||
opt
->
shortName
||
opt
->
arg
)
{
if
(
opt
!=
NULL
)
for
(;
(
opt
->
longName
||
opt
->
shortName
||
opt
->
arg
);
opt
++
)
{
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
(
opt
->
arg
)
/* XXX program error */
(
void
)
showShortOptions
(
opt
->
arg
,
fp
,
str
);
}
if
(
s
!=
str
||
!*
s
)
if
(
s
!=
str
||
*
s
!=
'\0'
)
return
0
;
fprintf
(
f
,
" [-%s]"
,
s
);
fprintf
(
f
p
,
" [-%s]"
,
s
);
return
strlen
(
s
)
+
4
;
}
void
poptPrintUsage
(
poptContext
con
,
FILE
*
f
,
/*@unused@*/
int
flags
)
{
void
poptPrintUsage
(
poptContext
con
,
FILE
*
fp
,
/*@unused@*/
int
flags
)
{
int
cursor
;
cursor
=
showHelpIntro
(
con
,
f
);
cursor
+=
showShortOptions
(
con
->
options
,
f
,
NULL
);
singleTableUsage
(
f
,
cursor
,
con
->
options
,
NULL
);
cursor
=
showHelpIntro
(
con
,
fp
);
cursor
+=
showShortOptions
(
con
->
options
,
fp
,
NULL
);
(
void
)
singleTableUsage
(
con
,
fp
,
cursor
,
con
->
options
,
NULL
);
(
void
)
itemUsage
(
fp
,
cursor
,
con
->
aliases
,
con
->
numAliases
,
NULL
);
(
void
)
itemUsage
(
fp
,
cursor
,
con
->
execs
,
con
->
numExecs
,
NULL
);
if
(
con
->
otherHelp
)
{
cursor
+=
strlen
(
con
->
otherHelp
)
+
1
;
if
(
cursor
>
79
)
fprintf
(
f
,
"
\n
"
);
fprintf
(
f
,
" %s"
,
con
->
otherHelp
);
if
(
cursor
>
79
)
fprintf
(
f
p
,
"
\n
"
);
fprintf
(
f
p
,
" %s"
,
con
->
otherHelp
);
}
fprintf
(
f
,
"
\n
"
);
fprintf
(
f
p
,
"
\n
"
);
}
void
poptSetOtherOptionHelp
(
poptContext
con
,
const
char
*
text
)
{
if
(
con
->
otherHelp
)
xfree
(
con
->
otherHelp
);
void
poptSetOtherOptionHelp
(
poptContext
con
,
const
char
*
text
)
{
con
->
otherHelp
=
_free
(
con
->
otherHelp
);
con
->
otherHelp
=
xstrdup
(
text
);
}
/*@=type@*/
popt/poptint.h
View file @
cc248aae
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
/** \ingroup popt
* \file popt/poptint.h
*/
/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
file accompanying popt source distributions, available from
ftp://ftp.r
edhat.com/pub/code/popt
*/
ftp://ftp.r
pm.org/pub/rpm/dist.
*/
#ifndef H_POPTINT
#define H_POPTINT
/**
* Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
* @param p memory to free
* @retval NULL always
*/
/*@unused@*/
static
inline
/*@null@*/
void
*
_free
(
/*@only@*/
/*@null@*/
const
void
*
p
)
/*@modifies p @*/
{
if
(
p
!=
NULL
)
free
((
void
*
)
p
);
return
NULL
;
}
/* Bit mask macros. */
typedef
unsigned
int
__pbm_bits
;
#define __PBM_NBITS (8 * sizeof (__pbm_bits))
#define __PBM_IX(d) ((d) / __PBM_NBITS)
#define __PBM_MASK(d) ((__pbm_bits) 1 << ((
d
) % __PBM_NBITS))
#define __PBM_MASK(d) ((__pbm_bits) 1 << ((
(unsigned)(d)
) % __PBM_NBITS))
typedef
struct
{
__pbm_bits
bits
[
1
];
}
pbm_set
;
#define __PBM_BITS(set) ((set)->bits)
#define PBM_ALLOC(d) calloc(__PBM_IX (d) + 1, sizeof(__pbm_bits))
#define PBM_FREE(s) free(s);
#define PBM_FREE(s)
_
free(s);
#define PBM_SET(d, s) (__PBM_BITS (s)[__PBM_IX (d)] |= __PBM_MASK (d))
#define PBM_CLR(d, s) (__PBM_BITS (s)[__PBM_IX (d)] &= ~__PBM_MASK (d))
#define PBM_ISSET(d, s) ((__PBM_BITS (s)[__PBM_IX (d)] & __PBM_MASK (d)) != 0)
struct
optionStackEntry
{
int
argc
;
/*@only
@*/
const
char
**
argv
;
/*@only
@*/
pbm_set
*
argb
;
/*@only@*/
/*@null
@*/
const
char
**
argv
;
/*@only@*/
/*@null
@*/
pbm_set
*
argb
;
int
next
;
/*@only
@*/
const
char
*
nextArg
;
/*@keep
@*/
const
char
*
nextCharArg
;
/*@dependent@*/
struct
poptAlias
*
currAlias
;
/*@only@*/
/*@null
@*/
const
char
*
nextArg
;
/*@keep@*/
/*@null
@*/
const
char
*
nextCharArg
;
/*@dependent@*/
/*@null@*/
poptItem
currAlias
;
int
stuffed
;
};
struct
execEntry
{
const
char
*
longName
;
char
shortName
;
const
char
*
script
;
};
struct
poptContext_s
{
struct
optionStackEntry
optionStack
[
POPT_OPTION_DEPTH
];
/*@dependent@*/
struct
optionStackEntry
*
os
;
/*@owned
@*/
const
char
**
leftovers
;
/*@dependent@*/
struct
optionStackEntry
*
os
;
/*@owned@*/
/*@null
@*/
const
char
**
leftovers
;
int
numLeftovers
;
int
nextLeftover
;
/*@keep@*/
const
struct
poptOption
*
options
;
/*@keep@*/
const
struct
poptOption
*
options
;
int
restLeftover
;
/*@only
@*/
const
char
*
appName
;
/*@only@*/
struct
poptAlias
*
aliases
;
/*@only@*/
/*@null
@*/
const
char
*
appName
;
/*@only@*/
/*@null@*/
poptItem
aliases
;
int
numAliases
;
int
flags
;
struct
execEntry
*
execs
;
/*@owned@*/
/*@null@*/
poptItem
execs
;
int
numExecs
;
/*@only
@*/
const
char
**
finalArgv
;
/*@only@*/
/*@null
@*/
const
char
**
finalArgv
;
int
finalArgvCount
;
int
finalArgvAlloced
;
/*@dependent@*/
struct
execEntry
*
doExec
;
/*@only@*/
const
char
*
execPath
;
/*@dependent@*/
/*@null@*/
poptItem
doExec
;
/*@only@*/
const
char
*
execPath
;
int
execAbsolute
;
/*@only@*/
const
char
*
otherHelp
;
pbm_set
*
arg_strip
;
/*@only@*/
const
char
*
otherHelp
;
/*@null@*/
pbm_set
*
arg_strip
;
};
#define xfree(_a) free((void *)_a)
#ifdef HAVE_LIBINTL_H
#include <libintl.h>
#endif
...
...
@@ -71,17 +80,17 @@ struct poptContext_s {
#if defined(HAVE_GETTEXT) && !defined(__LCLINT__)
#define _(foo) gettext(foo)
#else
#define _(foo)
(foo)
#define _(foo)
foo
#endif
#if defined(HAVE_DGETTEXT) && !defined(__LCLINT__)
#define D_(dom, str) dgettext(dom, str)
#define POPT_(foo) D_("popt", foo)
#else
#define
POPT_(foo) (foo)
#define
D_(dom, str) (str)
#define
D_(dom, str) str
#define
POPT_(foo) foo
#endif
#define N_(foo)
(foo)
#define N_(foo)
foo
#endif
popt/poptparse.c
View file @
cc248aae
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
/** \ingroup popt
* \file popt/poptparse.c
*/
/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
file accompanying popt source distributions, available from
ftp://ftp.r
edhat.com/pub/code/popt
*/
ftp://ftp.r
pm.org/pub/rpm/dist.
*/
#include "system.h"
...
...
@@ -14,6 +18,8 @@ int poptDupArgv(int argc, const char **argv,
char
*
dst
;
int
i
;
if
(
argc
<=
0
||
argv
==
NULL
)
/* XXX can't happen */
return
POPT_ERROR_NOARG
;
for
(
i
=
0
;
i
<
argc
;
i
++
)
{
if
(
argv
[
i
]
==
NULL
)
return
POPT_ERROR_NOARG
;
...
...
@@ -21,17 +27,27 @@ int poptDupArgv(int argc, const char **argv,
}
dst
=
malloc
(
nb
);
if
(
dst
==
NULL
)
/* XXX can't happen */
return
POPT_ERROR_MALLOC
;
argv2
=
(
void
*
)
dst
;
dst
+=
(
argc
+
1
)
*
sizeof
(
*
argv
);
/*@-branchstate@*/
for
(
i
=
0
;
i
<
argc
;
i
++
)
{
argv2
[
i
]
=
dst
;
dst
+=
strlen
(
strcpy
(
dst
,
argv
[
i
]))
+
1
;
}
/*@=branchstate@*/
argv2
[
argc
]
=
NULL
;
*
argvPtr
=
argv2
;
*
argcPtr
=
argc
;
if
(
argvPtr
)
{
*
argvPtr
=
argv2
;
}
else
{
free
(
argv2
);
argv2
=
NULL
;
}
if
(
argcPtr
)
*
argcPtr
=
argc
;
return
0
;
}
...
...
@@ -43,31 +59,32 @@ int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr)
const
char
**
argv
=
malloc
(
sizeof
(
*
argv
)
*
argvAlloced
);
int
argc
=
0
;
int
buflen
=
strlen
(
s
)
+
1
;
char
*
buf0
=
calloc
(
buflen
,
1
);
char
*
buf
=
buf0
;
char
*
buf
=
memset
(
alloca
(
buflen
),
0
,
buflen
);
int
rc
=
POPT_ERROR_MALLOC
;
if
(
argv
==
NULL
)
return
rc
;
argv
[
argc
]
=
buf
;
for
(
src
=
s
;
*
src
;
src
++
)
{
for
(
src
=
s
;
*
src
!=
'\0'
;
src
++
)
{
if
(
quote
==
*
src
)
{
quote
=
'\0'
;
}
else
if
(
quote
)
{
}
else
if
(
quote
!=
'\0'
)
{
if
(
*
src
==
'\\'
)
{
src
++
;
if
(
!*
src
)
{
free
(
argv
);
free
(
buf0
);
return
POPT_ERROR_BADQUOTE
;
rc
=
POPT_ERROR_BADQUOTE
;
goto
exit
;
}
if
(
*
src
!=
quote
)
*
buf
++
=
'\\'
;
}
*
buf
++
=
*
src
;
}
else
if
(
isspace
(
*
src
))
{
if
(
*
argv
[
argc
])
{
if
(
*
argv
[
argc
]
!=
'\0'
)
{
buf
++
,
argc
++
;
if
(
argc
==
argvAlloced
)
{
argvAlloced
+=
POPT_ARGV_ARRAY_GROW_DELTA
;
argv
=
realloc
(
argv
,
sizeof
(
*
argv
)
*
argvAlloced
);
if
(
argv
==
NULL
)
goto
exit
;
}
argv
[
argc
]
=
buf
;
}
...
...
@@ -75,18 +92,17 @@ int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr)
case
'"'
:
case
'\''
:
quote
=
*
src
;
break
;
/*@switchbreak@*/
break
;
case
'\\'
:
src
++
;
if
(
!*
src
)
{
free
(
argv
);
free
(
buf0
);
return
POPT_ERROR_BADQUOTE
;
rc
=
POPT_ERROR_BADQUOTE
;
goto
exit
;
}
/*@fallthrough@*/
default:
*
buf
++
=
*
src
;
break
;
/*@switchbreak@*/
break
;
}
}
...
...
@@ -94,9 +110,9 @@ int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr)
argc
++
,
buf
++
;
}
(
void
)
poptDupArgv
(
argc
,
argv
,
argcPtr
,
argvPtr
);
rc
=
poptDupArgv
(
argc
,
argv
,
argcPtr
,
argvPtr
);
free
(
argv
);
free
(
buf0
);
return
0
;
exit:
if
(
argv
)
free
(
argv
);
return
rc
;
}
popt/system.h
View file @
cc248aae
...
...
@@ -25,6 +25,14 @@
#include <libc.h>
#endif
#if defined(__LCLINT__)
/*@-declundef -incondefs -redecl@*/
/* LCL: missing annotation */
/*@only@*/
void
*
alloca
(
size_t
__size
)
/*@ensures MaxSet(result) == (__size - 1) @*/
/*@*/
;
/*@=declundef =incondefs =redecl@*/
#endif
/* AIX requires this to be the first thing in the file. */
#ifndef __GNUC__
# if HAVE_ALLOCA_H
...
...
@@ -42,7 +50,10 @@ char *alloca ();
#define alloca __builtin_alloca
#endif
/*@only@*/
char
*
xstrdup
(
const
char
*
str
);
/*@-redecl -redef@*/
/*@mayexit@*/
/*@only@*/
char
*
xstrdup
(
const
char
*
str
)
/*@*/
;
/*@=redecl =redef@*/
#if HAVE_MCHECK_H && defined(__GNUC__)
#define vmefail() (fprintf(stderr, "virtual memory exhausted.\n"), exit(EXIT_FAILURE), NULL)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment