aboutsummaryrefslogtreecommitdiffstats
path: root/admin
diff options
context:
space:
mode:
authorGerd Moellmann2001-08-16 15:23:50 +0000
committerGerd Moellmann2001-08-16 15:23:50 +0000
commit30b50b5ccae58bc42bbb2e5ba341c0a02d231000 (patch)
tree0c692fa31c22b961efd5ed9312e491101f356cd0 /admin
parentb76dfd21ba9096127691de31d02ad8a6ef73b4c7 (diff)
downloademacs-30b50b5ccae58bc42bbb2e5ba341c0a02d231000.tar.gz
emacs-30b50b5ccae58bc42bbb2e5ba341c0a02d231000.zip
*** empty log message ***
Diffstat (limited to 'admin')
-rw-r--r--admin/README3
-rwxr-xr-xadmin/build-configs70
-rwxr-xr-xadmin/check-doc-strings300
-rwxr-xr-xadmin/make-emacs175
-rwxr-xr-xadmin/revdiff122
5 files changed, 670 insertions, 0 deletions
diff --git a/admin/README b/admin/README
new file mode 100644
index 00000000000..a1edad489c2
--- /dev/null
+++ b/admin/README
@@ -0,0 +1,3 @@
1This directory contains scripts and other things useful for
2maintaining Emacs. These files are not part of Emacs releases because
3they are not deemed generally useful.
diff --git a/admin/build-configs b/admin/build-configs
new file mode 100755
index 00000000000..521afb3acff
--- /dev/null
+++ b/admin/build-configs
@@ -0,0 +1,70 @@
1#! /usr/bin/perl
2
3# Copyright (C) 2001 Free Software Foundation, Inc.
4#
5# This file is part of GNU Emacs.
6#
7# GNU Emacs is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2, or (at your option)
10# any later version.
11#
12# GNU Emacs is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with GNU Emacs; see the file COPYING. If not, write to the
19# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20# Boston, MA 02111-1307, USA.
21
22# Build Emacs in several different configurations.
23
24@configs =
25 (
26 ["--without-x", "--optim"],
27 ["--without-x-toolkit", "--optim"],
28 ["--without-toolkit-scroll-bars", "--optim"],
29 ["--with-x-toolkit=lucid", "--optim"],
30 ["--with-x-toolkit=motif", "--optim"],
31 ["--with-x-toolkit=motif", "--enable-checking"],
32 ["--with-x-toolkit=motif", "--gcc3"],
33 ["--with-x-toolkit=motif", ""],
34 );
35
36$log = "/tmp/$$.out";
37print "Using log file $log\n";
38unlink $log;
39
40$root = $ENV{"EMACS_ROOT"};
41$root = "/gd/gnu/emacs" unless $root;
42chdir ($root) or die "Cannot chdir to emacs";
43
44foreach $config (@configs)
45 {
46 my $configure_options = @$config[0];
47 my $make_options = @$config[1];
48 my $rc;
49
50 print "$configure_options, $make_options\n";
51 unlink "config.cache";
52
53 $rc = system ("$root/configure $configure_options >>$log 2>&1");
54 if ($rc != 0)
55 {
56 print "configure failed\n";
57 exit 1;
58 }
59
60 $rc = system ("make-emacs --all $make_options >>$log 2>&1");
61 if ($rc != 0)
62 {
63 print "Make failed\n";
64 exit 1;
65 }
66 }
67
68# Local Variables:
69# mode: cperl
70# End:
diff --git a/admin/check-doc-strings b/admin/check-doc-strings
new file mode 100755
index 00000000000..f5f750925eb
--- /dev/null
+++ b/admin/check-doc-strings
@@ -0,0 +1,300 @@
1: #-*- Perl -*-
2eval 'exec perl -w -S $0 ${1+"$@"}' # Portability kludge
3 if 0; # Author: Martin Buchholz
4
5use strict;
6use POSIX;
7
8(my $myName = $0) =~ s@.*/@@; my $usage="
9Usage: $myName
10
11Finds DOCSTRING arg mismatches between
12formal parameters, docstrings, and lispref texi.
13
14This program is in the public domain.\n";
15
16die $usage if @ARGV;
17die $usage unless -r "src/alloc.c" && -d "CVS" && -d "lisp";
18
19my %texi_funtype;
20my %texi_arglist;
21
22my %code_funtype;
23my %code_arglist;
24
25sub FileContents {
26 local $/ = undef;
27 open (FILE, "< $_[0]") or die "$_[0]: $!";
28 return scalar <FILE>;
29}
30
31sub Show_details {
32 my ($show_details, $function, $parms, $docstring) = @_;
33 if ($show_details) {
34 print "function = $function $parms\n$docstring\n", "-" x 70, "\n";
35 }
36}
37
38sub Check_texi_function {
39 my ($function, $funtype, $docstring, @parms) = @_;
40 my %docstring_parm;
41 my %docstring_word;
42 my %arglist_parm;
43 my $show_details = 0;
44
45 if (exists $texi_funtype{$function}) {
46 print "duplicate texidoc: $function @parms\n";
47 return; # later definition likely bogus package def
48 }
49
50 $texi_funtype{$function} = $funtype;
51 $texi_arglist{$function} = "@parms";
52
53 foreach my $parm (@parms) {
54 next if $parm eq '&optional' || $parm eq '&rest';
55 $arglist_parm{$parm} = 1;
56 }
57
58 foreach my $parm ($docstring =~ /\@var{([^{}]+)}/g) {
59 $docstring_parm{$parm} = 1;
60 }
61
62 foreach my $hit ($docstring =~ /[^\`]\`[A-Za-z-]+\'/g)
63 {
64 print "texi \@code missing: $function: $hit\n";
65 $show_details = 1;
66 }
67
68 # (my $raw_docstring = $docstring) =~ s/\@var{[^{}]+}//g;
69 # $raw_docstring =~ s/[^a-zA-Z_-]+/ /g;
70 # foreach my $word (split (' ', $raw_docstring)) {
71 # if ($word =~ /^[A-Z][A-Z-]+$/) {
72 # print "Missing \@var: $function: $word\n";
73 # }
74 # }
75
76 foreach my $parm (keys %docstring_parm) {
77 if (! exists $arglist_parm{$parm}) {
78 print "bogus texi parm: $function: $parm\n";
79 $show_details = 1;
80 }
81 }
82
83 foreach my $parm (keys %arglist_parm) {
84 if (! exists $docstring_parm{$parm}) {
85 print "undocumented texi parm: $function: $parm\n";
86 $show_details = 1;
87 }
88 }
89
90 Show_details $show_details, $function, "@parms", $docstring;
91}
92
93sub Check_function {
94 my ($function, $funtype, $docstring, @parms) = @_;
95 my %docstring_parm;
96 my %arglist_parm;
97 my $show_details = 0;
98
99 if (exists $code_funtype{$function}) {
100 print "duplicate codedef: $function @parms\n";
101 return; # later definition likely bogus package def
102 }
103
104 $code_funtype{$function} = $funtype;
105 $code_arglist{$function} = "@parms";
106 #foreach my $parm ($parms =~ /\b[a-z0-9-]{3,}\b/g) {
107 # $arglist_parm{$parm} = 1;
108 #}
109 foreach my $parm (@parms) {
110 next if $parm eq '&optional' || $parm eq '&rest';
111 $arglist_parm{$parm} = 1;
112 }
113 my $doc_tmp = $docstring;
114 $doc_tmp =~ s/[^A-Za-z0-9_-]/ /g;
115 foreach my $parm (split (' ', $doc_tmp)) {
116 if ($parm =~ /^[A-Z][A-Z0-9-]*$/) {
117 next if $parm =~ /I18N/;
118 next if $parm =~ /M17N/;
119 $parm =~ tr[A-Z][a-z];
120 $docstring_parm{$parm} = 1;
121 }
122 }
123 # foreach my $parm ($docstring =~ /\b[A-Z0-9-]{1,}\b/g) {
124 # next if $parm =~ /-$/;
125 # $parm =~ tr[A-Z][a-z];
126 # $docstring_parm{$parm} = 1;
127 # }
128 foreach my $parm (keys %docstring_parm) {
129 next if $parm eq 'tty';
130 next if $parm eq 'fsf';
131 next if $parm eq 'note';
132 next if $parm eq 'warning';
133 next if $parm eq 'bug';
134 next if $parm eq 'ascii';
135 next if $parm eq 'iso';
136 next if $parm eq 'and';
137 next if $parm eq 'absolutely';
138 next if $parm eq 'doc';
139 next if $parm eq 'user';
140 next if $parm eq 'not';
141 next if $parm eq 'must';
142 next if $parm eq 'nil';
143 next if $parm eq 'esc';
144 next if $parm eq 'lfd';
145 next if $parm eq 'gpm';
146 next if $parm eq 'primary';
147 next if $parm eq 'secondary';
148 next if $parm eq 'clipboard';
149 next if length $parm < 3;
150 if (! exists $arglist_parm{$parm}) {
151 print "bogus parm: $function: $parm\n";
152 $show_details = 1;
153 }
154 }
155 foreach my $parm (keys %arglist_parm) {
156 if (! exists $docstring_parm{$parm}) {
157 print "Undocumented parm: $function: $parm\n";
158 $show_details = 1;
159 }
160 }
161
162 if ($docstring !~ /[\]}!\)\.]\s*\Z/m &&
163 $docstring =~ /\S/ &&
164 $docstring !~ /Keywords supported/)
165 {
166 print "Missing trailing period: $function\n";
167 $show_details = 1;
168 }
169
170 if (exists $texi_arglist{$function}
171 and "@parms" ne $texi_arglist{$function}
172 and not ("@parms" eq 'int nargs Lisp-Object *args'
173 && $texi_arglist{$function} =~ /&rest/)) {
174 my @texi_parms = split (' ', $texi_arglist{$function});
175 my @a = ("@parms" =~ /&optional/g);
176 my @b = ("@parms" =~ /&rest/g);
177 my @c = ("@texi_parms" =~ /&optional/g);
178 my @d = ("@texi_parms" =~ /&rest/g);
179 if (@parms != @texi_parms
180 || (@a != @c) || (@b != @d)) {
181 print "serious mismatch: $function: @parms --- @texi_parms\n";
182 } else {
183 print "texi mismatch: $function: @parms --- $texi_arglist{$function}\n";
184 }
185 $show_details = 1;
186 }
187
188 if (exists $texi_funtype{$function}
189 && $texi_funtype{$function} ne $funtype) {
190 print "interactiveness mismatch: $function: $funtype --- $texi_funtype{$function}\n";
191 $show_details = 1;
192 }
193
194 Show_details $show_details, $function, "@parms", $docstring;
195}
196
197my $lisprefdir;
198if (-d "man/lispref") { $lisprefdir = "man/lispref"; }
199elsif (-d "lispref") { $lisprefdir = "lispref"; }
200else { die "Can't find lispref texi directory.\n"; }
201
202open (FIND, "find $lisprefdir -name '*.texi' -print |") or die;
203while (my $file = <FIND>) {
204 my @matches = ((FileContents $file) =~
205 /\@(def(?:fn|un))([^\n]+)\n(.*?)\n\@end def(?:un|fn)/sgo);
206 # /^\@(def(?:un|fn))\s+(.*)\n([.|\n]*?)^\@end def(?:un|fn)\n/mgo);
207 while (@matches) {
208 my ($defform, $defn, $docstring) = splice (@matches, 0, 3);
209 #print "defform = $defform\n";
210 #print "defn = $defn\n";
211 #print "docstring = $docstring\n";
212 my ($function, @parms, $funtype);
213 if ($defform eq 'defun') {
214 ($funtype, $function, @parms) = ('Function', split (' ', $defn));
215 } else {
216 die unless $defform eq 'deffn';
217 ($funtype, $function, @parms) = split (' ', $defn);
218 }
219 next if $funtype eq '{Syntax' or $funtype eq '{Prefix';
220
221 Check_texi_function $function, $funtype, $docstring, @parms;
222 }
223}
224
225open (FIND, "find src -name '*.c' -print |") or die;
226while (my $file = <FIND>) {
227 my @matches =
228 ((FileContents $file) =~
229 /\bDEFUN\s*\(\s*\"((?:[^\\\"]|\\.)+)\"\s*,\s*\S+\s*,\s*(\S+)\s*,\s*(\S+)\s*,\s*((?:0|\"(?:(?:[^\\\"]|\\.)*)\"))\s*,\s*\/\*(.*?)\*\/\s*\(([^()]*)\)\)/sgo);
230 while (@matches) {
231 my ($function, $minargs, $maxargs, $interactive, $docstring, $parms) = splice (@matches, 0, 6);
232 $docstring =~ s/^\n+//s;
233 $docstring =~ s/\n+$//s;
234 $parms =~ s/,/ /g;
235 my @parms = split (' ',$parms);
236 for (@parms) { tr/_/-/; s/-$//; }
237 if ($parms !~ /Lisp_Object/) {
238 if ($minargs < @parms) {
239 if ($maxargs =~ /^\d+$/) {
240 die unless $maxargs eq @parms;
241 splice (@parms, $minargs, 0, '&optional');
242 }
243 }
244 }
245 my $funtype = ($interactive =~ /\"/ ? 'Command' : 'Function');
246 Check_function $function, $funtype, $docstring, @parms;
247 }
248}
249
250my @pkgs;
251if (-d "../xemacs-packages") {
252 @pkgs = qw (libs/edebug libs/xemacs-base comm/eudc oa/edit-utils);
253} else {
254 @pkgs = ();
255}
256for (@pkgs) { s@^@../xemacs-packages/@; }
257open (FIND, "find lisp @pkgs -name '*.el' -print |") or die;
258while (my $file = <FIND>) {
259 my $contents = FileContents $file;
260 $contents =~ s/(?:\s|;);.*//mog;
261 my @matches =
262 ($contents =~
263 /\((def(?:un|subst|macro))\s+(\S+)\s+\(([^()]*)\)\s+\"((?:[^\\\"]|\\.)+)\"(.*?)\)/sgo);
264 while (@matches) {
265 my ($defform, $function, $parms, $docstring, $code_fragment) = splice (@matches, 0, 5);
266
267 my $funtype =
268 $defform eq 'defmacro' ? 'Macro' :
269 $code_fragment =~ /^\s*\(interactive\b/so ? 'Command' :
270 'Function';
271
272 $docstring =~ s/^\n+//s;
273 $docstring =~ s/\n+$//s;
274
275 my @parms = split (' ', $parms);
276
277 Check_function $function, $funtype, $docstring, @parms;
278 }
279}
280
281open (FIND, "find lisp @pkgs -name '*.el' -print |") or die;
282while (my $file = <FIND>) {
283 my $contents = FileContents $file;
284 $contents =~ s/(?:\s|;);.*//mog;
285
286 my @matches = ($contents =~ /^\((?:defalias|fset|define-function)\s+\'([A-Za-z0-9_-]+)\s+\'([A-Za-z0-9_-]+)/mog);
287 while (@matches) {
288 my ($alias, $aliasee) = splice (@matches, 0, 2);
289 print "alias $alias aliasee $aliasee\n";
290 if (exists $code_funtype{$aliasee}) { $code_funtype{$alias} = $code_funtype{$aliasee}; }
291 if (exists $code_arglist{$aliasee}) { $code_arglist{$alias} = $code_arglist{$aliasee}; }
292 }
293}
294
295foreach my $fun (sort keys %texi_funtype) {
296 if (not exists $code_funtype{$fun}) {
297 print "nuke-this-doc: $fun $texi_funtype{$fun}\n";
298 }
299}
300
diff --git a/admin/make-emacs b/admin/make-emacs
new file mode 100755
index 00000000000..83683c41269
--- /dev/null
+++ b/admin/make-emacs
@@ -0,0 +1,175 @@
1#! /usr/bin/perl
2
3# Copyright (C) 2001 Free Software Foundation, Inc.
4#
5# This file is part of GNU Emacs.
6#
7# GNU Emacs is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2, or (at your option)
10# any later version.
11#
12# GNU Emacs is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with GNU Emacs; see the file COPYING. If not, write to the
19# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20# Boston, MA 02111-1307, USA.
21
22# Build Emacs with various options for profiling, debugging,
23# with and without warnings enabled etc.
24
25require 5;
26use Getopt::Long;
27use File::Basename;
28use Cwd;
29
30# Default CVS sandbox directory. Only used when called from outside
31# of the sandbox.
32
33$root = $ENV{"EMACS_ROOT"};
34$root = "/gd/gnu/emacs" unless $root;
35
36# Default make command.
37
38$make = $ENV{"EMACS_MAKE"};
39$make = "gmake" unless $make;
40
41$rc = GetOptions ("help" => \$help,
42 "enable-checking" => \$enable_checking,
43 "no-warn" => \$no_warn,
44 "check-marked" => \$check_marked,
45 "all" => \$all,
46 "no-optim" => \$no_optim,
47 "union-type" => \$union_type,
48 "gprof" => \$profile,
49 "malloc-check" => \$malloc_check,
50 "no-mcheck" => \$no_mcheck,
51 "alias" => \$aliasing,
52 "wall" => \$wall,
53 "gcc3" => \$gcc3,
54 "trace-selection" => \$trace_selection,
55 "stabs" => \$use_stabs,
56 "optim" => \$optim);
57
58if ($rc == 0 || $help)
59 {
60 print <<USAGE;
61make-emacs [options] ...
62
63Build Emacs.
64
65 --help show this help
66 --all make clean versionclean first
67 --enable-checking ENABLE_CHECKING=1 (implies Lisp union type)
68 --no-warn disable warnings
69 --check-marked GC_CHECK_MARKED_OBJECTS=1
70 --optim no debug defines
71 --gprof make Emacs for profiling
72 --union-type define USE_LISP_UNION_TYPE (bad for GDB)
73 --malloc-check define GC_MALLOC_CHECK
74 --no-mcheck dont define GC_MCHECK
75 --wall compile with -Wall
76 --gcc3 use GCC 3.0 (30% slower compilation, slower code)
77 --trace-selection print traces in xselect.c
78 --stabs use -gstabs instead -g
79
80Default is to compile with warnings, with -DGC_MCHECK=1, and
81with -DGLYPH_DEBUG=1.
82
83USAGE
84 exit 1;
85 }
86
87# Chdir to the top-level directory of the tree. If not in a tree
88# containing Emacs, use the default.
89
90while (! -f "src/emacs.c" && cwd () ne "/")
91 {
92 chdir "..";
93 }
94
95chdir $root if cwd () eq "/";
96chdir "./src";
97print "Build in ", cwd (), "\n";
98
99# If first arg is `all' or if `--all' specified, ensure a clean
100# build.
101
102if (@ARGV && $ARGV[0] eq "all")
103 {
104 $all = 1;
105 shift @ARGV;
106 }
107
108system ("$make clean versionclean") if $all;
109
110if ($wall)
111 {
112 $warn = "-Wall";
113 }
114elsif (!$no_warn)
115 {
116 $warn = "-Wpointer-arith -Wchar-subscripts -Wformat -Wimplicit-int";
117 $warn = "$warn -Wreturn-type -Wswitch -Wuninitialized";
118 }
119
120$defs = "-DGLYPH_DEBUG=1" unless $optim;
121$defs = "$defs -DGC_CHECK_MARKED_OBJECTS=1" if $check_marked;
122$defs = "$defs -DENABLE_CHECKING=1" if $enable_checking;
123
124if ($profile)
125 {
126 $opts = "-pg";
127 $defs = "$defs -DPROFILING=1";
128 }
129else
130 {
131 if ($use_stabs)
132 {
133 $opts = "-gstabs";
134 }
135 else
136 {
137 $opts = "-g";
138 }
139 }
140
141$defs = "$defs -DUSE_LISP_UNION_TYPE" if $union_type;
142$defs = "$defs -DGC_MALLOC_CHECK=1 -DGC_PROTECT_MALLOC_STATE=1" if $malloc_check;
143$defs = "$defs -DGC_MCHECK=1" unless $no_mcheck;
144
145$defs = "$defs -DTRACE_SELECTION" if $trace_selection;
146
147# arch=pentium leads to slightly faster code than without.
148$opts = "$opts -march=pentiumpro";
149
150if ($optim)
151 {
152 $opts = "$opts -pipe -O3";
153 }
154elsif ($no_optim)
155 {
156 $opts = "$opts -pipe -fno-inline";
157 }
158else
159 {
160 $opts = "$opts -O -pipe -fno-inline";
161 }
162
163$opts = "$opts -fstrict-aliasing" if $aliasing;
164
165$opts = "$opts $defs" if $defs;
166$opts = "$opts $warn" if $warn;
167
168$cc = "/usr/bin/gcc";
169$cc = "/gd/local/bin/gcc" if $gcc3;
170
171exit system "$make CC=\"$cc\" CFLAGS=\"$opts\" @ARGV";
172
173# Local Variables:
174# mode: cperl
175# End:
diff --git a/admin/revdiff b/admin/revdiff
new file mode 100755
index 00000000000..bdd6a2210ce
--- /dev/null
+++ b/admin/revdiff
@@ -0,0 +1,122 @@
1#! /usr/bin/perl
2
3# Copyright (C) 2001 Free Software Foundation, Inc.
4#
5# This file is part of GNU Emacs.
6#
7# GNU Emacs is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2, or (at your option)
10# any later version.
11#
12# GNU Emacs is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with GNU Emacs; see the file COPYING. If not, write to the
19# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20# Boston, MA 02111-1307, USA.
21
22use File::Basename;
23
24if (@ARGV < 3)
25{
26 print <<USAGE;
27revdiff FILE OLD NEW
28
29Get a diff of FILE between revisions OLD and NEW. Store the
30diff in a file named FILE-OLD-NEW.diff. If NEW is +<number>
31or -<number>, build diffs between revisions OLD and OLD +/- <number>.
32OLD being `-' means use FILE's current revision.
33
34Examples:
35
36revdiff FILE - -1 get the latest change of FILE
37revdiff FILE 1.500 +2 get diffs 1.500-1.501 and 1.501-1.502.
38
39USAGE
40 exit 1;
41}
42
43$file = shift @ARGV;
44$old = shift @ARGV;
45
46sub diffit
47{
48 my ($old, $new) = @_;
49 print "cvs diff -r$old -r$new $file >$file-$old-$new.diff\n";
50 system "cvs diff -r$old -r$new $file >$file-$old-$new.diff";
51}
52
53sub current_revision ($)
54{
55 my ($file) = @_;
56 my $dir = dirname ($file);
57 my $base = basename ($file);
58 my $entries = "$dir/CVS/Entries";
59 die "Can't find $entries" unless -f $entries;
60 open (IN, "<$entries") or die "Cannot open $entries";
61 my $rev;
62 while ($line = <IN>)
63 {
64 if ($line =~ m,/$base/([^/]+),)
65 {
66 $rev = $1;
67 break;
68 }
69 }
70 die "Cannot determine current revision of $file" unless $rev;
71 close (IN);
72 return $rev;
73}
74
75if ($old eq "-")
76{
77 $old = current_revision ($file);
78}
79
80while (@ARGV)
81 {
82 my $new = shift @ARGV;
83 if ($new =~ /^[+]\d+$/)
84 {
85 my $n = $new;
86 for ($i = 0; $i < $n; ++$i)
87 {
88 unless ($old =~ /(.*)\.(\d+)$/)
89 {
90 die "Internal error";
91 }
92 my $j = $2 + 1;
93 $new = "$1.$j";
94 diffit ($old, $new);
95 $old = $new;
96 }
97 }
98 elsif ($new =~ /^[-]\d+$/)
99 {
100 my $n = - $new;
101 for ($i = 0; $i < $n; ++$i)
102 {
103 unless ($old =~ /(.*)\.(\d+)$/)
104 {
105 die "Internal error";
106 }
107 my $j = $2 - 1;
108 $new = "$1.$j";
109 diffit ($new, $old);
110 $old = $new;
111 }
112 }
113 else
114 {
115 diffit ($old, $new);
116 $old = $new;
117 }
118 }
119
120# Local Variables:
121# mode: cperl
122# End: