forked from BRL-CAD/brlcad
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathws.sh
334 lines (316 loc) · 9.06 KB
/
ws.sh
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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
#!/bin/sh
# W S . S H
# BRL-CAD
#
# Copyright (c) 2007-2022 United States Government as represented by
# the U.S. Army Research Laboratory.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
#
# 3. The name of the author may not be used to endorse or promote
# products derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
###
#
# The purpose of this script is to update source files in a project so
# that they have more consistent whitespace (aka "ws") formatting.
#
# The list of things the script can perform are as follows:
#
# a) removes whitespace on lines that only have whitespace.
#
# b) removes whitespace at the end of any line.
#
# c) removes successive blank lines so there are no more than two
# in a row anywhere in a given file. WS_SUCCESSIVE=2
#
# d) removes all blank lines at the end of a file.
#
# e) ensures that there is a newline at the end of file.
#
# f) expand embedded tabs to spaces. (DISABLED BY DEFAULT)
#
# g) unexpands leading whitespace and tabs, inserting tabs at the
# default system tabstops. WS_TABSTOPS=8
#
# *) show progress. WS_PROGRESS=yes
#
# *) keep backups if a change is made. WS_BACKUPS=yes
#
# By default, the script will perform all of the above actions. You
# can customize the set of changes the script performs by setting the
# WS environment variable to the letter(s) of the task to run. There
# are also several other WS_* variables that can be set to modify
# default behavior settings.
#
# Examples:
# # only remove blank lines and whitespace at end of lines
# WS=abd ./ws.sh some_file
#
# # reduce collections of blank lines to no more than 2 in a row
# WS_SUCCESSIVE=2 WS=ac ./ws.sh some_file
#
# # run all tasks on all files in current directory without backups
# WS_BACKUPS=no find . -type f -exec ./ws.sh {} \;
#
###
files="$*"
# default settings
if [ "x$WS" = "x" ] ; then
# run everything
# NOTE: step f is disabled
WS=abcdeghijklmnopqrstuvwxyz
fi
if [ "x$WS_SUCCESSIVE" = "x" ] ; then
# how many blank lines in a row (max)
WS_SUCCESSIVE=2
fi
if [ ! "x$WS_TABSTOPS" = "x" ] ; then
echo "\
Overriding the default *system* tabstop of 8 is highly discouraged for
cross-platform and cross-software compatibility reasons. Display of
tabs is generally best left at the default, and instead modifying your
software's indentation level or tab *display* width instead.
This script will not change the indentation levels of your file.
There are other/better tools for that job.
"
else
# default tabtops for inserting real tabs
WS_TABSTOPS=8
fi
if [ "x$WS_PROGRESS" = "x" ] ; then
# show progress
WS_PROGRESS=yes
fi
if [ "x$WS_BACKUPS" = "x" ] ; then
# keep backups
WS_BACKUPS=yes
fi
# generate a list of files to check, excluding directories that are
# not BRL-CAD sources, revision control files, or start with a dot
# among other files. have to take care if including shell scripts;
# look for mistakes in here/now documents. this is, if no file
# arguments were provided.
if [ "x$files" = "x" ] ; then
files="`find . -type f -and \( \
-name '*.[0-9n]' -or \
-name '*.[aA][cC]' -or \
-name '*.[aA][mM]' -or \
-name '*.[cC]' -or \
-name '*.[cC]++' -or \
-name '*.[cC][cC]' -or \
-name '*.[cC][pP]' -or \
-name '*.[cC][pP][pP]' -or \
-name '*.[cC][xX][xX]' -or \
-name '*.[eE][lL]' -or \
-name '*.[fF]' -or \
-name '*.[fF][mM][tT]' -or \
-name '*.[hH]' -or \
-name '*.[hH][hH]' -or \
-name '*.[iI][tT][cC][lL]' -or \
-name '*.[iI][tT][kK]' -or \
-name '*.[jJ][aA][vV][aA]' -or \
-name '*.[mM]' -or \
-name '*.[mM]4' -or \
-name '*.[mM][mM]' -or \
-name '*.[pP][lL]' -or \
-name '*.[pP][yY]' -or \
-name '*.[sS][hH]' -or \
-name '*.[tT][cC][lL]' -or \
-name '*.[tT][kK]' -or \
-name '*.[tT][xX][tT]' -or \
-name '*.[xX][mM][lL]' -or \
-name 'AUTHORS*' -or \
-name 'COPYING*' -or \
-name 'DEVINFO*' -or \
-name 'HACKING*' -or \
-name 'NEWS*' -or \
-name 'NOTES*' -or \
-name 'README*' -or \
-name 'TODO*' \
\) | \
grep -v '/other/' | \
grep -v '/CVS/' | \
grep -v '/\.' | \
grep -v 'autom4te.cache' | \
grep -v 'aclocal.m4' | \
grep -v '.ws.bak' | \
grep -v '.ws.expand' | \
grep -v '.ws.new' \
`"
fi
# successive lines step c preparation
count=0
regex=""
while [ $count -lt $WS_SUCCESSIVE ] ; do
regex="$regex\n"
count=$((count + 1))
done
step_c_regex="'s/\n$regex\n*/\n$regex/g'"
# tab expansion step g preparation
count=1
regex1=""
regex2=""
while [ $count -lt $WS_TABSTOPS ] ; do
regex1="$regex1 ?"
regex2="$regex2 "
count=$((count + 1))
done
step_g_regex1="'s/^([\t]*)$regex1\t/\1\t/g'"
step_g_regex2="'s/^([\t]*)[ ]$regex2/\1\t/g'"
# begin processing files
for file in $files ; do
# show progress
if [ "x$WS_PROGRESS" = "xyes" ] ; then
printf "$file ... "
fi
# sanity checks
if [ -d "$file" ] ; then
echo ""
echo "WARNING: $file is a directory, skipping"
continue
elif [ ! -f "$file" ] ; then
echo ""
echo "WARNING: $file does not exist, skipping"
continue
elif [ ! -r "$file" ] ; then
echo ""
echo "WARNING: $file is not readable, skipping"
continue
elif [ ! -w "$file" ] ; then
echo ""
echo "WARNING: $file is not writeable, skipping"
continue
fi
# process a backup until we're sure a change is made
if [ -f "$file.ws.new" ] ; then
echo ""
echo "WARNING: $file.ws.new was in the way (overwritten)"
rm -f "$file.ws.new"
fi
cp "$file" "$file.ws.new"
# BEGIN WORK STEPS
steps="`echo $WS | sed 's/\(.\)/\1 /g'`"
for step in $steps ; do
case x$step in
x[aA])
# remove whitespace on lines with only whitespace
if [ "x$WS_PROGRESS" = "xyes" ] ; then
printf "a"
fi
perl -pi -e 's/^[ \t]*$//g' "$file.ws.new"
;;
x[bB])
# remove whitespace at end of all lines
if [ "x$WS_PROGRESS" = "xyes" ] ; then
printf "b"
fi
perl -pi -e 's/[ \t]*$//g' "$file.ws.new"
;;
x[cC])
# remove successive blank lines
if [ "x$WS_PROGRESS" = "xyes" ] ; then
printf "c"
fi
cmd="perl -0777 -pi -e $step_c_regex \"$file.ws.new\""
eval "$cmd"
;;
x[dD])
# remove all blank lines from end of file
if [ "x$WS_PROGRESS" = "xyes" ] ; then
printf "d"
fi
perl -0777 -pi -e 's/\n\n*$/\n/' "$file.ws.new"
;;
x[eE])
# ensure there is a trailing newline
if [ "x$WS_PROGRESS" = "xyes" ] ; then
printf "e"
fi
perl -0777 -pi -e 's/([^\n])\z/\1\n/' "$file.ws.new"
;;
x[fF])
# convert embedded tabs to spaces
if [ "x$WS_PROGRESS" = "xyes" ] ; then
printf "f"
fi
if [ -f "$file.ws.expand" ] ; then
echo "WARNING: $file.ws.expand was in the way (overwritten)"
rm -f "$file.ws.expand"
fi
# copy before redirect so permissions are retained
cp -p "$file.ws.new" "$file.ws.expand"
expand -t $WS_TABSTOPS "$file.ws.new" > "$file.ws.expand"
mv "$file.ws.expand" "$file.ws.new"
;;
x[gG])
# convert leading whitespace and tabs, insert tabs
if [ "x$WS_PROGRESS" = "xyes" ] ; then
printf "g"
fi
cmd1="perl -pi -e $step_g_regex1 \"$file.ws.new\""
cmd2="perl -pi -e $step_g_regex2 \"$file.ws.new\""
# regex woes, nasty hack -- iterate to clean up
# indentation one tab at a time.
count=0
while [ $count -lt 10 ] ; do
eval "$cmd1"
eval "$cmd2"
count="$((count + 1))"
done
;;
esac
done
# if the file changed, move it into place and keep a backup
filediff="`diff $file $file.ws.new`"
if [ "x$filediff" = "x" ] ; then
if [ "x$WS_PROGRESS" = "xyes" ] ; then
echo ""
fi
rm -f "$file.ws.new"
else
if [ "x$WS_PROGRESS" = "xyes" ] ; then
echo " ... FILE CHANGED"
fi
if [ "x$WS_BACKUPS" = "xyes" ] ; then
if [ -f "$file.ws.bak" ] ; then
echo ""
echo "WARNING: $file.ws.bak was in the way (overwritten)"
rm -f "$file.ws.bak"
fi
mv "$file" "$file.ws.bak"
fi
mv "$file.ws.new" "$file"
fi
done # iteration over files
# Local Variables:
# mode: sh
# tab-width: 8
# sh-indentation: 4
# sh-basic-offset: 4
# indent-tabs-mode: t
# End:
# ex: shiftwidth=4 tabstop=8