Report abuse

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#!/usr/bin/perl
#
# File: DAMit2
# Author: Colin Mollenhour (mollenho@cs.utk.edu or colin@mollenhour.com)
# http://colin.mollenhour.com
#
# Reads a DAM (Document for API Modification) document and any number
# of files, and makes changes accordingly.
#
# This is version 2, which adds support for regular expressions in the DAM file!
#
# Use this script to make changes to your source files, or in library
#  files which reference other library files. 
#
# The DAM document should be in this format:
#
# #Comments should be preceded by #
# #Blank lines and comments are allowed anywhere.
# #old and new are separated by ==>
# #if a line does not have a replacement, it is ignored
#
# header1\.h  ==> newheader.h
# rotate_object\dd   ==> RotateObject$1D
# new MyClass  ==> MyClass::factory
# (MyClass1|MyClass1)->   ==> MyNamespace::$1->
# foo_\w+_bar   ==> Foo$1Bar

if( @ARGV < 2 || (@ARGV < 3 && $ARGV[@ARGV-1] eq "test")){
	print "Usage: DAMit2 dam.txt file [file] ... [test]\n";
	print "The \"test\" option will output the log, but not apply changes.\n";
	print "Examples:\n";
	print "DAM all files in current directory:\n";
	print "   DAMit2 dam.txt *.*`\n";
	print "DAM all .h files in current directory (recursive), but do not apply changes:\n";
	print "   DAMit2 dam.txt `find -name \\*.h` test\n";
	print "DAM all .h, .c, and .cpp files in current directory (recursive):\n";
	print "   DAMit2 dam.txt `find -name \\*.cpp` `find -name \\*.\\[hc\\]`\n";
	exit;
}

#build the DAM hash
$damfile = shift(@ARGV);
if($ARGV[@ARGV-1] eq "test"){
	$TESTING = 1;
	pop(@ARGV);
}else{
	$TESTING = 0;
}
open(DAM, $damfile) || die( "Unable to open $damfile : $!\n" );
%hash = ();	#hash of old and new function names 
while( <DAM> ){
	next if /^#/;								#skip comments
	chop;
	($old, $new) = split /\s+==>\s+/;					#get old and new function names
	$hash{ $old } = $new if $old && $new;		#add old and new to hash 
}
close DAM;

#process each file
foreach $arg (@ARGV){		#for each file
	&CMreplaceALL();
}
print "DAM'ed ".scalar(@ARGV)." files.\n";

#Does the replacement in $arg
sub CMreplaceALL{
	open FILE, "+<$arg" or die "Cannot open $arg: $!\n";
	flock FILE, 2;		#lock the file for rw
	@data = <FILE>;		#buffer all the data
	
	print "For file: $arg\n";
	$total = 0;
	$line = 1;
	foreach (@data){
		$before = $_;
		$replace = 0;
		while( ($old, $new) = each %hash ){
			eval '$count = ($_ =~ '."s/\\b$old\\b/$new/g)";
			$replace += $count;
		}
		$total += $replace;
		print "$line: -$before$line: +$_" if $replace != 0;
		$line++;
	}
	if( $total == 0 ){
		print "No replacements made in $arg\n\n";
	}else{
		if( !$TESTING ){   #overwrite file with new contents
			seek FILE, 0, 0;
			truncate FILE, 0;
			print FILE @data;
		}
		print "Made $total total replacements in $arg\n\n";
	}
	close FILE;
}