copyright year updated to 2012
[cvc5.git] / contrib / update-copyright.pl
1 #!/usr/bin/perl -w
2 #
3 # update-copyright.pl
4 # Morgan Deters <mdeters@cs.nyu.edu> for CVC4
5 # Copyright (c) 2009-2012 The CVC4 Project
6 #
7 # usage: update-copyright [-m] [files/directories...]
8 # update-copyright [-h | --help]
9 #
10 # This script goes through a source directory rewriting the top bits of
11 # source files to match a template (inline, below). For files with no
12 # top comment, it adds a fresh one.
13 #
14 # if no files/directories are unspecified, the script scans its own
15 # parent directory's "src" directory. Since it lives in contrib/ in
16 # the CVC4 source tree, that means src/ in the CVC4 source tree.
17 #
18 # If -m is specified as the first argument, all files and directories
19 # are scanned, but only ones modifed in the current working directory
20 # are modified (i.e., those that have status M in "svn status").
21 #
22 # It ignores any file/directory not starting with [a-zA-Z]
23 # (so, this includes . and .., vi swaps, .svn meta-info,
24 # .deps, etc.)
25 #
26 # It ignores any file not ending with one of:
27 # .c .cc .cpp .C .h .hh .hpp .H .y .yy .ypp .Y .l .ll .lpp .L .g
28 # (so, this includes emacs ~-backups, CVS detritus, etc.)
29 #
30 # It ignores any directory matching $excluded_directories
31 # (so, you should add here any sources imported but not covered under
32 # the license.)
33 #
34
35 my $excluded_directories = '^(minisat|CVS|generated)$';
36 my $excluded_paths = '^(src/parser/antlr_input_imports.cpp|src/bindings/compat/.*)$';
37
38 # Years of copyright for the template. E.g., the string
39 # "1985, 1987, 1992, 1997, 2008" or "2006-2009" or whatever.
40 my $years = '2009-2012';
41
42 my $standard_template = <<EOF;
43 ** This file is part of the CVC4 prototype.
44 ** Copyright (c) $years The Analysis of Computer Systems Group (ACSys)
45 ** Courant Institute of Mathematical Sciences
46 ** New York University
47 ** See the file COPYING in the top-level source directory for licensing
48 ** information.\\endverbatim
49 EOF
50
51 my $public_template = <<EOF;
52 ** This file is part of the CVC4 prototype.
53 ** Copyright (c) $years The Analysis of Computer Systems Group (ACSys)
54 ** Courant Institute of Mathematical Sciences
55 ** New York University
56 ** See the file COPYING in the top-level source directory for licensing
57 ** information.\\endverbatim
58 EOF
59
60 ## end config ##
61
62 use strict;
63 use Fcntl ':mode';
64
65 my $dir = $0;
66 $dir =~ s,/[^/]+/*$,,;
67
68 if($#ARGV >= 0 && $ARGV[0] eq '-h' || $ARGV[0] eq '--help') {
69 open(my $SELF, $0) || die "error opening $0 for reading";
70 while($_ = <$SELF>) {
71 last if !/^#/;
72 print;
73 }
74 close $SELF;
75 exit;
76 }
77
78 # whether we ONLY process files with svn status "M"
79 my $modonly = 0;
80
81 if($#ARGV >= 0 && $ARGV[0] eq '-m') {
82 $modonly = 1;
83 shift;
84 }
85
86 my @searchdirs = ();
87 if($#ARGV == -1) {
88 (chdir($dir."/..") && -f "src/include/cvc4_public.h") || die "can't find top-level source directory for CVC4";
89 my $pwd = `pwd`; chomp $pwd;
90
91 print <<EOF;
92 Warning: this script is dangerous. It will overwrite the header comments in your
93 source files to match the template in the script, attempting to retain file-specific
94 comments, but this isn't guaranteed. You should run this in an svn working directory
95 and run "svn diff" after to ensure everything was correctly rewritten.
96
97 The directories in which to search for and change sources is:
98 $pwd/src
99 $pwd/test
100
101 Continue? y or n:
102 EOF
103
104 $_ = <STDIN>; chomp;
105 die 'aborting operation' if !( $_ eq 'y' || $_ eq 'yes' || $_ eq 'Y' || $_ eq 'YES' );
106
107 $searchdirs[0] = 'src';
108 $searchdirs[1] = 'test';
109 } else {
110 @searchdirs = @ARGV;
111 }
112
113 print "Updating sources...\n";
114
115 while($#searchdirs >= 0) {
116 my $dir = shift @searchdirs;
117 my $mode = (stat($dir))[2] || warn "file or directory \`$dir' does not exist!";
118 my $is_directory = S_ISDIR($mode);
119 if($is_directory) {
120 recurse($dir);
121 } else {
122 if($dir =~ m,^(.*)\/([^/]*)$,) {
123 my($dir, $file) = ($1, $2);
124 if($dir eq "") {
125 $dir = "/";
126 }
127 handleFile($dir, $file);
128 } else {
129 handleFile(".", $dir);
130 }
131 }
132 }
133
134 sub handleFile {
135 my ($srcdir, $file) = @_;
136 return if !($file =~ /\.(c|cc|cpp|C|h|hh|hpp|H|y|yy|ypp|Y|l|ll|lpp|L|g|java)$/);
137 return if ($srcdir.'/'.$file) =~ /$excluded_paths/;
138 return if $modonly &&`svn status "$srcdir/$file" 2>/dev/null` !~ /^M/;
139 print "$srcdir/$file...";
140 my $infile = $srcdir.'/'.$file;
141 my $outfile = $srcdir.'/#'.$file.'.tmp';
142 open(my $IN, $infile) || die "error opening $infile for reading";
143 open(my $OUT, '>', $outfile) || die "error opening $outfile for writing";
144 open(my $AUTHOR, "$dir/get-authors " . $infile . '|');
145 my $author = <$AUTHOR>; chomp $author;
146 my $major_contributors = <$AUTHOR>; chomp $major_contributors;
147 my $minor_contributors = <$AUTHOR>; chomp $minor_contributors;
148 close $AUTHOR;
149 $_ = <$IN>;
150 if(m,^(%{)?/\*(\*| )\*\*\*,) {
151 print "updating\n";
152 if($file =~ /\.(y|yy|ypp|Y)$/) {
153 print $OUT "%{/******************* */\n";
154 print $OUT "/** $file\n";
155 } elsif($file =~ /\.g$/) {
156 # avoid javadoc-style comment here; antlr complains
157 print $OUT "/* ******************* */\n";
158 print $OUT "/*! \\file $file\n";
159 } else {
160 print $OUT "/********************* */\n";
161 print $OUT "/*! \\file $file\n";
162 }
163 print $OUT " ** \\verbatim\n";
164 print $OUT " ** Original author: $author\n";
165 print $OUT " ** Major contributors: $major_contributors\n";
166 print $OUT " ** Minor contributors (to current version): $minor_contributors\n";
167 print $OUT $standard_template;
168 print $OUT " **\n";
169 while(my $line = <$IN>) {
170 last if $line =~ /^ \*\*\s*$/;
171 if($line =~ /\*\//) {
172 print $OUT " ** [[ Add lengthier description here ]]\n";
173 print $OUT " ** \\todo document this file\n";
174 print $OUT $line;
175 last;
176 }
177 }
178 } else {
179 my $line = $_;
180 print "adding\n";
181 if($file =~ /\.(y|yy|ypp|Y)$/) {
182 print $OUT "%{/******************* */\n";
183 print $OUT "/*! \\file $file\n";
184 } elsif($file =~ /\.g$/) {
185 # avoid javadoc-style comment here; antlr complains
186 print $OUT "/* ******************* */\n";
187 print $OUT "/*! \\file $file\n";
188 } else {
189 print $OUT "/********************* */\n";
190 print $OUT "/*! \\file $file\n";
191 }
192 print $OUT " ** \\verbatim\n";
193 print $OUT " ** Original author: $author\n";
194 print $OUT " ** Major contributors: $major_contributors\n";
195 print $OUT " ** Minor contributors (to current version): $minor_contributors\n";
196 print $OUT $standard_template;
197 print $OUT " **\n";
198 print $OUT " ** \\brief [[ Add one-line brief description here ]]\n";
199 print $OUT " **\n";
200 print $OUT " ** [[ Add lengthier description here ]]\n";
201 print $OUT " ** \\todo document this file\n";
202 print $OUT " **/\n\n";
203 print $OUT $line;
204 if($file =~ /\.(y|yy|ypp|Y)$/) {
205 while(my $line = <$IN>) {
206 chomp $line;
207 if($line =~ '\s*%{(.*)') {
208 print $OUT "$1\n";
209 last;
210 }
211 # just in case something's weird with the file ?
212 if(!($line =~ '\s*')) {
213 print $OUT "$line\n";
214 last;
215 }
216 }
217 }
218 }
219 while(my $line = <$IN>) {
220 print $OUT $line;
221 }
222 close $IN;
223 close $OUT;
224 rename($outfile, $infile) || die "can't rename working file \`$outfile' to \`$infile'";
225 }
226
227 sub recurse {
228 my ($srcdir) = @_;
229 print "in dir $srcdir\n";
230 opendir(my $DIR, $srcdir);
231 while(my $file = readdir $DIR) {
232 next if !($file =~ /^[a-zA-Z]/);
233
234 my $mode = (stat($srcdir.'/'.$file))[2];
235 my $is_directory = S_ISDIR($mode);
236 if($is_directory) {
237 next if $file =~ /$excluded_directories/;
238 recurse($srcdir.'/'.$file);
239 } else {
240 handleFile($srcdir, $file);
241 }
242 }
243 closedir $DIR;
244 }
245
246 ### Local Variables:
247 ### perl-indent-level: 2
248 ### End: