LCOV - code coverage report
Current view: top level - tests - tld_test_versions.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 62.5 % 80 50
Test Date: 2025-07-17 21:03:15 Functions: 100.0 % 3 3
Legend: Lines: hit not hit

            Line data    Source code
       1              : /* TLD library -- test the TLD version in all files
       2              :  * Copyright (c) 2011-2023  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           32 :     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              : 
        

Generated by: LCOV version 2.0-1

Snap C++ | List of projects | List of versions