1170754Sdelphij/* Output routines for ed-script format. 2170754Sdelphij 3170754Sdelphij Copyright (C) 1988, 1989, 1991, 1992, 1993, 1995, 1998, 2001, 2004 4170754Sdelphij Free Software Foundation, Inc. 5170754Sdelphij 6170754Sdelphij This file is part of GNU DIFF. 7170754Sdelphij 8170754Sdelphij GNU DIFF is free software; you can redistribute it and/or modify 9170754Sdelphij it under the terms of the GNU General Public License as published by 10170754Sdelphij the Free Software Foundation; either version 2, or (at your option) 11170754Sdelphij any later version. 12170754Sdelphij 13170754Sdelphij GNU DIFF is distributed in the hope that it will be useful, 14170754Sdelphij but WITHOUT ANY WARRANTY; without even the implied warranty of 15170754Sdelphij MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16170754Sdelphij GNU General Public License for more details. 17170754Sdelphij 18170754Sdelphij You should have received a copy of the GNU General Public License 19170754Sdelphij along with this program; see the file COPYING. 20170754Sdelphij If not, write to the Free Software Foundation, 21170754Sdelphij 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 22170754Sdelphij 23170754Sdelphij#include "diff.h" 24170754Sdelphij 25170754Sdelphijstatic void print_ed_hunk (struct change *); 26170754Sdelphijstatic void print_rcs_hunk (struct change *); 27170754Sdelphijstatic void pr_forward_ed_hunk (struct change *); 28170754Sdelphij 29170754Sdelphij/* Print our script as ed commands. */ 30170754Sdelphij 31170754Sdelphijvoid 32170754Sdelphijprint_ed_script (struct change *script) 33170754Sdelphij{ 34170754Sdelphij print_script (script, find_reverse_change, print_ed_hunk); 35170754Sdelphij} 36170754Sdelphij 37170754Sdelphij/* Print a hunk of an ed diff */ 38170754Sdelphij 39170754Sdelphijstatic void 40170754Sdelphijprint_ed_hunk (struct change *hunk) 41170754Sdelphij{ 42170754Sdelphij lin f0, l0, f1, l1; 43170754Sdelphij enum changes changes; 44170754Sdelphij 45170754Sdelphij#ifdef DEBUG 46170754Sdelphij debug_script (hunk); 47170754Sdelphij#endif 48170754Sdelphij 49170754Sdelphij /* Determine range of line numbers involved in each file. */ 50170754Sdelphij changes = analyze_hunk (hunk, &f0, &l0, &f1, &l1); 51170754Sdelphij if (!changes) 52170754Sdelphij return; 53170754Sdelphij 54170754Sdelphij begin_output (); 55170754Sdelphij 56170754Sdelphij /* Print out the line number header for this hunk */ 57170754Sdelphij print_number_range (',', &files[0], f0, l0); 58170754Sdelphij fprintf (outfile, "%c\n", change_letter[changes]); 59170754Sdelphij 60170754Sdelphij /* Print new/changed lines from second file, if needed */ 61170754Sdelphij if (changes != OLD) 62170754Sdelphij { 63170754Sdelphij lin i; 64170754Sdelphij for (i = f1; i <= l1; i++) 65170754Sdelphij { 66170754Sdelphij if (files[1].linbuf[i][0] == '.' && files[1].linbuf[i][1] == '\n') 67170754Sdelphij { 68170754Sdelphij /* The file's line is just a dot, and it would exit 69170754Sdelphij insert mode. Precede the dot with another dot, exit 70170754Sdelphij insert mode, remove the extra dot, and then resume 71170754Sdelphij insert mode. */ 72170754Sdelphij fprintf (outfile, "..\n.\ns/.//\na\n"); 73170754Sdelphij } 74170754Sdelphij else 75170754Sdelphij print_1_line ("", &files[1].linbuf[i]); 76170754Sdelphij } 77170754Sdelphij 78170754Sdelphij fprintf (outfile, ".\n"); 79170754Sdelphij } 80170754Sdelphij} 81170754Sdelphij 82170754Sdelphij/* Print change script in the style of ed commands, 83170754Sdelphij but print the changes in the order they appear in the input files, 84170754Sdelphij which means that the commands are not truly useful with ed. */ 85170754Sdelphij 86170754Sdelphijvoid 87170754Sdelphijpr_forward_ed_script (struct change *script) 88170754Sdelphij{ 89170754Sdelphij print_script (script, find_change, pr_forward_ed_hunk); 90170754Sdelphij} 91170754Sdelphij 92170754Sdelphijstatic void 93170754Sdelphijpr_forward_ed_hunk (struct change *hunk) 94170754Sdelphij{ 95170754Sdelphij lin i, f0, l0, f1, l1; 96170754Sdelphij 97170754Sdelphij /* Determine range of line numbers involved in each file. */ 98170754Sdelphij enum changes changes = analyze_hunk (hunk, &f0, &l0, &f1, &l1); 99170754Sdelphij if (!changes) 100170754Sdelphij return; 101170754Sdelphij 102170754Sdelphij begin_output (); 103170754Sdelphij 104170754Sdelphij fprintf (outfile, "%c", change_letter[changes]); 105170754Sdelphij print_number_range (' ', files, f0, l0); 106170754Sdelphij fprintf (outfile, "\n"); 107170754Sdelphij 108170754Sdelphij /* If deletion only, print just the number range. */ 109170754Sdelphij 110170754Sdelphij if (changes == OLD) 111170754Sdelphij return; 112170754Sdelphij 113170754Sdelphij /* For insertion (with or without deletion), print the number range 114170754Sdelphij and the lines from file 2. */ 115170754Sdelphij 116170754Sdelphij for (i = f1; i <= l1; i++) 117170754Sdelphij print_1_line ("", &files[1].linbuf[i]); 118170754Sdelphij 119170754Sdelphij fprintf (outfile, ".\n"); 120170754Sdelphij} 121170754Sdelphij 122170754Sdelphij/* Print in a format somewhat like ed commands 123170754Sdelphij except that each insert command states the number of lines it inserts. 124170754Sdelphij This format is used for RCS. */ 125170754Sdelphij 126170754Sdelphijvoid 127170754Sdelphijprint_rcs_script (struct change *script) 128170754Sdelphij{ 129170754Sdelphij print_script (script, find_change, print_rcs_hunk); 130170754Sdelphij} 131170754Sdelphij 132170754Sdelphij/* Print a hunk of an RCS diff */ 133170754Sdelphij 134170754Sdelphijstatic void 135170754Sdelphijprint_rcs_hunk (struct change *hunk) 136170754Sdelphij{ 137170754Sdelphij lin i, f0, l0, f1, l1; 138170754Sdelphij long int tf0, tl0, tf1, tl1; 139170754Sdelphij 140170754Sdelphij /* Determine range of line numbers involved in each file. */ 141170754Sdelphij enum changes changes = analyze_hunk (hunk, &f0, &l0, &f1, &l1); 142170754Sdelphij if (!changes) 143170754Sdelphij return; 144170754Sdelphij 145170754Sdelphij begin_output (); 146170754Sdelphij 147170754Sdelphij translate_range (&files[0], f0, l0, &tf0, &tl0); 148170754Sdelphij 149170754Sdelphij if (changes & OLD) 150170754Sdelphij { 151170754Sdelphij fprintf (outfile, "d"); 152170754Sdelphij /* For deletion, print just the starting line number from file 0 153170754Sdelphij and the number of lines deleted. */ 154170754Sdelphij fprintf (outfile, "%ld %ld\n", tf0, tf0 <= tl0 ? tl0 - tf0 + 1 : 1); 155170754Sdelphij } 156170754Sdelphij 157170754Sdelphij if (changes & NEW) 158170754Sdelphij { 159170754Sdelphij fprintf (outfile, "a"); 160170754Sdelphij 161170754Sdelphij /* Take last-line-number from file 0 and # lines from file 1. */ 162170754Sdelphij translate_range (&files[1], f1, l1, &tf1, &tl1); 163170754Sdelphij fprintf (outfile, "%ld %ld\n", tl0, tf1 <= tl1 ? tl1 - tf1 + 1 : 1); 164170754Sdelphij 165170754Sdelphij /* Print the inserted lines. */ 166170754Sdelphij for (i = f1; i <= l1; i++) 167170754Sdelphij print_1_line ("", &files[1].linbuf[i]); 168170754Sdelphij } 169170754Sdelphij} 170