All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org
Cc: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [PATCH 02/75] parse-options: add one-shot mode
Date: Thu, 27 Dec 2018 17:25:23 +0100	[thread overview]
Message-ID: <20181227162536.15895-3-pclouds@gmail.com> (raw)
In-Reply-To: <20181227162536.15895-1-pclouds@gmail.com>

This is to help reimplement diff_opt_parse() using parse_options().
The behavior of parse_options() is changed to be the same as the
other:

- no argv0 in argv[], everything can be processed
- argv[] must not be updated, it's the caller's job to do that
- return the number of arguments processed
- leave all unknown options / non-options alone (this one can already
  be achieved with PARSE_OPT_KEEP_UNKNOWN and
  PARSE_OPT_STOP_AT_NON_OPTION)

This mode is NOT supposed to stay here for long. It's to help
converting diff/rev option parsing. Once that work is over and we can
just use parse_options() throughout the code base, this will be
deleted.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 parse-options.c | 23 ++++++++++++++++++++---
 parse-options.h | 17 +++++++++++++----
 2 files changed, 33 insertions(+), 7 deletions(-)

diff --git a/parse-options.c b/parse-options.c
index 6932eaff61..d47e217b07 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -415,15 +415,23 @@ void parse_options_start(struct parse_opt_ctx_t *ctx,
 			 const struct option *options, int flags)
 {
 	memset(ctx, 0, sizeof(*ctx));
-	ctx->argc = ctx->total = argc - 1;
-	ctx->argv = argv + 1;
-	ctx->out  = argv;
+	ctx->argc = argc;
+	ctx->argv = argv;
+	if (!(flags & PARSE_OPT_ONE_SHOT)) {
+		ctx->argc--;
+		ctx->argv++;
+	}
+	ctx->total = ctx->argc;
+	ctx->out   = argv;
 	ctx->prefix = prefix;
 	ctx->cpidx = ((flags & PARSE_OPT_KEEP_ARGV0) != 0);
 	ctx->flags = flags;
 	if ((flags & PARSE_OPT_KEEP_UNKNOWN) &&
 	    (flags & PARSE_OPT_STOP_AT_NON_OPTION))
 		die("STOP_AT_NON_OPTION and KEEP_UNKNOWN don't go together");
+	if ((flags & PARSE_OPT_ONE_SHOT) &&
+	    (flags & PARSE_OPT_KEEP_ARGV0))
+		BUG("Can't keep argv0 if you don't have it");
 	parse_options_check(options);
 }
 
