Fossil SCM

Initial --args FILENAME patch. Impl seems over-complex to me, but works as described in the list thread.

stephan 2011-10-04 21:41 UTC stephan-hack
Commit 8a6568c3a32521cfacb6034e32f61ab3b141f883
1 file changed +137
+137
--- src/main.c
+++ src/main.c
@@ -231,10 +231,144 @@
231231
return 0;
232232
}
233233
return 1+(cnt>1);
234234
}
235235
236
+/*
237
+** Reads all non-empty lines of the given file and replaces g.argv
238
+** with their contents. argsPos is the position of the --args
239
+** parameter, and zFile is assumed to be the argument immediately
240
+** following g.argv[argsPos].
241
+**
242
+** FIXME: this impl is certainly way too complicated.
243
+*/
244
+static void read_args_lines(unsigned int argsPos, char const * zFile){
245
+ Blob buffer = empty_blob;
246
+ Blob line = empty_blob;
247
+ typedef struct StringList {
248
+ char * str;
249
+ struct StringList * next;
250
+ } StringList;
251
+ StringList * head = NULL;
252
+ StringList * current = NULL;
253
+ FILE * infile;
254
+ int blobSize = 0;
255
+ unsigned int lineCount = 0;
256
+ unsigned int i = 0;
257
+ assert(argsPos>=1);
258
+ assert(g.argc>=(argsPos+1));
259
+ assert(0==strcmp(zFile,g.argv[argsPos+1]));
260
+ infile = fopen(zFile,"rb");
261
+ if(!infile){
262
+ fossil_panic("Could not open file [%s].",zFile);
263
+ }
264
+ blob_read_from_channel(&buffer,infile,-1);
265
+ fclose(infile);
266
+ blobSize = blob_size(&buffer);
267
+ if(blobSize<=0){
268
+ /* FIXME? error here? */
269
+ blob_reset(&buffer);
270
+ return;
271
+ }
272
+ blob_rewind(&buffer);
273
+ while(1){
274
+ int lineLen = blob_line(&buffer,&line);
275
+ StringList * next = NULL;
276
+ if(0==lineLen){
277
+ break;
278
+ }
279
+ else if(lineLen<2){
280
+ continue; /* ignore empty lines */
281
+ }
282
+ next = (StringList*)calloc(1,sizeof(StringList));
283
+ ++lineCount;
284
+ if( !head ) {
285
+ head = next;
286
+ }
287
+ if( current ){
288
+ current->next = next;
289
+ current = next;
290
+ }else{
291
+ assert(head==next);
292
+ current = head;
293
+ }
294
+ current->str = strdup(blob_buffer(&line));
295
+ current->str[lineLen-1] = 0/*replace \n with NULL. FIXME: strip \r as well.*/;
296
+ blob_reset(&line);
297
+ }
298
+ blob_reset(&buffer);
299
+ if(lineCount){
300
+ int const newArgc = g.argc + lineCount - 2;
301
+ unsigned int i;
302
+ unsigned int argOffset = 0;
303
+ char ** newArgv = calloc(newArgc,sizeof(char*));
304
+ assert(NULL != newArgv);
305
+ for(i = 0; i < argsPos; ++i){
306
+ newArgv[i] = g.argv[i];
307
+ }
308
+ argOffset = i;
309
+ current = head;
310
+ for( i = 0; i < lineCount; ++i, ++argOffset ){
311
+ StringList * toFree = current;
312
+ assert(NULL != current);
313
+ assert(NULL != current->str);
314
+ newArgv[argOffset] = current->str;
315
+ current = current->next;
316
+ free(toFree);
317
+ }
318
+ /* FIXME: to simplify the code we move the --args args AFTER all
319
+ others. This is, however, arguablly very wrong. We should
320
+ instead insert them in place of --args XYZ.
321
+ */
322
+ for(i = argsPos+2; i < g.argc; ++i, ++argOffset){
323
+ newArgv[argOffset] = g.argv[i];
324
+ }
325
+ assert(NULL==current);
326
+ g.argc = newArgc;
327
+ g.argv = newArgv;
328
+ }
329
+#if 0
330
+ {
331
+ int i;
332
+ printf("g.argc=%d\n",g.argc);
333
+ for( i = 0; i < g.argc; ++i ){
334
+ printf("g.argv[%d] = %s\n",i, g.argv[i]);
335
+ }
336
+ }
337
+#endif
338
+}
339
+
340
+
341
+/*
342
+** Reads the --args FILENAME CLI option and massages g.argc/g.argv
343
+*/
344
+static void expand_args_arg(){
345
+ assert((g.argc>0) && g.argv[g.argc-1]);
346
+ if(g.argc<3){
347
+ return;
348
+ }else{
349
+ unsigned int i = 1;
350
+ char got = 0;
351
+ for( ; i < (unsigned int)g.argc; ++i ){
352
+ if(0==strcmp("--args",g.argv[i])){
353
+ got = 1;
354
+ break;
355
+ }
356
+ }
357
+ if(!got){
358
+ return;
359
+ }else{
360
+ char const * zFile;
361
+ if(i==(g.argc-1)){
362
+ /* FIXME: error out/exit here. Missing filename. */
363
+ return;
364
+ }
365
+ zFile = g.argv[i+1];
366
+ read_args_lines(i,zFile);
367
+ }
368
+ }
369
+}
236370
237371
/*
238372
** This procedure runs first.
239373
*/
240374
int main(int argc, char **argv){
@@ -245,10 +379,13 @@
245379
246380
sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
247381
g.now = time(0);
248382
g.argc = argc;
249383
g.argv = argv;
384
+ expand_args_arg();
385
+ argc = g.argc;
386
+ argv = g.argv;
250387
for(i=0; i<argc; i++) g.argv[i] = fossil_mbcs_to_utf8(argv[i]);
251388
if( getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){
252389
zCmdName = "cgi";
253390
}else if( argc<2 ){
254391
fossil_fatal("Usage: %s COMMAND ...\n"
255392
--- src/main.c
+++ src/main.c
@@ -231,10 +231,144 @@
231 return 0;
232 }
233 return 1+(cnt>1);
234 }
235
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
237 /*
238 ** This procedure runs first.
239 */
240 int main(int argc, char **argv){
@@ -245,10 +379,13 @@
245
246 sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
247 g.now = time(0);
248 g.argc = argc;
249 g.argv = argv;
 
 
 
250 for(i=0; i<argc; i++) g.argv[i] = fossil_mbcs_to_utf8(argv[i]);
251 if( getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){
252 zCmdName = "cgi";
253 }else if( argc<2 ){
254 fossil_fatal("Usage: %s COMMAND ...\n"
255
--- src/main.c
+++ src/main.c
@@ -231,10 +231,144 @@
231 return 0;
232 }
233 return 1+(cnt>1);
234 }
235
236 /*
237 ** Reads all non-empty lines of the given file and replaces g.argv
238 ** with their contents. argsPos is the position of the --args
239 ** parameter, and zFile is assumed to be the argument immediately
240 ** following g.argv[argsPos].
241 **
242 ** FIXME: this impl is certainly way too complicated.
243 */
244 static void read_args_lines(unsigned int argsPos, char const * zFile){
245 Blob buffer = empty_blob;
246 Blob line = empty_blob;
247 typedef struct StringList {
248 char * str;
249 struct StringList * next;
250 } StringList;
251 StringList * head = NULL;
252 StringList * current = NULL;
253 FILE * infile;
254 int blobSize = 0;
255 unsigned int lineCount = 0;
256 unsigned int i = 0;
257 assert(argsPos>=1);
258 assert(g.argc>=(argsPos+1));
259 assert(0==strcmp(zFile,g.argv[argsPos+1]));
260 infile = fopen(zFile,"rb");
261 if(!infile){
262 fossil_panic("Could not open file [%s].",zFile);
263 }
264 blob_read_from_channel(&buffer,infile,-1);
265 fclose(infile);
266 blobSize = blob_size(&buffer);
267 if(blobSize<=0){
268 /* FIXME? error here? */
269 blob_reset(&buffer);
270 return;
271 }
272 blob_rewind(&buffer);
273 while(1){
274 int lineLen = blob_line(&buffer,&line);
275 StringList * next = NULL;
276 if(0==lineLen){
277 break;
278 }
279 else if(lineLen<2){
280 continue; /* ignore empty lines */
281 }
282 next = (StringList*)calloc(1,sizeof(StringList));
283 ++lineCount;
284 if( !head ) {
285 head = next;
286 }
287 if( current ){
288 current->next = next;
289 current = next;
290 }else{
291 assert(head==next);
292 current = head;
293 }
294 current->str = strdup(blob_buffer(&line));
295 current->str[lineLen-1] = 0/*replace \n with NULL. FIXME: strip \r as well.*/;
296 blob_reset(&line);
297 }
298 blob_reset(&buffer);
299 if(lineCount){
300 int const newArgc = g.argc + lineCount - 2;
301 unsigned int i;
302 unsigned int argOffset = 0;
303 char ** newArgv = calloc(newArgc,sizeof(char*));
304 assert(NULL != newArgv);
305 for(i = 0; i < argsPos; ++i){
306 newArgv[i] = g.argv[i];
307 }
308 argOffset = i;
309 current = head;
310 for( i = 0; i < lineCount; ++i, ++argOffset ){
311 StringList * toFree = current;
312 assert(NULL != current);
313 assert(NULL != current->str);
314 newArgv[argOffset] = current->str;
315 current = current->next;
316 free(toFree);
317 }
318 /* FIXME: to simplify the code we move the --args args AFTER all
319 others. This is, however, arguablly very wrong. We should
320 instead insert them in place of --args XYZ.
321 */
322 for(i = argsPos+2; i < g.argc; ++i, ++argOffset){
323 newArgv[argOffset] = g.argv[i];
324 }
325 assert(NULL==current);
326 g.argc = newArgc;
327 g.argv = newArgv;
328 }
329 #if 0
330 {
331 int i;
332 printf("g.argc=%d\n",g.argc);
333 for( i = 0; i < g.argc; ++i ){
334 printf("g.argv[%d] = %s\n",i, g.argv[i]);
335 }
336 }
337 #endif
338 }
339
340
341 /*
342 ** Reads the --args FILENAME CLI option and massages g.argc/g.argv
343 */
344 static void expand_args_arg(){
345 assert((g.argc>0) && g.argv[g.argc-1]);
346 if(g.argc<3){
347 return;
348 }else{
349 unsigned int i = 1;
350 char got = 0;
351 for( ; i < (unsigned int)g.argc; ++i ){
352 if(0==strcmp("--args",g.argv[i])){
353 got = 1;
354 break;
355 }
356 }
357 if(!got){
358 return;
359 }else{
360 char const * zFile;
361 if(i==(g.argc-1)){
362 /* FIXME: error out/exit here. Missing filename. */
363 return;
364 }
365 zFile = g.argv[i+1];
366 read_args_lines(i,zFile);
367 }
368 }
369 }
370
371 /*
372 ** This procedure runs first.
373 */
374 int main(int argc, char **argv){
@@ -245,10 +379,13 @@
379
380 sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
381 g.now = time(0);
382 g.argc = argc;
383 g.argv = argv;
384 expand_args_arg();
385 argc = g.argc;
386 argv = g.argv;
387 for(i=0; i<argc; i++) g.argv[i] = fossil_mbcs_to_utf8(argv[i]);
388 if( getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){
389 zCmdName = "cgi";
390 }else if( argc<2 ){
391 fossil_fatal("Usage: %s COMMAND ...\n"
392

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button