1 /*****************************************************************************
2 Major portions of this software are copyrighted by the Medical College
3 of Wisconsin, 1994-2000, and are released under the Gnu General Public
4 License, Version 2. See the file README.Copyright for details.
5 ******************************************************************************/
6
7 #include "cs.h"
8 #include <string.h>
9
10 #define BLEN 40960
11
12 /*------------------ 18 Nov 1999: utility routines --------------------*/
13
tokenize_string(char * sin,int * ntok,char *** stok)14 static void tokenize_string( char * sin , int * ntok , char *** stok )
15 {
16 int n_tok , ii ;
17 char ** s_tok , *cpt , *sss ;
18
19 if( stok == NULL ) return ;
20 if( ntok == NULL || sin == NULL || sin[0] == '\0' ){ *stok = NULL; return; }
21
22 n_tok = 0 ;
23 s_tok = (char **) malloc( sizeof(char *) ) ;
24
25 /* break input into tokens, copy them in the new arg list */
26
27 cpt = strtok( sin , " \t\n\r\f\v" ) ;
28 if( cpt == NULL ){ free(s_tok); *stok = NULL; return; } /* do nothing */
29
30 while( cpt != NULL ){
31 ii = strlen(cpt) ;
32 sss = (char *) malloc( sizeof(char) * (ii+1) ) ;
33 strcpy(sss,cpt) ;
34 n_tok++ ;
35 s_tok = (char **) realloc( s_tok , sizeof(char *) * n_tok ) ;
36 s_tok[n_tok-1] = sss ;
37
38 cpt = strtok( NULL , " \t\n\r\f\v" ) ;
39 }
40
41 *ntok = n_tok ; *stok = s_tok ; return ;
42 }
43
duplicate_string_list(int nin,char ** sin,char *** sout)44 static void duplicate_string_list( int nin , char ** sin , char *** sout )
45 {
46 int ii , ll ;
47 char ** s_out = NULL ;
48
49 if( sout == NULL ) return ;
50 if( nin < 1 || sin == NULL ){ *sout = NULL ; return ; }
51
52 s_out = (char **) malloc( sizeof(char *) * nin ) ;
53 for( ii=0 ; ii < nin ; ii++ ){
54 ll = strlen(sin[ii]) ;
55 s_out[ii] = (char *) malloc( sizeof(char) * (ll+1) );
56 strcpy( s_out[ii] , sin[ii] ) ;
57 }
58
59 *sout = s_out ; return ;
60 }
61
free_string_list(int nin,char ** sin)62 static void free_string_list( int nin , char ** sin )
63 {
64 int ii ;
65 if( sin == NULL ) return ;
66 for( ii=0 ; ii < nin ; ii++ ) if( sin[ii] != NULL ) free(sin[ii]) ;
67 free(sin) ; return ;
68 }
69
appendto_string_list(int * nfirst,char *** sfirst,int nsecond,char ** ssecond)70 static void appendto_string_list( int *nfirst , char *** sfirst ,
71 int nsecond , char ** ssecond )
72 {
73 int nf=*nfirst , ii , ll ;
74 char ** sf ;
75
76 if( nsecond < 1 || ssecond == NULL ) return ; /* nothing to do */
77
78 if( *sfirst == NULL || nf == 0 )
79 sf = (char **) malloc( sizeof(char *) * nsecond ) ;
80 else
81 sf = (char **) realloc( *sfirst , sizeof(char *)*(nf+nsecond) ) ;
82
83 for( ii=0 ; ii < nsecond ; ii++ ){
84 ll = strlen(ssecond[ii]) ;
85 sf[nf+ii] = (char *) malloc( sizeof(char) * (ll+1) ) ;
86 strcpy( sf[nf+ii] , ssecond[ii] ) ;
87 }
88
89 *nfirst = nf+nsecond ;
90 *sfirst = sf ; return ;
91 }
92
93 /*----------------------------------------------------------------------------
94 18 Nov 1999: Take the input string (sin) and put its pieces at the
95 front of the arg list, just after argv[0].
96 If *new_argv is returned as NULL, then there are no new args.
97 ------------------------------------------------------------------------------*/
98
prepend_string_to_args(char * sin,int argc,char * argv[],int * new_argc,char *** new_argv)99 void prepend_string_to_args( char * sin ,
100 int argc , char * argv[] ,
101 int * new_argc , char *** new_argv )
102 {
103 int n_argc , ii , ntok=0 ;
104 char ** n_argv , ** stok=NULL ;
105 char * cpt , * sss ;
106
107 if( new_argc == NULL || new_argv == NULL ) return ; /* error */
108
109 if( sin == NULL || sin[0] == '\0' ){ *new_argv = NULL; return; } /* do nothing */
110
111 /*-- if no inputs after argv[0], prepend and append are identical --*/
112
113 if( argc < 2 ){
114 append_string_to_args( sin , argc , argv , new_argc , new_argv ) ;
115 return ;
116 }
117
118 /*-- OK, must do it my way --*/
119
120 tokenize_string( sin , &ntok , &stok ) ;
121 if( stok == NULL || ntok < 1 ){ *new_argv = NULL; return; } /* do nothing */
122
123 /* copy first input arg to output */
124
125 duplicate_string_list( 1 , argv , &n_argv ) ;
126 n_argc = 1 ;
127
128 /* append token list to output */
129
130 appendto_string_list( &n_argc , &n_argv , ntok , stok ) ;
131 free_string_list( ntok , stok ) ;
132
133 /* append rest of input args to output */
134
135 appendto_string_list( &n_argc , &n_argv , argc-1 , argv+1 ) ;
136
137 *new_argc = n_argc ; /* the results! */
138 *new_argv = n_argv ;
139 return ;
140 }
141
142 /*----------------------------------------------------------------------------
143 18 Nov 1999: Take the input string (sin) and append its pieces to
144 the existing command line arguments.
145 If *new_argv is returned as NULL, then there are no new args.
146 ------------------------------------------------------------------------------*/
147
append_string_to_args(char * sin,int argc,char * argv[],int * new_argc,char *** new_argv)148 void append_string_to_args( char * sin ,
149 int argc , char * argv[] ,
150 int * new_argc , char *** new_argv )
151 {
152 int n_argc , ii , ntok=0 ;
153 char ** n_argv , ** stok=NULL ;
154 char * cpt , * sss ;
155
156 if( new_argc == NULL || new_argv == NULL ) return ; /* error */
157
158 if( sin == NULL || sin[0] == '\0' ){ *new_argv = NULL; return; } /* do nothing */
159
160 tokenize_string( sin , &ntok , &stok ) ;
161 if( stok == NULL || ntok < 1 ){ *new_argv = NULL; return; } /* do nothing */
162
163 /* copy input args to output */
164
165 if( argc > 0 ){
166 duplicate_string_list( argc , argv , &n_argv ) ;
167 n_argc = argc ;
168 } else { /* shouldn't happen */
169 n_argv = NULL ;
170 n_argc = 0 ;
171 }
172
173 /* append token list to output */
174
175 appendto_string_list( &n_argc , &n_argv , ntok , stok ) ;
176 free_string_list( ntok , stok ) ;
177
178 *new_argc = n_argc ; /* the results! */
179 *new_argv = n_argv ;
180 return ;
181 }
182
183 /*-------------------------------------------------------------------------------
184 Copy stdin to the command line arguments if the last argument on the
185 command line is '-@'.
186 18 Nov 1999: modified to put the actual args mangling in the routine above.
187 ---------------------------------------------------------------------------------*/
188
addto_args(int argc,char * argv[],int * new_argc,char *** new_argv)189 void addto_args( int argc , char * argv[] , int * new_argc , char *** new_argv )
190 {
191 int ii , nsin , nall ;
192 char lbuf[4096] ;
193 char * sin , * cpt ;
194
195 /*-- sanity checks --*/
196
197 if( new_argc == NULL || new_argv == NULL ) return ;
198
199 if( strcmp(argv[argc-1],"-@") != 0 ){ *new_argv = NULL; return; } /* do nothing */
200
201 /* suck the standard input in */
202
203 nall = BLEN ;
204 sin = (char *) malloc( sizeof(char) * nall ) ; /* will hold stdin */
205 nsin = 0 ;
206
207 sin[0] = '\0'; /* 'terminate' this empty string 18 Apr 2006 [rickr] */
208
209 do{
210 cpt = afni_fgets( lbuf , BLEN , stdin ) ; /* read line */
211 if( cpt == NULL ) break ; /* end of file */
212 ii = strlen(lbuf) ;
213 if( ii+nsin >= nall-4 ){ /* make more sin space */
214 nall += BLEN ;
215 sin = (char *) realloc( sin , sizeof(char) * nall ) ;
216 }
217 strcat(sin,lbuf) ; nsin = strlen(sin) ; /* add to sin array */
218 } while(1) ;
219
220 if( nsin == 0 ){ *new_argv = NULL; free(sin); return; } /* nothing was read */
221
222 append_string_to_args( sin , argc-1 , argv , new_argc , new_argv ) ; /* real work */
223
224 free(sin) ; return ;
225 }
226