1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2 // -*- Mode: C++ -*-
3 //
4 // Copyright (C) 2013-2020 Red Hat, Inc.
5 //
6 // Author: Dodji Seketeli
7 
8 #include <string>
9 #include <fstream>
10 #include <iostream>
11 #include <cstdlib>
12 #include "abg-tools-utils.h"
13 #include "abg-diff-utils.h"
14 #include "test-utils.h"
15 
16 using std::string;
17 using std::ofstream;
18 using std::cerr;
19 
20 /// This structure describes the set of strings we want to diff
21 /// against each other as well as the reports we expect from these
22 /// diffs.
23 struct SESInOutSpec
24 {
25   // This is the path to the report we expect from the diff algorithm
26   // applied to second_string (below) diffed against first_string.
27   const char* in_path;
28   // This is the path where to store the report of the diff algorithm
29   // applied to second_string (below) diffed against first_string.
30   const char* out_path;
31   // This is the first string to feed the diff algorithm with.
32   const char* first_string;
33   // This is the second string to feed the diff algorithm with.
34   const char* second_string;
35 };// end struct SESInOutSpec
36 
37 SESInOutSpec in_out_specs[] =
38 {
39   {
40     "data/test-core-diff/report0.txt",
41     "output/test-core-diff/report0.txt",
42     "abcabba",
43     "cbabac"
44   },
45   {
46     "data/test-core-diff/report1.txt",
47     "output/test-core-diff/report1.txt",
48     "xxabxx",
49     "xbx"
50   },
51   {
52     "data/test-core-diff/report2.txt",
53     "output/test-core-diff/report2.txt",
54     "xxabxx",
55     "xbcx"
56   },
57   {
58     "data/test-core-diff/report3.txt",
59     "output/test-core-diff/report3.txt",
60     "abc",
61     "abdecfgc"
62   },
63   {
64     "data/test-core-diff/report4.txt",
65     "output/test-core-diff/report4.txt",
66     "xxx",
67     "xxx"
68   },
69   {
70     "data/test-core-diff/report5.txt",
71     "output/test-core-diff/report5.txt",
72     "xabx",
73     "xbx"
74   },
75   {
76     "data/test-core-diff/report6.txt",
77     "output/test-core-diff/report6.txt",
78     "fou",
79     "fubar"
80   },
81   {
82     "data/test-core-diff/report7.txt",
83     "output/test-core-diff/report7.txt",
84     "sqkdjfjdsql",
85     "sqdmlkjfmljdsqf"
86   },
87   {
88     "data/test-core-diff/report8.txt",
89     "output/test-core-diff/report8.txt",
90     "abcdef",
91     "bcghai"
92   },
93   {
94     "data/test-core-diff/report9.txt",
95     "output/test-core-diff/report9.txt",
96     "abcdef",
97     "bjcghai"
98   },
99   {
100     "data/test-core-diff/report10.txt",
101     "output/test-core-diff/report10.txt",
102     "a",
103     "ab"
104   },
105   {
106     "data/test-core-diff/report11.txt",
107     "output/test-core-diff/report11.txt",
108     "a",
109     "abd"
110   },
111   {
112     "data/test-core-diff/report12.txt",
113     "output/test-core-diff/report12.txt",
114     "a",
115     "cba"
116   },
117   {
118     "data/test-core-diff/report13.txt",
119     "output/test-core-diff/report13.txt",
120     "abcdefghi",
121     "jklmnopqrstadubvfwxgh"
122   },
123   // This should be the last entry.
124   {NULL, NULL, NULL, NULL}
125 };
126 
127 using abigail::diff_utils::edit_script;
128 using abigail::diff_utils::compute_ses;
129 using abigail::diff_utils::display_edit_script;
130 
131 int
main()132 main()
133 {
134   unsigned result = 1;
135 
136   bool problem = false;
137   string in_path, out_path;
138 
139   for (SESInOutSpec *s = in_out_specs; s->in_path; ++s)
140     {
141       string input_suffix(s->in_path);
142       in_path =
143 	string(abigail::tests::get_src_dir()) + "/tests/" + input_suffix;
144 
145       string output_suffix(s->out_path);
146       out_path =
147 	string(abigail::tests::get_build_dir()) + "/tests/" + output_suffix;
148 
149       if (!abigail::tools_utils::ensure_parent_dir_created(out_path))
150 	{
151 	  cerr << "Could not create parent director for " << out_path;
152 	  problem = true;
153 	  return result;
154 	}
155 
156       ofstream of(out_path.c_str(), std::ios_base::trunc);
157       if (!of.is_open())
158 	{
159 	  cerr << "failed to read " << out_path << "\n";
160 	  problem = true;
161 	  continue;
162 	}
163 
164       edit_script ses;
165       // Compute the Shortest Edit Script (aka diff) that changes
166       // s->first_string into s->second_string.
167       compute_ses(s->first_string, s->second_string, ses);
168       // Emit a report about that edit script
169       display_edit_script(ses, s->first_string, s->second_string, of);
170       of.close();
171       // Diff that report against what we expect.
172       string cmd = "diff -u " + in_path + " " + out_path;
173       if (system(cmd.c_str()))
174 	problem= true;
175     }
176 
177   return problem;
178 }
179