@@ -535,6 +543,10 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
 	for (; ctx->argc; ctx->argc--, ctx->argv++) {
 		const char *arg = ctx->argv[0];
 
+		if (ctx->flags & PARSE_OPT_ONE_SHOT &&
+		    ctx->argc != ctx->total)
+			break;
+
 		if (*arg != '-' || !arg[1]) {
 			if (parse_nodash_opt(ctx, arg, options) == 0)
 				continue;
@@ -609,6 +621,8 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
 		}
 		continue;
 unknown:
+		if (ctx->flags & PARSE_OPT_ONE_SHOT)
+			break;
 		if (!(ctx->flags & PARSE_OPT_KEEP_UNKNOWN))
 			return PARSE_OPT_UNKNOWN;
 		ctx->out[ctx->cpidx++] = ctx->argv[0];
@@ -622,6 +636,9 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
 
 int parse_options_end(struct parse_opt_ctx_t *ctx)
 {
+	if (ctx->flags & PARSE_OPT_ONE_SHOT)
+		return ctx->total - ctx->argc;
+
 	MOVE_ARRAY(ctx->out + ctx->cpidx, ctx->argv, ctx->argc);
 	ctx->out[ctx->cpidx + ctx->argc] = NULL;
 	return ctx->cpidx + ctx->argc;
diff --git a/parse-options.h b/parse-options.h
index 1947cb27cf..043d296ea4 100644
--- a/parse-options.h
+++ b/parse-options.h
@@ -27,7 +27,8 @@ enum parse_opt_flags {
 	PARSE_OPT_STOP_AT_NON_OPTION = 2,
 	PARSE_OPT_KEEP_ARGV0 = 4,
 	PARSE_OPT_KEEP_UNKNOWN = 8,
-	PARSE_OPT_NO_INTERNAL_HELP = 16
+	PARSE_OPT_NO_INTERNAL_HELP = 16,
+	PARSE_OPT_ONE_SHOT = 32
 };
 
 enum parse_opt_option_flags {
@@ -169,10 +170,18 @@ struct option {
 	  N_("no-op (backward compatibility)"),		\
 	  PARSE_OPT_HIDDEN | PARSE_OPT_NOARG, parse_opt_noop_cb }
 
-/* parse_options() will filter out the processed options and leave the
- * non-option arguments in argv[]. usagestr strings should be marked
- * for translation with N_().
+/*
+ * parse_options() will filter out the processed options and leave the
+ * non-option arguments in argv[]. argv0 is assumed program name and
+ * skipped.
+ *
+ * usagestr strings should be marked for translation with N_().
+ *
  * Returns the number of arguments left in argv[].
+ *
+ * In one-shot mode, argv0 is not a program name, argv[] is left
+ * untouched and parse_options() returns the number of options
+ * processed.
  */
 int parse_options(int argc, const char **argv, const char *prefix,
 		  const struct option *options,
-- 
2.20.0.482.g66447595a7


  parent reply	other threads:[~2018-12-27 16:25 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-27 16:25 [PATCH 00/75] Convert diff opt parser to parse_options() Nguyễn Thái Ngọc Duy
2018-12-27 16:25 ` [PATCH 01/75] parse-options.h: remove extern on function prototypes Nguyễn Thái Ngọc Duy
2018-12-27 16:25 ` Nguyễn Thái Ngọc Duy [this message]
2018-12-27 16:25 ` [PATCH 03/75] parse-options: allow keep-unknown + stop-at-non-opt combination Nguyễn Thái Ngọc Duy
2018-12-27 16:25 ` [PATCH 04/75] parse-options: disable option abbreviation with PARSE_OPT_KEEP_UNKNOWN Nguyễn Thái Ngọc Duy
2018-12-27 16:25 ` [PATCH 05/75] parse-options: add OPT_BITOP() Nguyễn Thái Ngọc Duy
2018-12-27 16:25 ` [PATCH 06/75] parse-options: stop abusing 'callback' for lowlevel callbacks Nguyễn Thái Ngọc Duy
2018-12-27 16:25 ` [PATCH 07/75] parse-options: avoid magic return codes Nguyễn Thái Ngọc Duy
2018-12-27 16:25 ` [PATCH 08/75] parse-options: allow ll_callback with OPTION_CALLBACK Nguyễn Thái Ngọc Duy
2018-12-27 16:25 ` [PATCH 09/75] diff.h: keep forward struct declarations sorted Nguyễn Thái Ngọc Duy
2018-12-27 16:25 ` [PATCH 10/75] diff.h: avoid bit fields in struct diff_flags Nguyễn Thái Ngọc Duy
2019-01-09 20:21   ` Stefan Beller
2018-12-27 16:25 ` [PATCH 11/75] diff.c: prepare to use parse_options() for parsing Nguyễn Thái Ngọc Duy
2018-12-27 16:25 ` [PATCH 12/75] diff.c: convert -u|-p|--patch Nguyễn Thái Ngọc Duy
2018-12-27 16:25 ` [PATCH 73/75] range-diff: use parse_options() instead of diff_opt_parse() Nguyễn Thái Ngọc Duy
2018-12-27 16:25 ` [PATCH 74/75] diff --no-index: " Nguyễn Thái Ngọc Duy
2018-12-27 20:34   ` Eric Sunshine
2018-12-27 16:25 ` [PATCH 75/75] am: avoid diff_opt_parse() Nguyễn Thái Ngọc Duy

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=20181227162536.15895-3-pclouds@gmail.com \
    --to=pclouds@gmail.com \
    --cc=git@vger.kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.