scripts/unify-sources.sh
author Peter Kovacs <kpeter@inf.elte.hu>
Mon, 20 Oct 2008 12:17:24 +0200
changeset 340 cdbff91c2166
parent 336 e05633b02e40
child 341 d900fd1e760f
permissions -rwxr-xr-x
Small improvements in the unifier script
     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 -n " [$3 failed]"
    92 	FAILED=YES
    93     fi
    94 }
    95 
    96 function check_warning() {
    97     echo -n " [$2 warning]"
    98     WARNED=YES
    99 }
   100 
   101 function check_init() {
   102     echo Check source files...
   103     FAILED_FILES=0
   104     WARNED_FILES=0
   105     TOTAL_FILES=0
   106 }
   107 
   108 function check_done() {
   109     echo $FAILED_FILES out of $TOTAL_FILES files has been failed.
   110     echo $WARNED_FILES out of $TOTAL_FILES files has been warned.
   111 
   112     if [ $FAILED_FILES -gt 0 ]
   113     then
   114 	return 1
   115     elif [ $WARNED_FILES -gt 0 ]
   116     then
   117 	if [ "$WARNING" == 'INTERACTIVE' ]
   118 	then
   119 	    echo -n "Assume as normal behaviour? (yes/no) "
   120 	    while read answer
   121 	    do
   122 		if [ "$answer" == 'yes' ]
   123 		then
   124 		    return 0
   125 		elif [ "$answer" == 'no' ]
   126 		then
   127 		    return 1
   128 		fi
   129 		echo -n "Assume as normal behaviour? (yes/no) "		    
   130 	    done
   131 	elif [ "$WARNING" == 'WERROR' ]
   132 	then
   133 	    return 1
   134 	fi
   135     fi
   136 }
   137 
   138 function check_begin() {
   139     ((TOTAL_FILES++))
   140     FAILED=NO
   141     WARNED=NO
   142 }
   143 
   144 function check_end() {
   145     if [ $FAILED == YES ]
   146     then
   147 	((++FAILED_FILES))
   148     fi
   149     if [ $WARNED == YES ]
   150     then
   151 	((++WARNED_FILES))
   152     fi
   153 }
   154 
   155 
   156 
   157 # checks
   158 
   159 function header_check() {
   160     if echo $1 | grep -q -E 'Makefile\.am$'
   161     then
   162 	return
   163     fi
   164 
   165     TMP_FILE=`mktemp`
   166 
   167     (echo "/* -*- mode: C++; indent-tabs-mode: nil; -*-
   168  *
   169  * This file is a part of LEMON, a generic C++ optimization library.
   170  *
   171  * Copyright (C) "$YEAR"
   172  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
   173  * (Egervary Research Group on Combinatorial Optimization, EGRES).
   174  *
   175  * Permission to use, modify and distribute this software is granted
   176  * provided that this copyright notice appears in all copies. For
   177  * precise terms see the accompanying LICENSE file.
   178  *
   179  * This software is provided \"AS IS\" with no warranty of any kind,
   180  * express or implied, and with no claim as to its suitability for any
   181  * purpose.
   182  *
   183  */
   184 "
   185     awk 'BEGIN { pm=0; }
   186      pm==3 { print }
   187      /\/\* / && pm==0 { pm=1;}
   188      /[^:blank:]/ && (pm==0 || pm==2) { pm=3; print;}
   189      /\*\// && pm==1 { pm=2;}
   190     ' $1
   191     ) >$TMP_FILE
   192 
   193     "$ACTION"_action "$TMP_FILE" "$1" header
   194 }
   195 
   196 function tabs_check() {
   197     if echo $1 | grep -q -v -E 'Makefile\.am$'
   198     then
   199         OLD_PATTERN=$(echo -e '\t')
   200         NEW_PATTERN='        '
   201     else
   202         OLD_PATTERN='        '
   203         NEW_PATTERN=$(echo -e '\t')
   204     fi
   205     TMP_FILE=`mktemp`
   206     cat $1 | sed -e "s/$OLD_PATTERN/$NEW_PATTERN/g" >$TMP_FILE
   207 
   208     "$ACTION"_action "$TMP_FILE" "$1" 'tabs'
   209 }
   210 
   211 function spaces_check() {
   212     TMP_FILE=`mktemp`
   213     cat $1 | sed -e 's/ \+$//g' >$TMP_FILE
   214 
   215     "$ACTION"_action "$TMP_FILE" "$1" 'trailing spaces'
   216 }
   217 
   218 function long_lines_check() {
   219     if cat $1 | grep -q -E '.{81,}'
   220     then
   221 	"$ACTION"_warning $1 'long lines'
   222     fi
   223 }
   224 
   225 # process the file
   226 
   227 function process_file() {
   228     echo -n "    $ACTION $1..."
   229 
   230     CHECKING="header tabs spaces long_lines"
   231 
   232     "$ACTION"_begin $1
   233     for check in $CHECKING
   234     do
   235 	"$check"_check $1
   236     done
   237     "$ACTION"_end $1
   238     echo
   239 }
   240 
   241 function process_all {
   242     "$ACTION"_init
   243     while read file
   244     do
   245 	process_file $file
   246     done < <($FILES)
   247     "$ACTION"_done
   248 }
   249 
   250 while [ $# -gt 0 ]
   251 do
   252     
   253     if [ "$1" == '--help' ] || [ "$1" == '-h' ]
   254     then
   255 	echo -n \
   256 "Usage:
   257   $0 [OPTIONS] [files]
   258 Options:
   259   --dry-run|-n
   260      Check the given files, but do not modify them.
   261   --interactive|-i
   262      If --dry-run is specified and files are warned, then a message is
   263      prompted whether the warnings should be turned to errors.
   264   --werror|-w
   265      If --dry-run is specified, the warnings are turned to errors.
   266   --all|-a
   267      Check all source files in the repository.
   268   --modified|-m
   269      Check only the modified source files. This option is proper to
   270      use before a commit. E.g. all files which are modified or added
   271      into the repository will be updated.
   272   --changed|-c
   273      Check only the changed source files compared to the parent(s) of
   274      the current hg node.  This option is proper to use as hg hook
   275      script. E.g. to check all your commited source files with this
   276      script add the following section to the appropriate .hg/hgrc
   277      file.
   278 
   279        [hooks]
   280        pretxncommit.checksources = scripts/unify-sources.sh -c -n -i
   281 
   282   --help|-h
   283      Print this help message.
   284   files
   285      The files to check/unify. If no file names are given, the modified
   286      source files will be checked/unified (just like using the
   287      --modified|-m option).
   288 "
   289         exit 0
   290     elif [ "$1" == '--dry-run' ] || [ "$1" == '-n' ]
   291     then
   292 	[ -n "$ACTION" ] && echo "Conflicting action options" >&2 && exit 1
   293 	ACTION=check
   294     elif [ "$1" == "--all" ] || [ "$1" == '-a' ]
   295     then
   296 	[ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1
   297 	FILES=all_files
   298     elif [ "$1" == "--changed" ] || [ "$1" == '-c' ]
   299     then
   300 	[ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1
   301 	FILES=changed_files
   302     elif [ "$1" == "--modified" ] || [ "$1" == '-m' ]
   303     then
   304 	[ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1
   305 	FILES=modified_files
   306     elif [ "$1" == "--interactive" ] || [ "$1" == "-i" ]
   307     then
   308 	[ -n "$WARNING" ] && echo "Conflicting warning options" >&2 && exit 1
   309 	WARNING='INTERACTIVE'
   310     elif [ "$1" == "--werror" ] || [ "$1" == "-w" ]
   311     then
   312 	[ -n "$WARNING" ] && echo "Conflicting warning options" >&2 && exit 1
   313 	WARNING='WERROR'
   314     elif [ $(echo x$1 | cut -c 2) == '-' ]
   315     then
   316 	echo "Invalid option $1" >&2 && exit 1
   317     else
   318 	[ -n "$FILES" ] && echo "Invalid option $1" >&2 && exit 1
   319 	GIVEN_FILES=$@
   320 	FILES=given_files
   321 	break
   322     fi
   323     
   324     shift
   325 done
   326 
   327 if [ -z $FILES ]
   328 then
   329     FILES=modified_files
   330 fi
   331 
   332 if [ -z $ACTION ]
   333 then
   334     ACTION=update
   335 fi
   336 
   337 process_all