1129471Spjd/* Output routines for ed-script format. 2162142Spjd 3129471Spjd Copyright (C) 1988, 1989, 1991, 1992, 1993, 1995, 1998, 2001 Free 4129471Spjd Software Foundation, Inc. 5129471Spjd 6129471Spjd This file is part of GNU DIFF. 7129471Spjd 8129471Spjd GNU DIFF is free software; you can redistribute it and/or modify 9129471Spjd it under the terms of the GNU General Public License as published by 10129471Spjd the Free Software Foundation; either version 2, or (at your option) 11129471Spjd any later version. 12129471Spjd 13162834Spjd GNU DIFF is distributed in the hope that it will be useful, 14129471Spjd but WITHOUT ANY WARRANTY; without even the implied warranty of 15129471Spjd MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16129471Spjd GNU General Public License for more details. 17129471Spjd 18129471Spjd You should have received a copy of the GNU General Public License 19129471Spjd along with this program; see the file COPYING. 20129471Spjd If not, write to the Free Software Foundation, 21129471Spjd 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 22129471Spjd 23129471Spjd#include "diff.h" 24129471Spjd 25129471Spjdstatic void print_ed_hunk (struct change *); 26129471Spjdstatic void print_rcs_hunk (struct change *); 27129471Spjdstatic void pr_forward_ed_hunk (struct change *); 28129471Spjd 29129471Spjd/* Print our script as ed commands. */ 30129471Spjd 31129471Spjdvoid 32129471Spjdprint_ed_script (struct change *script) 33162142Spjd{ 34129471Spjd print_script (script, find_reverse_change, print_ed_hunk); 35129471Spjd} 36129471Spjd 37129471Spjd/* Print a hunk of an ed diff */ 38129471Spjd 39129471Spjdstatic void 40129471Spjdprint_ed_hunk (struct change *hunk) 41129471Spjd{ 42129471Spjd lin f0, l0, f1, l1; 43129471Spjd enum changes changes; 44129471Spjd 45129471Spjd#ifdef DEBUG 46129471Spjd debug_script (hunk); 47249440Sjmg#endif 48249440Sjmg 49249440Sjmg /* Determine range of line numbers involved in each file. */ 50249440Sjmg changes = analyze_hunk (hunk, &f0, &l0, &f1, &l1); 51129471Spjd if (!changes) 52129471Spjd return; 53129471Spjd 54129471Spjd begin_output (); 55129471Spjd 56129471Spjd /* Print out the line number header for this hunk */ 57132381Spjd print_number_range (',', &files[0], f0, l0); 58132381Spjd fprintf (outfile, "%c\n", change_letter[changes]); 59162142Spjd 60153250Spjd /* Print new/changed lines from second file, if needed */ 61238219Strasz if (changes != OLD) 62289520Strasz { 63289520Strasz lin i; 64162142Spjd for (i = f1; i <= l1; i++) 65162142Spjd { 66153250Spjd if (files[1].linbuf[i][0] == '.' && files[1].linbuf[i][1] == '\n') 67153250Spjd { 68293738Strasz /* The file's line is just a dot, and it would exit 69293738Strasz insert mode. Precede the dot with another dot, exit 70293738Strasz insert mode, remove the extra dot, and then resume 71293738Strasz insert mode. */ 72293738Strasz fprintf (outfile, "..\n.\ns/.//\na\n"); 73293738Strasz } 74153250Spjd else 75153250Spjd print_1_line ("", &files[1].linbuf[i]); 76260385Sscottl } 77132381Spjd 78129471Spjd fprintf (outfile, ".\n"); 79129471Spjd } 80129471Spjd} 81 82/* Print change script in the style of ed commands, 83 but print the changes in the order they appear in the input files, 84 which means that the commands are not truly useful with ed. */ 85 86void 87pr_forward_ed_script (struct change *script) 88{ 89 print_script (script, find_change, pr_forward_ed_hunk); 90} 91 92static void 93pr_forward_ed_hunk (struct change *hunk) 94{ 95 lin i, f0, l0, f1, l1; 96 97 /* Determine range of line numbers involved in each file. */ 98 enum changes changes = analyze_hunk (hunk, &f0, &l0, &f1, &l1); 99 if (!changes) 100 return; 101 102 begin_output (); 103 104 fprintf (outfile, "%c", change_letter[changes]); 105 print_number_range (' ', files, f0, l0); 106 fprintf (outfile, "\n"); 107 108 /* If deletion only, print just the number range. */ 109 110 if (changes == OLD) 111 return; 112 113 /* For insertion (with or without deletion), print the number range 114 and the lines from file 2. */ 115 116 for (i = f1; i <= l1; i++) 117 print_1_line ("", &files[1].linbuf[i]); 118 119 fprintf (outfile, ".\n"); 120} 121 122/* Print in a format somewhat like ed commands 123 except that each insert command states the number of lines it inserts. 124 This format is used for RCS. */ 125 126void 127print_rcs_script (struct change *script) 128{ 129 print_script (script, find_change, print_rcs_hunk); 130} 131 132/* Print a hunk of an RCS diff */ 133 134static void 135print_rcs_hunk (struct change *hunk) 136{ 137 lin i, f0, l0, f1, l1; 138 long tf0, tl0, tf1, tl1; 139 140 /* Determine range of line numbers involved in each file. */ 141 enum changes changes = analyze_hunk (hunk, &f0, &l0, &f1, &l1); 142 if (!changes) 143 return; 144 145 begin_output (); 146 147 translate_range (&files[0], f0, l0, &tf0, &tl0); 148 149 if (changes & OLD) 150 { 151 fprintf (outfile, "d"); 152 /* For deletion, print just the starting line number from file 0 153 and the number of lines deleted. */ 154 fprintf (outfile, "%ld %ld\n", tf0, tf0 <= tl0 ? tl0 - tf0 + 1 : 1); 155 } 156 157 if (changes & NEW) 158 { 159 fprintf (outfile, "a"); 160 161 /* Take last-line-number from file 0 and # lines from file 1. */ 162 translate_range (&files[1], f1, l1, &tf1, &tl1); 163 fprintf (outfile, "%ld %ld\n", tl0, tf1 <= tl1 ? tl1 - tf1 + 1 : 1); 164 165 /* Print the inserted lines. */ 166 for (i = f1; i <= l1; i++) 167 print_1_line ("", &files[1].linbuf[i]); 168 } 169} 170