Blame src/ed.c

Packit 33f14e
/* Output routines for ed-script format.
Packit 33f14e
Packit 33f14e
   Copyright (C) 1988-1989, 1991-1993, 1995, 1998, 2001, 2004, 2006, 2009-2013,
Packit 33f14e
   2015-2017 Free Software Foundation, Inc.
Packit 33f14e
Packit 33f14e
   This file is part of GNU DIFF.
Packit 33f14e
Packit 33f14e
   This program is free software: you can redistribute it and/or modify
Packit 33f14e
   it under the terms of the GNU General Public License as published by
Packit 33f14e
   the Free Software Foundation, either version 3 of the License, or
Packit 33f14e
   (at your option) any later version.
Packit 33f14e
Packit 33f14e
   This program is distributed in the hope that it will be useful,
Packit 33f14e
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 33f14e
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 33f14e
   GNU General Public License for more details.
Packit 33f14e
Packit 33f14e
   You should have received a copy of the GNU General Public License
Packit 33f14e
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
Packit 33f14e
Packit 33f14e
#include "diff.h"
Packit 33f14e
Packit 33f14e
static void print_ed_hunk (struct change *);
Packit 33f14e
static void print_rcs_hunk (struct change *);
Packit 33f14e
static void pr_forward_ed_hunk (struct change *);
Packit 33f14e

Packit 33f14e
/* Print our script as ed commands.  */
Packit 33f14e
Packit 33f14e
void
Packit 33f14e
print_ed_script (struct change *script)
Packit 33f14e
{
Packit 33f14e
  print_script (script, find_reverse_change, print_ed_hunk);
Packit 33f14e
}
Packit 33f14e
Packit 33f14e
/* Print a hunk of an ed diff */
Packit 33f14e
Packit 33f14e
static void
Packit 33f14e
print_ed_hunk (struct change *hunk)
Packit 33f14e
{
Packit 33f14e
  lin f0, l0, f1, l1;
Packit 33f14e
  enum changes changes;
Packit 33f14e
Packit 33f14e
#ifdef DEBUG
Packit 33f14e
  debug_script (hunk);
Packit 33f14e
#endif
Packit 33f14e
Packit 33f14e
  /* Determine range of line numbers involved in each file.  */
Packit 33f14e
  changes = analyze_hunk (hunk, &f0, &l0, &f1, &l1;;
Packit 33f14e
  if (!changes)
Packit 33f14e
    return;
Packit 33f14e
Packit 33f14e
  begin_output ();
Packit 33f14e
Packit 33f14e
  /* Print out the line number header for this hunk */
Packit 33f14e
  print_number_range (',', &files[0], f0, l0);
Packit 33f14e
  fputc (change_letter[changes], outfile);
Packit 33f14e
  fputc ('\n', outfile);
Packit 33f14e
Packit 33f14e
  /* Print new/changed lines from second file, if needed */
Packit 33f14e
  if (changes != OLD)
Packit 33f14e
    {
Packit 33f14e
      lin i;
Packit 33f14e
      bool insert_mode = true;
Packit 33f14e
Packit 33f14e
      for (i = f1; i <= l1; i++)
Packit 33f14e
	{
Packit 33f14e
	  if (!insert_mode)
Packit 33f14e
	    {
Packit 33f14e
	      fputs ("a\n", outfile);
Packit 33f14e
	      insert_mode = true;
Packit 33f14e
	    }
Packit 33f14e
	  if (files[1].linbuf[i][0] == '.' && files[1].linbuf[i][1] == '\n')
Packit 33f14e
	    {
Packit 33f14e
	      /* The file's line is just a dot, and it would exit
Packit 33f14e
		 insert mode.  Precede the dot with another dot, exit
Packit 33f14e
		 insert mode and remove the extra dot.  */
Packit 33f14e
	      fputs ("..\n.\ns/.//\n", outfile);
Packit 33f14e
	      insert_mode = false;
Packit 33f14e
	    }
Packit 33f14e
	  else
Packit 33f14e
	    print_1_line ("", &files[1].linbuf[i]);
Packit 33f14e
	}
Packit 33f14e
Packit 33f14e
      if (insert_mode)
Packit 33f14e
	fputs (".\n", outfile);
Packit 33f14e
    }
Packit 33f14e
}
Packit 33f14e

Packit 33f14e
/* Print change script in the style of ed commands,
Packit 33f14e
   but print the changes in the order they appear in the input files,
Packit 33f14e
   which means that the commands are not truly useful with ed.
Packit 33f14e
   Because of the issue with lines containing just a dot, the output
Packit 33f14e
   is not even parseable.  */
Packit 33f14e
Packit 33f14e
void
Packit 33f14e
pr_forward_ed_script (struct change *script)
Packit 33f14e
{
Packit 33f14e
  print_script (script, find_change, pr_forward_ed_hunk);
Packit 33f14e
}
Packit 33f14e
Packit 33f14e
static void
Packit 33f14e
pr_forward_ed_hunk (struct change *hunk)
Packit 33f14e
{
Packit 33f14e
  lin i, f0, l0, f1, l1;
Packit 33f14e
Packit 33f14e
  /* Determine range of line numbers involved in each file.  */
Packit 33f14e
  enum changes changes = analyze_hunk (hunk, &f0, &l0, &f1, &l1;;
Packit 33f14e
  if (!changes)
Packit 33f14e
    return;
Packit 33f14e
Packit 33f14e
  begin_output ();
Packit 33f14e
Packit 33f14e
  fputc (change_letter[changes], outfile);
Packit 33f14e
  print_number_range (' ', files, f0, l0);
Packit 33f14e
  fputc ('\n', outfile);
Packit 33f14e
Packit 33f14e
  /* If deletion only, print just the number range.  */
Packit 33f14e
Packit 33f14e
  if (changes == OLD)
Packit 33f14e
    return;
Packit 33f14e
Packit 33f14e
  /* For insertion (with or without deletion), print the number range
Packit 33f14e
     and the lines from file 2.  */
Packit 33f14e
Packit 33f14e
  for (i = f1; i <= l1; i++)
Packit 33f14e
    print_1_line ("", &files[1].linbuf[i]);
Packit 33f14e
Packit 33f14e
  fputs (".\n", outfile);
Packit 33f14e
}
Packit 33f14e

Packit 33f14e
/* Print in a format somewhat like ed commands
Packit 33f14e
   except that each insert command states the number of lines it inserts.
Packit 33f14e
   This format is used for RCS.  */
Packit 33f14e
Packit 33f14e
void
Packit 33f14e
print_rcs_script (struct change *script)
Packit 33f14e
{
Packit 33f14e
  print_script (script, find_change, print_rcs_hunk);
Packit 33f14e
}
Packit 33f14e
Packit 33f14e
/* Print a hunk of an RCS diff */
Packit 33f14e
Packit 33f14e
static void
Packit 33f14e
print_rcs_hunk (struct change *hunk)
Packit 33f14e
{
Packit 33f14e
  lin i, f0, l0, f1, l1;
Packit 33f14e
  printint tf0, tl0, tf1, tl1;
Packit 33f14e
Packit 33f14e
  /* Determine range of line numbers involved in each file.  */
Packit 33f14e
  enum changes changes = analyze_hunk (hunk, &f0, &l0, &f1, &l1;;
Packit 33f14e
  if (!changes)
Packit 33f14e
    return;
Packit 33f14e
Packit 33f14e
  begin_output ();
Packit 33f14e
Packit 33f14e
  translate_range (&files[0], f0, l0, &tf0, &tl0);
Packit 33f14e
Packit 33f14e
  if (changes & OLD)
Packit 33f14e
    {
Packit 33f14e
      /* For deletion, print just the starting line number from file 0
Packit 33f14e
	 and the number of lines deleted.  */
Packit 33f14e
      fprintf (outfile, "d%"pI"d %"pI"d\n", tf0,
Packit 33f14e
	       tf0 <= tl0 ? tl0 - tf0 + 1 : 1);
Packit 33f14e
    }
Packit 33f14e
Packit 33f14e
  if (changes & NEW)
Packit 33f14e
    {
Packit 33f14e
      /* Take last-line-number from file 0 and # lines from file 1.  */
Packit 33f14e
      translate_range (&files[1], f1, l1, &tf1, &tl1);
Packit 33f14e
      fprintf (outfile, "a%"pI"d %"pI"d\n", tl0,
Packit 33f14e
	       tf1 <= tl1 ? tl1 - tf1 + 1 : 1);
Packit 33f14e
Packit 33f14e
      /* Print the inserted lines.  */
Packit 33f14e
      for (i = f1; i <= l1; i++)
Packit 33f14e
	print_1_line ("", &files[1].linbuf[i]);
Packit 33f14e
    }
Packit 33f14e
}