summaryrefslogtreecommitdiff
path: root/src/lib/libremessages
blob: 429a997880430988d1b3008f5d4e4a4c59b480a6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#!/usr/bin/env bash
# This may be included with or without `set -euE`
# When run directly, it does `set -euE`

# Copyright (C) 2011 Joshua Ismael Haase Hernández (xihh) <hahj87@gmail.com>
# Copyright (C) 2012 Nicolás Reynolds <fauno@parabola.nu>
# Copyright (C) 2012-2014 Luke Shumaker <lukeshu@sbcglobal.net>

# For just the setup_traps() function:
#   Copyright (C) 2002-2006 Judd Vinet <jvinet@zeroflux.org>
#   Copyright (C) 2006-2010 Pacman Development Team <pacman-dev@archlinux.org>
#   Copyright (C) 2005 Aurelien Foret <orelien@chez.com>
#   Copyright (C) 2005 Christian Hamar <krics@linuxforum.hu>
#   Copyright (C) 2006 Alex Smith <alex@alex-smith.me.uk>
#   Copyright (C) 2006 Andras Voroskoi <voroskoi@frugalware.org>
#   Copyright (C) 2006 Miklos Vajna <vmiklos@frugalware.org>
#
# License: GNU GPLv2+
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

################################################################################
# Inherit most functions from devtools                                         #
################################################################################

. "$(librelib common.sh)"

################################################################################
# Own functions                                                                #
################################################################################

# Usage: panic
# For programming errors, bails immediately with little fanfare.
panic() {
	echo "$(_l _ 'panic: malformed call to internal function')" >&2
	exit 1
}

# Usage: print MESG [ARGS...]
# Like printf, but gettext-aware, and prints a trailing newline
print() {
	[[ $# -ge 1 ]] || panic
	local mesg="$(_ "$1")"
	shift
	printf -- "$mesg\n" "$@"
}

# Do HTML-style whitespace collapsing on standard IO.
# It considers newline, tab, and space to be whitespace.
_libremessages_html_whitespace_collapse() {
	[[ $# == 0 ]] || panic
	tr '\n' ' ' | sed -r -e 's/\t/ /g' -e 's/  +/ /g'
}


# Usage: prose MESG [ARGS...]
# Do HTML-style whitespace collapsing on the first argument, translate it
# (gettext), then word-wrap it to 75 columns.
# This is useful for printing a paragraph of prose in --help text.
prose() {
	[[ $# -ge 1 ]] || panic
	local mesg="$(_ "$(_libremessages_html_whitespace_collapse <<<"$1")")"; shift
	printf -- "$mesg" "$@" | fmt -u
}

# Usage: bullet MESG [ARGS...]
# Like prose, but print a bullet "-" before the first line, and indent the
# remaining lines.
bullet() {
	[[ $# -ge 1 ]] || panic
	local mesg="$(_ "$(_libremessages_html_whitespace_collapse <<<"$1")")"; shift
	# Wrap the text to 71 columns; 75 (the default) minus a 4 column indent
	printf -- "$mesg" "$@" | fmt -u -w 71 | sed -e '1s/^/  - /' -e '2,$s/^/    /'
}

# Usage: flag FLAG DESCRIPTION
# Print a flag and description formatted for --help text.
#   ex: flag '-C <FILE>' 'Use this file instead of pacman.conf'
# The description is fed through gettext, the flag is not, so if part of the
# flag needs to be translated, you must do that yourself:
#   ex: flag "-C <$(_ FILE)>" 'Use this file instead of pacman.conf'
# If you want to line-break the description in the source, so it isn't
# crazy-long, feel free, it is reflowed/wrapped the same way as prose and
# bullet.
flag() {
	[[ $# == 2 ]] || panic
	local flag=$1
	local desc="$(_ "$(_libremessages_html_whitespace_collapse <<<"$2")")"

	# Unless the $flag is extra-wide, the $desc should start at
	# column 16 (that is two literal-tabs).  If $flag is wide,
	# this should be increased in increments of 8 (that is, a
	# literal-tab).  Everything should be wrapped to 75 columns.

	# The printf-format we use has 3 spaces built into it (two at
	# the beginning, and a seperator).  Therefore, the default
	# indent is 16-3=13 columns.  And the width left for $desc
	# is (75-3)-indent = 72-indent.

	declare -i indent=13
	while [[ $indent -le ${#flag} ]]; do
		indent=$((indent+8))
	done

	local lines
	IFS=$'\n' lines=($(fmt -u -w $((72-indent)) <<<"$desc"))
	local line
	for line in "${lines[@]}"; do
		printf "  %-${indent}s %s\n" "$flag" "$line"
		flag=''
	done
}

# Usage: term_title MESG [ARGS...]
# Sets the terminal title
term_title() {
	[[ $# -ge 1 ]] || panic
	local fmt=''
	case "$TERM" in
		screen|tmux) fmt='\ek%s\e\\';;
		xterm*|rxvt*) fmt='\e]0;%s\a';;
	esac
	printf "$fmt" "$(printf -- "$@")"
}

# Usage: setup_traps [handler]
# Sets up traps on TERM, HUP, QUIT and INT signals, as well as the ERR event,
# similar to makepkg.
#
# If `handler` is specified, instead of using the default handler
# (which is good for most purposes), it will call the command handler
# with the arguments:
#
#   ${handler} SIGNAL_NAME MESSAGE_FMT [MESSAGE_PARAMS...]
#
# where MESSAGE_* are printf-like stuff.
setup_traps() {
	[[ $# -le 1 ]] || panic
	if [[ $# == 1 ]]; then
		eval "_libremessages_trap_exit() { $1 \"\$@\"; }"
	else
		_libremessages_trap_exit() {
			local signal=$1; shift
			echo
			error "$@"
			trap -- "$signal"
			kill "-$signal" "$$"
		}
	fi
	set -E
	for signal in TERM HUP QUIT; do
		trap "_libremessages_trap_exit $signal '%s signal caught. Exiting...' $signal" $signal
	done
	trap '_libremessages_trap_exit INT "Aborted by user! Exiting..."' INT
	trap '_libremessages_trap_exit USR1 "An unknown error has occurred. Exiting..."' ERR
}

################################################################################
# Run one of the defined functions if invoked directly                         #
################################################################################

if [[ "${0##*/}" == libremessages ]]; then
	set -euE
	"$@"
fi