git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Pierre Habouzit <madcoder@debian.org>
To: git@vger.kernel.org
Cc: peff@peff.net, Johannes.Schindelin@gmx.de, gitster@pobox.com,
	Pierre Habouzit <madcoder@debian.org>
Subject: [PATCH] parse-opt: fake short strings for callers to believe in.
Date: Mon, 23 Jun 2008 23:11:22 +0200	[thread overview]
Message-ID: <1214255482-2086-5-git-send-email-madcoder@debian.org> (raw)
In-Reply-To: <1214255482-2086-4-git-send-email-madcoder@debian.org>

If we begin to parse -abc and that the parser knew about -a and -b, it
will fake a -c switch for the caller to deal with.

Of course in the case of -acb (supposing -c is not taking an argument) the
caller will have to be especially clever to do the same thing. We could
think about exposing an API to do so if it's really needed, but oh well...

Signed-off-by: Pierre Habouzit <madcoder@debian.org>
---
 parse-options.c |   18 ++++++++++++++++--
 parse-options.h |   12 ++++++++++++
 2 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/parse-options.c b/parse-options.c
index 1a1d4dc..f3fd296 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -248,6 +248,7 @@ void parse_options_start(struct parse_opt_ctx_t *ctx,
 	ctx->argv = argv + 1;
 	ctx->out  = argv;
 	ctx->flags = flags;
+	strbuf_init(&ctx->buf, 0);
 }
 
 static int usage_with_options_internal(const char * const *,
@@ -257,6 +258,9 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
                        const struct option *options,
                        const char * const usagestr[])
 {
+	/* we must reset ->opt, unknown short option leave it dangling */
+	ctx->opt = NULL;
+
 	for (; ctx->argc; ctx->argc--, ctx->argv++) {
 		const char *arg = ctx->argv[0];
 
@@ -275,7 +279,7 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
 			  case -1:
 				return parse_options_usage(usagestr, options);
 			  case -2:
-				return PARSE_OPT_UNKNOWN;
+				goto unknown_fixup;
 			}
 			if (ctx->opt)
 				check_typos(arg + 1, options);
@@ -286,10 +290,19 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
 				  case -1:
 					return parse_options_usage(usagestr, options);
 				  case -2:
-					return PARSE_OPT_UNKNOWN;
+					goto unknown_fixup;
 				}
 			}
 			continue;
