From owner-svn-src-head@FreeBSD.ORG Sun Jun 2 22:04:40 2013 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id DC8C3CBB; Sun, 2 Jun 2013 22:04:40 +0000 (UTC) (envelope-from dteske@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id CCCBA1A84; Sun, 2 Jun 2013 22:04:40 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r52M4eQA067559; Sun, 2 Jun 2013 22:04:40 GMT (envelope-from dteske@svn.freebsd.org) Received: (from dteske@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r52M4eYr067556; Sun, 2 Jun 2013 22:04:40 GMT (envelope-from dteske@svn.freebsd.org) Message-Id: <201306022204.r52M4eYr067556@svn.freebsd.org> From: Devin Teske Date: Sun, 2 Jun 2013 22:04:40 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r251265 - in head/usr.sbin/bsdconfig: . share X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 02 Jun 2013 22:04:40 -0000 Author: dteske Date: Sun Jun 2 22:04:39 2013 New Revision: 251265 URL: http://svnweb.freebsd.org/changeset/base/251265 Log: Fix option processing from the library layer to address unexpected behavior(s); e.g., `-Xd' versus `-dX' did not produce the same results. The libraries common.subr and dialog.subr automatically process the arguments passed to the program and enable/disable functionality without the need to process the arguments within your program. For example, if "$@" contains `-d', common.subr will see this and enable debugging regardless of whether you process "$@" yourself or not (this automatic processing can easily be disabled for custom scripts that don't want it; see the afore- mentioned scripts for additional details). NOTE: common.subr stores a copy of "$@" in $ARGV for convenient (and repeated) processing by libraries such as dialog.subr which provide such transparent functionality for the consuming script(s). However, the libraries don't know if a program wants to accept `extra' options. Flags are not really a problem, because the library can be programmed to silently ignore unknown flags. The trouble comes into play when the program wants to define an option that takes an argument. For example: bsdconfig -D logfile -X In the above example, the library uses getopts to process $ARGV and if it doesn't know that `-D' takes an argument, the option processing will prematurely terminate on `logfile' (this is standard/correct behavior for getopts but is undesired in our situation where we have partially off-loaded main argument processing). The problem is solved by allowing the program to define an extra set of options to be included in each library's handling of $ARGV. Only options that require arguments are truly necessary to be pre-specified in this new manner. Modified: head/usr.sbin/bsdconfig/bsdconfig head/usr.sbin/bsdconfig/share/common.subr head/usr.sbin/bsdconfig/share/dialog.subr Modified: head/usr.sbin/bsdconfig/bsdconfig ============================================================================== --- head/usr.sbin/bsdconfig/bsdconfig Sun Jun 2 20:02:50 2013 (r251264) +++ head/usr.sbin/bsdconfig/bsdconfig Sun Jun 2 22:04:39 2013 (r251265) @@ -29,6 +29,21 @@ # ############################################################ INCLUDES +# When common.subr is included, it automatically scans "$@" for `-d' and/or +# `-D file' arguments to conditionally enable debugging. Similarly, when +# dialog.subr is included, it automatically scans "$@" for `-X' and/or `-S'. +# To prevent this scanning from becoming confused by extra options, define +# any/all extra arguments to use in the optstring to getopts when scanning +# for dedicated options such as those described. +# +# NOTE: This needs to be declared before including `common.subr'. +# NOTE: You really only need to list flags that require an argument as unknown +# flags are silently accepted unless they take an argument (in which case +# the following argument will terminate option processing unless it looks +# like a flag). +# +GETOPTS_EXTRA="f:" + BSDCFG_SHARE="/usr/share/bsdconfig" . $BSDCFG_SHARE/common.subr || exit 1 f_dprintf "%s: loading includes..." "$0" Modified: head/usr.sbin/bsdconfig/share/common.subr ============================================================================== --- head/usr.sbin/bsdconfig/share/common.subr Sun Jun 2 20:02:50 2013 (r251264) +++ head/usr.sbin/bsdconfig/share/common.subr Sun Jun 2 22:04:39 2013 (r251265) @@ -77,6 +77,33 @@ export UNAME_R="$(uname -r)" # Release L # GETOPTS_STDARGS="dD:" +# +# The getopts builtin will return 1 either when the end of "$@" or the first +# invalid flag is reached. This makes it impossible to determine if you've +# processed all the arguments or simply have hit an invalid flag. In the cases +# where we want to tolerate invalid flags (f_debug_init() for example), the +# following variable can be appended to your optstring argument to getopts, +# preventing it from prematurely returning 1 before the end of the arguments. +# +# NOTE: This assumes that all unknown flags are argument-less. +# +GETOPTS_ALLFLAGS="abcdefghijklmnopqrstuvwxyz" +GETOPTS_ALLFLAGS="${GETOPTS_ALLFLAGS}ABCDEFGHIJKLMNOPQRSTUVWXYZ" +GETOPTS_ALLFLAGS="${GETOPTS_ALLFLAGS}0123456789" + +# +# When we get included, f_debug_init() will fire (unless $DEBUG_SELF_INITIALIZE +# is set to disable automatic initialization) and process "$@" for a few global +# options such as `-d' and/or `-D file'. However, if your program takes custom +# flags that take arguments, this automatic processing may fail unexpectedly. +# +# The solution to this problem is to pre-define (before including this file) +# the following variable (which defaults to NULL) to indicate that there are +# extra flags that should be considered when performing automatic processing of +# globally persistent flags. +# +: ${GETOPTS_EXTRA:=} + ############################################################ FUNCTIONS # f_dprintf $fmt [ $opts ... ] @@ -114,11 +141,11 @@ f_debug_init() local OPTIND f_dprintf "f_debug_init: ARGV=[%s] GETOPTS_STDARGS=[%s]" \ "$ARGV" "$GETOPTS_STDARGS" - while getopts "$GETOPTS_STDARGS" flag > /dev/null; do + while getopts "$GETOPTS_STDARGS$GETOPTS_EXTRA$GETOPTS_ALLFLAGS" flag \ + > /dev/null; do case "$flag" in d) debug=1;; D) debugFile="$OPTARG";; - \?) continue;; esac done shift $(( $OPTIND - 1 )) Modified: head/usr.sbin/bsdconfig/share/dialog.subr ============================================================================== --- head/usr.sbin/bsdconfig/share/dialog.subr Sun Jun 2 20:02:50 2013 (r251264) +++ head/usr.sbin/bsdconfig/share/dialog.subr Sun Jun 2 22:04:39 2013 (r251265) @@ -1970,18 +1970,20 @@ f_dialog_init() f_dprintf "f_dialog_init: ARGV=[%s] GETOPTS_STDARGS=[%s]" \ "$ARGV" "$GETOPTS_STDARGS" SECURE=$( set -- $ARGV - while getopts "$GETOPTS_STDARGS" flag > /dev/null; do + while getopts \ + "$GETOPTS_STDARGS$GETOPTS_EXTRA$GETOPTS_ALLFLAGS" \ + flag > /dev/null; do case "$flag" in S) echo 1;; - \?) continue;; esac done ) USE_XDIALOG=$( set -- $ARGV - while getopts $GETOPTS_STDARGS flag > /dev/null; do + while getopts \ + "$GETOPTS_STDARGS$GETOPTS_EXTRA$GETOPTS_ALLFLAGS" \ + flag > /dev/null; do case "$flag" in S|X) echo 1;; - \?) continue;; esac done )