Andre Noll [Sun, 5 Mar 2017 18:55:13 +0000 (19:55 +0100)]
subcommand: Use POSIX compatible command regex.
The POSIX way to ask for one or more matches of the preceeding atom
is {1,} while the plus character is a non-portable shortcut.
Note that since the closing brace of the regex bound is inside
parameter expansion, we need to escape it with a backslash while the
opening brace must not be escaped.
Andre Noll [Thu, 28 Jul 2016 11:56:05 +0000 (13:56 +0200)]
gsu_make_tempfile(): Avoid reading an unbound variable.
If a gsu script
(a) enables the -u option to treat unset variables as
an error for parameter expansion,
(b) does not set TMPDIR,
(c) calls gsu_make_tempfile(),
gsu_make_tempfile() fails with an "TMPDIR: unbound variable" error.
The code already contains a fallback for this case, so we can use
the :- construct to avoid the error and fall back to /tmp if TMPDIR
is unset or NULL.
Andre Noll [Wed, 20 Jan 2016 09:54:35 +0000 (10:54 +0100)]
Add gsu_make_tempfile() and fix bug in gui module.
While mkstemp(3) is required by POSIX.1-2001, mktemp(1) is not in POSIX
and the various Unixes ship different and incompatible implementations
of this command line utility.
This commit adds the new public gsu_make_tempfile() helper to the
common part of gsu and changes the gui module to use it.
The mktemp invocation in the gui module was buggy because it ran
mktemp with a relative template (no slash). Hence the temporary file
was created in the current working directory. Of course this fails
if $CWD is not writable. The new public function gets this right.
If a subcommand does not set $ret (like the minimal "hello" example
does), and sets the nounset bash option (set -u), gsu aborts at
the attempt to reference $ret. Fix this flaw by setting $ret to
$GSU_SUCCESS prior to calling the subcommand.
Andre Noll [Tue, 3 Mar 2015 17:15:52 +0000 (18:15 +0100)]
_gsu_print_available_commands(): Don't abort if set -e is set.
It was pointed out by Congmao Wang that the example hello.bash script
prints only the first subcommand and exits if it is called with an
invalid subcommand and set -e is set. This is due to the "let count++"
statement which returns 1 in the first iteration of the loop since
count is zero.
This patch changes the statement to "let ++count" which returns zero
in all cases.
Andre Noll [Sat, 14 Feb 2015 20:17:53 +0000 (21:17 +0100)]
common: Fix gsu_is_a_number().
We must use [ ... ] in gsu_is_a_number() because arithmetic expansion
with ((...)) undergoes parameter and variable expansion. For example
x=foo
gsu_is_a_number "$x"
will pass "foo" to gsu_is_a_number() where the expression (("$1"))
tries to expand the (non-existing) variable foo, aborting the script
if set -u was given.
This bug was introduced a few month ago in commit 44860e92 (Use modern
style arithmetic evaluation everwhere).
Andre Noll [Sat, 30 Aug 2014 12:46:37 +0000 (14:46 +0200)]
Add README.
Up to now the API of gsu was completely undocumented. This commit
tries to improve on this. It adds a README file which explains the
public functions and variables of the three gsu modules (subcommand,
config and gui). Most features are illustrated by examples.
The README file is formatted in the grutatxt markup language, so it
can easily be converted to a nice html document.
Many thanks to George Wang who read an early draft of this document
and contributed many improvements.
Andre Noll [Sat, 6 Sep 2014 17:41:16 +0000 (19:41 +0200)]
gui: Introduce _set_dialog_ret().
The improved exit code handling for dialog(1) also makes sense for
the other invocations of dialog. This patch abtracts out the logic
into the new internal _set_dialog_ret() function.
Andre Noll [Mon, 1 Sep 2014 22:23:41 +0000 (00:23 +0200)]
gui: Conform to $ret and $result conventions.
Unlike the rest of gsu, the functions of the gui module did not follow
the rule that functions should always set $ret to indicate error or
success, and $result to either the result of the function (if any)
or to an error context string. This commit makes all functions of
the gui module conform to this rule.
This patch also improves the error handling of _gsu_menu(). This
function should distinguish between three cases, according to the
exit code of dialog(1): OK (user selected the OK button), Cancel
(user pressed the escape key or selected the Cancel button), and error
(dialog(1) failed to execute or returned unsuccessfully).
The old code does not distinguish between the last two cases. Hence one
could not exit the application by pressing CTRL+C from a menu. This
patch changes _gsu_menu() to look more carefully at the exit code of
dialog(1) to tell apart the "error" case and the "cancel" case.
Andre Noll [Mon, 1 Sep 2014 21:58:29 +0000 (23:58 +0200)]
gui: Make _gsu_node_name_pattern private.
Conform to the convention that the name of a private variables should
start with an underscore character. Also there is no need to export
the variable.
Andre Noll [Mon, 1 Sep 2014 21:54:09 +0000 (23:54 +0200)]
gui: Make gsu_menu() private.
Its single caller is _browse(), which is a private function as
well. This patch prepends an underscore to the function name to
indicate that the function is not supposed to be called by application
code.
Andre Noll [Sun, 31 Aug 2014 17:06:40 +0000 (19:06 +0200)]
Fix _gsu_banner_msg().
This function did not print the banner at all. It also had only a
single caller. This patch removes the function and changes the single
caller to print the banner text.
Andre Noll [Sun, 31 Aug 2014 19:01:02 +0000 (21:01 +0200)]
Unify gsu_dir handling.
The three locations which include the common part of gsu need to know
the gsu installation directory. Currently we rely on the application
to set $gsu_dir. This is unnecessary since gsu can tell where it is
installed by examining ${BASH_SOURCE[0]}.
Also the fallback to $HOME/.gsu is not required. This commit unifies
all three locations and also calls _gsu_setup as early as possible:
when the gsu module is sourced.
This function is rather confused. It uses gsu_short_msg() to print
the header to stderr while the list of subcommands is printed to
stdout. This is "fixed" by executing all commands in a subshell and
redirecting stderr to stdout.
It's easier to just print everything to stdout. This patch also
renames the loop variable i to cmd, declares $count as a local
integer variable and switches to single quoted string constants.
Andre Noll [Tue, 26 Aug 2014 21:18:58 +0000 (23:18 +0200)]
gsu: Improve documentation of _gsu_get_command_regex().
Although this function is private, it is central to the subcommand
part of gsu and should thus be properly documented. The new text is
more precise about the meaning of the regular expression that is used
to identify subcommands.
Andre Noll [Tue, 26 Aug 2014 19:52:07 +0000 (21:52 +0200)]
gsu: Don't fail if HOME is unset.
As pointed out by Joffrey Fitz, gsu-based scripts do not work when
run as a user without home directory. This happens for example if
the script is executed through a web application as the www-data user.
This patch replaces all references to HOME by ${HOME:-}, i.e. we just
default to the empty string but don't fail immediately.
Andre Noll [Mon, 25 Aug 2014 20:24:07 +0000 (22:24 +0200)]
gsu: Improve documentation of gsu_getopts().
The sentence which explains how $o_X is set for both types of options
was rather confusing. The new text should be better.
While we're at it,
* mention that getopts is a bash builtin
* switch to "modern" ((expr)) arithmetic evaluation in example
* use '' to quote constants in example
Andre Noll [Sun, 24 Aug 2014 14:57:08 +0000 (16:57 +0200)]
gsu: Improve help text of complete subcommand.
The current help text talks about two forms to run this command,
but only one is mentioned. This commit tries to clarify that the
function behaves differently when called without argument.
Andre Noll [Fri, 16 May 2014 13:35:32 +0000 (15:35 +0200)]
gsu: User banner text also for gsu gui.
Currently the $gsu_banner_txt variable is used only for subcommand
utilities but not for dialog-based tools. There is no real reason for
this restriction, so this commit starts to use the variable also for
the various GUIs.
Andre Noll [Fri, 13 Dec 2013 09:57:42 +0000 (10:57 +0100)]
gsu_gui: Add check for dialog executable.
Currently, programs which use gsu_gui exit silently with no indication about
what went wrong if dialog is not installed. This patch makes it print an error
message in this case.
Andre Noll [Wed, 12 Oct 2011 08:26:38 +0000 (10:26 +0200)]
gsu_getopts: Rename local variable opt to _gsu_getopts_opt.
As pointed out by Sebastian Stark, calling the loop variable "opt"
in code which is supposed to be eval'd by the application may conflict
with another local variable of the same name defined in the function
which calls gsu_getopt().
This could lead to rather obscure bugs which are hard to detect.
The callers don't use this loop variable directly, so we are free
to call it whatever we want. Therefore this patch renames $opt to
something which is much less likely to cause a conflict.
Andre Noll [Thu, 29 Sep 2011 13:12:33 +0000 (15:12 +0200)]
gsu: Overhaul of the rexexp matching for help commands.
The old sed scripts were unreadable and broken on non-gnu systems
since they made use of some gnuisms of grep and sed like \+ in regular
expressions to match at least one character or sed's T command which
jumps to a label if no substitution has been made since the most
recent reading of an input line.
This patch switches to extended regular expressions and replaces all
broken sed scripts by portable ones, which are known to work at least
on FreeBSD and MacOS. The new scripts are commented verbosely so that
any subsequent changes do not require a full rewrite, hopefully.
Andre Noll [Fri, 23 Sep 2011 15:21:58 +0000 (17:21 +0200)]
gsu: Initial completion support.
This adds the framework for command completion of scripts which make
use of the gsu subcommand library. The idea is to implement as much
as possible as generic helpers within gsu in order to minimize code
duplication in the scripts which source the gsu library.
The new "complete" subcommand is automatically included in each
application, just like the help, man and prefs commands we already
have. This subommand is meant to be used as the completer which calls
the custom subcommand completers included in the application.
Two new public helper functions, gsu_complete_options() and
gsu_cword_is_option_parameter() are introduced in this commit.
The former function takes a usual getopt string and completes according
to all options in this string. The latter is useful for completers
which need to determine whether the current word is the parameter to
some option in order to find out how to complete the current word.
For example, the -s option of cmt's vmem command takes a mandatory
parameter which is a number. So the completer for this command must
complete differently depending on whether the previous word is "-s".
Andre Noll [Fri, 23 Sep 2011 12:03:38 +0000 (14:03 +0200)]
Split gsu.
This patch splits the gsu file into two files for config parsing and
subcommand handling respectively. Each part may be used independently
of the other.
Moreover, all scripts which use gsu now include the needed parts
directly rather than relying on the shell to have already sourced
the needed gsu files. This shortens bash startup time and makes gsu
easier to use for people whose login shell is not bash.
Andre Noll [Tue, 2 Aug 2011 13:12:48 +0000 (15:12 +0200)]
Allow hyphens in command names.
There is no reason to forbid subcommands with hyphens, and sometimes
it is just natural have such a command. For instance if the subcommand
wraps an existing command with a hyphen like "apt-get".
So change the regular expression for subcommands accordingly.
Andre Noll [Tue, 2 Aug 2011 13:09:21 +0000 (15:09 +0200)]
gsu: Avoid duplication of command regex.
The regular expression for fining the subcommands was duplicated
four times in gsu. Needless to say that this resulted in more than
one variant of the expression...
Avoid this duplication by introducing the global gsu_command_regex
variable. While at it, use a more clever sed command in
_gsu_available_commands() which allows to kill a grep command.
Andre Noll [Thu, 25 Mar 2010 14:23:25 +0000 (15:23 +0100)]
gsu: Fix com_prefs() for invalid preferences.
The prefs command would print only empty values for
all options that come after an invalid option.
Refuse to execute com_prefs() in this case is the most
simple fix.