scripts/unify-sources.sh
author Alpar Juttner <alpar@cs.elte.hu>
Wed, 22 Oct 2008 14:41:18 +0100
changeset 345 9c2a532aa5ef
parent 337 0fbbb4bc42dd
parent 341 d900fd1e760f
child 353 f8832dc16d45
permissions -rwxr-xr-x
Merge
     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 triggered warnings.
    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 triggered warnings.
   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 "Are the files with warnings acceptable? (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 "Are the files with warnings acceptable? (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 files, but do not modify them.
   272   --interactive|-i
   273      If --dry-run is specified and the checker emits warnings,
   274      then the user is asked if the warnings should be considered
   275      errors.
   276   --werror|-w
   277      Make all warnings into errors.
   278   --all|-a
   279      Check all source files in the repository.
   280   --modified|-m
   281      Check only the modified (and new) source files. This option is
   282      useful to check the modification before making a commit.
   283   --changed|-c
   284      Check only the changed source files compared to the parent(s) of
   285      the current hg node.  This option is useful as hg hook script.
   286      To automatically check all your changes before making a commit,
   287      add the following section to the appropriate .hg/hgrc file.
   288 
   289        [hooks]
   290        pretxncommit.checksources = scripts/unify-sources.sh -c -n -i
   291 
   292   --help|-h
   293      Print this help message.
   294   files
   295      The files to check/unify. If no file names are given, the modified
   296      source files will be checked/unified (just like using the
   297      --modified|-m option).
   298 "
   299         exit 0
   300     elif [ "$1" == '--dry-run' ] || [ "$1" == '-n' ]
   301     then
   302 	[ -n "$ACTION" ] && echo "Conflicting action options" >&2 && exit 1
   303 	ACTION=check
   304     elif [ "$1" == "--all" ] || [ "$1" == '-a' ]
   305     then
   306 	[ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1
   307 	FILES=all_files
   308     elif [ "$1" == "--changed" ] || [ "$1" == '-c' ]
   309     then
   310 	[ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1
   311 	FILES=changed_files
   312     elif [ "$1" == "--modified" ] || [ "$1" == '-m' ]
   313     then
   314 	[ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1
   315 	FILES=modified_files
   316     elif [ "$1" == "--interactive" ] || [ "$1" == "-i" ]
   317     then
   318 	[ -n "$WARNING" ] && echo "Conflicting warning options" >&2 && exit 1
   319 	WARNING='INTERACTIVE'
   320     elif [ "$1" == "--werror" ] || [ "$1" == "-w" ]
   321     then
   322 	[ -n "$WARNING" ] && echo "Conflicting warning options" >&2 && exit 1
   323 	WARNING='WERROR'
   324     elif [ $(echo x$1 | cut -c 2) == '-' ]
   325     then
   326 	echo "Invalid option $1" >&2 && exit 1
   327     else
   328 	[ -n "$FILES" ] && echo "Invalid option $1" >&2 && exit 1
   329 	GIVEN_FILES=$@
   330 	FILES=given_files
   331 	break
   332     fi
   333     
   334     shift
   335 done
   336 
   337 if [ -z $FILES ]
   338 then
   339     FILES=modified_files
   340 fi
   341 
   342 if [ -z $ACTION ]
   343 then
   344     ACTION=update
   345 fi
   346 
   347 process_all