/***************************************************************************** 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 #define BLEN 40960 /*------------------ 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 = afni_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 ; }