Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_posix/sys/src/ape/cmd/diff/side.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* sdiff-format output routines for GNU DIFF.
2
   Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
3
 
4
This file is part of GNU DIFF.
5
 
6
GNU DIFF is distributed in the hope that it will be useful,
7
but WITHOUT ANY WARRANTY.  No author or distributor
8
accepts responsibility to anyone for the consequences of using it
9
or for whether it serves any particular purpose or works at all,
10
unless he says so in writing.  Refer to the GNU DIFF General Public
11
License for full details.
12
 
13
Everyone is granted permission to copy, modify and redistribute
14
GNU DIFF, but only under the conditions described in the
15
GNU DIFF General Public License.   A copy of this license is
16
supposed to have been given to you along with GNU DIFF so you
17
can know your rights and responsibilities.  It should be in a
18
file named COPYING.  Among other things, the copyright notice
19
and this notice must be preserved on all copies.  */
20
 
21
 
22
#include "diff.h"
23
 
24
static unsigned print_half_line PARAMS((char const * const *, unsigned, unsigned));
25
static unsigned tab_from_to PARAMS((unsigned, unsigned));
26
static void print_1sdiff_line PARAMS((char const * const *, int, char const * const *));
27
static void print_sdiff_common_lines PARAMS((int, int));
28
static void print_sdiff_hunk PARAMS((struct change *));
29
 
30
/* Next line number to be printed in the two input files.  */
31
static int next0, next1;
32
 
33
/* Print the edit-script SCRIPT as a sdiff style output.  */
34
 
35
void
36
print_sdiff_script (script)
37
     struct change *script;
38
{
39
  begin_output ();
40
 
41
  next0 = next1 = - files[0].prefix_lines;
42
  print_script (script, find_change, print_sdiff_hunk);
43
 
44
  print_sdiff_common_lines (files[0].valid_lines, files[1].valid_lines);
45
}
46
 
47
/* Tab from column FROM to column TO, where FROM <= TO.  Yield TO.  */
48
 
49
static unsigned
50
tab_from_to (from, to)
51
     unsigned from, to;
52
{
53
  FILE *out = outfile;
54
  unsigned tab;
55
 
56
  if (! tab_expand_flag)
57
    for (tab = from + TAB_WIDTH - from % TAB_WIDTH;  tab <= to;  tab += TAB_WIDTH)
58
      {
59
	putc ('\t', out);
60
	from = tab;
61
      }
62
  while (from++ < to)
63
    putc (' ', out);
64
  return to;
65
}
66
 
67
/*
68
 * Print the text for half an sdiff line.  This means truncate to width
69
 * observing tabs, and trim a trailing newline.  Returns the last column
70
 * written (not the number of chars).
71
 */
72
static unsigned
73
print_half_line (line, indent, out_bound)
74
     char const * const *line;
75
     unsigned indent, out_bound;
76
{
77
  FILE *out = outfile;
78
  register unsigned in_position = 0, out_position = 0;
79
  register char const
80
	*text_pointer = line[0],
81
	*text_limit = line[1];
82
 
83
  while (text_pointer < text_limit)
84
    {
85
      register unsigned char c = *text_pointer++;
86
 
87
      switch (c)
88
	{
89
	case '\t':
90
	  {
91
	    unsigned spaces = TAB_WIDTH - in_position % TAB_WIDTH;
92
	    if (in_position == out_position)
93
	      {
94
		unsigned tabstop = out_position + spaces;
95
		if (tab_expand_flag)
96
		  {
97
		    if (out_bound < tabstop)
98
		      tabstop = out_bound;
99
		    for (;  out_position < tabstop;  out_position++)
100
		      putc (' ', out);
101
		  }
102
		else
103
		  if (tabstop < out_bound)
104
		    {
105
		      out_position = tabstop;
106
		      putc (c, out);
107
		    }
108
	      }
109
	    in_position += spaces;
110
	  }
111
	  break;
112
 
113
	case '\r':
114
	  {
115
	    putc (c, out);
116
	    tab_from_to (0, indent);
117
	    in_position = out_position = 0;
118
	  }
119
	  break;
120
 
121
	case '\b':
122
	  if (in_position != 0 && --in_position < out_bound)
123
	    if (out_position <= in_position)
124
	      /* Add spaces to make up for suppressed tab past out_bound.  */
125
	      for (;  out_position < in_position;  out_position++)
126
		putc (' ', out);
127
	    else
128
	      {
129
		out_position = in_position;
130
		putc (c, out);
131
	      }
132
	  break;
133
 
134
	case '\f':
135
	case '\v':
136
	control_char:
137
	  if (in_position < out_bound)
138
	    putc (c, out);
139
	  break;
140
 
141
	default:
142
	  if (! ISPRINT (c))
143
	    goto control_char;
144
	  /* falls through */
145
	case ' ':
146
	  if (in_position++ < out_bound)
147
	    {
148
	      out_position = in_position;
149
	      putc (c, out);
150
	    }
151
	  break;
152
 
153
	case '\n':
154
	  return out_position;
155
	}
156
    }
157
 
158
  return out_position;
159
}
160
 
