eggert@twinsun.com (Paul Eggert) (11/11/89)
We evaluated a test copy of Saber C by trying it out on GNU DIFF 1.10, and
found a few bugs. We delinted DIFF first so that Saber C could focus on
runtime errors. Here are many lint fixes and some runtime fixes to GNU DIFF
1.10. Patches are relative to a previous bug report that sped up GNU DIFF
1.10.
The runtime fixes are:
shift_boundaries() referenced one past the end of files[f].equivs when
end==i_end. Interchanging the order of tests fixed the problem
(analyze.c:517 below).
diff_2_files() did a free(script) followed by a return script?1:0; ANSI
C doesn't let a program examine a pointer to freed storage.
(analyze.c:816 below).
line_cmp() referred to uninitialized storage when going one past the
end of the input file. (fix in io.c:122 below).
find_equiv_class(n) referred to current->linbuf[n] even when n <
current->prefix_lines, causing a reference to uninitialized storage.
(fixes near io.c:499 below).
The lint fixes are:
Adding procedure declarations.
Removing code and variables that were never used. In particular:
Many routines took a struct file_data * parameter and never
used it.
The regex code permits obscure syntax, but this is never used.
Casting ...alloc() size arguments to unsigned.
Adding "" arguments to message routines.
'preceeding' -> 'preceding'
===================================================================
RCS file: RCS/analyze.c,v
retrieving revision 1.1
diff -c -r1.1 analyze.c
*** /tmp/,RCSt1a21584 Fri Nov 10 11:48:13 1989
--- analyze.c Thu Nov 9 22:00:31 1989
***************
*** 23,28 ****
--- 23,38 ----
#include "diff.h"
+ void finish_output ();
+ void pr_forward_ed_script ();
+ void print_context_header ();
+ void print_context_script ();
+ void print_ed_script ();
+ void print_ifdef_script ();
+ void print_normal_script ();
+ void print_rcs_script ();
+ void setup_output ();
+
extern int no_discards;
static int *xvec, *yvec; /* Vectors being compared. */
***************
*** 248,259 ****
files[0].changed_flag[files[0].realindexes[xoff++]] = 1;
else
{
! int c, d, f, b;
/* Find a point of correspondence in the middle of the files. */
d = diag (xoff, xlim, yoff, ylim, &c);
- f = fdiag[d];
b = bdiag[d];
if (c == 1)
--- 258,268 ----
files[0].changed_flag[files[0].realindexes[xoff++]] = 1;
else
{
! int c, d, b;
/* Find a point of correspondence in the middle of the files. */
d = diag (xoff, xlim, yoff, ylim, &c);
b = bdiag[d];
if (c == 1)
***************
*** 276,285 ****
{
/* Use that point to split this problem into two subproblems. */
compareseq (xoff, b, yoff, b - d);
- /* This used to use f instead of b,
- but that is incorrect!
- It is not necessarily the case that diagonal d
- has a snake from b to f. */
compareseq (b, xlim, b - d, ylim);
}
}
--- 285,290 ----
***************
*** 301,307 ****
discard_confusing_lines (filevec)
struct file_data filevec[];
{
! int f, i, j, k;
char *discarded[2];
int *equiv_count[2];
--- 306,312 ----
discard_confusing_lines (filevec)
struct file_data filevec[];
{
! int f, i;
char *discarded[2];
int *equiv_count[2];
***************
*** 329,336 ****
/* Set up tables of which lines are going to be discarded. */
! discarded[0] = (char *) xmalloc (filevec[0].buffered_lines);
! discarded[1] = (char *) xmalloc (filevec[1].buffered_lines);
bzero (discarded[0], filevec[0].buffered_lines);
bzero (discarded[1], filevec[1].buffered_lines);
--- 334,341 ----
/* Set up tables of which lines are going to be discarded. */
! discarded[0] = (char *) xmalloc ((unsigned) filevec[0].buffered_lines);
! discarded[1] = (char *) xmalloc ((unsigned) filevec[1].buffered_lines);
bzero (discarded[0], filevec[0].buffered_lines);
bzero (discarded[1], filevec[1].buffered_lines);
***************
*** 421,427 ****
{
char *discards = discarded[f];
int end = filevec[f].buffered_lines;
! j = 0;
for (i = 0; i < end; ++i)
if (no_discards || discards[i] == 0)
{
--- 426,432 ----
{
char *discards = discarded[f];
int end = filevec[f].buffered_lines;
! int j = 0;
for (i = 0; i < end; ++i)
if (no_discards || discards[i] == 0)
{
***************
*** 468,476 ****
int i = 0;
int j = 0;
int i_end = filevec[f].buffered_lines;
! int j_end = filevec[1-f].buffered_lines;
! int preceeding = -1;
! int other_preceeding = -1;
while (1)
{
--- 473,480 ----
int i = 0;
int j = 0;
int i_end = filevec[f].buffered_lines;
! int preceding = -1;
! int other_preceding = -1;
while (1)
{
***************
*** 483,490 ****
{
while (other_changed[j++])
/* Non-corresponding lines in the other file
! will count as the preceeding batch of changes. */
! other_preceeding = j;
i++;
}
--- 487,494 ----
{
while (other_changed[j++])
/* Non-corresponding lines in the other file
! will count as the preceding batch of changes. */
! other_preceding = j;
i++;
}
***************
*** 510,521 ****
/* You might ask, how could this run follow right after another?
Only because the previous run was shifted here. */
! if (files[f].equivs[start] == files[f].equivs[end]
&& !other_changed[j]
! && end != i_end
! && !((preceeding >= 0 && start == preceeding)
! || (other_preceeding >= 0
! && other_start == other_preceeding)))
{
changed[end++] = 1;
changed[start++] = 0;
--- 514,525 ----
/* You might ask, how could this run follow right after another?
Only because the previous run was shifted here. */
! if (end != i_end
! && files[f].equivs[start] == files[f].equivs[end]
&& !other_changed[j]
! && !((preceding >= 0 && start == preceding)
! || (other_preceding >= 0
! && other_start == other_preceding)))
{
changed[end++] = 1;
changed[start++] = 0;
***************
*** 529,536 ****
break;
}
! preceeding = i;
! other_preceeding = j;
}
}
}
--- 533,540 ----
break;
}
! preceding = i;
! other_preceding = j;
}
}
}
***************
*** 686,694 ****
&& output_style != OUTPUT_RCS)
{
if (filevec[0].missing_newline)
! message ("No newline at end of file %s\n", filevec[0].name);
if (filevec[1].missing_newline)
! message ("No newline at end of file %s\n", filevec[1].name);
}
/* Allocate vectors for the results of comparison:
--- 690,698 ----
&& output_style != OUTPUT_RCS)
{
if (filevec[0].missing_newline)
! message ("No newline at end of file %s\n", filevec[0].name, "");
if (filevec[1].missing_newline)
! message ("No newline at end of file %s\n", filevec[1].name, "");
}
/* Allocate vectors for the results of comparison:
***************
*** 696,703 ****
is an insertion or deletion.
Allocate an extra element, always zero, at each end of each vector. */
! filevec[0].changed_flag = (char *) xmalloc (filevec[0].buffered_lines + 2);
! filevec[1].changed_flag = (char *) xmalloc (filevec[1].buffered_lines + 2);
bzero (filevec[0].changed_flag, filevec[0].buffered_lines + 2);
bzero (filevec[1].changed_flag, filevec[1].buffered_lines + 2);
filevec[0].changed_flag++;
--- 700,707 ----
is an insertion or deletion.
Allocate an extra element, always zero, at each end of each vector. */
! filevec[0].changed_flag = (char *) xmalloc ((unsigned)filevec[0].buffered_lines + 2);
! filevec[1].changed_flag = (char *) xmalloc ((unsigned)filevec[1].buffered_lines + 2);
bzero (filevec[0].changed_flag, filevec[0].buffered_lines + 2);
bzero (filevec[1].changed_flag, filevec[1].buffered_lines + 2);
filevec[0].changed_flag++;
***************
*** 799,804 ****
--- 803,811 ----
free (filevec[i].linbuf);
}
+ if (!script)
+ return 0;
+
for (e = script; e; e = p)
{
p = e->link;
***************
*** 805,809 ****
free (e);
}
! return script ? 1 : 0;
}
--- 812,816 ----
free (e);
}
! return 1;
}
===================================================================
RCS file: RCS/context.c,v
retrieving revision 1.1
diff -c -r1.1 context.c
*** /tmp/,RCSt1a21584 Fri Nov 10 11:48:13 1989
--- context.c Thu Nov 9 21:43:40 1989
***************
*** 20,29 ****
#include "diff.h"
#include "regex.h"
static void pr_context_hunk ();
static struct change *find_hunk ();
static void mark_ignorable ();
! static int find_function ();
/* Last place find_function started searching from. */
static int find_function_last_search;
--- 20,31 ----
#include "diff.h"
#include "regex.h"
+ void translate_range ();
+
static void pr_context_hunk ();
static struct change *find_hunk ();
static void mark_ignorable ();
! static void find_function ();
/* Last place find_function started searching from. */
static int find_function_last_search;
***************
*** 64,70 ****
print_script (script, find_hunk, pr_context_hunk);
}
! /* Print a pair of line numbers with a comma, translated for file FILE.
If the second number is smaller, use the first in place of it.
Args A and B are internal line numbers.
--- 66,72 ----
print_script (script, find_hunk, pr_context_hunk);
}
! /* Print a pair of line numbers with a comma.
If the second number is smaller, use the first in place of it.
Args A and B are internal line numbers.
***************
*** 71,82 ****
We print the translated (real) line numbers. */
static void
! print_context_number_range (file, a, b)
! struct file_data *file;
int a, b;
{
int trans_a, trans_b;
! translate_range (file, a, b, &trans_a, &trans_b);
/* Note: we can have B < A in the case of a range of no lines.
In this case, we should print the line number before the range,
--- 73,83 ----
We print the translated (real) line numbers. */
static void
! print_context_number_range (a, b)
int a, b;
{
int trans_a, trans_b;
! translate_range (a, b, &trans_a, &trans_b);
/* Note: we can have B < A in the case of a range of no lines.
In this case, we should print the line number before the range,
***************
*** 101,107 ****
int first0, last0, first1, last1, show_from, show_to, i;
struct change *next;
char *prefix;
- int lastline;
char *function;
int function_length;
--- 102,107 ----
***************
*** 122,128 ****
/* If desired, find the preceding function definition line in file 0. */
function = 0;
if (function_regexp)
! find_function (&files[0], first0, &function, &function_length);
/* If we looked for and found a function this is part of,
include its name in the header of the diff section. */
--- 122,128 ----
/* If desired, find the preceding function definition line in file 0. */
function = 0;
if (function_regexp)
! find_function (first0, &function, &function_length);
/* If we looked for and found a function this is part of,
include its name in the header of the diff section. */
***************
*** 135,141 ****
}
fprintf (outfile, "\n*** ");
! print_context_number_range (&files[0], first0, last0);
fprintf (outfile, " ****\n");
if (show_from)
--- 135,141 ----
}
fprintf (outfile, "\n*** ");
! print_context_number_range (first0, last0);
fprintf (outfile, " ****\n");
if (show_from)
***************
*** 164,170 ****
}
fprintf (outfile, "--- ");
! print_context_number_range (&files[1], first1, last1);
fprintf (outfile, " ----\n");
if (show_to)
--- 164,170 ----
}
fprintf (outfile, "--- ");
! print_context_number_range (first1, last1);
fprintf (outfile, " ----\n");
if (show_to)
***************
*** 258,272 ****
}
}
! /* Find the last function-header line in FILE prior to line number LINENUM.
This is a line containing a match for the regexp in `function_regexp'.
Store the address of the line text into LINEP and the length of the
line into LENP.
Do not store anything if no function-header is found. */
! static int
! find_function (file, linenum, linep, lenp)
! struct file_data *file;
int linenum;
char **linep;
int *lenp;
--- 258,271 ----
}
}
! /* Find the last function-header line prior to line number LINENUM.
This is a line containing a match for the regexp in `function_regexp'.
Store the address of the line text into LINEP and the length of the
line into LENP.
Do not store anything if no function-header is found. */
! static void
! find_function (linenum, linep, lenp)
int linenum;
char **linep;
int *lenp;
***************
*** 288,294 ****
*linep = files[0].linbuf[i].text;
*lenp = files[0].linbuf[i].length;
find_function_last_match = i;
! return 1;
}
}
/* If we search back to where we started searching the previous time,
--- 287,293 ----
*linep = files[0].linbuf[i].text;
*lenp = files[0].linbuf[i].length;
find_function_last_match = i;
! return;
}
}
/* If we search back to where we started searching the previous time,
***************
*** 298,304 ****
i = find_function_last_match;
*linep = files[0].linbuf[i].text;
*lenp = files[0].linbuf[i].length;
- return 1;
}
- return 0;
}
--- 297,301 ----
===================================================================
RCS file: RCS/diff.c,v
retrieving revision 1.2
diff -c -r1.2 diff.c
*** /tmp/,RCSt1a21584 Fri Nov 10 11:48:14 1989
--- diff.c Thu Nov 9 21:40:50 1989
***************
*** 48,54 ****
int count;
{
int i;
! int length = 0;
char *result;
for (i = 0; i < count; i++)
--- 48,54 ----
int count;
{
int i;
! unsigned length = 0;
char *result;
for (i = 0; i < count; i++)
***************
*** 300,307 ****
val = re_compile_pattern (ignore_regexp, strlen (ignore_regexp),
&ignore_regexp_compiled);
if (val != 0)
! error ("-I option: ", val);
! ignore_regexp_compiled.fastmap = (char *) xmalloc (256);
}
if (function_regexp)
--- 300,307 ----
val = re_compile_pattern (ignore_regexp, strlen (ignore_regexp),
&ignore_regexp_compiled);
if (val != 0)
! error ("-I option: ", "", "");
! ignore_regexp_compiled.fastmap = (char *) xmalloc ((unsigned)256);
}
if (function_regexp)
***************
*** 311,318 ****
val = re_compile_pattern (function_regexp, strlen (function_regexp),
&function_regexp_compiled);
if (val != 0)
! error ("-F option: ", val);
! function_regexp_compiled.fastmap = (char *) xmalloc (256);
}
if (output_style != OUTPUT_CONTEXT)
--- 311,318 ----
val = re_compile_pattern (function_regexp, strlen (function_regexp),
&function_regexp_compiled);
if (val != 0)
! error ("-F option: ", "", "");
! function_regexp_compiled.fastmap = (char *) xmalloc ((unsigned)256);
}
if (output_style != OUTPUT_CONTEXT)
***************
*** 323,329 ****
switch_string = option_list (argv + 1, optind - 1);
! val = compare_files (0, argv[optind], 0, argv[optind + 1], 0);
/* Print any messages that were saved up for last. */
print_message_queue ();
--- 323,329 ----
switch_string = option_list (argv + 1, optind - 1);
! val = compare_files ((char *)0, argv[optind], (char *)0, argv[optind + 1], 0);
/* Print any messages that were saved up for last. */
print_message_queue ();
***************
*** 345,351 ****
{
if (output_style != OUTPUT_NORMAL
&& output_style != style)
! error ("conflicting specifications of output style");
output_style = style;
}
--- 345,351 ----
{
if (output_style != OUTPUT_NORMAL
&& output_style != style)
! error ("conflicting specifications of output style", "", "");
output_style = style;
}
===================================================================
RCS file: RCS/diff.h,v
retrieving revision 1.1
diff -c -r1.1 diff.h
*** /tmp/,RCSt1a21584 Fri Nov 10 11:48:15 1989
--- diff.h Thu Nov 9 21:23:55 1989
***************
*** 321,331 ****
void *xmalloc ();
void *xrealloc ();
- void *xcalloc();
char *concat ();
void free ();
char *rindex ();
char *index ();
void message ();
void print_message_queue ();
--- 321,337 ----
void *xmalloc ();
void *xrealloc ();
char *concat ();
void free ();
char *rindex ();
char *index ();
+ void analyze_hunk ();
+ void error ();
+ void fatal ();
void message ();
+ void perror_with_name ();
+ void pfatal_with_name ();
+ void print_1_line ();
void print_message_queue ();
+ void print_script ();
===================================================================
RCS file: RCS/dir.c,v
retrieving revision 1.1
diff -c -r1.1 dir.c
*** /tmp/,RCSt1a21584 Fri Nov 10 11:48:15 1989
--- dir.c Thu Nov 9 21:47:29 1989
***************
*** 39,45 ****
register DIR *reading;
register struct direct *next;
struct dirdata dirdata;
- int compare_names ();
/* Address of block containing the files that are described. */
char **files;
--- 39,44 ----
===================================================================
RCS file: RCS/ed.c,v
retrieving revision 1.1
diff -c -r1.1 ed.c
*** /tmp/,RCSt1a21584 Fri Nov 10 11:48:16 1989
--- ed.c Thu Nov 9 21:21:01 1989
***************
*** 22,28 ****
static void print_rcs_hunk ();
static void print_ed_hunk ();
static void pr_forward_ed_hunk ();
! static void print_range_length ();
void translate_range ();
struct change *find_change ();
struct change *find_reverse_change ();
--- 22,28 ----
static void print_rcs_hunk ();
static void print_ed_hunk ();
static void pr_forward_ed_hunk ();
! void print_number_range ();
void translate_range ();
struct change *find_change ();
struct change *find_reverse_change ();
***************
*** 58,64 ****
return;
/* Print out the line number header for this hunk */
! print_number_range (',', &files[0], f0, l0);
fprintf (outfile, "%c\n", change_letter (inserts, deletes));
/* Print new/changed lines from second file, if needed */
--- 58,64 ----
return;
/* Print out the line number header for this hunk */
! print_number_range (',', f0, l0);
fprintf (outfile, "%c\n", change_letter (inserts, deletes));
/* Print new/changed lines from second file, if needed */
***************
*** 71,77 ****
/* Resume the insert, if we stopped. */
if (! inserting)
fprintf (outfile, "%da\n",
! i - f1 + translate_line_number (&files[0], f0) - 1);
inserting = 1;
/* If the file's line is just a dot, it would confuse `ed'.
--- 71,77 ----
/* Resume the insert, if we stopped. */
if (! inserting)
fprintf (outfile, "%da\n",
! i - f1 + translate_line_number (f0) - 1);
inserting = 1;
/* If the file's line is just a dot, it would confuse `ed'.
***************
*** 86,92 ****
fprintf (outfile, ".\n");
/* Now change that double dot to the desired single dot. */
fprintf (outfile, "%ds/^\\.\\././\n",
! i - f1 + translate_line_number (&files[0], f0));
inserting = 0;
}
else
--- 86,92 ----
fprintf (outfile, ".\n");
/* Now change that double dot to the desired single dot. */
fprintf (outfile, "%ds/^\\.\\././\n",
! i - f1 + translate_line_number (f0));
inserting = 0;
}
else
***************
*** 125,131 ****
return;
fprintf (outfile, "%c", change_letter (inserts, deletes));
! print_number_range (' ', files, f0, l0);
fprintf (outfile, "\n");
/* If deletion only, print just the number range. */
--- 125,131 ----
return;
fprintf (outfile, "%c", change_letter (inserts, deletes));
! print_number_range (' ', f0, l0);
fprintf (outfile, "\n");
/* If deletion only, print just the number range. */
***************
*** 169,175 ****
if (!deletes && !inserts)
return;
! translate_range (&files[0], f0, l0, &tf0, &tl0);
if (deletes)
{
--- 169,175 ----
if (!deletes && !inserts)
return;
! translate_range (f0, l0, &tf0, &tl0);
if (deletes)
{
***************
*** 186,192 ****
fprintf (outfile, "a");
/* Take last-line-number from file 0 and # lines from file 1. */
! translate_range (&files[1], f1, l1, &tf1, &tl1);
fprintf (outfile, "%d %d\n",
tl0,
(tl1 >= tf1 ? tl1 - tf1 + 1 : 1));
--- 186,192 ----
fprintf (outfile, "a");
/* Take last-line-number from file 0 and # lines from file 1. */
! translate_range (f1, l1, &tf1, &tl1);
fprintf (outfile, "%d %d\n",
tl0,
(tl1 >= tf1 ? tl1 - tf1 + 1 : 1));
===================================================================
RCS file: RCS/io.c,v
retrieving revision 1.1
diff -c -r1.1 io.c
*** /tmp/,RCSt1a21584 Fri Nov 10 11:48:17 1989
--- io.c Thu Nov 9 22:43:22 1989
***************
*** 69,75 ****
else if ((current->stat.st_mode & S_IFMT) == S_IFREG)
{
current->bufsize = current->stat.st_size;
! current->buffer = (char *) xmalloc (current->bufsize + 2);
current->buffered_chars
= read (current->desc, current->buffer, current->bufsize);
if (current->buffered_chars < 0)
--- 69,75 ----
else if ((current->stat.st_mode & S_IFMT) == S_IFREG)
{
current->bufsize = current->stat.st_size;
! current->buffer = (char *) xmalloc ((unsigned)current->bufsize + 2);
current->buffered_chars
= read (current->desc, current->buffer, current->bufsize);
if (current->buffered_chars < 0)
***************
*** 80,86 ****
int cc;
current->bufsize = 4096;
! current->buffer = (char *) xmalloc (current->bufsize + 2);
current->buffered_chars = 0;
/* Not a regular file; read it in a little at a time, growing the
--- 80,86 ----
int cc;
current->bufsize = 4096;
! current->buffer = (char *) xmalloc ((unsigned)current->bufsize + 2);
current->buffered_chars = 0;
/* Not a regular file; read it in a little at a time, growing the
***************
*** 95,101 ****
{
current->bufsize = current->bufsize * 2;
current->buffer = (char *) xrealloc (current->buffer,
! current->bufsize + 2);
}
}
if (cc < 0)
--- 95,101 ----
{
current->bufsize = current->bufsize * 2;
current->buffer = (char *) xrealloc (current->buffer,
! (unsigned)current->bufsize + 2);
}
}
if (cc < 0)
***************
*** 119,124 ****
--- 119,127 ----
else
current->missing_newline = 0;
+ /* Don't use uninitialized storage. */
+ current->buffer[current->buffered_chars] = '\0';
+
return 0;
}
***************
*** 487,494 ****
find_equiv_class (n)
int n;
{
! int bucket = current->linbuf[n].hash % nbuckets;
! struct equivclass *b = buckets[bucket], *p = NULL;
/* Equivalence class 0 is permanently allocated to lines that were
not hashed because they were parts of identical prefixes or
--- 490,497 ----
find_equiv_class (n)
int n;
{
! int bucket;
! struct equivclass *b, *p = NULL;
/* Equivalence class 0 is permanently allocated to lines that were
not hashed because they were parts of identical prefixes or
***************
*** 497,506 ****
|| current->linbuf[n].text >= current->suffix_begin)
return 0;
/* Check through the appropriate bucket to see if there isn't already
an equivalence class for this line. */
! while (b)
! {
if (b->line.hash == current->linbuf[n].hash
&& (b->line.length == current->linbuf[n].length
/* Lines of different lengths can match with certain options. */
--- 500,510 ----
|| current->linbuf[n].text >= current->suffix_begin)
return 0;
+ bucket = current->linbuf[n].hash % nbuckets;
+
/* Check through the appropriate bucket to see if there isn't already
an equivalence class for this line. */
! for (b = buckets[bucket]; b; p = b, b = b->next)
if (b->line.hash == current->linbuf[n].hash
&& (b->line.length == current->linbuf[n].length
/* Lines of different lengths can match with certain options. */
***************
*** 507,514 ****
|| length_varies)
&& !line_cmp (&b->line, ¤t->linbuf[n]))
return b - equivs;
- p = b, b = b->next;
- }
/* Create a new equivalence class in this bucket. */
--- 511,516 ----
***************
*** 529,535 ****
struct file_data filevec[];
{
int i, j;
- struct equivclass *b, *f;
int binary = 0;
int this_binary;
--- 531,536 ----
===================================================================
RCS file: RCS/normal.c,v
retrieving revision 1.1
diff -c -r1.1 normal.c
*** /tmp/,RCSt1a21584 Fri Nov 10 11:48:18 1989
--- normal.c Thu Nov 9 20:36:56 1989
***************
*** 51,59 ****
return;
/* Print out the line number header for this hunk */
! print_number_range (',', &files[0], first0, last0);
fprintf (outfile, "%c", change_letter (inserts, deletes));
! print_number_range (',', &files[1], first1, last1);
fprintf (outfile, "\n");
/* Print the lines that the first file has. */
--- 51,59 ----
return;
/* Print out the line number header for this hunk */
! print_number_range (',', first0, last0);
fprintf (outfile, "%c", change_letter (inserts, deletes));
! print_number_range (',', first1, last1);
fprintf (outfile, "\n");
/* Print the lines that the first file has. */
===================================================================
RCS file: RCS/regex.c,v
retrieving revision 1.1
diff -c -r1.1 regex.c
*** /tmp/,RCSt1a21584 Fri Nov 10 11:48:18 1989
--- regex.c Thu Nov 9 21:44:02 1989
***************
*** 53,58 ****
--- 53,61 ----
#ifdef sparc
#include <alloca.h>
#endif
+
+ void *malloc();
+ void *realloc();
#endif
/*
***************
*** 117,122 ****
--- 120,130 ----
#define SIGN_EXTEND_CHAR(x) (x)
#endif
+ #ifdef diff
+ #define obscurable 0
+ #else
+ #define obscurable 1
+
static int obscure_syntax = 0;
/* Specify the precise syntax of regexp for compilation.
***************
*** 135,140 ****
--- 143,149 ----
obscure_syntax = syntax;
return ret;
}
+ #endif
/* re_compile_pattern takes a regular-expression string
and converts it into a buffer full of byte commands for matching.
***************
*** 280,285 ****
--- 289,295 ----
switch (c)
{
case '$':
+ #if obscurable
if (obscure_syntax & RE_TIGHT_VBAR)
{
if (! (obscure_syntax & RE_CONTEXT_INDEP_OPS) && p != pend)
***************
*** 291,307 ****
PATPUSH (endline);
break;
}
/* $ means succeed if at end of line, but only in special contexts.
If randomly in the middle of a pattern, it is a normal character. */
if (p == pend || *p == '\n'
! || (obscure_syntax & RE_CONTEXT_INDEP_OPS)
|| (obscure_syntax & RE_NO_BK_PARENS
? *p == ')'
! : *p == '\\' && p[1] == ')')
! || (obscure_syntax & RE_NO_BK_VBAR
? *p == '|'
! : *p == '\\' && p[1] == '|'))
{
PATPUSH (endline);
break;
--- 301,326 ----
PATPUSH (endline);
break;
}
+ #endif
/* $ means succeed if at end of line, but only in special contexts.
If randomly in the middle of a pattern, it is a normal character. */
if (p == pend || *p == '\n'
! || (
! #if obscurable
! obscure_syntax & RE_CONTEXT_INDEP_OPS)
|| (obscure_syntax & RE_NO_BK_PARENS
? *p == ')'
! :
! #endif
! *p == '\\' && p[1] == ')')
! || (
! #if obscurable
! obscure_syntax & RE_NO_BK_VBAR
? *p == '|'
! :
! #endif
! *p == '\\' && p[1] == '|'))
{
PATPUSH (endline);
break;
***************
*** 312,319 ****
/* ^ means succeed if at beg of line, but only if no preceding pattern. */
if (laststart && p[-2] != '\n'
! && ! (obscure_syntax & RE_CONTEXT_INDEP_OPS))
goto normal_char;
if (obscure_syntax & RE_TIGHT_VBAR)
{
if (p != pattern + 1
--- 331,342 ----
/* ^ means succeed if at beg of line, but only if no preceding pattern. */
if (laststart && p[-2] != '\n'
! #if obscurable
! && ! (obscure_syntax & RE_CONTEXT_INDEP_OPS)
! #endif
! )
goto normal_char;
+ #if obscurable
if (obscure_syntax & RE_TIGHT_VBAR)
{
if (p != pattern + 1
***************
*** 323,339 ****
begalt = b;
}
else
PATPUSH (begline);
break;
case '+':
case '?':
if (obscure_syntax & RE_BK_PLUS_QM)
goto normal_char;
handle_plus:
case '*':
/* If there is no previous pattern, char not special. */
! if (!laststart && ! (obscure_syntax & RE_CONTEXT_INDEP_OPS))
goto normal_char;
/* If there is a sequence of repetition chars,
collapse it down to equivalent to just one. */
--- 346,369 ----
begalt = b;
}
else
+ #endif
PATPUSH (begline);
break;
case '+':
case '?':
+ #if obscurable
if (obscure_syntax & RE_BK_PLUS_QM)
goto normal_char;
handle_plus:
+ #endif
case '*':
/* If there is no previous pattern, char not special. */
! if (!laststart
! #if obscurable
! && ! (obscure_syntax & RE_CONTEXT_INDEP_OPS)
! #endif
! )
goto normal_char;
/* If there is a sequence of repetition chars,
collapse it down to equivalent to just one. */
***************
*** 348,356 ****
PATFETCH (c);
if (c == '*')
;
! else if (!(obscure_syntax & RE_BK_PLUS_QM)
! && (c == '+' || c == '?'))
;
else if ((obscure_syntax & RE_BK_PLUS_QM)
&& c == '\\')
{
--- 378,391 ----
PATFETCH (c);
if (c == '*')
;
! else if (
! #if obscurable
! !(obscure_syntax & RE_BK_PLUS_QM)
! &&
! #endif
! (c == '+' || c == '?'))
;
+ #if obscurable
else if ((obscure_syntax & RE_BK_PLUS_QM)
&& c == '\\')
{
***************
*** 364,369 ****
--- 399,405 ----
}
c = c1;
}
+ #endif
else
{
PATUNFETCH;
***************
*** 423,428 ****
--- 459,465 ----
{
PATFETCH (c);
+ #if obscurable
/* If awk, \ escapes characters when inside [...]. */
if ((obscure_syntax & RE_AWK_CLASS_HACK) && c == '\\')
{
***************
*** 430,435 ****
--- 467,473 ----
b[c1 / BYTEWIDTH] |= 1 << (c1 % BYTEWIDTH);
continue;
}
+ #endif
if (c == ']' && p != p1 + 1) break;
if (*p == '-' && p[1] != ']')
***************
*** 452,479 ****
break;
case '(':
! if (! (obscure_syntax & RE_NO_BK_PARENS))
! goto normal_char;
! else
goto handle_open;
case ')':
! if (! (obscure_syntax & RE_NO_BK_PARENS))
! goto normal_char;
! else
goto handle_close;
case '\n':
! if (! (obscure_syntax & RE_NEWLINE_OR))
! goto normal_char;
! else
goto handle_bar;
case '|':
! if (! (obscure_syntax & RE_NO_BK_VBAR))
! goto normal_char;
! else
goto handle_bar;
case '\\':
if (p == pend) goto invalid_pattern;
--- 490,525 ----
break;
case '(':
! #if obscurable
! if (obscure_syntax & RE_NO_BK_PARENS)
goto handle_open;
+ else
+ #endif
+ goto normal_char;
case ')':
! #if obscurable
! if (obscure_syntax & RE_NO_BK_PARENS)
goto handle_close;
+ else
+ #endif
+ goto normal_char;
case '\n':
! #if obscurable
! if (obscure_syntax & RE_NEWLINE_OR)
goto handle_bar;
+ else
+ #endif
+ goto normal_char;
case '|':
! #if obscurable
! if (obscure_syntax & RE_NO_BK_VBAR)
goto handle_bar;
+ else
+ #endif
+ goto normal_char;
case '\\':
if (p == pend) goto invalid_pattern;
***************
*** 481,489 ****
--- 527,537 ----
switch (c)
{
case '(':
+ #if obscurable
if (obscure_syntax & RE_NO_BK_PARENS)
goto normal_backsl;
handle_open:
+ #endif
if (stackp == stacke) goto nesting_too_deep;
if (regnum < RE_NREGS)
{
***************
*** 500,508 ****
--- 548,558 ----
break;
case ')':
+ #if obscurable
if (obscure_syntax & RE_NO_BK_PARENS)
goto normal_backsl;
handle_close:
+ #endif
if (stackp == stackb) goto unmatched_close;
begalt = *--stackp + bufp->buffer;
if (fixup_jump)
***************
*** 520,528 ****
--- 570,580 ----
break;
case '|':
+ #if obscurable
if (obscure_syntax & RE_NO_BK_VBAR)
goto normal_backsl;
handle_bar:
+ #endif
insert_jump (on_failure_jump, begalt, b + 6, b);
pending_exact = 0;
b += 3;
***************
*** 608,620 ****
PATPUSH (c1);
break;
case '+':
case '?':
if (obscure_syntax & RE_BK_PLUS_QM)
goto handle_plus;
- default:
normal_backsl:
/* You might think it would be useful for \ to mean
not to translate; but if we don't translate it
it will never match anything. */
--- 660,675 ----
PATPUSH (c1);
break;
+ #if obscurable
case '+':
case '?':
if (obscure_syntax & RE_BK_PLUS_QM)
goto handle_plus;
normal_backsl:
+ #endif
+
+ default:
/* You might think it would be useful for \ to mean
not to translate; but if we don't translate it
it will never match anything. */
***************
*** 627,635 ****
normal_char:
if (!pending_exact || pending_exact + *pending_exact + 1 != b
|| *pending_exact == 0177 || *p == '*' || *p == '^'
! || ((obscure_syntax & RE_BK_PLUS_QM)
? *p == '\\' && (p[1] == '+' || p[1] == '?')
! : (*p == '+' || *p == '?')))
{
laststart = b;
PATPUSH (exactn);
--- 682,694 ----
normal_char:
if (!pending_exact || pending_exact + *pending_exact + 1 != b
|| *pending_exact == 0177 || *p == '*' || *p == '^'
! || (
! #if obscurable
! (obscure_syntax & RE_BK_PLUS_QM)
? *p == '\\' && (p[1] == '+' || p[1] == '?')
! :
! #endif
! (*p == '+' || *p == '?')))
{
laststart = b;
PATPUSH (exactn);
***************
*** 677,683 ****
static int
store_jump (from, opcode, to)
char *from, *to;
! char opcode;
{
from[0] = opcode;
from[1] = (to - (from + 3)) & 0377;
--- 736,742 ----
static int
store_jump (from, opcode, to)
char *from, *to;
! enum regexpcode opcode;
{
from[0] = opcode;
from[1] = (to - (from + 3)) & 0377;
***************
*** 693,699 ****
static int
insert_jump (op, from, to, current_end)
! char op;
char *from, *to, *current_end;
{
register char *pto = current_end + 3;
--- 752,758 ----
static int
insert_jump (op, from, to, current_end)
! enum regexpcode op;
char *from, *to, *current_end;
{
register char *pto = current_end + 3;
***************
*** 717,727 ****
struct re_pattern_buffer *bufp;
{
unsigned char *pattern = (unsigned char *) bufp->buffer;
- int size = bufp->used;
register char *fastmap = bufp->fastmap;
register unsigned char *p = pattern;
! register unsigned char *pend = pattern + size;
! register int j, k;
unsigned char *translate = (unsigned char *) bufp->translate;
unsigned char *stackb[NFAILURES];
--- 776,785 ----
struct re_pattern_buffer *bufp;
{
unsigned char *pattern = (unsigned char *) bufp->buffer;
register char *fastmap = bufp->fastmap;
register unsigned char *p = pattern;
! register unsigned char *pend = pattern + bufp->used;
! register int j;
unsigned char *translate = (unsigned char *) bufp->translate;
unsigned char *stackb[NFAILURES];
***************
*** 900,906 ****
int size, startpos, range;
struct re_registers *regs;
{
! return re_search_2 (pbufp, 0, 0, string, size, startpos, range, regs, size);
}
/* Like re_match_2 but tries first a match starting at index STARTPOS,
--- 958,964 ----
int size, startpos, range;
struct re_registers *regs;
{
! return re_search_2 (pbufp, (char *)0, 0, string, size, startpos, range, regs, size);
}
/* Like re_match_2 but tries first a match starting at index STARTPOS,
***************
*** 1012,1018 ****
return -1;
}
! #ifndef emacs /* emacs never uses this */
int
re_match (pbufp, string, size, pos, regs)
struct re_pattern_buffer *pbufp;
--- 1070,1076 ----
return -1;
}
! #if !defined (emacs) && !defined (diff)
int
re_match (pbufp, string, size, pos, regs)
struct re_pattern_buffer *pbufp;
***************
*** 1572,1578 ****
/* Entry points compatible with bsd4.2 regex library */
! #ifndef emacs
static struct re_pattern_buffer re_comp_buf;
--- 1630,1636 ----
/* Entry points compatible with bsd4.2 regex library */
! #if !defined (emacs) && !defined (diff)
static struct re_pattern_buffer re_comp_buf;
===================================================================
RCS file: RCS/regex.h,v
retrieving revision 1.1
diff -c -r1.1 regex.h
*** /tmp/,RCSt1a21584 Fri Nov 10 11:48:19 1989
--- regex.h Thu Nov 9 21:23:35 1989
***************
*** 183,189 ****
/* Is this really advertised? */
extern void re_compile_fastmap ();
extern int re_search (), re_search_2 ();
! extern int re_match (), re_match_2 ();
/* 4.2 bsd compatibility (yuck) */
extern char *re_comp ();
--- 183,192 ----
/* Is this really advertised? */
extern void re_compile_fastmap ();
extern int re_search (), re_search_2 ();
! #ifndef diff
! extern int re_match ();
! #endif
! extern int re_match_2 ();
/* 4.2 bsd compatibility (yuck) */
extern char *re_comp ();
===================================================================
RCS file: RCS/util.c,v
retrieving revision 1.2
diff -c -r1.2 util.c
*** /tmp/,RCSt1a21584 Fri Nov 10 11:48:20 1989
--- util.c Thu Nov 9 21:41:06 1989
***************
*** 19,24 ****
--- 19,26 ----
#include "diff.h"
+ void perror ();
+
/* Use when a system call returns non-zero status.
TEXT should normally be the file name. */
***************
*** 65,71 ****
char *text;
{
print_message_queue ();
! error ("%s", text);
exit (2);
}
--- 67,73 ----
char *text;
{
print_message_queue ();
! error ("%s", text, "");
exit (2);
}
***************
*** 448,454 ****
/* Translate an internal line number (an index into diff's table of lines)
into an actual line number in the input file.
! The internal line number is LNUM. FILE points to the data on the file.
Internal line numbers count from 0 within the current chunk.
Actual line numbers count from 1 within the entire file;
--- 450,456 ----
/* Translate an internal line number (an index into diff's table of lines)
into an actual line number in the input file.
! The internal line number is LNUM.
Internal line numbers count from 0 within the current chunk.
Actual line numbers count from 1 within the entire file;
***************
*** 457,464 ****
The `ltran' feature is no longer in use. */
int
! translate_line_number (file, lnum)
! struct file_data *file;
int lnum;
{
return lnum + 1;
--- 459,465 ----
The `ltran' feature is no longer in use. */
int
! translate_line_number (lnum)
int lnum;
{
return lnum + 1;
***************
*** 465,480 ****
}
void
! translate_range (file, a, b, aptr, bptr)
! struct file_data *file;
int a, b;
int *aptr, *bptr;
{
! *aptr = translate_line_number (file, a - 1) + 1;
! *bptr = translate_line_number (file, b + 1) - 1;
}
! /* Print a pair of line numbers with SEPCHAR, translated for file FILE.
If the two numbers are identical, print just one number.
Args A and B are internal line numbers.
--- 466,480 ----
}
void
! translate_range (a, b, aptr, bptr)
int a, b;
int *aptr, *bptr;
{
! *aptr = translate_line_number (a - 1) + 1;
! *bptr = translate_line_number (b + 1) - 1;
}
! /* Print a pair of line numbers with SEPCHAR.
If the two numbers are identical, print just one number.
Args A and B are internal line numbers.
***************
*** 481,493 ****
We print the translated (real) line numbers. */
void
! print_number_range (sepchar, file, a, b)
char sepchar;
- struct file_data *file;
int a, b;
{
int trans_a, trans_b;
! translate_range (file, a, b, &trans_a, &trans_b);
/* Note: we can have B < A in the case of a range of no lines.
In this case, we should print the line number before the range,
--- 481,492 ----
We print the translated (real) line numbers. */
void
! print_number_range (sepchar, a, b)
char sepchar;
int a, b;
{
int trans_a, trans_b;
! translate_range (a, b, &trans_a, &trans_b);
/* Note: we can have B < A in the case of a range of no lines.
In this case, we should print the line number before the range,
***************
*** 540,546 ****
|| 0 > re_search (&ignore_regexp_compiled,
files[0].linbuf[i].text,
files[0].linbuf[i].length, 0,
! files[0].linbuf[i].length, 0)))
nontrivial = 1;
for (i = next->line1; i <= l1 && ! nontrivial; i++)
--- 539,545 ----
|| 0 > re_search (&ignore_regexp_compiled,
files[0].linbuf[i].text,
files[0].linbuf[i].length, 0,
! files[0].linbuf[i].length, (struct re_registers *)0)))
nontrivial = 1;
for (i = next->line1; i <= l1 && ! nontrivial; i++)
***************
*** 549,555 ****
|| 0 > re_search (&ignore_regexp_compiled,
files[1].linbuf[i].text,
files[1].linbuf[i].length, 0,
! files[1].linbuf[i].length, 0)))
nontrivial = 1;
}
--- 548,554 ----
|| 0 > re_search (&ignore_regexp_compiled,
files[1].linbuf[i].text,
files[1].linbuf[i].length, 0,
! files[1].linbuf[i].length, (struct re_registers *)0)))
nontrivial = 1;
}
***************
*** 574,580 ****
xmalloc (size)
unsigned size;
{
! register void *value = (void *) malloc (size);
if (!value)
fatal ("virtual memory exhausted");
--- 573,580 ----
xmalloc (size)
unsigned size;
{
! extern void *malloc();
! register void *value = malloc (size);
if (!value)
fatal ("virtual memory exhausted");
***************
*** 588,594 ****
void *old;
unsigned int size;
{
! register void *value = (void *) realloc (old, size);
if (!value)
fatal ("virtual memory exhausted");
--- 588,595 ----
void *old;
unsigned int size;
{
! extern void *realloc();
! register void *value = realloc (old, size);
if (!value)
fatal ("virtual memory exhausted");
***************
*** 595,611 ****
return value;
}
- void *
- xcalloc (nitems, size)
- int nitems, size;
- {
- void *value = (void *) calloc (nitems, size);
-
- if (! value)
- fatal ("virtual memory exhausted");
- return value;
- }
-
/* Concatenate three strings, returning a newly malloc'd string. */
char *
--- 596,601 ----
***************
*** 612,618 ****
concat (s1, s2, s3)
char *s1, *s2, *s3;
{
! int len = strlen (s1) + strlen (s2) + strlen (s3);
char *new = (char *) xmalloc (len + 1);
strcpy (new, s1);
strcat (new, s2);
--- 602,608 ----
concat (s1, s2, s3)
char *s1, *s2, *s3;
{
! unsigned len = strlen (s1) + strlen (s2) + strlen (s3);
char *new = (char *) xmalloc (len + 1);
strcpy (new, s1);
strcat (new, s2);
***************
*** 620,625 ****
--- 610,616 ----
return new;
}
+ #ifdef DEBUG
debug_script (sp)
struct change *sp;
{
***************
*** 629,631 ****
--- 620,623 ----
sp->line0, sp->line1, sp->deleted, sp->inserted);
fflush (stderr);
}
+ #endif