Line data Source code
1 : /* TLD library -- test the TLD version in all files
2 : * Copyright (c) 2011-2021 Made to Order Software Corp. All Rights Reserved
3 : *
4 : * Permission is hereby granted, free of charge, to any person obtaining a
5 : * copy of this software and associated documentation files (the
6 : * "Software"), to deal in the Software without restriction, including
7 : * without limitation the rights to use, copy, modify, merge, publish,
8 : * distribute, sublicense, and/or sell copies of the Software, and to
9 : * permit persons to whom the Software is furnished to do so, subject to
10 : * the following conditions:
11 : *
12 : * The above copyright notice and this permission notice shall be included
13 : * in all copies or substantial portions of the Software.
14 : *
15 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 : * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 : * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 : * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 : * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 : * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 : */
23 :
24 : /** \file
25 : * \brief Test the tld library versions.
26 : *
27 : * This file implements various test to verify that the
28 : * version is properly defined in all the files as expected.
29 : *
30 : * In the compiled data, the version gets copied using the
31 : * configure_file() from cmake. Other files, such as the changelog,
32 : * require manual labor and thus the version could end up
33 : * being wrong (humans are notorious to forget stuff like that).
34 : */
35 :
36 : #include "libtld/tld.h"
37 : #include <string.h>
38 : #include <stdlib.h>
39 : #include <stdio.h>
40 : #include <limits.h>
41 :
42 : int err_count = 0;
43 : int verbose = 0;
44 :
45 :
46 :
47 1 : void check_version_compiled_with(const char *version)
48 : {
49 1 : if(verbose)
50 : {
51 0 : printf("version library was compiled with: %s\n", LIBTLD_VERSION);
52 : }
53 :
54 1 : if(strcmp(LIBTLD_VERSION, version) != 0)
55 : {
56 0 : ++err_count;
57 0 : fprintf(stderr, "error: compiled with version %s, expected %s instead.\n", LIBTLD_VERSION, version);
58 : }
59 1 : }
60 :
61 :
62 :
63 : // Newer versions retrieve the version directly from the changelog file
64 : //void check_main_cmakefiles_txt(const char *path, const char *version)
65 : //{
66 : // const int cmakelists_txt_len = 15;
67 : // const int len = strlen(path);
68 : // char *filename = malloc(len + cmakelists_txt_len + 1);
69 : // FILE *f;
70 : // char buf[1024];
71 : // char *str;
72 : // int major = 0;
73 : // int minor = 0;
74 : // int patch = 0;
75 : //
76 : // memcpy(filename, path, len);
77 : // memcpy(filename + len, "/CMakeLists.txt", cmakelists_txt_len + 1); // copy string and '\0'
78 : //
79 : // f = fopen(filename, "r");
80 : // if(f == NULL)
81 : // {
82 : // ++err_count;
83 : // perror("error: fopen()");
84 : // fprintf(stderr, "error: could not open main CMakeLists.txt file (full path: \"%s\")\n:", filename);
85 : // free(filename);
86 : // return;
87 : // }
88 : //
89 : // while(fgets(buf, sizeof(buf), f) != (char *) 0)
90 : // {
91 : // str = strstr(buf, "LIBTLD_VERSION_MAJOR");
92 : // if(str != (char *) 0 && str > buf && str[-1] != '{')
93 : // {
94 : // major = atol(str + 20);
95 : // }
96 : // str = strstr(buf, "LIBTLD_VERSION_MINOR");
97 : // if(str != (char *) 0 && str > buf && str[-1] != '{')
98 : // {
99 : // minor = atol(str + 20);
100 : // }
101 : // str = strstr(buf, "LIBTLD_VERSION_PATCH");
102 : // if(str != (char *) 0 && str > buf && str[-1] != '{')
103 : // {
104 : // patch = atol(str + 20);
105 : // }
106 : // }
107 : // fclose(f);
108 : //
109 : // snprintf(buf, sizeof(buf), "%d.%d.%d", major, minor, patch);
110 : //
111 : // if(verbose)
112 : // {
113 : // printf("main CMakeLists.txt version: %s\n", buf);
114 : // }
115 : //
116 : // if(strcmp(buf, version) != 0)
117 : // {
118 : // ++err_count;
119 : // fprintf(stderr, "error: main CMakeLists.txt version (%s) is %s, expected %s instead.\n", filename, buf, version);
120 : // }
121 : //
122 : // free(filename);
123 : //}
124 :
125 :
126 1 : void check_libtld_only_cmakefiles_txt(const char *path, const char *version)
127 : {
128 1 : const int cmakelists_txt_len = 31;
129 1 : const int len = strlen(path);
130 1 : char *filename = malloc(len + cmakelists_txt_len + 1);
131 : FILE *f;
132 : char buf[1024];
133 : char *str;
134 1 : int major = 0;
135 1 : int minor = 0;
136 1 : int patch = 0;
137 :
138 1 : memcpy(filename, path, len);
139 1 : memcpy(filename + len, "/dev/libtld-only-CMakeLists.txt", cmakelists_txt_len + 1); // copy string and '\0'
140 :
141 1 : f = fopen(filename, "r");
142 1 : if(f == NULL)
143 : {
144 0 : ++err_count;
145 0 : perror("error: fopen()");
146 0 : fprintf(stderr, "error: could not open libtld only CMakeLists.txt file (full path: \"%s\")\n:", filename);
147 0 : free(filename);
148 0 : return;
149 : }
150 :
151 130 : while(fgets(buf, sizeof(buf), f) != (char *) 0)
152 : {
153 128 : str = strstr(buf, "LIBTLD_VERSION_MAJOR");
154 128 : if(str != (char *) 0 && str > buf && str[-1] != '{')
155 : {
156 1 : major = atol(str + 20);
157 : }
158 128 : str = strstr(buf, "LIBTLD_VERSION_MINOR");
159 128 : if(str != (char *) 0 && str > buf && str[-1] != '{')
160 : {
161 1 : minor = atol(str + 20);
162 : }
163 128 : str = strstr(buf, "LIBTLD_VERSION_PATCH");
164 128 : if(str != (char *) 0 && str > buf && str[-1] != '{')
165 : {
166 1 : patch = atol(str + 20);
167 : }
168 : }
169 1 : fclose(f);
170 :
171 1 : snprintf(buf, sizeof(buf), "%d.%d.%d", major, minor, patch);
172 :
173 1 : if(verbose)
174 : {
175 0 : printf("libtld only CMakeLists.txt version: %s\n", buf);
176 : }
177 :
178 1 : if(strcmp(buf, version) != 0)
179 : {
180 0 : ++err_count;
181 0 : fprintf(stderr, "error: libtld only CMakeLists.txt version (%s) is %s, expected %s instead.\n", filename, buf, version);
182 : }
183 :
184 1 : free(filename);
185 : }
186 :
187 :
188 1 : void check_changelog(const char *path, const char *version)
189 : {
190 1 : const int changelog_len = 17;
191 1 : const int len = strlen(path);
192 1 : char *filename = malloc(len + changelog_len + 1);
193 : FILE *f;
194 : char buf[1024];
195 : char *str;
196 : char *debian_version;
197 : int i;
198 :
199 1 : memcpy(filename, path, len);
200 1 : memcpy(filename + len, "/debian/changelog", changelog_len + 1); // copy string and '\0'
201 :
202 1 : f = fopen(filename, "r");
203 1 : if(f == NULL)
204 : {
205 0 : ++err_count;
206 0 : perror("error: fopen()");
207 0 : fprintf(stderr, "error: could not open debian/changelog file (full path: \"%s\")\n:", filename);
208 0 : free(filename);
209 0 : return;
210 : }
211 :
212 1 : if(fgets(buf, sizeof(buf), f) == (char *) 0)
213 : {
214 0 : ++err_count;
215 0 : perror("error: fgets()");
216 0 : fprintf(stderr, "error: could not read the first line of debian/changelog (full path: \"%s\")\n:", filename);
217 0 : free(filename);
218 0 : fclose(f);
219 0 : return;
220 : }
221 :
222 1 : fclose(f);
223 :
224 1 : if(buf[0] != 'l'
225 1 : || buf[1] != 'i'
226 1 : || buf[2] != 'b'
227 1 : || buf[3] != 't'
228 1 : || buf[4] != 'l'
229 1 : || buf[5] != 'd'
230 1 : || buf[6] != ' '
231 1 : || buf[7] != '(')
232 : {
233 0 : ++err_count;
234 0 : fprintf(stderr, "error: debian/changelog does not start with \"libtld (\" as expected (full path: \"%s\")\n:", filename);
235 0 : free(filename);
236 0 : return;
237 : }
238 :
239 1 : debian_version = buf + 8;
240 :
241 1 : for(i = 0; debian_version[i] != '\0' && debian_version[i] != ')'; ++i);
242 :
243 1 : if(debian_version[i] != ')')
244 : {
245 0 : ++err_count;
246 0 : fprintf(stderr, "error: debian/changelog does not seem to include a valid version (full path: \"%s\")\n:", filename);
247 0 : free(filename);
248 0 : return;
249 : }
250 1 : debian_version[i] = '\0'; // this modifies buf which is fine
251 :
252 : // the debian version is likely to include a build number and platform name
253 1 : i = 0;
254 6 : for(str = debian_version; *str != '\0'; ++str)
255 : {
256 6 : if(*str == '~')
257 : {
258 : // stop immediately
259 0 : break;
260 : }
261 6 : else if(*str == '.')
262 : {
263 3 : ++i;
264 3 : if(i >= 3)
265 : {
266 : // stop at the 3rd '.' (i.e. build number)
267 1 : break;
268 : }
269 : }
270 : }
271 1 : *str = '\0'; // remove extra stuff
272 :
273 1 : if(verbose)
274 : {
275 0 : printf("changelog version: %s\n", debian_version);
276 : }
277 :
278 1 : if(strcmp(debian_version, version) != 0)
279 : {
280 0 : ++err_count;
281 0 : fprintf(stderr, "error: changelog version (%s) is %s, expected %s instead.\n", filename, debian_version, version);
282 : }
283 :
284 1 : free(filename);
285 : }
286 :
287 :
288 :
289 1 : int main(int argc, char *argv[])
290 : {
291 1 : const char *version = tld_version();
292 1 : char *path = (char *) 0;
293 : int i;
294 :
295 2 : for(i = 1; i < argc; ++i)
296 : {
297 1 : if(strcmp(argv[i], "-v") == 0)
298 : {
299 0 : verbose = 1;
300 : }
301 : else
302 : {
303 1 : path = argv[i];
304 : }
305 : }
306 :
307 1 : if(path == (char *) 0)
308 : {
309 0 : ++err_count;
310 0 : fprintf(stderr, "error: mandatory source path not specified on command line.\n");
311 : }
312 : else
313 : {
314 1 : if(verbose)
315 : {
316 0 : printf("runtime libtld version: %s\n", version);
317 : }
318 : else
319 : {
320 1 : printf("%s\n", version);
321 : }
322 :
323 1 : check_version_compiled_with(version);
324 : //check_main_cmakefiles_txt(path, version);
325 1 : check_libtld_only_cmakefiles_txt(path, version);
326 1 : check_changelog(path, version);
327 : }
328 :
329 1 : exit(err_count ? 1 : 0);
330 : }
331 :
332 : /* vim: ts=4 sw=4 et
333 : */
334 :
|