Re: [RFC] Re: Convert 'git blame' to parse_options()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Jun 23, 2008 at 04:25:10PM +0000, Linus Torvalds wrote:
> 
> 
> On Mon, 23 Jun 2008, Johannes Schindelin wrote:
> > 
> > Thinking about the recursive approach again, I came up with this POC:
> 
> "recursive" is pointless.
> 
> The problem with the current "parse_options()" is not that it's recursive 
> (although that has been claimed multiple times!.
> 
> The problem with parse_options() is that it's currently impossible to 
> write something that handles _partial_ cases.
> 
> Let me explain.
> 
> Look at cmd_apply() in builtin-apply.c. Notice how it currently absolutely 
> CANNOT sanely be turned into using "parse_options()", not because it needs 
> any "recursive" handling, but simply because it wants to do *incremental* 
> handling.
> 
> It should be perfectly possible to change that argument loop from
> 
> 	for (i = 1; i < argc; i++) {
> 		const char *arg = argv[i];
> 		if (strcmp(arg, "-")) {
> 			.. handle <stdin> ..
> 			continue;
> 		}
> 		...
> 
> to doing something like this:
> 
> 	for (;;) {
> 		const char *arg;
> 		argc = parse_options(argc, argv,
> 			options, usage, PARSE_OPT_STOP_AT_UNKNOWN);
> 		if (!argc)
> 			break;
> 		arg = argv[1];
> 		argv++;
> 		argc--;
> 		if (strcmp(arg, "-")) {
> 			.. handle <stdin> ..
> 			continue;
> 		}
> 		...	
> 
> or whatever. See?

  Indeed, I read the thread many times, and I like the incremental
approach very much, it really makes sense, and we can easily migrate
code this way indeed. In fact that should have been the way
parse_options was designed from the beginning.

  There is a bit of work to do from this "handwaved" solution, because
people care about the filtered argv, so one should rememeber some kind
of "writing" position. SOmething like:


  parse_opt_ctx_t ctx;

  /* will basically copy argc/argv */
  parse_options_start(&ctx, argc, argv);

  for (;;) {
      const char *arg;
      int res = parse_options_step(&ctx, options, usage, 0));

      if (res == PARSE_OPT_HELP) {
          /* generate help and exit */
      }
      if (res == PARSE_OPT_DONE)
          break;

      arg = ctx->argv[ctx->pos++];
      if (strcmp(arg, "-")) {
          ... handle <stdin>....
          continue;
      }
  }

  argc = parse_options_end(&ctx);

  /* at this point (argc,argv) is almost what parse_options would have
     left us */


  THis way, parse_options can be written:

      parse_opt_ctx_t ctx;
      parse_options_start(&ctx, argc, argv);
      switch (parse_options_step(&ctx, options, usage, 0)) {
	  case PARSE_OPT_HELP: exit....
	  case PARSE_OPT_DONE: break;
	  default: exit(error("unknown option ....");
      }
      return parse_options_end(&ctx);

-- 
·O·  Pierre Habouzit
··O                                                madcoder@xxxxxxxxxx
OOO                                                http://www.madism.org

Attachment: pgpczOdrkmBMB.pgp
Description: PGP signature


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux