2014-07-23 11:17:30 +04:00
/** \ingroup popt
* \ file popt / poptparse . c
*/
/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING
file accompanying popt source distributions , available from
ftp : //ftp.rpm.org/pub/rpm/dist. */
# include "system.h"
# define POPT_ARGV_ARRAY_GROW_DELTA 5
int poptDupArgv ( int argc , const char * * argv ,
int * argcPtr , const char * * * argvPtr )
{
size_t nb = ( argc + 1 ) * sizeof ( * argv ) ;
const char * * argv2 ;
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 ;
nb + = strlen ( argv [ i ] ) + 1 ;
}
2018-05-08 08:25:12 +03:00
dst = malloc ( nb ) ;
2014-07-23 11:17:30 +04:00
if ( dst = = NULL ) /* XXX can't happen */
return POPT_ERROR_MALLOC ;
2018-05-08 08:25:12 +03:00
argv2 = ( void * ) dst ;
2014-07-23 11:17:30 +04:00
dst + = ( argc + 1 ) * sizeof ( * argv ) ;
2018-05-08 08:25:12 +03:00
* dst = ' \0 ' ;
2014-07-23 11:17:30 +04:00
for ( i = 0 ; i < argc ; i + + ) {
argv2 [ i ] = dst ;
2018-05-08 08:25:12 +03:00
dst = stpcpy ( dst , argv [ i ] ) ;
dst + + ; /* trailing NUL */
2014-07-23 11:17:30 +04:00
}
argv2 [ argc ] = NULL ;
if ( argvPtr ) {
* argvPtr = argv2 ;
} else {
free ( argv2 ) ;
argv2 = NULL ;
}
if ( argcPtr )
* argcPtr = argc ;
return 0 ;
}
int poptParseArgvString ( const char * s , int * argcPtr , const char * * * argvPtr )
{
const char * src ;
char quote = ' \0 ' ;
int argvAlloced = POPT_ARGV_ARRAY_GROW_DELTA ;
2018-05-08 08:25:12 +03:00
const char * * argv = malloc ( sizeof ( * argv ) * argvAlloced ) ;
2014-07-23 11:17:30 +04:00
int argc = 0 ;
2018-05-08 08:25:12 +03:00
size_t buflen = strlen ( s ) + 1 ;
char * buf , * bufOrig = NULL ;
2014-07-23 11:17:30 +04:00
int rc = POPT_ERROR_MALLOC ;
if ( argv = = NULL ) return rc ;
2018-05-08 08:25:12 +03:00
buf = bufOrig = calloc ( ( size_t ) 1 , buflen ) ;
if ( buf = = NULL ) {
free ( argv ) ;
return rc ;
}
2014-07-23 11:17:30 +04:00
argv [ argc ] = buf ;
for ( src = s ; * src ! = ' \0 ' ; src + + ) {
if ( quote = = * src ) {
quote = ' \0 ' ;
} else if ( quote ! = ' \0 ' ) {
if ( * src = = ' \\ ' ) {
src + + ;
if ( ! * src ) {
rc = POPT_ERROR_BADQUOTE ;
goto exit ;
}
if ( * src ! = quote ) * buf + + = ' \\ ' ;
}
* buf + + = * src ;
2018-05-08 08:25:12 +03:00
} else if ( _isspaceptr ( src ) ) {
2014-07-23 11:17:30 +04:00
if ( * argv [ argc ] ! = ' \0 ' ) {
buf + + , argc + + ;
if ( argc = = argvAlloced ) {
argvAlloced + = POPT_ARGV_ARRAY_GROW_DELTA ;
2018-05-08 08:25:12 +03:00
argv = realloc ( argv , sizeof ( * argv ) * argvAlloced ) ;
2014-07-23 11:17:30 +04:00
if ( argv = = NULL ) goto exit ;
}
argv [ argc ] = buf ;
}
} else switch ( * src ) {
case ' " ' :
case ' \' ' :
quote = * src ;
/*@switchbreak@*/ break ;
case ' \\ ' :
src + + ;
if ( ! * src ) {
rc = POPT_ERROR_BADQUOTE ;
goto exit ;
}
/*@fallthrough@*/
default :
* buf + + = * src ;
/*@switchbreak@*/ break ;
}
}
if ( strlen ( argv [ argc ] ) ) {
argc + + , buf + + ;
}
rc = poptDupArgv ( argc , argv , argcPtr , argvPtr ) ;
exit :
2018-05-08 08:25:12 +03:00
if ( bufOrig ) free ( bufOrig ) ;
2014-07-23 11:17:30 +04:00
if ( argv ) free ( argv ) ;
return rc ;
}
/* still in the dev stage.
* return values , perhaps 1 = = file erro
* 2 = = line to long
* 3 = = umm . . . . more ?
*/
2018-05-08 08:25:12 +03:00
int poptConfigFileToString ( FILE * fp , char * * argstrp ,
/*@unused@*/ UNUSED ( int flags ) )
2014-07-23 11:17:30 +04:00
{
char line [ 999 ] ;
char * argstr ;
char * p ;
char * q ;
char * x ;
2018-05-08 08:25:12 +03:00
size_t t ;
size_t argvlen = 0 ;
2014-07-23 11:17:30 +04:00
size_t maxlinelen = sizeof ( line ) ;
size_t linelen ;
2018-05-08 08:25:12 +03:00
size_t maxargvlen = ( size_t ) 480 ;
2014-07-23 11:17:30 +04:00
* argstrp = NULL ;
/* | this_is = our_line
* p q x
*/
if ( fp = = NULL )
return POPT_ERROR_NULLARG ;
2018-05-08 08:25:12 +03:00
argstr = calloc ( maxargvlen , sizeof ( * argstr ) ) ;
2014-07-23 11:17:30 +04:00
if ( argstr = = NULL ) return POPT_ERROR_MALLOC ;
while ( fgets ( line , ( int ) maxlinelen , fp ) ! = NULL ) {
p = line ;
/* loop until first non-space char or EOL */
2018-05-08 08:25:12 +03:00
while ( * p ! = ' \0 ' & & _isspaceptr ( p ) )
2014-07-23 11:17:30 +04:00
p + + ;
linelen = strlen ( p ) ;
2018-05-08 08:25:12 +03:00
if ( linelen > = maxlinelen - 1 ) {
free ( argstr ) ;
2014-07-23 11:17:30 +04:00
return POPT_ERROR_OVERFLOW ; /* XXX line too long */
2018-05-08 08:25:12 +03:00
}
2014-07-23 11:17:30 +04:00
if ( * p = = ' \0 ' | | * p = = ' \n ' ) continue ; /* line is empty */
if ( * p = = ' # ' ) continue ; /* comment line */
q = p ;
2018-05-08 08:25:12 +03:00
while ( * q ! = ' \0 ' & & ( ! _isspaceptr ( q ) ) & & * q ! = ' = ' )
2014-07-23 11:17:30 +04:00
q + + ;
2018-05-08 08:25:12 +03:00
if ( _isspaceptr ( q ) ) {
2014-07-23 11:17:30 +04:00
/* a space after the name, find next non space */
* q + + = ' \0 ' ;
2018-05-08 08:25:12 +03:00
while ( * q ! = ' \0 ' & & _isspaceptr ( q ) ) q + + ;
2014-07-23 11:17:30 +04:00
}
if ( * q = = ' \0 ' ) {
/* single command line option (ie, no name=val, just name) */
q [ - 1 ] = ' \0 ' ; /* kill off newline from fgets() call */
2018-05-08 08:25:12 +03:00
argvlen + = ( t = ( size_t ) ( q - p ) ) + ( sizeof ( " -- " ) - 1 ) ;
2014-07-23 11:17:30 +04:00
if ( argvlen > = maxargvlen ) {
maxargvlen = ( t > maxargvlen ) ? t * 2 : maxargvlen * 2 ;
2018-05-08 08:25:12 +03:00
argstr = realloc ( argstr , maxargvlen ) ;
2014-07-23 11:17:30 +04:00
if ( argstr = = NULL ) return POPT_ERROR_MALLOC ;
}
strcat ( argstr , " -- " ) ;
strcat ( argstr , p ) ;
continue ;
}
if ( * q ! = ' = ' )
continue ; /* XXX for now, silently ignore bogus line */
/* *q is an equal sign. */
* q + + = ' \0 ' ;
/* find next non-space letter of value */
2018-05-08 08:25:12 +03:00
while ( * q ! = ' \0 ' & & _isspaceptr ( q ) )
2014-07-23 11:17:30 +04:00
q + + ;
if ( * q = = ' \0 ' )
continue ; /* XXX silently ignore missing value */
/* now, loop and strip all ending whitespace */
x = p + linelen ;
2018-05-08 08:25:12 +03:00
while ( _isspaceptr ( - - x ) )
* x = ' \0 ' ; /* null out last char if space (including fgets() NL) */
2014-07-23 11:17:30 +04:00
/* rest of line accept */
2018-05-08 08:25:12 +03:00
t = ( size_t ) ( x - p ) ;
2014-07-23 11:17:30 +04:00
argvlen + = t + ( sizeof ( " ' --=' " ) - 1 ) ;
if ( argvlen > = maxargvlen ) {
maxargvlen = ( t > maxargvlen ) ? t * 2 : maxargvlen * 2 ;
2018-05-08 08:25:12 +03:00
argstr = realloc ( argstr , maxargvlen ) ;
2014-07-23 11:17:30 +04:00
if ( argstr = = NULL ) return POPT_ERROR_MALLOC ;
}
strcat ( argstr , " -- " ) ;
strcat ( argstr , p ) ;
strcat ( argstr , " = \" " ) ;
strcat ( argstr , q ) ;
strcat ( argstr , " \" " ) ;
}
* argstrp = argstr ;
return 0 ;
}