1.1 --- a/scripts/unify-sources.sh Fri Oct 16 10:21:37 2009 +0200
1.2 +++ b/scripts/unify-sources.sh Thu Nov 05 15:50:01 2009 +0100
1.3 @@ -1,17 +1,220 @@
1.4 #!/bin/bash
1.5 +#
1.6 +# This file is a part of LEMON, a generic C++ optimization library.
1.7 +#
1.8 +# Copyright (C) 2003-2009
1.9 +# Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
1.10 +# (Egervary Research Group on Combinatorial Optimization, EGRES).
1.11 +#
1.12 +# Permission to use, modify and distribute this software is granted
1.13 +# provided that this copyright notice appears in all copies. For
1.14 +# precise terms see the accompanying LICENSE file.
1.15 +#
1.16 +# This software is provided "AS IS" with no warranty of any kind,
1.17 +# express or implied, and with no claim as to its suitability for any
1.18 +# purpose.
1.19
1.20 -YEAR=`date +2003-%Y`
1.21 +YEAR=`date +%Y`
1.22 HGROOT=`hg root`
1.23
1.24 -function update_header() {
1.25 +function hg_year() {
1.26 + if [ -n "$(hg st $1)" ]; then
1.27 + echo $YEAR
1.28 + else
1.29 + hg log -l 1 --template='{date|isodate}\n' $1 |
1.30 + cut -d '-' -f 1
1.31 + fi
1.32 +}
1.33 +
1.34 +# file enumaration modes
1.35 +
1.36 +function all_files() {
1.37 + hg status -a -m -c |
1.38 + cut -d ' ' -f 2 | grep -E '(\.(cc|h|dox)$|Makefile\.am$)' |
1.39 + while read file; do echo $HGROOT/$file; done
1.40 +}
1.41 +
1.42 +function modified_files() {
1.43 + hg status -a -m |
1.44 + cut -d ' ' -f 2 | grep -E '(\.(cc|h|dox)$|Makefile\.am$)' |
1.45 + while read file; do echo $HGROOT/$file; done
1.46 +}
1.47 +
1.48 +function changed_files() {
1.49 + {
1.50 + if [ -n "$HG_PARENT1" ]
1.51 + then
1.52 + hg status --rev $HG_PARENT1:$HG_NODE -a -m
1.53 + fi
1.54 + if [ -n "$HG_PARENT2" ]
1.55 + then
1.56 + hg status --rev $HG_PARENT2:$HG_NODE -a -m
1.57 + fi
1.58 + } | cut -d ' ' -f 2 | grep -E '(\.(cc|h|dox)$|Makefile\.am$)' |
1.59 + sort | uniq |
1.60 + while read file; do echo $HGROOT/$file; done
1.61 +}
1.62 +
1.63 +function given_files() {
1.64 + for file in $GIVEN_FILES
1.65 + do
1.66 + echo $file
1.67 + done
1.68 +}
1.69 +
1.70 +# actions
1.71 +
1.72 +function update_action() {
1.73 + if ! diff -q $1 $2 >/dev/null
1.74 + then
1.75 + echo -n " [$3 updated]"
1.76 + rm $2
1.77 + mv $1 $2
1.78 + CHANGED=YES
1.79 + fi
1.80 +}
1.81 +
1.82 +function update_warning() {
1.83 + echo -n " [$2 warning]"
1.84 + WARNED=YES
1.85 +}
1.86 +
1.87 +function update_init() {
1.88 + echo Update source files...
1.89 + TOTAL_FILES=0
1.90 + CHANGED_FILES=0
1.91 + WARNED_FILES=0
1.92 +}
1.93 +
1.94 +function update_done() {
1.95 + echo $CHANGED_FILES out of $TOTAL_FILES files has been changed.
1.96 + echo $WARNED_FILES out of $TOTAL_FILES files triggered warnings.
1.97 +}
1.98 +
1.99 +function update_begin() {
1.100 + ((TOTAL_FILES++))
1.101 + CHANGED=NO
1.102 + WARNED=NO
1.103 +}
1.104 +
1.105 +function update_end() {
1.106 + if [ $CHANGED == YES ]
1.107 + then
1.108 + ((++CHANGED_FILES))
1.109 + fi
1.110 + if [ $WARNED == YES ]
1.111 + then
1.112 + ((++WARNED_FILES))
1.113 + fi
1.114 +}
1.115 +
1.116 +function check_action() {
1.117 + if [ "$3" == 'tabs' ]
1.118 + then
1.119 + if echo $2 | grep -q -v -E 'Makefile\.am$'
1.120 + then
1.121 + PATTERN=$(echo -e '\t')
1.122 + else
1.123 + PATTERN=' '
1.124 + fi
1.125 + elif [ "$3" == 'trailing spaces' ]
1.126 + then
1.127 + PATTERN='\ +$'
1.128 + else
1.129 + PATTERN='*'
1.130 + fi
1.131 +
1.132 + if ! diff -q $1 $2 >/dev/null
1.133 + then
1.134 + if [ "$PATTERN" == '*' ]
1.135 + then
1.136 + diff $1 $2 | grep '^[0-9]' | sed "s|^\(.*\)c.*$|$2:\1: check failed: $3|g" |
1.137 + sed "s/:\([0-9]*\),\([0-9]*\):\(.*\)$/:\1:\3 (until line \2)/g"
1.138 + else
1.139 + grep -n -E "$PATTERN" $2 | sed "s|^\([0-9]*\):.*$|$2:\1: check failed: $3|g"
1.140 + fi
1.141 + FAILED=YES
1.142 + fi
1.143 +}
1.144 +
1.145 +function check_warning() {
1.146 + if [ "$2" == 'long lines' ]
1.147 + then
1.148 + grep -n -E '.{81,}' $1 | sed "s|^\([0-9]*\):.*$|$1:\1: warning: $2|g"
1.149 + else
1.150 + echo "$1: warning: $2"
1.151 + fi
1.152 + WARNED=YES
1.153 +}
1.154 +
1.155 +function check_init() {
1.156 + echo Check source files...
1.157 + FAILED_FILES=0
1.158 + WARNED_FILES=0
1.159 + TOTAL_FILES=0
1.160 +}
1.161 +
1.162 +function check_done() {
1.163 + echo $FAILED_FILES out of $TOTAL_FILES files has been failed.
1.164 + echo $WARNED_FILES out of $TOTAL_FILES files triggered warnings.
1.165 +
1.166 + if [ $WARNED_FILES -gt 0 -o $FAILED_FILES -gt 0 ]
1.167 + then
1.168 + if [ "$WARNING" == 'INTERACTIVE' ]
1.169 + then
1.170 + echo -n "Are the files with errors/warnings acceptable? (yes/no) "
1.171 + while read answer
1.172 + do
1.173 + if [ "$answer" == 'yes' ]
1.174 + then
1.175 + return 0
1.176 + elif [ "$answer" == 'no' ]
1.177 + then
1.178 + return 1
1.179 + fi
1.180 + echo -n "Are the files with errors/warnings acceptable? (yes/no) "
1.181 + done
1.182 + elif [ "$WARNING" == 'WERROR' ]
1.183 + then
1.184 + return 1
1.185 + fi
1.186 + fi
1.187 +}
1.188 +
1.189 +function check_begin() {
1.190 + ((TOTAL_FILES++))
1.191 + FAILED=NO
1.192 + WARNED=NO
1.193 +}
1.194 +
1.195 +function check_end() {
1.196 + if [ $FAILED == YES ]
1.197 + then
1.198 + ((++FAILED_FILES))
1.199 + fi
1.200 + if [ $WARNED == YES ]
1.201 + then
1.202 + ((++WARNED_FILES))
1.203 + fi
1.204 +}
1.205 +
1.206 +
1.207 +
1.208 +# checks
1.209 +
1.210 +function header_check() {
1.211 + if echo $1 | grep -q -E 'Makefile\.am$'
1.212 + then
1.213 + return
1.214 + fi
1.215 +
1.216 TMP_FILE=`mktemp`
1.217 - FILE_NAME=$1
1.218
1.219 (echo "/* -*- mode: C++; indent-tabs-mode: nil; -*-
1.220 *
1.221 * This file is a part of LEMON, a generic C++ optimization library.
1.222 *
1.223 - * Copyright (C) "$YEAR"
1.224 + * Copyright (C) 2003-"$(hg_year $1)"
1.225 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
1.226 * (Egervary Research Group on Combinatorial Optimization, EGRES).
1.227 *
1.228 @@ -25,110 +228,163 @@
1.229 *
1.230 */
1.231 "
1.232 - awk 'BEGIN { pm=0; }
1.233 + awk 'BEGIN { pm=0; }
1.234 pm==3 { print }
1.235 /\/\* / && pm==0 { pm=1;}
1.236 /[^:blank:]/ && (pm==0 || pm==2) { pm=3; print;}
1.237 /\*\// && pm==1 { pm=2;}
1.238 ' $1
1.239 - ) >$TMP_FILE
1.240 + ) >$TMP_FILE
1.241
1.242 - HEADER_CH=`diff -q $TMP_FILE $FILE_NAME >/dev/null&&echo NO||echo YES`
1.243 -
1.244 - rm $FILE_NAME
1.245 - mv $TMP_FILE $FILE_NAME
1.246 + "$ACTION"_action "$TMP_FILE" "$1" header
1.247 }
1.248
1.249 -function update_tabs() {
1.250 +function tabs_check() {
1.251 + if echo $1 | grep -q -v -E 'Makefile\.am$'
1.252 + then
1.253 + OLD_PATTERN=$(echo -e '\t')
1.254 + NEW_PATTERN=' '
1.255 + else
1.256 + OLD_PATTERN=' '
1.257 + NEW_PATTERN=$(echo -e '\t')
1.258 + fi
1.259 TMP_FILE=`mktemp`
1.260 - FILE_NAME=$1
1.261 + cat $1 | sed -e "s/$OLD_PATTERN/$NEW_PATTERN/g" >$TMP_FILE
1.262
1.263 - cat $1 |
1.264 - sed -e 's/\t/ /g' >$TMP_FILE
1.265 -
1.266 - TABS_CH=`diff -q $TMP_FILE $FILE_NAME >/dev/null&&echo NO||echo YES`
1.267 -
1.268 - rm $FILE_NAME
1.269 - mv $TMP_FILE $FILE_NAME
1.270 + "$ACTION"_action "$TMP_FILE" "$1" 'tabs'
1.271 }
1.272
1.273 -function remove_trailing_space() {
1.274 +function spaces_check() {
1.275 TMP_FILE=`mktemp`
1.276 - FILE_NAME=$1
1.277 + cat $1 | sed -e 's/ \+$//g' >$TMP_FILE
1.278
1.279 - cat $1 |
1.280 - sed -e 's/ \+$//g' >$TMP_FILE
1.281 -
1.282 - SPACES_CH=`diff -q $TMP_FILE $FILE_NAME >/dev/null&&echo NO||echo YES`
1.283 -
1.284 - rm $FILE_NAME
1.285 - mv $TMP_FILE $FILE_NAME
1.286 + "$ACTION"_action "$TMP_FILE" "$1" 'trailing spaces'
1.287 }
1.288
1.289 -function long_line_test() {
1.290 - cat $1 |grep -q -E '.{81,}'
1.291 -}
1.292 -
1.293 -function update_file() {
1.294 - echo -n ' update' $i ...
1.295 -
1.296 - update_header $1
1.297 - update_tabs $1
1.298 - remove_trailing_space $1
1.299 -
1.300 - CHANGED=NO;
1.301 - if [[ $HEADER_CH = YES ]];
1.302 +function long_lines_check() {
1.303 + if cat $1 | grep -q -E '.{81,}'
1.304 then
1.305 - echo -n ' [header updated]'
1.306 - CHANGED=YES;
1.307 - fi
1.308 - if [[ $TABS_CH = YES ]];
1.309 - then
1.310 - echo -n ' [tabs removed]'
1.311 - CHANGED=YES;
1.312 - fi
1.313 - if [[ $SPACES_CH = YES ]];
1.314 - then
1.315 - echo -n ' [trailing spaces removed]'
1.316 - CHANGED=YES;
1.317 - fi
1.318 - if long_line_test $1 ;
1.319 - then
1.320 - echo -n ' [LONG LINES]'
1.321 - ((LONG_LINE_FILES++))
1.322 - fi
1.323 - echo
1.324 - if [[ $CHANGED = YES ]];
1.325 - then
1.326 - ((CHANGED_FILES++))
1.327 + "$ACTION"_warning $1 'long lines'
1.328 fi
1.329 }
1.330
1.331 -CHANGED_FILES=0
1.332 -TOTAL_FILES=0
1.333 -LONG_LINE_FILES=0
1.334 -if [ $# == 0 ]; then
1.335 - echo Update all source files...
1.336 - for i in `hg manifest|grep -E '\.(cc|h|dox)$'`
1.337 +# process the file
1.338 +
1.339 +function process_file() {
1.340 + if [ "$ACTION" == 'update' ]
1.341 + then
1.342 + echo -n " $ACTION $1..."
1.343 + else
1.344 + echo " $ACTION $1..."
1.345 + fi
1.346 +
1.347 + CHECKING="header tabs spaces long_lines"
1.348 +
1.349 + "$ACTION"_begin $1
1.350 + for check in $CHECKING
1.351 do
1.352 - update_file $HGROOT/$i
1.353 - ((TOTAL_FILES++))
1.354 + "$check"_check $1
1.355 done
1.356 - echo ' done.'
1.357 -else
1.358 - for i in $*
1.359 + "$ACTION"_end $1
1.360 + if [ "$ACTION" == 'update' ]
1.361 + then
1.362 + echo
1.363 + fi
1.364 +}
1.365 +
1.366 +function process_all {
1.367 + "$ACTION"_init
1.368 + while read file
1.369 do
1.370 - update_file $i
1.371 - ((TOTAL_FILES++))
1.372 - done
1.373 + process_file $file
1.374 + done < <($FILES)
1.375 + "$ACTION"_done
1.376 +}
1.377 +
1.378 +while [ $# -gt 0 ]
1.379 +do
1.380 +
1.381 + if [ "$1" == '--help' ] || [ "$1" == '-h' ]
1.382 + then
1.383 + echo -n \
1.384 +"Usage:
1.385 + $0 [OPTIONS] [files]
1.386 +Options:
1.387 + --dry-run|-n
1.388 + Check the files, but do not modify them.
1.389 + --interactive|-i
1.390 + If --dry-run is specified and the checker emits warnings,
1.391 + then the user is asked if the warnings should be considered
1.392 + errors.
1.393 + --werror|-w
1.394 + Make all warnings into errors.
1.395 + --all|-a
1.396 + Check all source files in the repository.
1.397 + --modified|-m
1.398 + Check only the modified (and new) source files. This option is
1.399 + useful to check the modification before making a commit.
1.400 + --changed|-c
1.401 + Check only the changed source files compared to the parent(s) of
1.402 + the current hg node. This option is useful as hg hook script.
1.403 + To automatically check all your changes before making a commit,
1.404 + add the following section to the appropriate .hg/hgrc file.
1.405 +
1.406 + [hooks]
1.407 + pretxncommit.checksources = scripts/unify-sources.sh -c -n -i
1.408 +
1.409 + --help|-h
1.410 + Print this help message.
1.411 + files
1.412 + The files to check/unify. If no file names are given, the modified
1.413 + source files will be checked/unified (just like using the
1.414 + --modified|-m option).
1.415 +"
1.416 + exit 0
1.417 + elif [ "$1" == '--dry-run' ] || [ "$1" == '-n' ]
1.418 + then
1.419 + [ -n "$ACTION" ] && echo "Conflicting action options" >&2 && exit 1
1.420 + ACTION=check
1.421 + elif [ "$1" == "--all" ] || [ "$1" == '-a' ]
1.422 + then
1.423 + [ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1
1.424 + FILES=all_files
1.425 + elif [ "$1" == "--changed" ] || [ "$1" == '-c' ]
1.426 + then
1.427 + [ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1
1.428 + FILES=changed_files
1.429 + elif [ "$1" == "--modified" ] || [ "$1" == '-m' ]
1.430 + then
1.431 + [ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1
1.432 + FILES=modified_files
1.433 + elif [ "$1" == "--interactive" ] || [ "$1" == "-i" ]
1.434 + then
1.435 + [ -n "$WARNING" ] && echo "Conflicting warning options" >&2 && exit 1
1.436 + WARNING='INTERACTIVE'
1.437 + elif [ "$1" == "--werror" ] || [ "$1" == "-w" ]
1.438 + then
1.439 + [ -n "$WARNING" ] && echo "Conflicting warning options" >&2 && exit 1
1.440 + WARNING='WERROR'
1.441 + elif [ $(echo x$1 | cut -c 2) == '-' ]
1.442 + then
1.443 + echo "Invalid option $1" >&2 && exit 1
1.444 + else
1.445 + [ -n "$FILES" ] && echo "Invalid option $1" >&2 && exit 1
1.446 + GIVEN_FILES=$@
1.447 + FILES=given_files
1.448 + break
1.449 + fi
1.450 +
1.451 + shift
1.452 +done
1.453 +
1.454 +if [ -z $FILES ]
1.455 +then
1.456 + FILES=modified_files
1.457 fi
1.458 -echo $CHANGED_FILES out of $TOTAL_FILES files has been changed.
1.459 -if [[ $LONG_LINE_FILES -gt 1 ]]; then
1.460 - echo
1.461 - echo WARNING: $LONG_LINE_FILES files contains long lines!
1.462 - echo
1.463 -elif [[ $LONG_LINE_FILES -gt 0 ]]; then
1.464 - echo
1.465 - echo WARNING: a file contains long lines!
1.466 - echo
1.467 +
1.468 +if [ -z $ACTION ]
1.469 +then
1.470 + ACTION=update
1.471 fi
1.472 +
1.473 +process_all