xref: /openbsd-src/gnu/usr.bin/cvs/diff/ed.c (revision c71bc7e269286e43816004eb0fcd7a55f036cd69)
12286d8edStholo /* Output routines for ed-script format.
2b2346922Stholo    Copyright (C) 1988, 89, 91, 92, 93, 1998 Free Software Foundation, Inc.
32286d8edStholo 
42286d8edStholo This file is part of GNU DIFF.
52286d8edStholo 
62286d8edStholo GNU DIFF is free software; you can redistribute it and/or modify
72286d8edStholo it under the terms of the GNU General Public License as published by
82286d8edStholo the Free Software Foundation; either version 2, or (at your option)
92286d8edStholo any later version.
102286d8edStholo 
112286d8edStholo GNU DIFF is distributed in the hope that it will be useful,
122286d8edStholo but WITHOUT ANY WARRANTY; without even the implied warranty of
132286d8edStholo MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
142286d8edStholo GNU General Public License for more details.
152286d8edStholo 
16*c71bc7e2Stholo */
172286d8edStholo 
182286d8edStholo #include "diff.h"
192286d8edStholo 
202286d8edStholo static void print_ed_hunk PARAMS((struct change *));
212286d8edStholo static void print_rcs_hunk PARAMS((struct change *));
222286d8edStholo static void pr_forward_ed_hunk PARAMS((struct change *));
232286d8edStholo 
242286d8edStholo /* Print our script as ed commands.  */
252286d8edStholo 
262286d8edStholo void
print_ed_script(script)272286d8edStholo print_ed_script (script)
282286d8edStholo     struct change *script;
292286d8edStholo {
302286d8edStholo   print_script (script, find_reverse_change, print_ed_hunk);
312286d8edStholo }
322286d8edStholo 
332286d8edStholo /* Print a hunk of an ed diff */
342286d8edStholo 
352286d8edStholo static void
print_ed_hunk(hunk)362286d8edStholo print_ed_hunk (hunk)
372286d8edStholo      struct change *hunk;
382286d8edStholo {
392286d8edStholo   int f0, l0, f1, l1;
402286d8edStholo   int deletes, inserts;
412286d8edStholo 
422286d8edStholo #if 0
432286d8edStholo   hunk = flip_script (hunk);
442286d8edStholo #endif
452286d8edStholo #ifdef DEBUG
462286d8edStholo   debug_script (hunk);
472286d8edStholo #endif
482286d8edStholo 
492286d8edStholo   /* Determine range of line numbers involved in each file.  */
502286d8edStholo   analyze_hunk (hunk, &f0, &l0, &f1, &l1, &deletes, &inserts);
512286d8edStholo   if (!deletes && !inserts)
522286d8edStholo     return;
532286d8edStholo 
542286d8edStholo   begin_output ();
552286d8edStholo 
562286d8edStholo   /* Print out the line number header for this hunk */
572286d8edStholo   print_number_range (',', &files[0], f0, l0);
58b2346922Stholo   printf_output ("%c\n", change_letter (inserts, deletes));
592286d8edStholo 
602286d8edStholo   /* Print new/changed lines from second file, if needed */
612286d8edStholo   if (inserts)
622286d8edStholo     {
632286d8edStholo       int i;
642286d8edStholo       int inserting = 1;
652286d8edStholo       for (i = f1; i <= l1; i++)
662286d8edStholo 	{
672286d8edStholo 	  /* Resume the insert, if we stopped.  */
682286d8edStholo 	  if (! inserting)
69b2346922Stholo 	    printf_output ("%da\n",
702286d8edStholo 			   i - f1 + translate_line_number (&files[0], f0) - 1);
712286d8edStholo 	  inserting = 1;
722286d8edStholo 
732286d8edStholo 	  /* If the file's line is just a dot, it would confuse `ed'.
742286d8edStholo 	     So output it with a double dot, and set the flag LEADING_DOT
752286d8edStholo 	     so that we will output another ed-command later
762286d8edStholo 	     to change the double dot into a single dot.  */
772286d8edStholo 
782286d8edStholo 	  if (files[1].linbuf[i][0] == '.'
792286d8edStholo 	      && files[1].linbuf[i][1] == '\n')
802286d8edStholo 	    {
81b2346922Stholo 	      printf_output ("..\n");
82b2346922Stholo 	      printf_output (".\n");
832286d8edStholo 	      /* Now change that double dot to the desired single dot.  */
84b2346922Stholo 	      printf_output ("%ds/^\\.\\././\n",
852286d8edStholo 			     i - f1 + translate_line_number (&files[0], f0));
862286d8edStholo 	      inserting = 0;
872286d8edStholo 	    }
882286d8edStholo 	  else
892286d8edStholo 	    /* Line is not `.', so output it unmodified.  */
902286d8edStholo 	    print_1_line ("", &files[1].linbuf[i]);
912286d8edStholo 	}
922286d8edStholo 
932286d8edStholo       /* End insert mode, if we are still in it.  */
942286d8edStholo       if (inserting)
95b2346922Stholo 	printf_output (".\n");
962286d8edStholo     }
972286d8edStholo }
982286d8edStholo 
992286d8edStholo /* Print change script in the style of ed commands,
1002286d8edStholo    but print the changes in the order they appear in the input files,
1012286d8edStholo    which means that the commands are not truly useful with ed.  */
1022286d8edStholo 
1032286d8edStholo void
pr_forward_ed_script(script)1042286d8edStholo pr_forward_ed_script (script)
1052286d8edStholo      struct change *script;
1062286d8edStholo {
1072286d8edStholo   print_script (script, find_change, pr_forward_ed_hunk);
1082286d8edStholo }
1092286d8edStholo 
1102286d8edStholo static void
pr_forward_ed_hunk(hunk)1112286d8edStholo pr_forward_ed_hunk (hunk)
1122286d8edStholo      struct change *hunk;
1132286d8edStholo {
1142286d8edStholo   int i;
1152286d8edStholo   int f0, l0, f1, l1;
1162286d8edStholo   int deletes, inserts;
1172286d8edStholo 
1182286d8edStholo   /* Determine range of line numbers involved in each file.  */
1192286d8edStholo   analyze_hunk (hunk, &f0, &l0, &f1, &l1, &deletes, &inserts);
1202286d8edStholo   if (!deletes && !inserts)
1212286d8edStholo     return;
1222286d8edStholo 
1232286d8edStholo   begin_output ();
1242286d8edStholo 
125b2346922Stholo   printf_output ("%c", change_letter (inserts, deletes));
1262286d8edStholo   print_number_range (' ', files, f0, l0);
127b2346922Stholo   printf_output ("\n");
1282286d8edStholo 
1292286d8edStholo   /* If deletion only, print just the number range.  */
1302286d8edStholo 
1312286d8edStholo   if (!inserts)
1322286d8edStholo     return;
1332286d8edStholo 
1342286d8edStholo   /* For insertion (with or without deletion), print the number range
1352286d8edStholo      and the lines from file 2.  */
1362286d8edStholo 
1372286d8edStholo   for (i = f1; i <= l1; i++)
1382286d8edStholo     print_1_line ("", &files[1].linbuf[i]);
1392286d8edStholo 
140b2346922Stholo   printf_output (".\n");
1412286d8edStholo }
1422286d8edStholo 
1432286d8edStholo /* Print in a format somewhat like ed commands
1442286d8edStholo    except that each insert command states the number of lines it inserts.
1452286d8edStholo    This format is used for RCS.  */
1462286d8edStholo 
1472286d8edStholo void
print_rcs_script(script)1482286d8edStholo print_rcs_script (script)
1492286d8edStholo      struct change *script;
1502286d8edStholo {
1512286d8edStholo   print_script (script, find_change, print_rcs_hunk);
1522286d8edStholo }
1532286d8edStholo 
1542286d8edStholo /* Print a hunk of an RCS diff */
1552286d8edStholo 
1562286d8edStholo static void
print_rcs_hunk(hunk)1572286d8edStholo print_rcs_hunk (hunk)
1582286d8edStholo      struct change *hunk;
1592286d8edStholo {
1602286d8edStholo   int i;
1612286d8edStholo   int f0, l0, f1, l1;
1622286d8edStholo   int deletes, inserts;
1632286d8edStholo   int tf0, tl0, tf1, tl1;
1642286d8edStholo 
1652286d8edStholo   /* Determine range of line numbers involved in each file.  */
1662286d8edStholo   analyze_hunk (hunk, &f0, &l0, &f1, &l1, &deletes, &inserts);
1672286d8edStholo   if (!deletes && !inserts)
1682286d8edStholo     return;
1692286d8edStholo 
1702286d8edStholo   begin_output ();
1712286d8edStholo 
1722286d8edStholo   translate_range (&files[0], f0, l0, &tf0, &tl0);
1732286d8edStholo 
1742286d8edStholo   if (deletes)
1752286d8edStholo     {
176b2346922Stholo       printf_output ("d");
1772286d8edStholo       /* For deletion, print just the starting line number from file 0
1782286d8edStholo 	 and the number of lines deleted.  */
179b2346922Stholo       printf_output ("%d %d\n",
1802286d8edStholo 		     tf0,
1812286d8edStholo 		     (tl0 >= tf0 ? tl0 - tf0 + 1 : 1));
1822286d8edStholo     }
1832286d8edStholo 
1842286d8edStholo   if (inserts)
1852286d8edStholo     {
186b2346922Stholo       printf_output ("a");
1872286d8edStholo 
1882286d8edStholo       /* Take last-line-number from file 0 and # lines from file 1.  */
1892286d8edStholo       translate_range (&files[1], f1, l1, &tf1, &tl1);
190b2346922Stholo       printf_output ("%d %d\n",
1912286d8edStholo 		     tl0,
1922286d8edStholo 		     (tl1 >= tf1 ? tl1 - tf1 + 1 : 1));
1932286d8edStholo 
1942286d8edStholo       /* Print the inserted lines.  */
1952286d8edStholo       for (i = f1; i <= l1; i++)
1962286d8edStholo 	print_1_line ("", &files[1].linbuf[i]);
1972286d8edStholo     }
1982286d8edStholo }
199