~q3cpma/mus

ref: e99afe099fd0b6cf6a4cce58902c9612ecd9fca9 mus/mus_util.sh -rw-r--r-- 2.7 KiB
e99afe09q3cpma Finish build.sh and README, move TODO to root 1 year, 1 month ago
                                                                                
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
# Portable echo, without any option
echop()
{
	printf '%s\n' "$*"
}

# Print all arguments to stderr and exits with status 1
die()
{
	echop "[$(basename -- "$0")]" "$@" >&2
	exit 1
}

# Convert all arguments to lowercase
toupper()
{
	readargs "$@" | tr '[:lower:]' '[:upper:]'
}

# Format stdin so that __foo_bar__ is underlined and **foo*bar** is emboldened
text_format()
{
	if [ -t 1 ]
	then
		set +e
		_sgr0=$(tput sgr0)
		_bold=$(tput bold)
		_smul=$(tput smul)
		_rmul=$(tput rmul)
		set -e
	else
		_sgr0=
		_bold=
		_smul=
		_rmul=
	fi
	sed -E \
		-e ":a; s#([^_]|^)__(([^_]*(_[^_])*[^_]*)+)__([^_]|\$)#\1$_smul\2$_rmul\5#; ta" \
		-e ":b; s#([^*]|^)\*\*(([^\*]*(\*[^*])*[^*]*)+)\*\*([^*]|\$)#\1$_bold\2$_sgr0\5#; tb"
}

# flock wrapper with timeout handling. Pass $1 to sh with the rest of $@ as
# arguments; the file to flock must be the last argument
flock_try_cmd()
{
	set +e
	_cmd=$1
	shift
	eval _file=\$\{$#\}
	flock -E2 -w2 -- "$_file" sh -c "$_cmd" argv0 "$@"
	[ $? -eq 2 ] && die "$_file: lock aquisition timed out"
	set -e
}

# poll until a condition is true
poll_test()
{
	_poll_duration=$1
	shift
    until [ "$@" ]
	do
		sleep $_poll_duration
	done
}

# Returns 0 if $1 matches $2 (as an ERE), 1 otherwise
match()
{
	echop "$1" | grep -Eqx -- "$2"
}

# Die with an appropriate message if "test $1" returns false for any of the
# remaining argument paths or if one of these doesn't exists
requirefile()
{
	_testarg=$1
	shift
	for _i
	do
		[ ! -L "$_i" ] && [ ! -e "$_i" ] && die "$_i: file not found"
		if [ "$_testarg" != "-e" ] && [ ! "$_testarg" "$_i" ]
		then
			case "$_testarg" in
				-b)
					die "$_i: not a block device"
					;;
				-c)
					die "$_i: not a character special file"
					;;
				-d)
					die "$_i: not a directory"
					;;
				-f)
					die "$_i: not a regular file"
					;;
				-g)
					die "$_i: not a setgid file"
					;;
				-h|-L)
					die "$_i: not a symbolic link"
					;;
				-p)
					die "$_i: not a FIFO"
					;;
				-r)
					die "$_i: not a readable file"
					;;
				-S)
					die "$_i: not a socket"
					;;
				-s)
					die "$_i: not a non-empty file"
					;;
				-u)
					die "$_i: not a setuid file"
					;;
				-w)
					die "$_i: not a writeable file"
					;;
				-x)
					die "$_i: not a executable file"
					;;
			esac
		fi
	done
}

# Die with an appropriate message if one of the argument paths exists
forbidfile()
{
	for _i
	do
		if [ -L "$_i" ] || [ -e "$_i" ]
		then
			die "$_i: file already exists"
		fi
	done
}

# Output all arguments separated by '\n'. If there is no argument or the only
# argument is '-', output stdin instead
readargs()
{
	if [ $# -eq 0 ] || ([ $# -eq 1 ] && [ "$1" = "-" ])
	then
		cat
	else
		printf '%s\n' "$@"
	fi
}

# Portable xargs -d'\n'
xargsnl()
{
	tr '\n' '\0' | xargs -0 "$@"
}