>From bffe3fef5440f17aa37d0167e4b5af8a2906838c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niklas=20Hamb=C3=BCchen?= <[email protected]>
Date: Sun, 14 Aug 2011 19:30:57 +0200
Subject: [PATCH] Add --ed-line-numbers-only option to diff

---
 src/analyze.c |    6 +++++-
 src/diff.c    |    8 +++++++-
 src/diff.h    |    4 ++++
 src/ed.c      |   37 +++++++++++++++++++++++++++++++++++++
 4 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/src/analyze.c b/src/analyze.c
index e797248..95e1e62 100644
--- a/src/analyze.c
+++ b/src/analyze.c
@@ -597,7 +597,7 @@ diff_2_files (struct comparison *cmp)
       /* Get the results of comparison in the form of a chain
 	 of `struct change's -- an edit script.  */
 
-      if (output_style == OUTPUT_ED)
+      if (output_style == OUTPUT_ED || output_style == OUTPUT_ED_LINE_NUMBERS_ONLY)
 	script = build_reverse_script (cmp->file);
       else
 	script = build_script (cmp->file);
@@ -660,6 +660,10 @@ diff_2_files (struct comparison *cmp)
 		  print_ed_script (script);
 		  break;
 
+		case OUTPUT_ED_LINE_NUMBERS_ONLY:
+		  print_ed_script_line_numbers_only (script);
+		  break;
+
 		case OUTPUT_FORWARD_ED:
 		  pr_forward_ed_script (script);
 		  break;
diff --git a/src/diff.c b/src/diff.c
index cc1b611..2ad39b2 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -106,7 +106,7 @@ static bool unidirectional_new_file;
 static bool report_identical_files;
 
 static char const shortopts[] =
-"0123456789abBcC:dD:eEfF:hHiI:lL:nNpPqrsS:tTuU:vwW:x:X:y";
+"0123456789abBcC:dD:eEfF:hHiI:lL:nNopPqrsS:tTuU:vwW:x:X:y";
 
 /* Values for long options that do not have single-letter equivalents.  */
 enum
@@ -162,6 +162,7 @@ static struct option const longopts[] =
   {"changed-group-format", 1, 0, CHANGED_GROUP_FORMAT_OPTION},
   {"context", 2, 0, 'C'},
   {"ed", 0, 0, 'e'},
+  {"ed-line-numbers-only", 0, 0, 'o'},
   {"exclude", 1, 0, 'x'},
   {"exclude-from", 1, 0, 'X'},
   {"expand-tabs", 0, 0, 't'},
@@ -379,6 +380,10 @@ main (int argc, char **argv)
 	  specify_style (OUTPUT_ED);
 	  break;
 
+	case 'o':
+	  specify_style (OUTPUT_ED_LINE_NUMBERS_ONLY);
+	  break;
+
 	case 'E':
 	  if (ignore_white_space < IGNORE_TAB_EXPANSION)
 	    ignore_white_space = IGNORE_TAB_EXPANSION;
@@ -864,6 +869,7 @@ static char const * const option_help_msgid[] = {
   -F RE  --show-function-line=RE  Show the most recent line matching RE."),
   N_("-q  --brief  Output only whether files differ."),
   N_("-e  --ed  Output an ed script."),
+  N_("-o  --ed-line-numbers-only  Output an ed script, line numebers only."),
   N_("--normal  Output a normal diff."),
   N_("-n  --rcs  Output an RCS format diff."),
   N_("-y  --side-by-side  Output in two columns.\n\
diff --git a/src/diff.h b/src/diff.h
index 71b33f4..7237016 100644
--- a/src/diff.h
+++ b/src/diff.h
@@ -64,6 +64,9 @@ enum output_style
   /* Output the differences as commands suitable for `ed' (-e).  */
   OUTPUT_ED,
 
+  /* Output the differences as `ed'-style line number headers (-o).  */
+  OUTPUT_ED_LINE_NUMBERS_ONLY,
+
   /* Output the diff as a forward ed script (-f).  */
   OUTPUT_FORWARD_ED,
 
@@ -327,6 +330,7 @@ int diff_dirs (struct comparison const *, int (*) (struct comparison const *, ch
 
 /* ed.c */
 void print_ed_script (struct change *);
+void print_ed_script_line_numbers_only (struct change *);
 void pr_forward_ed_script (struct change *);
 
 /* ifdef.c */
diff --git a/src/ed.c b/src/ed.c
index 08acf50..23f8a7b 100644
--- a/src/ed.c
+++ b/src/ed.c
@@ -21,6 +21,7 @@
 #include "diff.h"
 
 static void print_ed_hunk (struct change *);
+static void print_ed_hunk_line_number_header (struct change *);
 static void print_rcs_hunk (struct change *);
 static void pr_forward_ed_hunk (struct change *);
 
@@ -32,6 +33,42 @@ print_ed_script (struct change *script)
   print_script (script, find_reverse_change, print_ed_hunk);
 }
 
+/* Print our script as ed commands,
+   printing line number headers only, omitting the actual contents.  */
+
+void
+print_ed_script_line_numbers_only (struct change *script)
+{
+  print_script (script, find_reverse_change, print_ed_hunk_line_number_header);
+}
+
+/* Print the line number headers of an ed diff */
+
+static void
+print_ed_hunk_line_number_header (struct change *hunk)
+{
+  lin f0, l0, f1, l1;
+  enum changes changes;
+
+#ifdef DEBUG
+  debug_script (hunk);
+#endif
+
+  /* Determine range of line numbers involved in each file.  */
+  changes = analyze_hunk (hunk, &f0, &l0, &f1, &l1);
+  if (!changes)
+    return;
+
+  begin_output ();
+
+  /* Print out the line number header for this hunk */
+  print_number_range (',', &files[0], f0, l0);
+  fputc (change_letter[changes], outfile);
+  fputc ('\n', outfile);
+
+  /* Do not print the actual change content. */
+}
+
 /* Print a hunk of an ed diff */
 
 static void
-- 
1.7.4.1

Reply via email to