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