PageRenderTime 26ms CodeModel.GetById 10ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

/contrib/cvs/diff/ed.c

https://bitbucket.org/freebsd/freebsd-head/
C | 198 lines | 120 code | 33 blank | 45 comment | 19 complexity | 16220baaa4e21fd3e948c29f17889581 MD5 | raw file
  1/* Output routines for ed-script format.
  2   Copyright (C) 1988, 89, 91, 92, 93, 1998 Free Software Foundation, Inc.
  3
  4This file is part of GNU DIFF.
  5
  6GNU DIFF is free software; you can redistribute it and/or modify
  7it under the terms of the GNU General Public License as published by
  8the Free Software Foundation; either version 2, or (at your option)
  9any later version.
 10
 11GNU DIFF is distributed in the hope that it will be useful,
 12but WITHOUT ANY WARRANTY; without even the implied warranty of
 13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 14GNU General Public License for more details.
 15
 16*/
 17
 18#include "diff.h"
 19
 20static void print_ed_hunk PARAMS((struct change *));
 21static void print_rcs_hunk PARAMS((struct change *));
 22static void pr_forward_ed_hunk PARAMS((struct change *));
 23
 24/* Print our script as ed commands.  */
 25
 26void
 27print_ed_script (script)
 28    struct change *script;
 29{
 30  print_script (script, find_reverse_change, print_ed_hunk);
 31}
 32
 33/* Print a hunk of an ed diff */
 34
 35static void
 36print_ed_hunk (hunk)
 37     struct change *hunk; 
 38{
 39  int f0, l0, f1, l1;
 40  int deletes, inserts;
 41
 42#if 0
 43  hunk = flip_script (hunk);
 44#endif
 45#ifdef DEBUG
 46  debug_script (hunk);
 47#endif
 48
 49  /* Determine range of line numbers involved in each file.  */
 50  analyze_hunk (hunk, &f0, &l0, &f1, &l1, &deletes, &inserts);
 51  if (!deletes && !inserts)
 52    return;
 53
 54  begin_output ();
 55
 56  /* Print out the line number header for this hunk */
 57  print_number_range (',', &files[0], f0, l0);
 58  printf_output ("%c\n", change_letter (inserts, deletes));
 59
 60  /* Print new/changed lines from second file, if needed */
 61  if (inserts)
 62    {
 63      int i;
 64      int inserting = 1;
 65      for (i = f1; i <= l1; i++)
 66	{
 67	  /* Resume the insert, if we stopped.  */
 68	  if (! inserting)
 69	    printf_output ("%da\n",
 70			   i - f1 + translate_line_number (&files[0], f0) - 1);
 71	  inserting = 1;
 72
 73	  /* If the file's line is just a dot, it would confuse `ed'.
 74	     So output it with a double dot, and set the flag LEADING_DOT
 75	     so that we will output another ed-command later
 76	     to change the double dot into a single dot.  */
 77
 78	  if (files[1].linbuf[i][0] == '.'
 79	      && files[1].linbuf[i][1] == '\n')
 80	    {
 81	      printf_output ("..\n");
 82	      printf_output (".\n");
 83	      /* Now change that double dot to the desired single dot.  */
 84	      printf_output ("%ds/^\\.\\././\n",
 85			     i - f1 + translate_line_number (&files[0], f0));
 86	      inserting = 0;
 87	    }
 88	  else
 89	    /* Line is not `.', so output it unmodified.  */
 90	    print_1_line ("", &files[1].linbuf[i]);
 91	}
 92
 93      /* End insert mode, if we are still in it.  */
 94      if (inserting)
 95	printf_output (".\n");
 96    }
 97}
 98
 99/* Print change script in the style of ed commands,
100   but print the changes in the order they appear in the input files,
101   which means that the commands are not truly useful with ed.  */
102
103void
104pr_forward_ed_script (script)
105     struct change *script;
106{
107  print_script (script, find_change, pr_forward_ed_hunk);
108}
109
110static void
111pr_forward_ed_hunk (hunk)
112     struct change *hunk;
113{
114  int i;
115  int f0, l0, f1, l1;
116  int deletes, inserts;
117
118  /* Determine range of line numbers involved in each file.  */
119  analyze_hunk (hunk, &f0, &l0, &f1, &l1, &deletes, &inserts);
120  if (!deletes && !inserts)
121    return;
122
123  begin_output ();
124
125  printf_output ("%c", change_letter (inserts, deletes));
126  print_number_range (' ', files, f0, l0);
127  printf_output ("\n");
128
129  /* If deletion only, print just the number range.  */
130
131  if (!inserts)
132    return;
133
134  /* For insertion (with or without deletion), print the number range
135     and the lines from file 2.  */
136
137  for (i = f1; i <= l1; i++)
138    print_1_line ("", &files[1].linbuf[i]);
139
140  printf_output (".\n");
141}
142
143/* Print in a format somewhat like ed commands
144   except that each insert command states the number of lines it inserts.
145   This format is used for RCS.  */
146
147void
148print_rcs_script (script)
149     struct change *script;
150{
151  print_script (script, find_change, print_rcs_hunk);
152}
153
154/* Print a hunk of an RCS diff */
155
156static void
157print_rcs_hunk (hunk)
158     struct change *hunk;
159{
160  int i;
161  int f0, l0, f1, l1;
162  int deletes, inserts;
163  int tf0, tl0, tf1, tl1;
164
165  /* Determine range of line numbers involved in each file.  */
166  analyze_hunk (hunk, &f0, &l0, &f1, &l1, &deletes, &inserts);
167  if (!deletes && !inserts)
168    return;
169
170  begin_output ();
171
172  translate_range (&files[0], f0, l0, &tf0, &tl0);
173
174  if (deletes)
175    {
176      printf_output ("d");
177      /* For deletion, print just the starting line number from file 0
178	 and the number of lines deleted.  */
179      printf_output ("%d %d\n",
180		     tf0,
181		     (tl0 >= tf0 ? tl0 - tf0 + 1 : 1));	     
182    }
183
184  if (inserts)
185    {
186      printf_output ("a");
187
188      /* Take last-line-number from file 0 and # lines from file 1.  */
189      translate_range (&files[1], f1, l1, &tf1, &tl1);
190      printf_output ("%d %d\n",
191		     tl0,
192		     (tl1 >= tf1 ? tl1 - tf1 + 1 : 1));	     
193
194      /* Print the inserted lines.  */
195      for (i = f1; i <= l1; i++)
196	print_1_line ("", &files[1].linbuf[i]);
197    }
198}