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