Fossil

Check-in [8a6568c3a3]
Login

Check-in [8a6568c3a3]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Initial --args FILENAME patch. Impl seems over-complex to me, but works as described in the list thread.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | stephan-hack
Files: files | file ages | folders
SHA1: 8a6568c3a32521cfacb6034e32f61ab3b141f883
User & Date: stephan 2011-10-04 21:41:35.436
Context
2011-10-04
23:03
Simplify the implementation of the --args FILENAME patch, as requested by the FIXME comment. ... (check-in: eb8d989dae user: drh tags: stephan-hack)
21:41
Initial --args FILENAME patch. Impl seems over-complex to me, but works as described in the list thread. ... (check-in: 8a6568c3a3 user: stephan tags: stephan-hack)
21:28
merging with trunk [d4a341b49dd1b701] before applying --args FILENAME patch, to simplify downstream merge. ... (check-in: 312d522fe4 user: stephan tags: stephan-hack)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/main.c.
229
230
231
232
233
234
235






































































































































236
237
238
239
240
241
242
243
244
245
246
247
248
249



250
251
252
253
254
255
256
  if( cnt==1 ){
    *pIndex = m;
    return 0;
  }
  return 1+(cnt>1);
}








































































































































/*
** This procedure runs first.
*/
int main(int argc, char **argv){
  const char *zCmdName = "unknown";
  int idx;
  int rc;
  int i;

  sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
  g.now = time(0);
  g.argc = argc;
  g.argv = argv;



  for(i=0; i<argc; i++) g.argv[i] = fossil_mbcs_to_utf8(argv[i]);
  if( getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){
    zCmdName = "cgi";
  }else if( argc<2 ){
    fossil_fatal("Usage: %s COMMAND ...\n"
                 "\"%s help\" for a list of available commands\n"
                 "\"%s help COMMAND\" for specific details\n",







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>














>
>
>







229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
  if( cnt==1 ){
    *pIndex = m;
    return 0;
  }
  return 1+(cnt>1);
}

/*
** Reads all non-empty lines of the given file and replaces g.argv
** with their contents. argsPos is the position of the --args
** parameter, and zFile is assumed to be the argument immediately
** following g.argv[argsPos].
**
** FIXME: this impl is certainly way too complicated.
*/
static void read_args_lines(unsigned int argsPos, char const * zFile){
  Blob buffer = empty_blob;
  Blob line = empty_blob;
  typedef struct StringList {
    char * str;
    struct StringList * next;
  } StringList;
  StringList * head = NULL;
  StringList * current = NULL;
  FILE * infile;
  int blobSize = 0;
  unsigned int lineCount = 0;
  unsigned int i = 0;
  assert(argsPos>=1);
  assert(g.argc>=(argsPos+1));
  assert(0==strcmp(zFile,g.argv[argsPos+1]));
  infile = fopen(zFile,"rb");
  if(!infile){
    fossil_panic("Could not open file [%s].",zFile);
  }
  blob_read_from_channel(&buffer,infile,-1);
  fclose(infile);
  blobSize = blob_size(&buffer);
  if(blobSize<=0){
    /* FIXME? error here? */
    blob_reset(&buffer);
    return;
  }
  blob_rewind(&buffer);
  while(1){
    int lineLen = blob_line(&buffer,&line);
    StringList * next = NULL;
    if(0==lineLen){
      break;
    }
    else if(lineLen<2){
      continue; /* ignore empty lines */
    }
    next = (StringList*)calloc(1,sizeof(StringList));
    ++lineCount;
    if( !head ) {
      head = next;
    }
    if( current ){
      current->next = next;
      current = next;
    }else{
      assert(head==next);
      current = head;
    }
    current->str = strdup(blob_buffer(&line));
    current->str[lineLen-1] = 0/*replace \n with NULL. FIXME: strip \r as well.*/;
    blob_reset(&line);
  }
  blob_reset(&buffer);
  if(lineCount){
    int const newArgc = g.argc + lineCount - 2;
    unsigned int i;
    unsigned int argOffset = 0;
    char ** newArgv = calloc(newArgc,sizeof(char*));
    assert(NULL != newArgv);
    for(i = 0; i < argsPos; ++i){
      newArgv[i] = g.argv[i];
    }
    argOffset = i;
    current = head;
    for( i = 0; i < lineCount; ++i, ++argOffset ){
      StringList * toFree = current;
      assert(NULL != current);
      assert(NULL != current->str);
      newArgv[argOffset] = current->str;
      current = current->next;
      free(toFree);
    }
    /* FIXME: to simplify the code we move the --args args AFTER all
       others. This is, however, arguablly very wrong. We should
       instead insert them in place of --args XYZ.
    */
    for(i = argsPos+2; i < g.argc; ++i, ++argOffset){
      newArgv[argOffset] = g.argv[i];
    }
    assert(NULL==current);
    g.argc = newArgc;
    g.argv = newArgv;
  }
#if 0
  {
    int i;
    printf("g.argc=%d\n",g.argc);
    for( i = 0; i < g.argc; ++i ){
      printf("g.argv[%d] = %s\n",i, g.argv[i]);
    }
  }
#endif
}


/*
** Reads the --args FILENAME CLI option and massages g.argc/g.argv
*/
static void expand_args_arg(){
  assert((g.argc>0) && g.argv[g.argc-1]);
  if(g.argc<3){
    return;
  }else{
    unsigned int i = 1;
    char got = 0;
    for( ; i < (unsigned int)g.argc; ++i ){
      if(0==strcmp("--args",g.argv[i])){
        got = 1;
        break;
      }
    }
    if(!got){
      return;
    }else{
      char const * zFile;
      if(i==(g.argc-1)){
        /* FIXME: error out/exit here. Missing filename. */
        return;
      }
      zFile = g.argv[i+1];
      read_args_lines(i,zFile);
    }
  }
}

/*
** This procedure runs first.
*/
int main(int argc, char **argv){
  const char *zCmdName = "unknown";
  int idx;
  int rc;
  int i;

  sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
  g.now = time(0);
  g.argc = argc;
  g.argv = argv;
  expand_args_arg();
  argc = g.argc;
  argv = g.argv;
  for(i=0; i<argc; i++) g.argv[i] = fossil_mbcs_to_utf8(argv[i]);
  if( getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){
    zCmdName = "cgi";
  }else if( argc<2 ){
    fossil_fatal("Usage: %s COMMAND ...\n"
                 "\"%s help\" for a list of available commands\n"
                 "\"%s help COMMAND\" for specific details\n",