Author: dteske
Date: Thu Mar  5 05:54:34 2015
New Revision: 279624
URL: https://svnweb.freebsd.org/changeset/base/279624

Log:
  sysrc(8): Add `key-=remove' and improve `key+=append' syntax
  
  MFC after:    3 days
  X-MFC-to:     stable/10 stable/9

Modified:
  head/usr.sbin/sysrc/sysrc
  head/usr.sbin/sysrc/sysrc.8

Modified: head/usr.sbin/sysrc/sysrc
==============================================================================
--- head/usr.sbin/sysrc/sysrc   Thu Mar  5 05:53:08 2015        (r279623)
+++ head/usr.sbin/sysrc/sysrc   Thu Mar  5 05:54:34 2015        (r279624)
@@ -1,6 +1,6 @@
 #!/bin/sh
 #-
-# Copyright (c) 2010-2014 Devin Teske
+# Copyright (c) 2010-2015 Devin Teske
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -40,7 +40,7 @@ BSDCFG_SHARE="/usr/share/bsdconfig"
 #
 # Version information
 #
-SYSRC_VERSION="6.2 Nov-3,2014"
+SYSRC_VERSION="6.3 Mar-4,2015"
 
 #
 # Options
@@ -94,7 +94,7 @@ help()
        local optfmt="\t%-11s%s\n"
        local envfmt="\t%-17s%s\n"
 
-       f_err "Usage: %s [OPTIONS] name[[+]=value] ...\n" "$pgm"
+       f_err "Usage: %s [OPTIONS] name[[+|-]=value] ...\n" "$pgm"
 
        f_err "OPTIONS:\n"
        f_err "$optfmt" "-a" \
@@ -531,6 +531,7 @@ while [ $# -gt 0 ]; do
 
        case "$NAME" in
        *+) mode=APPEND NAME="${NAME%+}" ;;
+       *-) mode=REMOVE NAME="${NAME%-}" ;;
         *) mode=ASSIGN
        esac
 
@@ -594,29 +595,70 @@ while [ $# -gt 0 ]; do
                fi
 
                #
-               # If `-N' is passed, simplify the output
+               # Determine both `before' value and appropriate `new' value
                #
-               if [ ! "$SHOW_VALUE" ]; then
-                       echo "$NAME"
-                       case "$mode" in
-                       APPEND)
-                               before=$( f_sysrc_get "$NAME" )
-                               f_sysrc_set "$NAME" "$before${1#*=}"
-                               ;;
-                       *)
-                               f_sysrc_set "$NAME" "${1#*=}"
+               case "$mode" in
+               APPEND)
+                       before=$( f_sysrc_get "$NAME" )
+                       add="${1#*=}"
+                       delim="${add%"${add#?}"}" # first character
+                       oldIFS="$IFS"
+                       case "$delim" in
+                       ""|[$IFS]|[a-zA-Z0-9]) delim=" " ;;
+                       *) IFS="$delim"
                        esac
-               else
+                       new="$before"
+                       for a in $add; do
+                               [ "$a" ] || continue
+                               skip=
+                               for b in $before; do
+                                       [ "$b" = "$a" ] && skip=1 break
+                               done
+                               [ "$skip" ] || new="$new$delim$a"
+                       done
+                       new="${new#"$delim"}" IFS="$oldIFS"
+                       unset add delim oldIFS a skip b
+                       [ "$SHOW_FILE" ] && before=$( f_sysrc_find "$NAME" )
+                       ;;
+               REMOVE)
+                       before=$( f_sysrc_get "$NAME" )
+                       remove="${1#*=}"
+                       delim="${remove%"${remove#?}"}" # first character
+                       oldIFS="$IFS"
+                       case "$delim" in
+                       ""|[$IFS]|[a-zA-Z0-9]) delim=" " ;;
+                       *) IFS="$delim"
+                       esac
+                       new=
+                       for b in $before; do
+                               [ "$b" ] || continue
+                               add=1
+                               for r in $remove; do
+                                       [ "$r" = "$b" ] && add= break
+                               done
+                               [ "$add" ] && new="$new$delim$b"
+                       done
+                       new="${new#"$delim"}" IFS="$oldIFS"
+                       unset remove delim oldIFS b add r
+                       [ "$SHOW_FILE" ] && before=$( f_sysrc_find "$NAME" )
+                       ;;
+               *)
                        if [ "$SHOW_FILE" ]; then
                                before=$( f_sysrc_find "$NAME" )
                        else
                                before=$( f_sysrc_get "$NAME" )
                        fi
-                       if case "$mode" in
-                               APPEND) f_sysrc_set "$NAME" "$before${1#*=}" ;;
-                                    *) f_sysrc_set "$NAME" "${1#*=}"
-                               esac
-                       then
+                       new="${1#*=}"
+               esac
+
+               #
+               # If `-N' is passed, simplify the output
+               #
+               if [ ! "$SHOW_VALUE" ]; then
+                       echo "$NAME"
+                       f_sysrc_set "$NAME" "$new"
+               else
+                       if f_sysrc_set "$NAME" "$new"; then
                                if [ "$SHOW_FILE" ]; then
                                        after=$( f_sysrc_find "$NAME" )
                                else

