/*****************************************************************************
Major portions of this software are copyrighted by the Medical College
of Wisconsin, 1994-2000, and are released under the Gnu General Public
License, Version 2. See the file README.Copyright for details.
******************************************************************************/
#include "cs.h"
#include "string.h"
#define BLEN 4096
/*------------------ 18 Nov 1999: utility routines --------------------*/
static void tokenize_string( char * sin , int * ntok , char *** stok )
{
int n_tok , ii ;
char ** s_tok , *cpt , *sss ;
if( stok == NULL ) return ;
if( ntok == NULL || sin == NULL || sin[0] == '\0' ){ *stok = NULL; return; }
n_tok = 0 ;
s_tok = (char **) malloc( sizeof(char *) ) ;
/* break input into tokens, copy them in the new arg list */
cpt = strtok( sin , " \t\n\r\f\v" ) ;
if( cpt == NULL ){ free(s_tok); *stok = NULL; return; } /* do nothing */
while( cpt != NULL ){
ii = strlen(cpt) ;
sss = (char *) malloc( sizeof(char) * (ii+1) ) ;
strcpy(sss,cpt) ;
n_tok++ ;
s_tok = (char **) realloc( s_tok , sizeof(char *) * n_tok ) ;
s_tok[n_tok-1] = sss ;
cpt = strtok( NULL , " \t\n\r\f\v" ) ;
}
*ntok = n_tok ; *stok = s_tok ; return ;
}
static void duplicate_string_list( int nin , char ** sin , char *** sout )
{
int ii , ll ;
char ** s_out = NULL ;
if( sout == NULL ) return ;
if( nin < 1 || sin == NULL ){ *sout = NULL ; return ; }
s_out = (char **) malloc( sizeof(char *) * nin ) ;
for( ii=0 ; ii < nin ; ii++ ){
ll = strlen(sin[ii]) ;
s_out[ii] = (char *) malloc( sizeof(char) * (ll+1) );
strcpy( s_out[ii] , sin[ii] ) ;
}
*sout = s_out ; return ;
}
static void free_string_list( int nin , char ** sin )
{
int ii ;
if( sin == NULL ) return ;
for( ii=0 ; ii < nin ; ii++ ) if( sin[ii] != NULL ) free(sin[ii]) ;
free(sin) ; return ;
}
static void appendto_string_list( int *nfirst , char *** sfirst ,
int nsecond , char ** ssecond )
{
int nf=*nfirst , ii , ll ;
char ** sf ;
if( nsecond < 1 || ssecond == NULL ) return ; /* nothing to do */
if( *sfirst == NULL || nf == 0 )
sf = (char **) malloc( sizeof(char *) * nsecond ) ;
else
sf = (char **) realloc( *sfirst , sizeof(char *)*(nf+nsecond) ) ;
for( ii=0 ; ii < nsecond ; ii++ ){
ll = strlen(ssecond[ii]) ;
sf[nf+ii] = (char *) malloc( sizeof(char) * (ll+1) ) ;
strcpy( sf[nf+ii] , ssecond[ii] ) ;
}
*nfirst = nf+nsecond ;
*sfirst = sf ; return ;
}
/*----------------------------------------------------------------------------
18 Nov 1999: Take the input string (sin) and put its pieces at the
front of the arg list, just after argv[0].
If *new_argv is returned as NULL, then there are no new args.
------------------------------------------------------------------------------*/
void prepend_string_to_args( char * sin ,
int argc , char * argv[] ,
int * new_argc , char *** new_argv )
{
int n_argc , ii , ntok=0 ;
char ** n_argv , ** stok=NULL ;
char * cpt , * sss ;
if( new_argc == NULL || new_argv == NULL ) return ; /* error */
if( sin == NULL || sin[0] == '\0' ){ *new_argv = NULL; return; } /* do nothing */
/*-- if no inputs after argv[0], prepend and append are identical --*/
if( argc < 2 ){
append_string_to_args( sin , argc , argv , new_argc , new_argv ) ;
return ;
}
/*-- OK, must do it my way --*/
tokenize_string( sin , &ntok , &stok ) ;
if( stok == NULL || ntok < 1 ){ *new_argv = NULL; return; } /* do nothing */
/* copy first input arg to output */
duplicate_string_list( 1 , argv , &n_argv ) ;
n_argc = 1 ;
/* append token list to output */
appendto_string_list( &n_argc , &n_argv , ntok , stok ) ;
free_string_list( ntok , stok ) ;
/* append rest of input args to output */
appendto_string_list( &n_argc , &n_argv , argc-1 , argv+1 ) ;
*new_argc = n_argc ; /* the results! */
*new_argv = n_argv ;
return ;
}
/*----------------------------------------------------------------------------
18 Nov 1999: Take the input string (sin) and append its pieces to
the existing command line arguments.
If *new_argv is returned as NULL, then there are no new args.
------------------------------------------------------------------------------*/
void append_string_to_args( char * sin ,
int argc , char * argv[] ,
int * new_argc , char *** new_argv )
{
int n_argc , ii , ntok=0 ;
char ** n_argv , ** stok=NULL ;
char * cpt , * sss ;
if( new_argc == NULL || new_argv == NULL ) return ; /* error */
if( sin == NULL || sin[0] == '\0' ){ *new_argv = NULL; return; } /* do nothing */
tokenize_string( sin , &ntok , &stok ) ;
if( stok == NULL || ntok < 1 ){ *new_argv = NULL; return; } /* do nothing */
/* copy input args to output */
if( argc > 0 ){
duplicate_string_list( argc , argv , &n_argv ) ;
n_argc = argc ;
} else { /* shouldn't happen */
n_argv = NULL ;
n_argc = 0 ;
}
/* append token list to output */
appendto_string_list( &n_argc , &n_argv , ntok , stok ) ;
free_string_list( ntok , stok ) ;
*new_argc = n_argc ; /* the results! */
*new_argv = n_argv ;
return ;
}
/*-------------------------------------------------------------------------------
Copy stdin to the command line arguments if the last argument on the
command line is '-@'.
18 Nov 1999: modified to put the actual args mangling in the routine above.
---------------------------------------------------------------------------------*/
void addto_args( int argc , char * argv[] , int * new_argc , char *** new_argv )
{
int ii , nsin , nall ;
char lbuf[4096] ;
char * sin , * cpt ;
/*-- sanity checks --*/
if( new_argc == NULL || new_argv == NULL ) return ;
if( strcmp(argv[argc-1],"-@") != 0 ){ *new_argv = NULL; return; } /* do nothing */
/* suck the standard input in */
nall = BLEN ;
sin = (char *) malloc( sizeof(char) * nall ) ; /* will hold stdin */
nsin = 0 ;
sin[0] = '\0'; /* 'terminate' this empty string 18 Apr 2006 [rickr] */
do{
cpt = fgets( lbuf , BLEN , stdin ) ; /* read line */
if( cpt == NULL ) break ; /* end of file */
ii = strlen(lbuf) ;
if( ii+nsin >= nall-4 ){ /* make more sin space */
nall += BLEN ;
sin = (char *) realloc( sin , sizeof(char) * nall ) ;
}
strcat(sin,lbuf) ; nsin = strlen(sin) ; /* add to sin array */
} while(1) ;
if( nsin == 0 ){ *new_argv = NULL; free(sin); return; } /* nothing was read */
append_string_to_args( sin , argc-1 , argv , new_argc , new_argv ) ; /* real work */
free(sin) ; return ;
}
syntax highlighted by Code2HTML, v. 0.9.1