161
/*
162
 * Print side by side lines with a separator in the middle.
163
 * 0 parameters are taken to indicate white space text.
164
 * Blank lines that can easily be caught are reduced to a single newline.
165
 */
166
 
167
static void
168
print_1sdiff_line (left, sep, right)
169
     char const * const *left;
170
     int sep;
171
     char const * const *right;
172
{
173
  FILE *out = outfile;
174
  unsigned hw = sdiff_half_width, c2o = sdiff_column2_offset;
175
  unsigned col = 0;
176
  int put_newline = 0;
177
 
178
  if (left)
179
    {
180
      if (left[1][-1] == '\n')
181
	put_newline = 1;
182
      col = print_half_line (left, 0, hw);
183
    }
184
 
185
  if (sep != ' ')
186
    {
187
      col = tab_from_to (col, (hw + c2o - 1) / 2) + 1;
188
      if (sep == '|' && put_newline != (right[1][-1] == '\n'))
189
	sep = put_newline ? '/' : '\\';
190
      putc (sep, out);
191
    }
192
 
193
  if (right)
194
    {
195
      if (right[1][-1] == '\n')
196
	put_newline = 1;
197
      if (**right != '\n')
198
	{
199
	  col = tab_from_to (col, c2o);
200
	  print_half_line (right, col, hw);
201
	}
202
    }
203
 
204
  if (put_newline)
205
    putc ('\n', out);
206
}
207
 
208
/* Print lines common to both files in side-by-side format.  */
209
static void
210
print_sdiff_common_lines (limit0, limit1)
211
     int limit0, limit1;
212
{
213
  int i0 = next0, i1 = next1;
214
 
215
  if (! sdiff_skip_common_lines  &&  (i0 != limit0 || i1 != limit1))
216
    {
217
      if (sdiff_help_sdiff)
218
	fprintf (outfile, "i%d,%d\n", limit0 - i0, limit1 - i1);
219
 
220
      if (! sdiff_left_only)
221
	{
222
	  while (i0 != limit0 && i1 != limit1)
223
	    print_1sdiff_line (&files[0].linbuf[i0++], ' ', &files[1].linbuf[i1++]);
224
	  while (i1 != limit1)
225
	    print_1sdiff_line (0, ')', &files[1].linbuf[i1++]);
226
	}
227
      while (i0 != limit0)
228
	print_1sdiff_line (&files[0].linbuf[i0++], '(', 0);
229
    }
230
 
231
  next0 = limit0;
232
  next1 = limit1;
233
}
234
 
235
/* Print a hunk of an sdiff diff.
236
   This is a contiguous portion of a complete edit script,
237
   describing changes in consecutive lines.  */
238
 
239
static void
240
print_sdiff_hunk (hunk)
241
     struct change *hunk;
242
{
243
  int first0, last0, first1, last1, deletes, inserts;
244
  register int i, j;
245
 
246
  /* Determine range of line numbers involved in each file.  */
247
  analyze_hunk (hunk, &first0, &last0, &first1, &last1, &deletes, &inserts);
248
  if (!deletes && !inserts)
249
    return;
250
 
251
  /* Print out lines up to this change.  */
252
  print_sdiff_common_lines (first0, first1);
253
 
254
  if (sdiff_help_sdiff)
255
    fprintf (outfile, "c%d,%d\n", last0 - first0 + 1, last1 - first1 + 1);
256
 
257
  /* Print ``xxx  |  xxx '' lines */
258
  if (inserts && deletes)
259
    {
260
      for (i = first0, j = first1;  i <= last0 && j <= last1; ++i, ++j)
261
	print_1sdiff_line (&files[0].linbuf[i], '|', &files[1].linbuf[j]);
262
      deletes = i <= last0;
263
      inserts = j <= last1;
264
      next0 = first0 = i;
265
      next1 = first1 = j;
266
    }
267
 
268
 
269
  /* Print ``     >  xxx '' lines */
270
  if (inserts)
271
    {
272
      for (j = first1; j <= last1; ++j)
273
	print_1sdiff_line (0, '>', &files[1].linbuf[j]);
274
      next1 = j;
275
    }
276
 
277
  /* Print ``xxx  <     '' lines */
278
  if (deletes)
279
    {
280
      for (i = first0; i <= last0; ++i)
281
	print_1sdiff_line (&files[0].linbuf[i], '<', 0);
282
      next0 = i;
283
    }
284
}