Modified: head/usr.sbin/sysrc/sysrc.8
==============================================================================
--- head/usr.sbin/sysrc/sysrc.8 Thu Mar  5 05:53:08 2015        (r279623)
+++ head/usr.sbin/sysrc/sysrc.8 Thu Mar  5 05:54:34 2015        (r279624)
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2011-2014 Devin Teske
+.\" Copyright (c) 2011-2015 Devin Teske
 .\" All rights reserved.
 .\"
 .\" Redistribution and use in source and binary forms, with or without
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd November 4, 2014
+.Dd March 4, 2015
 .Dt SYSRC 8
 .Os
 .Sh NAME
@@ -35,7 +35,7 @@
 .Op Fl cdDeFhinNqvx
 .Op Fl f Ar file
 .Op Fl j Ar jail | Fl R Ar dir
-.Ar name Ns Op Ns Oo + Oc Ns = Ns Ar value
+.Ar name Ns Op Ns Oo +|- Oc Ns = Ns Ar value
 .Ar ...
 .Nm
 .Op Fl cdDeFhinNqvx
@@ -136,9 +136,14 @@ and also has the same
 .Ql name[=value]
 syntax for making queries/assignments.
 In addition
-.Pq unlike Xr sysctl 8 ,
+.Pq but unlike Xr sysctl 8 ,
 .Ql name+=value
-is supported for appending values.
+is supported for adding items to values
+.Pq see APPENDING VALUES
+and
+.Ql name-=value
+is supported for removing items from values
+.Pq see SUBTRACTING VALUES .
 .Pp
 However, while
 .Xr sysctl 8
@@ -187,6 +192,115 @@ modifying these integral files (yet taki
 grow unwieldy should
 .Nm
 be called repeatedly).
+.Sh APPENDING VALUES
+When using the
+.Ql key+=value
+syntax to add items to existing values,
+the first character of the value is taken as the delimiter separating items
+.Pq usually Qo \  Qc or Qo , Qc .
+For example, in the following statement:
+.Bl -tag -width indent+
+.It \ 
+.Nm
+cloned_interfaces+=" gif0"
+.El
+.Pp
+the first character is a space, informing
+.Nm
+that existing values are to be considered separated by whitespace.
+If
+.Ql gif0
+is not found in the existing value for
+.Va cloned_interfaces ,
+it is added
+.Pq with delimiter only if existing value is non-NULL .
+.Pp
+For convenience, if the first character is alpha-numeric
+.Pq letters A-Z, a-z, or numbers 0-9 ,
+.Nm
+uses the default setting of whitespace as separator.
+For example, the above and below statements are equivalent since
+.Dq gif0
+starts with an alpha-numeric character
+.Pq the letter Li g :
+.Pp
+.Bl -tag -width indent+
+.It \ 
+.Nm
+cloned_interfaces+=gif0
+.El
+.Pp
+Take the following sequence for example:
+.Bl -tag -width indent+
+.It \ 
+.Nm
+cloned_interfaces= # start with NULL
+.It \ 
+.Nm
+cloned_interfaces+=gif0
+.Dl # NULL -> `gif0' Pq NB: no preceding delimiter
+.It \ 
+.Nm
+cloned_interfaces+=gif0 # no change
+.It \ 
+.Nm
+cloned_interfaces+="tun0 gif0"
+.Dl # `gif0' -> `gif0 tun0' Pq NB: no duplication
+.El
+.Pp
+.Nm
+prevents the same value from being added if already there.
+.Sh SUBTRACTING VALUES
+When using the
+.Ql key-=value
+syntax to remove items from existing values,
+the first character of the value is taken as the delimiter separating items
+.Pq usually Qo \  Qc or Qo , Qc .
+For example, in the following statement:
+.Pp
+.Dl Nm cloned_interfaces-=" gif0"
+.Pp
+the first character is a space, informing
+.Nm
+that existing values are to be considered separated by whitespace.
+If
+.Ql gif0
+is found in the existing value for
+.Va cloned_interfaces ,
+it is removed
+.Pq extra delimiters removed .
+.Pp
+For convenience, if the first character is alpha-numeric
+.Pq letters A-Z, a-z, or numbers 0-9 ,
+.Nm
+uses the default setting of whitespace as separator.
+For example, the above and below statements are equivalent since
+.Dq gif0
+starts with an alpha-numeric character
+.Pq the letter Li g :
+.Pp
+.Bl -tag -width indent+
+.It \ 
+.Nm
+cloned_interfaces-=gif0
+.El
+.Pp
+Take the following sequence for example:
+.Bl -tag -width indent+
+.It \ 
+.Nm
+foo="bar baz" # start
+.It \ 
+.Nm
+foo-=bar # `bar baz' -> `baz'
+.It \ 
+.Nm
+foo-=baz # `baz' -> NULL
+.El
+.Pp
+.Nm
+removes all occurrences of all items provided
+and collapses extra delimiters between items.
 .Sh ENVIRONMENT
 The following environment variables are referenced by
 .Nm :
@@ -250,8 +364,12 @@ Working on other files, such as
 Appending to existing values:
 .Pp
 .Nm
-\&cloned_interfaces+=" gif0"
-.Dl appends Qo \ gif0 Qc to $cloned_interfaces .
+\&cloned_interfaces+=gif0
+.Dl appends Qo gif0 Qc to $cloned_interfaces Pq see APPENDING VALUES .
+.Pp
+.Nm
+\&cloned_interfaces-=gif0
+.Dl removes Qo gif0 Qc from $cloned_interfaces Pq see SUBTRACTING VALUES .
 .Pp
 In addition to the above syntax,
 .Nm
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to