Line data Source code
1 : /* TLD library -- test the TLD version in all files
2 : * Copyright (c) 2011-2022 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 2 : void check_version_compiled_with(const char *version)
48 : {
49 2 : if(verbose)
50 : {
51 0 : printf("version library was compiled with: %s\n", LIBTLD_VERSION);
52 : }
53 :
54 2 : 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 2 : }
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 : //void check_libtld_only_cmakefiles_txt(const char *path, const char *version)
127 : //{
128 : // const int cmakelists_txt_len = 31;
129 : // const int len = strlen(path);
130 : // char *filename = malloc(len + cmakelists_txt_len + 1);
131 : // FILE *f;
132 : // char buf[1024];
133 : // char *str;
134 : // int major = 0;
135 : // int minor = 0;
136 : // int patch = 0;
137 : //
138 : // memcpy(filename, path, len);
139 : // memcpy(filename + len, "/dev/libtld-only-CMakeLists.txt", cmakelists_txt_len + 1); // copy string and '\0'
140 : //
141 : // f = fopen(filename, "r");
142 : // if(f == NULL)
143 : // {
144 : // ++err_count;
145 : // perror("error: fopen()");
146 : // fprintf(stderr, "error: could not open libtld only CMakeLists.txt file (full path: \"%s\")\n:", filename);
147 : // free(filename);
148 : // return;
149 : // }
150 : //
151 : // while(fgets(buf, sizeof(buf), f) != (char *) 0)
152 : // {
153 : // str = strstr(buf, "LIBTLD_VERSION_MAJOR");
154 : // if(str != (char *) 0 && str > buf && str[-1] != '{')
155 : // {
156 : // major = atol(str + 20);
157 : // }
158 : // str = strstr(buf, "LIBTLD_VERSION_MINOR");
159 : // if(str != (char *) 0 && str > buf && str[-1] != '{')
160 : // {
161 : // minor = atol(str + 20);
162 : // }
163 : // str = strstr(buf, "LIBTLD_VERSION_PATCH");
164 : // if(str != (char *) 0 && str > buf && str[-1] != '{')
165 : // {
166 : // patch = atol(str + 20);
167 : // }
168 : // }
169 : // fclose(f);
170 : //
171 : // snprintf(buf, sizeof(buf), "%d.%d.%d", major, minor, patch);
172 : //
173 : // if(verbose)
174 : // {
175 : // printf("libtld only CMakeLists.txt version: %s\n", buf);
176 : // }
177 : //
178 : // if(strcmp(buf, version) != 0)
179 : // {
180 : // ++err_count;
181 : // fprintf(stderr, "error: libtld only CMakeLists.txt version (%s) is %s, expected %s instead.\n", filename, buf, version);
182 : // }
183 : //
184 : // free(filename);
185 : //}
186 :
187 :
188 2 : void check_changelog(const char *path, const char *version)
189 : {
190 2 : const int changelog_len = 17;
191 2 : const int len = strlen(path);
192 2 : char *filename = malloc(len + changelog_len + 1);
193 : FILE *f;
194 2 : char buf[1024];
195 : char *str;
196 : char *debian_version;
197 : int i;
198 :
199 2 : memcpy(filename, path, len);
200 2 : memcpy(filename + len, "/debian/changelog", changelog_len + 1); // copy string and '\0'
201 :
202 2 : f = fopen(filename, "r");
203 2 : 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 2 : 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 2 : fclose(f);
223 :
224 2 : if(buf[0] != 'l'
225 2 : || buf[1] != 'i'
226 2 : || buf[2] != 'b'
227 2 : || buf[3] != 't'
228 2 : || buf[4] != 'l'
229 2 : || buf[5] != 'd'
230 2 : || buf[6] != ' '
231 2 : || 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 2 : debian_version = buf + 8;
240 :
241 2 : for(i = 0; debian_version[i] != '\0' && debian_version[i] != ')'; ++i);
242 :
243 2 : 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 2 : 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 2 : i = 0;
254 14 : for(str = debian_version; *str != '\0'; ++str)
255 : {
256 14 : if(*str == '~')
257 : {
258 : // stop immediately
259 0 : break;
260 : }
261 14 : else if(*str == '.')
262 : {
263 6 : ++i;
264 6 : if(i >= 3)
265 : {
266 : // stop at the 3rd '.' (i.e. build number)
267 2 : break;
268 : }
269 : }
270 : }
271 2 : *str = '\0'; // remove extra stuff
272 :
273 2 : if(verbose)
274 : {
275 0 : printf("changelog version: %s\n", debian_version);
276 : }
277 :
278 2 : 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 2 : free(filename);
285 : }
286 :
287 :
288 :
289 2 : int main(int argc, char *argv[])
290 : {
291 2 : const char *version = tld_version();
292 2 : char *path = (char *) 0;
293 : int i;
294 :
295 4 : for(i = 1; i < argc; ++i)
296 : {
297 2 : if(strcmp(argv[i], "-v") == 0)
298 : {
299 0 : verbose = 1;
300 : }
301 : else
302 : {
303 2 : path = argv[i];
304 : }
305 : }
306 :
307 2 : 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 2 : if(verbose)
315 : {
316 0 : printf("runtime libtld version: %s\n", version);
317 : }
318 : else
319 : {
320 2 : printf("%s\n", version);
321 : }
322 :
323 2 : check_version_compiled_with(version);
324 : //check_main_cmakefiles_txt(path, version);
325 : //check_libtld_only_cmakefiles_txt(path, version);
326 2 : check_changelog(path, version);
327 : }
328 :
329 2 : exit(err_count ? 1 : 0);
330 : }
331 :
332 : /* vim: ts=4 sw=4 et
333 : */
334 :
|