scripts/unify-sources.sh
author Peter Kovacs <kpeter@inf.elte.hu>
Tue, 15 Mar 2011 19:32:21 +0100
changeset 1047 ddd3c0d3d9bf
parent 702 c706534d4740
permissions -rwxr-xr-x
Implement the scaling Price Refinement heuristic in CostScaling (#417)
instead of Early Termination.

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