From 6b7f9285c430ae198b1190a6454b503da716fa6f Mon Sep 17 00:00:00 2001 From: Einhard Leichtfuß Date: Tue, 25 Dec 2018 19:43:45 +0100 Subject: Use arrays for the program variables Also, - Fix --search-by-data with $output_program != cat. `- Required a the introduction of $tmp_dir. - Correct some bad explanation in ctct_config(5). - Correctly initialize $user_config_file in the script. --- CHANGELOG | 2 ++ TODO | 4 +++- ctct.in | 71 ++++++++++++++++++++++++++++++++++++++++---------------- ctct_config.5.in | 45 ++++++++++++++++++++--------------- ctct_config.in | 10 ++++---- 5 files changed, 87 insertions(+), 45 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index a9b6d65..967666e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -19,6 +19,8 @@ General: `- E.g., if $datadir/a+b exists, it will no longer be listed or matched. - Make --search-by-data more efficient. `- Call grep on all files at once. +- Use arrays for the program variables. + `- This allows for example (sed -E 's/\s+/ /') as output_program. Manual: diff --git a/TODO b/TODO index aa09340..a23117d 100644 --- a/TODO +++ b/TODO @@ -3,7 +3,6 @@ TODO file for ctct [GENERAL] * Honor $VISUAL. * Honor XDG user dirs. -* Use arrays for the program configuration variables. * Use git tags for future versions. * [consider] Remove character restriction except '.', '/'. * [consider] Require at least one argument for --search-by-*. @@ -28,7 +27,10 @@ TODO file for ctct separator. [INTERNAL] +* Be consistent in usage of [, test, [[. +* Be consistent in quoting. * [consider] Initial cd to $datadir. +* [consider] Global attribute for a program variable whether non 'cat'. [MANUAL] * Add an EXAMPLE section to ctct(1). diff --git a/ctct.in b/ctct.in index e1cad6b..55f926d 100644 --- a/ctct.in +++ b/ctct.in @@ -18,15 +18,18 @@ # along with ctct. If not, see . # +typeset -a fallback_editor default_editor +typeset -a input_program output_program visual_program + ## DEFAULT SETTINGS: sysconfdir="@sysconfdir_expanded@" -user_config_file="@user_config_file@" +user_config_file="@default_user_config_file@" datadir="@default_datadir@" -fallback_editor="@default_fallback_editor@" -default_editor= # none - use $EDITOR -input_program="@default_input_program@" -output_program="@default_output_program@" -visual_program="@default_visual_program@" +fallback_editor=("@default_fallback_editor@") +default_editor=() # none - use $EDITOR +input_program=("@default_input_program@") +output_program=("@default_output_program@") +visual_program=("@default_visual_program@") confirm_deletion=@default_confirm_deletion@ confirm_default_yes=@default_confirm_default_yes@ @@ -67,6 +70,7 @@ EOF function cleanup() { test -v tmp_file && test -f "$tmp_file" && rm -f "$tmp_file" + test -v tmp_dir && test -d "$tmp_dir" && rm -rf "$tmp_dir" } trap cleanup EXIT @@ -168,11 +172,16 @@ function display_exact() check_syntax "$1" || return $RET_BADSYNTAX file="$datadir/$(get_filename "$1")" || return $RET_FAILURE - if test "$visual_program" = "cat" + if [ "$visual_program" = "cat" ] && [ ${#visual_program[@]} -eq 1 ] + then + "${output_program[@]}" < "$file" || return $RET_ERROR + elif [ "$output_program" = "cat" ] && [ ${#output_program[@]} -eq 1 ] then - $output_program < "$file" || return $RET_ERROR + "${visual_program[@]}" < "$file" || return $RET_ERROR else - $output_program < "$file" | $visual_program || return $RET_ERROR + "${output_program[@]}" < "$file" | "${visual_program[@]}" + [[ ${PIPESTATUS[0]} -eq 0 || ${PIPESTATUS[1]} -eq 0 ]] \ + || return $RET_ERROR fi return $RET_SUCCESS @@ -234,6 +243,21 @@ function search_by_data() cd "$datadir" files=( $(list_all || return $RET_ERROR) ) + if [ "$output_program" = "cat" ] && [ ${#output_program[@]} -eq 1 ] + then + unset tmp_dir + else + tmp_dir="$(mktemp -d)" + + for file in ${files[@]} + do + "${output_program[@]}" < $file > "${tmp_dir}/${file}" \ + || return $RET_ERROR + done + + cd "$tmp_dir" + fi + for regexp in "${@,,}" do files=( $(grep -Eil "$regexp" ${files[@]}) ) @@ -242,6 +266,11 @@ function search_by_data() [ $ret -gt 1 ] && return $RET_ERROR done + if test -n "$tmp_dir" + then + rm -rf "$tmp_dir" && unset tmp_dir || return $RET_ERROR + fi + print_msg "$msg" printf " %s\n" ${files[@]} return $RET_SUCCESS @@ -266,7 +295,8 @@ function list_all() # $1: contact name function edit_contact() { - local file editor new + local file new + typeset -a editor check_syntax "$1" || return $RET_BADSYNTAX @@ -282,17 +312,18 @@ function edit_contact() fi fi - if test -n "$default_editor" + if test -n "${default_editor[*]}" then - editor="$default_editor" - elif test -n "$EDITOR" && which "$EDITOR" >/dev/null 2>&1 + editor=( "${default_editor[@]}" ) + elif test -n "$EDITOR" && which "${EDITOR% *}" >/dev/null 2>&1 then - editor="$EDITOR" + editor=( $EDITOR ) else - editor="$fallback_editor" + editor=( "${fallback_editor[@]}" ) fi - if test "$input_program" = "cat" -a "$output_program" = "cat" + if [ "$input_program" = "cat" ] && [ ${#input_program[@]} -eq 1 ] \ + && [ "$output_program" = "cat" ] && [ ${#output_program[@]} -eq 1 ] then if $new then @@ -300,18 +331,18 @@ function edit_contact() touch "$file" || return $RET_ERROR fi - $editor "$file" || return $RET_ERROR + "${editor[@]}" "$file" || return $RET_ERROR else tmp_file="$(mktemp || return $RET_ERROR)" chmod 600 "$tmp_file" || return $RET_ERROR if ! $new then - $output_program < "$file" > "$tmp_file" || return $RET_ERROR + "${output_program[@]}" < "$file" > "$tmp_file" || return $RET_ERROR fi - $editor "$tmp_file" || return $RET_ERROR - $input_program < "$tmp_file" > "$file" || return $RET_ERROR + "${editor[@]}" "$tmp_file" || return $RET_ERROR + "${input_program[@]}" < "$tmp_file" > "$file" || return $RET_ERROR rm -f "$tmp_file" && unset tmp_file || return $RET_ERROR fi diff --git a/ctct_config.5.in b/ctct_config.5.in index f29f64b..198683f 100644 --- a/ctct_config.5.in +++ b/ctct_config.5.in @@ -37,12 +37,18 @@ Any configuration is done by setting shell variables\. Configuration may be overriden in per-user configuration scripts, see .BR user_config_file \. .P +To configure the choice of external programs, array variables are used\. +For these, the first element is the executable name; further elements may +specify arguments to the respective program\. +.P The following variables are recognized: .\" .TP -.B user_config_file -The per user configuration file. -If set, this variable must contain the prefix +.BR user_config_file "=\fIfile\fP" +The per user configuration file\. +If set, +.I file +must contain the prefix .I $HOME or alternatively any other variable resolving to a directory below the respective home directory\. @@ -50,17 +56,17 @@ The default value is .IR @default_user_config_file@ \. .\" .TP -.B datadir +.BR datadir "=\fIpath\fP" The location of the directory where the contact data are stored\. Typically, -.B datadir +.I path should contain the prefix .IR $HOME \. The default value is .IR @default_datadir@ \. .\" .TP -.B default_editor +.BR default_editor "=(\fIprogram\fP [\|\fIarg\fP \.\.\.\|])" The editor to use when .B ctct is called with the @@ -71,10 +77,10 @@ If set, supersedes both the environment variable and the .BR fallback_editor \. -By default, unset. +By default, unset\. .\" .TP -.B fallback_editor +.BR fallback_editor "=(\fIprogram\fP [\|\fIarg\fP \.\.\.\|])" The editor to fall back to if neither the environment variable .RB $ EDITOR nor @@ -84,9 +90,9 @@ The default value is .IR @default_fallback_editor@ \. .\" .TP -.B input_program -The program with arguments -that gets passed the data written after editing a contact entry\. +.BR input_program "=(\fIprogram\fP [\|\fIarg\fP \.\.\.\|])" +The program that gets passed the data written after editing a contact +entry\. This is mostly useful in combination with an .B output_program to enable encryption\. @@ -107,14 +113,15 @@ option, will operate on a temporary file populated by the output of When editing is done, the .B input_program will receive the content of that temporary file on stdin and its stdout -will be written on disk. +will be written on disk\. The default value is .IR @default_input_program@ \. .\" .TP -.B output_program -The program with arguments -that any contact data that are to be print are passed to\. +.BR output_program "=(\fIprogram\fP [\|\fIarg\fP \.\.\.\|])" +The program to convert data as stored on disk to human readable form\. +It should be inverse to +.BR input_program \. Note, that the respective program must accept its input on stdin and print its output on stdout\. This option is hence not useful for pagers such as @@ -130,11 +137,11 @@ For further details, see .BR input_program \. .\" .TP -.B visual_program +.BR visual_program "=(\fIprogram\fP [\|\fIarg\fP \.\.\.\|])" The program that the data as written by the .B output_program are passed to\. -It can be used with any program accepting its input on stdin. +It can be used with any program accepting its input on stdin\. Common options are .BR less (1) and @@ -146,7 +153,7 @@ The default value is .IR @default_visual_program@ \. .\" .TP -.B confirm_deletion +.BR confirm_deletion "=\fIboolean\fP" Whether to ask for confirmation upon deleting an entry, that is when .BR ctct (1) is called with the @@ -156,7 +163,7 @@ The default value is .IR @default_confirm_deletion@ \. .\" .TP -.B confirm_default_yes +.BR confirm_default_yes "=\fIboolean\fP" Whether to assume yes as answer to confirmation when no answer, that is an empty answer is given\. This option only has an effect, if diff --git a/ctct_config.in b/ctct_config.in index 19b1799..a5cba35 100644 --- a/ctct_config.in +++ b/ctct_config.in @@ -6,10 +6,10 @@ # user_config_file="@default_user_config_file@" # datadir="@default_datadir@" -# fallback_editor="@default_fallback_editor@" -# default_editor= -# input_program="@default_input_program@" -# output_program="@default_output_program@" -# visual_program="@default_visual_program@" +# fallback_editor=("@default_fallback_editor@") +# default_editor=() +# input_program=("@default_input_program@") +# output_program=("@default_output_program@") +# visual_program=("@default_visual_program@") # confirm_deletion=@default_confirm_deletion@ # confirm_default_yes=@default_confirm_default_yes@ -- cgit v1.2.3