+unknown_fixup:
+			/* fake a short option thing to hide the fact that we may have
+			 * started to parse aggregated stuff
+			 */
+			strbuf_reset(&ctx->buf);
+			strbuf_addch(&ctx->buf, '-');
+			strbuf_addstr(&ctx->buf, ctx->opt);
+			*ctx->argv = ctx->buf.buf;
+			return PARSE_OPT_UNKNOWN;
 		}
 
 		if (!arg[2]) { /* "--" */
@@ -318,6 +331,7 @@ int parse_options_end(struct parse_opt_ctx_t *ctx)
 {
 	memmove(ctx->out + ctx->cpidx, ctx->argv, ctx->argc * sizeof(*ctx->out));
 	ctx->out[ctx->cpidx + ctx->argc] = NULL;
+	strbuf_release(&ctx->buf);
 	return ctx->cpidx + ctx->argc;
 }
 
diff --git a/parse-options.h b/parse-options.h
index 9da5e8c..14447d5 100644
--- a/parse-options.h
+++ b/parse-options.h
@@ -1,6 +1,8 @@
 #ifndef PARSE_OPTIONS_H
 #define PARSE_OPTIONS_H
 
+#include "strbuf.h"
+
 enum parse_opt_type {
 	/* special types */
 	OPTION_END,
@@ -119,12 +121,18 @@ enum {
 	PARSE_OPT_UNKNOWN,
 };
 
+/*
+ * It's okay for the caller to consume argv/argc in the usual way.
+ * Other fields of that structure are private to parse-options and should not
+ * be modified in any way.
+ */
 struct parse_opt_ctx_t {
 	const char **argv;
 	const char **out;
 	int argc, cpidx;
 	const char *opt;
 	int flags;
+	struct strbuf buf;
 };
 
 extern int parse_options_usage(const char * const *usagestr,
@@ -133,6 +141,10 @@ extern int parse_options_usage(const char * const *usagestr,
 extern void parse_options_start(struct parse_opt_ctx_t *ctx,
                                 int argc, const char **argv, int flags);
 
+/* Warning: you cannot keep pointers to ctx->argv during the parse
+ *          because some "option strings" are faked. It's okay to use
+ *          ctx->argv after a parse_options_end obviously
+ */
 extern int parse_options_step(struct parse_opt_ctx_t *ctx,
                               const struct option *options,
                               const char * const usagestr[]);
-- 
1.5.6.117.g5fe2

  reply	other threads:[~2008-06-23 21:12 UTC|newest]

Thread overview: 82+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-06-23  5:15 Convert 'git blame' to parse_options() Linus Torvalds
2008-06-23  6:35 ` Junio C Hamano
2008-06-23 12:28   ` Johannes Schindelin
2008-06-23  8:22 ` [RFC] " Pierre Habouzit
2008-06-23 12:26   ` Johannes Schindelin
2008-06-23 15:53     ` Pierre Habouzit
2008-06-23 16:25       ` Johannes Schindelin
2008-06-23 16:25     ` Linus Torvalds
2008-06-23 16:49       ` Jeff King
2008-06-23 17:06         ` Linus Torvalds
2008-06-23 17:15           ` Jeff King
2008-06-23 17:32             ` Linus Torvalds
2008-06-23 18:15               ` Jeff King
2008-06-23 18:36                 ` Linus Torvalds
2008-06-23 18:20               ` Linus Torvalds
2008-06-23 18:33                 ` Jeff King
2008-06-23 18:47                   ` Linus Torvalds
2008-06-23 19:16                     ` Linus Torvalds
2008-06-23 21:09                       ` Pierre Habouzit
2008-06-23 21:11                         ` [PATCH] parse-opt: have parse_options_{start,end} Pierre Habouzit
2008-06-23 21:11                           ` [PATCH] parse-opt: Export a non NORETURN usage dumper Pierre Habouzit
2008-06-23 21:11                             ` [PATCH] parse-opt: create parse_options_step Pierre Habouzit
2008-06-23 21:11                               ` [PATCH] parse-opt: do not pring errors on unknown options, return -2 intead Pierre Habouzit
2008-06-23 21:11                                 ` Pierre Habouzit [this message]
2008-06-23 22:08                                 ` Junio C Hamano
2008-06-23 22:13                                   ` Pierre Habouzit
2008-06-23 21:23                         ` [RFC] Re: Convert 'git blame' to parse_options() Pierre Habouzit
2008-06-23 21:23                         ` Junio C Hamano
2008-06-23 21:28                           ` Pierre Habouzit
2008-06-23 21:26                         ` Linus Torvalds
2008-06-23 21:41                           ` Linus Torvalds
2008-06-23 21:47                           ` Pierre Habouzit
2008-06-23 22:11                           ` Junio C Hamano
2008-06-23 22:24                             ` Pierre Habouzit
2008-06-23 22:36                               ` Pierre Habouzit
2008-06-23 22:38                               ` Junio C Hamano
2008-06-23 23:31                                 ` Pierre Habouzit
2008-06-23 23:40                                   ` Linus Torvalds
2008-06-23 23:51                                   ` Junio C Hamano
2008-06-24  7:50                                     ` Pierre Habouzit
2008-06-24  1:27                                   ` Jeff King
2008-06-23 19:53                     ` Jeff King
2008-06-23 20:04                       ` Pierre Habouzit
2008-06-23 20:12                       ` Linus Torvalds
2008-06-24  5:35                         ` Jeff King
2008-06-24 16:59                           ` Linus Torvalds
2008-06-24 17:13                             ` Johannes Schindelin
2008-06-24 17:34                             ` Jeff King
2008-06-24 17:44                               ` Linus Torvalds
2008-06-24 19:46                                 ` Jeff King
2008-06-24  0:30                 ` Junio C Hamano
2008-06-24  8:24                   ` Pierre Habouzit
2008-06-24 17:05                     ` Linus Torvalds
2008-06-24 19:30                       ` Pierre Habouzit
2008-06-24 19:43                         ` Pierre Habouzit
2008-06-25  6:09                         ` Johannes Sixt
2008-06-23 17:04       ` Johannes Schindelin
2008-06-23 17:21         ` Linus Torvalds
2008-06-23 18:39           ` Johannes Schindelin
2008-06-23 17:26         ` Jeff King
2008-06-23 18:41           ` Johannes Schindelin
2008-06-23 19:24       ` Pierre Habouzit
2008-06-23 16:11   ` Linus Torvalds
2008-06-24  9:12 ` Making parse-opt incremental, reworked series Pierre Habouzit
2008-06-24  9:12   ` [PATCH 1/7] parse-opt: have parse_options_{start,end} Pierre Habouzit
2008-06-24  9:12     ` [PATCH 2/7] parse-opt: Export a non NORETURN usage dumper Pierre Habouzit
2008-06-24  9:12       ` [PATCH 3/7] parse-opt: create parse_options_step Pierre Habouzit
2008-06-24  9:12         ` [PATCH 4/7] parse-opt: do not pring errors on unknown options, return -2 intead Pierre Habouzit
2008-06-24  9:12           ` [PATCH 5/7] parse-opt: fake short strings for callers to believe in Pierre Habouzit
2008-06-24  9:12             ` [PATCH 6/7] parse-opt: add PARSE_OPT_KEEP_ARGV0 parser option Pierre Habouzit
2008-06-24  9:12               ` [PATCH 7/7] Migrate git-blame to parse-option partially Pierre Habouzit
2008-06-24 10:03               ` [PATCH 6/7] parse-opt: add PARSE_OPT_KEEP_ARGV0 parser option Pierre Habouzit
2008-06-24 17:18               ` Linus Torvalds
2008-06-24 19:27                 ` Pierre Habouzit
2008-06-24 20:55                 ` Pierre Habouzit
2008-06-24 17:20             ` [PATCH 5/7] parse-opt: fake short strings for callers to believe in Linus Torvalds
2008-06-24 19:26               ` Pierre Habouzit
2008-06-25 15:07                 ` Andreas Ericsson
2008-06-24 20:58             ` [REPLACEMENT PATCH] " Pierre Habouzit
2008-06-26  8:35               ` Pierre Habouzit
2008-06-26  8:40                 ` Junio C Hamano
2008-06-26  9:37                   ` Pierre Habouzit

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1214255482-2086-5-git-send-email-madcoder@debian.org \
    --to=madcoder@debian.org \
    --cc=Johannes.Schindelin@gmx.de \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=peff@peff.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).