• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2 // -*- Mode: C++ -*-
3 //
4 // Copyright (C) 2013-2022 Red Hat, Inc.
5 //
6 // Author: Dodji Seketeli
7 
8 /// @file
9 ///
10 /// This file implements a simple command line utility for
11 /// interactively testing the diff2 algorithms declared and defined in
12 /// abg-diff-utils.{h,cc}
13 ///
14 /// The resulting binary name is testdiff2.  Run it to see a help message
15 /// showing you how to use it.
16 
17 #include <cstring>
18 #include <iostream>
19 #include "abg-diff-utils.h"
20 
21 using std::cout;
22 using std::string;
23 
24 using abigail::diff_utils::ses_len;
25 using abigail::diff_utils::point;
26 using abigail::diff_utils::snake;
27 using abigail::diff_utils::compute_middle_snake;
28 using abigail::diff_utils::print_snake;
29 using abigail::diff_utils::compute_lcs;
30 using abigail::diff_utils::edit_script;
31 using abigail::diff_utils::compute_ses;
32 using abigail::diff_utils::display_edit_script;
33 
34 struct options
35 {
36   bool show_help;
37   bool ses_len;
38   bool reverse;
39   bool middle_snake;
40   bool lcs;
41   bool ses;
42   const char* str1;
43   const char* str2;
44 
optionsoptions45   options()
46     : show_help(false),
47       ses_len(false),
48       reverse(false),
49       middle_snake(false),
50       lcs(false),
51       ses(false),
52       str1(0),
53       str2(0)
54   {}
55 };// end struct options
56 
57 static void
show_help(const string & progname)58 show_help(const string& progname)
59 {
60    cout << "usage: " << progname << " [options] str1 str2\n"
61 	<< "where [options] can be:\n"
62 	<< "--seslen	print the length of the SES of the two strings\n"
63 	<< "--reverse	compute the d-paths in reverse order when applicable\n"
64 	<< "--middle-snake	display middle snake & length of SES\n"
65 	<< "--lcs	display the longest common subsequence\n"
66 	<< "--ses	display the shortest edit script transforming str1 into str2\n";
67 }
68 
69 static void
parse_command_line(int argc,char * argv[],options & opts)70 parse_command_line(int argc, char* argv[], options &opts)
71 {
72   if (argc < 3)
73     {
74       opts.show_help = true;
75       return;
76     }
77 
78   for (int i = 1; i < argc; ++i)
79     {
80       if (argv[i][0] != '-')
81 	{
82 	  if (!opts.str1)
83 	    opts.str1 = argv[i];
84 	  else if (!opts.str2)
85 	    opts.str2 = argv[i];
86 	  else
87 	    {
88 	      opts.show_help = true;
89 	      return;
90 	    }
91 	}
92       else if (strcmp(argv[i], "--seslen") == 0)
93 	opts.ses_len = true;
94       else if (strcmp(argv[i], "--reverse") == 0)
95 	opts.reverse = true;
96       else if (strcmp(argv[i], "--middle-snake") == 0)
97 	opts.middle_snake = true;
98       else if (strcmp(argv[i], "--lcs") == 0)
99 	opts.lcs = true;
100       else if (strcmp(argv[i], "--ses") == 0)
101 	opts.ses = true;
102       else
103 	opts.show_help = true;
104     }
105 }
106 
107 int
main(int argc,char * argv[])108 main(int argc, char*argv[])
109 {
110   options opts;
111   parse_command_line(argc, argv, opts);
112 
113   if (opts.show_help)
114     {
115       show_help(argv[0]);
116       return -1;
117     }
118 
119   if (opts.ses_len)
120     {
121       int len = ses_len(opts.str1, opts.str2, opts.reverse);
122       cout << len << "\n";
123       return 0;
124     }
125 
126   if (opts.middle_snake)
127     {
128       int ses_len = 0;
129       snake s;
130       if (compute_middle_snake(opts.str1, opts.str2,
131 			       s, ses_len))
132 	{
133 	  print_snake(opts.str1, opts.str2, s, cout);
134 	  cout << "ses len: " << ses_len << "\n";
135 	}
136       return 0;
137     }
138 
139   if (opts.lcs)
140     {
141       string lcs;
142       int ses_len = 0;
143       compute_lcs(opts.str1, opts.str2, ses_len, lcs);
144       cout << "lcs: " << lcs << "\n"
145 	   << "ses len: " << ses_len << "\n";
146       return 0;
147     }
148 
149   if (opts.ses)
150     {
151       edit_script ses;
152       compute_ses(opts.str1, opts.str2, ses);
153       display_edit_script(ses, opts.str1, opts.str2, cout);
154       return 0;
155     }
156 
157   return 0;
158 }
159