scripts/unify-sources.sh
author Peter Kovacs <kpeter@inf.elte.hu>
Mon, 20 Oct 2008 12:46:39 +0200
changeset 341 d900fd1e760f
parent 340 cdbff91c2166
child 343 2f5c0c42a5cd
permissions -rwxr-xr-x
Print the failed line numbers in the unifier script (ticket #138)
     1 #!/bin/bash
     2 
     3 YEAR=`date +2003-%Y`
     4 HGROOT=`hg root`
     5 
     6 # file enumaration modes
     7 
     8 function all_files() {
     9     hg status -a -m -c |
    10     cut -d ' ' -f 2 | grep -E '(\.(cc|h|dox)$|Makefile\.am$)' |
    11     while read file; do echo $HGROOT/$file; done
    12 }
    13 
    14 function modified_files() {
    15     hg status -a -m |
    16     cut -d ' ' -f 2 | grep -E  '(\.(cc|h|dox)$|Makefile\.am$)' |
    17     while read file; do echo $HGROOT/$file; done
    18 }
    19 
    20 function changed_files() {
    21     {
    22         if [ -n "$HG_PARENT1" ]
    23         then
    24             hg status --rev $HG_PARENT1:$HG_NODE -a -m
    25         fi
    26         if [ -n "$HG_PARENT2" ]
    27         then
    28             hg status --rev $HG_PARENT2:$HG_NODE -a -m
    29         fi
    30     } | cut -d ' ' -f 2 | grep -E '(\.(cc|h|dox)$|Makefile\.am$)' | 
    31     sort | uniq |
    32     while read file; do echo $HGROOT/$file; done
    33 }
    34 
    35 function given_files() {
    36     for file in $GIVEN_FILES
    37     do
    38 	echo $file
    39     done
    40 }
    41 
    42 # actions
    43 
    44 function update_action() {
    45     if ! diff -q $1 $2 >/dev/null
    46     then
    47 	echo -n " [$3 updated]"
    48 	rm $2
    49 	mv $1 $2
    50 	CHANGED=YES
    51     fi
    52 }
    53 
    54 function update_warning() {
    55     echo -n " [$2 warning]"
    56     WARNED=YES
    57 }
    58 
    59 function update_init() {
    60     echo Update source files...
    61     TOTAL_FILES=0
    62     CHANGED_FILES=0
    63     WARNED_FILES=0
    64 }
    65 
    66 function update_done() {
    67     echo $CHANGED_FILES out of $TOTAL_FILES files has been changed.
    68     echo $WARNED_FILES out of $TOTAL_FILES files has been warned.
    69 }
    70 
    71 function update_begin() {
    72     ((TOTAL_FILES++))
    73     CHANGED=NO
    74     WARNED=NO
    75 }
    76 
    77 function update_end() {
    78     if [ $CHANGED == YES ]
    79     then
    80 	((++CHANGED_FILES))
    81     fi
    82     if [ $WARNED == YES ]
    83     then
    84 	((++WARNED_FILES))
    85     fi
    86 }
    87 
    88 function check_action() {
    89     if ! diff -q $1 $2 >/dev/null
    90     then
    91 	echo
    92 	echo -n "      $3 failed at line(s): "
    93 	echo -n $(diff $1 $2 | grep '^[0-9]' | sed "s/^\(.*\)c.*$/ \1/g" | 
    94 	          sed "s/,/-/g" | paste -s -d',')
    95 	FAILED=YES
    96     fi
    97 }
    98 
    99 function check_warning() {
   100     echo
   101     if [ "$2" == 'long lines' ]
   102     then
   103         echo -n "      $2 warning at line(s): "
   104         echo -n $(grep -n -E '.{81,}' $1 | sed "s/^\([0-9]*\)/ \1\t/g" | 
   105                   cut -f 1 | paste -s -d',')
   106     else
   107         echo -n "      $2 warning"
   108     fi
   109     WARNED=YES
   110 }
   111 
   112 function check_init() {
   113     echo Check source files...
   114     FAILED_FILES=0
   115     WARNED_FILES=0
   116     TOTAL_FILES=0
   117 }
   118 
   119 function check_done() {
   120     echo $FAILED_FILES out of $TOTAL_FILES files has been failed.
   121     echo $WARNED_FILES out of $TOTAL_FILES files has been warned.
   122 
   123     if [ $FAILED_FILES -gt 0 ]
   124     then
   125 	return 1
   126     elif [ $WARNED_FILES -gt 0 ]
   127     then
   128 	if [ "$WARNING" == 'INTERACTIVE' ]
   129 	then
   130 	    echo -n "Assume as normal behaviour? (yes/no) "
   131 	    while read answer
   132 	    do
   133 		if [ "$answer" == 'yes' ]
   134 		then
   135 		    return 0
   136 		elif [ "$answer" == 'no' ]
   137 		then
   138 		    return 1
   139 		fi
   140 		echo -n "Assume as normal behaviour? (yes/no) "		    
   141 	    done
   142 	elif [ "$WARNING" == 'WERROR' ]
   143 	then
   144 	    return 1
   145 	fi
   146     fi
   147 }
   148 
   149 function check_begin() {
   150     ((TOTAL_FILES++))
   151     FAILED=NO
   152     WARNED=NO
   153 }
   154 
   155 function check_end() {
   156     if [ $FAILED == YES ]
   157     then
   158 	((++FAILED_FILES))
   159     fi
   160     if [ $WARNED == YES ]
   161     then
   162 	((++WARNED_FILES))
   163     fi
   164 }
   165 
   166 
   167 
   168 # checks
   169 
   170 function header_check() {
   171     if echo $1 | grep -q -E 'Makefile\.am$'
   172     then
   173 	return
   174     fi
   175 
   176     TMP_FILE=`mktemp`
   177 
   178     (echo "/* -*- mode: C++; indent-tabs-mode: nil; -*-
   179  *
   180  * This file is a part of LEMON, a generic C++ optimization library.
   181  *
   182  * Copyright (C) "$YEAR"
   183  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   184  * (Egervary Research Group on Combinatorial Optimization, EGRES).
   185  *
   186  * Permission to use, modify and distribute this software is granted
   187  * provided that this copyright notice appears in all copies. For
   188  * precise terms see the accompanying LICENSE file.
   189  *
   190  * This software is provided \"AS IS\" with no warranty of any kind,
   191  * express or implied, and with no claim as to its suitability for any
   192  * purpose.
   193  *
   194  */
   195 "
   196     awk 'BEGIN { pm=0; }
   197      pm==3 { print }
   198      /\/\* / && pm==0 { pm=1;}
   199      /[^:blank:]/ && (pm==0 || pm==2) { pm=3; print;}
   200      /\*\// && pm==1 { pm=2;}
   201     ' $1
   202     ) >$TMP_FILE
   203 
   204     "$ACTION"_action "$TMP_FILE" "$1" header
   205 }
   206 
   207 function tabs_check() {
   208     if echo $1 | grep -q -v -E 'Makefile\.am$'
   209     then
   210         OLD_PATTERN=$(echo -e '\t')
   211         NEW_PATTERN='        '
   212     else
   213         OLD_PATTERN='        '
   214         NEW_PATTERN=$(echo -e '\t')
   215     fi
   216     TMP_FILE=`mktemp`
   217     cat $1 | sed -e "s/$OLD_PATTERN/$NEW_PATTERN/g" >$TMP_FILE
   218 
   219     "$ACTION"_action "$TMP_FILE" "$1" 'tabs'
   220 }
   221 
   222 function spaces_check() {
   223     TMP_FILE=`mktemp`
   224     cat $1 | sed -e 's/ \+$//g' >$TMP_FILE
   225 
   226     "$ACTION"_action "$TMP_FILE" "$1" 'trailing spaces'
   227 }
   228 
   229 function long_lines_check() {
   230     if cat $1 | grep -q -E '.{81,}'
   231     then
   232 	"$ACTION"_warning $1 'long lines'
   233     fi
   234 }
   235 
   236 # process the file
   237 
   238 function process_file() {
   239     echo -n "    $ACTION $1..."
   240 
   241     CHECKING="header tabs spaces long_lines"
   242 
   243     "$ACTION"_begin $1
   244     for check in $CHECKING
   245     do
   246 	"$check"_check $1
   247     done
   248     "$ACTION"_end $1
   249     echo
   250 }
   251 
   252 function process_all {
   253     "$ACTION"_init
   254     while read file
   255     do
   256 	process_file $file
   257     done < <($FILES)
   258     "$ACTION"_done
   259 }
   260 
   261 while [ $# -gt 0 ]
   262 do
   263     
   264     if [ "$1" == '--help' ] || [ "$1" == '-h' ]
   265     then
   266 	echo -n \
   267 "Usage:
   268   $0 [OPTIONS] [files]
   269 Options:
   270   --dry-run|-n
   271      Check the given files, but do not modify them.
   272   --interactive|-i
   273      If --dry-run is specified and files are warned, then a message is
   274      prompted whether the warnings should be turned to errors.
   275   --werror|-w
   276      If --dry-run is specified, the warnings are turned to errors.
   277   --all|-a
   278      Check all source files in the repository.
   279   --modified|-m
   280      Check only the modified source files. This option is proper to
   281      use before a commit. E.g. all files which are modified or added
   282      into the repository will be updated.
   283   --changed|-c
   284      Check only the changed source files compared to the parent(s) of
   285      the current hg node.  This option is proper to use as hg hook
   286      script. E.g. to check all your commited source files with this
   287      script add the following section to the appropriate .hg/hgrc
   288      file.
   289 
   290        [hooks]
   291        pretxncommit.checksources = scripts/unify-sources.sh -c -n -i
   292 
   293   --help|-h
   294      Print this help message.
   295   files
   296      The files to check/unify. If no file names are given, the modified
   297      source files will be checked/unified (just like using the
   298      --modified|-m option).
   299 "
   300         exit 0
   301     elif [ "$1" == '--dry-run' ] || [ "$1" == '-n' ]
   302     then
   303 	[ -n "$ACTION" ] && echo "Conflicting action options" >&2 && exit 1
   304 	ACTION=check
   305     elif [ "$1" == "--all" ] || [ "$1" == '-a' ]
   306     then
   307 	[ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1
   308 	FILES=all_files
   309     elif [ "$1" == "--changed" ] || [ "$1" == '-c' ]
   310     then
   311 	[ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1
   312 	FILES=changed_files
   313     elif [ "$1" == "--modified" ] || [ "$1" == '-m' ]
   314     then
   315 	[ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1
   316 	FILES=modified_files
   317     elif [ "$1" == "--interactive" ] || [ "$1" == "-i" ]
   318     then
   319 	[ -n "$WARNING" ] && echo "Conflicting warning options" >&2 && exit 1
   320 	WARNING='INTERACTIVE'
   321     elif [ "$1" == "--werror" ] || [ "$1" == "-w" ]
   322     then
   323 	[ -n "$WARNING" ] && echo "Conflicting warning options" >&2 && exit 1
   324 	WARNING='WERROR'
   325     elif [ $(echo x$1 | cut -c 2) == '-' ]
   326     then
   327 	echo "Invalid option $1" >&2 && exit 1
   328     else
   329 	[ -n "$FILES" ] && echo "Invalid option $1" >&2 && exit 1
   330 	GIVEN_FILES=$@
   331 	FILES=given_files
   332 	break
   333     fi
   334     
   335     shift
   336 done
   337 
   338 if [ -z $FILES ]
   339 then
   340     FILES=modified_files
   341 fi
   342 
   343 if [ -z $ACTION ]
   344 then
   345     ACTION=update
   346 fi
   347 
   348 process_all