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