From: Mark Walters Date: Sun, 3 Jun 2012 11:48:48 +0000 (+0100) Subject: [PATCH] cli: make the command line parser's errors more informative. X-Git-Url: http://git.tremily.us/gitweb.cgi?a=commitdiff_plain;h=9728a606001bca28871e5aff072aec85bacc151a;p=notmuch-archives.git [PATCH] cli: make the command line parser's errors more informative. --- diff --git a/b5/b0bb644df922ccf88b40d125c7734a3574ad06 b/b5/b0bb644df922ccf88b40d125c7734a3574ad06 new file mode 100644 index 000000000..1bb88d97e --- /dev/null +++ b/b5/b0bb644df922ccf88b40d125c7734a3574ad06 @@ -0,0 +1,189 @@ +Return-Path: +X-Original-To: notmuch@notmuchmail.org +Delivered-To: notmuch@notmuchmail.org +Received: from localhost (localhost [127.0.0.1]) + by olra.theworths.org (Postfix) with ESMTP id C5828431FBD + for ; Sun, 3 Jun 2012 04:48:52 -0700 (PDT) +X-Virus-Scanned: Debian amavisd-new at olra.theworths.org +X-Spam-Flag: NO +X-Spam-Score: 0.201 +X-Spam-Level: +X-Spam-Status: No, score=0.201 tagged_above=-999 required=5 + tests=[DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, + FREEMAIL_ENVFROM_END_DIGIT=1, FREEMAIL_FROM=0.001, + RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled +Received: from olra.theworths.org ([127.0.0.1]) + by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024) + with ESMTP id 1PHnEloarOmA for ; + Sun, 3 Jun 2012 04:48:52 -0700 (PDT) +Received: from mail-wg0-f45.google.com (mail-wg0-f45.google.com + [74.125.82.45]) (using TLSv1 with cipher RC4-SHA (128/128 bits)) (No client + certificate requested) by olra.theworths.org (Postfix) with ESMTPS id + 0C380431FAE for ; Sun, 3 Jun 2012 04:48:51 -0700 + (PDT) +Received: by wgbdt14 with SMTP id dt14so2743148wgb.2 + for ; Sun, 03 Jun 2012 04:48:50 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; + h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; + bh=LEHOHYCG8CDKJS852BxNc9bn0alJQB3UZE6HydZVfgM=; + b=0ORIE44Bm7fQNY4VLejFJJryJsthvQAMb3BU8iLNaZ2pTeV2gGsjYp3tATomSefybi + QHC6KGnOKAt9l+H9MQ3axu4sKh33oJIqHSGePn566c5+f/jSZnc3O1AkVrb2ADY4ZBWt + 2PQ8DSSyQJCj+fZNlfeQhoeWwDPkmazIxLwrkDXYqdatAp9mEIiC5Zgk1Rp+IJn1DN7h + W/irr1JNt85hkKb5Y0j7phaoROu8t7bDFrVUEqsgIaim2gJxMaqrWvGC0CyzmSpA1Epi + bLIGY/cvwNRGbdid43FvjlLqOUtkYu1R/iUF5OBEqED1VX7tVuqzniJmaC8GUlPjRMOg + J74A== +Received: by 10.216.216.148 with SMTP id g20mr8109988wep.187.1338724130670; + Sun, 03 Jun 2012 04:48:50 -0700 (PDT) +Received: from localhost (94-192-233-223.zone6.bethere.co.uk. + [94.192.233.223]) by mx.google.com with ESMTPS id + m20sm12149276wie.6.2012.06.03.04.48.49 (version=TLSv1/SSLv3 cipher=OTHER); + Sun, 03 Jun 2012 04:48:50 -0700 (PDT) +From: Mark Walters +To: notmuch@notmuchmail.org +Subject: [PATCH] cli: make the command line parser's errors more informative. +Date: Sun, 3 Jun 2012 12:48:48 +0100 +Message-Id: <1338724128-13158-1-git-send-email-markwalters1009@gmail.com> +X-Mailer: git-send-email 1.7.9.1 +In-Reply-To: <1338723972-13063-1-git-send-email-markwalters1009@gmail.com> +References: <1338723972-13063-1-git-send-email-markwalters1009@gmail.com> +X-BeenThere: notmuch@notmuchmail.org +X-Mailman-Version: 2.1.13 +Precedence: list +List-Id: "Use and development of the notmuch mail system." + +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +X-List-Received-Date: Sun, 03 Jun 2012 11:48:52 -0000 + +Previously, the cli parser was a little erratic in what errors it +reported and would fail silently in many cases (for example, when no +argument was passed to an integer option). This was particularly +annoying as the user could not (easily) tell whether the command +failed or just there were no search results. + +This patch tries to make the handling consistent and return a helpful +error message in all cases. +--- + + command-line-arguments.c | 66 ++++++++++++++++++++++++++++++++-------------- + 1 files changed, 46 insertions(+), 20 deletions(-) + +diff --git a/command-line-arguments.c b/command-line-arguments.c +index b0a0dab..ea56467 100644 +--- a/command-line-arguments.c ++++ b/command-line-arguments.c +@@ -30,9 +30,9 @@ _process_keyword_arg (const notmuch_opt_desc_t *arg_desc, char next, const char + keywords++; + } + if (next != 0) +- fprintf (stderr, "unknown keyword: %s\n", arg_str); ++ fprintf (stderr, "Unknown argument \"%s\" for option \"%s\".\n", arg_str, arg_desc->name); + else +- fprintf (stderr, "option %s needs a keyword\n", arg_desc->name); ++ fprintf (stderr, "Option \"%s\" needs a keyword argument.\n", arg_desc->name); + return FALSE; + } + +@@ -51,9 +51,43 @@ _process_boolean_arg (const notmuch_opt_desc_t *arg_desc, char next, const char + *((notmuch_bool_t *)arg_desc->output_var) = TRUE; + return TRUE; + } ++ fprintf (stderr, "Unknown argument \"%s\" for (boolean) option \"%s\".\n", arg_str, arg_desc->name); + return FALSE; + } + ++static notmuch_bool_t ++_process_int_arg (const notmuch_opt_desc_t *arg_desc, char next, const char *arg_str) { ++ ++ char *endptr; ++ if (next == 0 || arg_str[0] == 0) { ++ fprintf (stderr, "Option \"%s\" needs an integer argument.\n", arg_desc->name); ++ return FALSE; ++ } ++ ++ *((int *)arg_desc->output_var) = strtol (arg_str, &endptr, 10); ++ if (*endptr == 0) ++ return TRUE; ++ ++ fprintf (stderr, "Unable to parse argument \"%s\" for option \"%s\" as an integer.\n", ++ arg_str, arg_desc->name); ++ return FALSE; ++} ++ ++static notmuch_bool_t ++_process_string_arg (const notmuch_opt_desc_t *arg_desc, char next, const char *arg_str) { ++ ++ if (next == 0) { ++ fprintf (stderr, "Option \"%s\" needs a string argument.\n", arg_desc->name); ++ return FALSE; ++ } ++ if (arg_str[0] == 0) { ++ fprintf (stderr, "String argument for option \"%s\" must be non-empty.\n", arg_desc->name); ++ return FALSE; ++ } ++ *((const char **)arg_desc->output_var) = arg_str; ++ return TRUE; ++} ++ + /* + Search for the {pos_arg_index}th position argument, return FALSE if + that does not exist. +@@ -99,20 +133,13 @@ parse_option (const char *arg, + char next = arg[strlen (try->name)]; + const char *value= arg+strlen(try->name)+1; + +- char *endptr; +- +- /* Everything but boolean arguments (switches) needs a +- * delimiter, and a non-zero length value. Boolean +- * arguments may take an optional =true or =false value. +- */ +- if (next != '=' && next != ':' && next != 0) return FALSE; +- if (next == 0) { +- if (try->opt_type != NOTMUCH_OPT_BOOLEAN && +- try->opt_type != NOTMUCH_OPT_KEYWORD) +- return FALSE; +- } else { +- if (value[0] == 0) return FALSE; +- } ++ /* If this is not the end of the argument (i.e. the next ++ * character is not a space or a delimiter) we stop ++ * parsing for this option but allow the parsing to ++ * continue to for other options. This should allow ++ * options to be initial segments of other options. */ ++ if (next != '=' && next != ':' && next != 0) ++ goto DONE_THIS_OPTION; + + if (try->output_var == NULL) + INTERNAL_ERROR ("output pointer NULL for option %s", try->name); +@@ -125,12 +152,10 @@ parse_option (const char *arg, + return _process_boolean_arg (try, next, value); + break; + case NOTMUCH_OPT_INT: +- *((int *)try->output_var) = strtol (value, &endptr, 10); +- return (*endptr == 0); ++ return _process_int_arg (try, next, value); + break; + case NOTMUCH_OPT_STRING: +- *((const char **)try->output_var) = value; +- return TRUE; ++ return _process_string_arg (try, next, value); + break; + case NOTMUCH_OPT_POSITION: + case NOTMUCH_OPT_END: +@@ -139,6 +164,7 @@ parse_option (const char *arg, + /*UNREACHED*/ + } + } ++ DONE_THIS_OPTION: + try++; + } + fprintf (stderr, "Unrecognized option: --%s\n", arg); +-- +1.7.9.1 +