libmicrohttpd2

HTTP server C library (MHD 2.x, alpha)
Log | Files | Refs | README | LICENSE

test_lib_info_version.c (10518B)


      1 /* SPDX-License-Identifier: LGPL-2.1-or-later OR (GPL-2.0-or-later WITH eCos-exception-2.0) */
      2 /*
      3   This file is part of GNU libmicrohttpd.
      4   Copyright (C) 2023-2025 Evgeny Grin (Karlson2k)
      5 
      6   GNU libmicrohttpd is free software; you can redistribute it and/or
      7   modify it under the terms of the GNU Lesser General Public
      8   License as published by the Free Software Foundation; either
      9   version 2.1 of the License, or (at your option) any later version.
     10 
     11   GNU libmicrohttpd is distributed in the hope that it will be useful,
     12   but WITHOUT ANY WARRANTY; without even the implied warranty of
     13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14   Lesser General Public License for more details.
     15 
     16   Alternatively, you can redistribute GNU libmicrohttpd and/or
     17   modify it under the terms of the GNU General Public License as
     18   published by the Free Software Foundation; either version 2 of
     19   the License, or (at your option) any later version, together
     20   with the eCos exception, as follows:
     21 
     22     As a special exception, if other files instantiate templates or
     23     use macros or inline functions from this file, or you compile this
     24     file and link it with other works to produce a work based on this
     25     file, this file does not by itself cause the resulting work to be
     26     covered by the GNU General Public License. However the source code
     27     for this file must still be made available in accordance with
     28     section (3) of the GNU General Public License v2.
     29 
     30     This exception does not invalidate any other reasons why a work
     31     based on this file might be covered by the GNU General Public
     32     License.
     33 
     34   You should have received copies of the GNU Lesser General Public
     35   License and the GNU General Public License along with this library;
     36   if not, see <https://www.gnu.org/licenses/>.
     37 */
     38 
     39 /**
     40  * @file test_lib_info_version.c
     41  * @brief  test for getting version info by MHD_lib_get_info_fixed_sz()
     42  * @author Karlson2k (Evgeny Grin)
     43  */
     44 #include "mhd_sys_options.h"
     45 #include <stdio.h>
     46 #include <stdlib.h>
     47 #include <string.h>
     48 #include <stdint.h>
     49 #include "microhttpd2.h"
     50 
     51 /* Helpers */
     52 
     53 static void
     54 flush_std_all (void)
     55 {
     56   fflush (stdout);
     57   fflush (stderr);
     58 }
     59 
     60 
     61 #define ERR_PRINT_LINE() \
     62         ((void) fprintf (stderr, "At the line number %u: ", \
     63                          (unsigned) __LINE__))
     64 
     65 /* 1 = success, 0 = failure */
     66 static int
     67 tst_EXPECT_OK_helper (enum MHD_StatusCode code,
     68                       unsigned long line_num,
     69                       const char *expression)
     70 {
     71   if (MHD_SC_OK == code)
     72     return 1;
     73 
     74   fflush (stdout);
     75   (void) fprintf (stderr,
     76                   "At the line number %lu: "
     77                   "MHD function failed: \n"
     78                   "\"%s\"\n returned %lu.\n",
     79                   line_num,
     80                   expression,
     81                   (unsigned long) code);
     82   flush_std_all ();
     83   return 0;
     84 }
     85 
     86 
     87 /**
     88  * Check whether SC code is OK, print error if not.
     89  * @warning Do not use function call in the argument
     90  * @param sc the status code to check
     91  * @return one if succeed,
     92  *         zero if failed
     93  */
     94 #define tst_EXPECT_OK(mhd_func_call) \
     95         (tst_EXPECT_OK_helper ((mhd_func_call), __LINE__, #mhd_func_call))
     96 
     97 
     98 /* The test */
     99 
    100 
    101 #ifdef PACKAGE_VERSION
    102 static const char str_macro_pkg_ver[] = PACKAGE_VERSION;
    103 #else  /* ! PACKAGE_VERSION */
    104 static const char str_macro_pkg_ver[] = "error!";
    105 #error No PACKAGE_VERSION defined
    106 #endif /* ! PACKAGE_VERSION */
    107 
    108 #ifdef VERSION
    109 static const char str_macro_ver[] = VERSION;
    110 #else  /* ! VERSION */
    111 static const char str_macro_ver[] = "error!";
    112 #error No PACKAGE_VERSION defined
    113 #endif /* ! VERSION */
    114 
    115 #ifdef MHD_VERSION
    116 static const uint_fast32_t bin_macro = (uint_fast32_t) (MHD_VERSION);
    117 #else  /* ! MHD_VERSION */
    118 static const uint_fast32_t bin_macro = 0;
    119 #error MHD_VERSION is not defined
    120 #endif /* ! MHD_VERSION */
    121 
    122 /* 0 = success, 1 = error */
    123 static int
    124 test_macro1_vs_macro2_str (void)
    125 {
    126   printf ("Checking PACKAGE_VERSION macro vs VERSION macro.\n");
    127   if (0 != strcmp (str_macro_pkg_ver, str_macro_ver))
    128   {
    129     fflush (stdout);
    130     fprintf (stderr, "'%s' vs '%s' - FAILED.\n",
    131              str_macro_pkg_ver, str_macro_ver);
    132     return 1;
    133   }
    134   printf ("'%s' vs '%s' - success.\n",
    135           str_macro_pkg_ver, str_macro_ver);
    136   return 0;
    137 }
    138 
    139 
    140 /* 0 = success, 1 = error */
    141 static int
    142 test_macro2_vs_func_str (void)
    143 {
    144   union MHD_LibInfoFixedData info_data;
    145 
    146   if (! tst_EXPECT_OK (MHD_lib_get_info_fixed ( \
    147                          MHD_LIB_INFO_FIXED_VERSION_STRING, \
    148                          &info_data)))
    149     return 1;
    150 
    151   printf ("Checking VERSION macro vs "
    152           "MHD_lib_get_info_fixed (MHD_LIB_INFO_FIXED_VERSION_STR) "
    153           "function.\n");
    154   if (NULL == info_data.v_version_string.cstr)
    155   {
    156     fflush (stdout);
    157     fprintf (stderr, "info_data.v_string.cstr is NULL.\n");
    158     return 1;
    159   }
    160   if (0 != strcmp (str_macro_ver, info_data.v_version_string.cstr))
    161   {
    162     fflush (stdout);
    163     fprintf (stderr, "'%s' vs '%s' - FAILED.\n",
    164              str_macro_ver, info_data.v_version_string.cstr);
    165     return 1;
    166   }
    167   printf ("'%s' vs '%s' - success.\n",
    168           str_macro_ver, info_data.v_version_string.cstr);
    169   return 0;
    170 }
    171 
    172 
    173 /* 0 = success, 1 = error */
    174 static int
    175 test_func_str_vs_macro_bin (void)
    176 {
    177   char bin_print[64];
    178   int res;
    179   union MHD_LibInfoFixedData info_data;
    180 
    181   if (! tst_EXPECT_OK (MHD_lib_get_info_fixed ( \
    182                          MHD_LIB_INFO_FIXED_VERSION_STRING, \
    183                          &info_data)))
    184     return 1;
    185 
    186   printf ("Checking MHD_lib_get_info_fixed(MHD_LIB_INFO_FIXED_VERSION_STR) " \
    187           "function vs MHD_VERSION macro.\n");
    188 #ifdef HAVE_SNPRINTF
    189   res = snprintf (bin_print, sizeof(bin_print), "%X.%X.%X",
    190                   (unsigned int) ((bin_macro >> 24) & 0xFF),
    191                   (unsigned int) ((bin_macro >> 16) & 0xFF),
    192                   (unsigned int) ((bin_macro >> 8) & 0xFF));
    193 #else  /* ! HAVE_SNPRINTF */
    194   res = sprintf (bin_print, "%X.%X.%X",
    195                  (unsigned int) ((bin_macro >> 24) & 0xFF),
    196                  (unsigned int) ((bin_macro >> 16) & 0xFF),
    197                  (unsigned int) ((bin_macro >> 8) & 0xFF));
    198 #endif /* ! HAVE_SNPRINTF */
    199   if ((9 < res) || (0 >= res))
    200   {
    201     fflush (stdout);
    202     fprintf (stderr, "snprintf() error.\n");
    203     exit (99);
    204   }
    205 
    206   if (0 != strcmp (info_data.v_version_string.cstr, bin_print))
    207   {
    208     fflush (stdout);
    209     fprintf (stderr, "'%s' vs '0x%08lX' ('%s') - FAILED.\n",
    210              info_data.v_version_string.cstr,
    211              (unsigned long) bin_macro,
    212              bin_print);
    213     return 1;
    214   }
    215   printf ("'%s' vs '0x%08lX' ('%s') - success.\n",
    216           info_data.v_version_string.cstr,
    217           (unsigned long) bin_macro,
    218           bin_print);
    219   return 0;
    220 }
    221 
    222 
    223 /* 0 = success, 1 = error */
    224 static int
    225 test_macro_vs_func_bin (void)
    226 {
    227   const uint_fast32_t bin_func = MHD_lib_get_info_ver_num ();
    228 
    229   printf ("Checking MHD_VERSION macro vs "
    230           "MHD_lib_get_info_ver_num() function.\n");
    231   if (bin_macro != bin_func)
    232   {
    233     fflush (stdout);
    234     fprintf (stderr, "'0x%08lX' vs '0x%08lX' - FAILED.\n",
    235              (unsigned long) bin_macro, (unsigned long) bin_func);
    236     return 1;
    237   }
    238   printf ("'0x%08lX' vs '0x%08lX' - success.\n",
    239           (unsigned long) bin_macro, (unsigned long) bin_func);
    240   return 0;
    241 }
    242 
    243 
    244 /* 0 = success, 1 = error */
    245 static int
    246 test_func_bin_format (void)
    247 {
    248   const uint_fast32_t bin_func = MHD_lib_get_info_ver_num ();
    249   unsigned int test_byte;
    250   int ret = 0;
    251   printf ("Checking format of MHD_lib_get_info_ver_num() "
    252           "function return value.\n");
    253   test_byte = (unsigned int) ((bin_func >> 24) & 0xFF);
    254   if ((0xA <= (test_byte & 0xF))
    255       || (0xA <= (test_byte >> 4)))
    256   {
    257     fflush (stdout);
    258     fprintf (stderr,
    259              "Invalid value in the first (most significant) byte: %02X\n",
    260              test_byte);
    261     ret = 1;
    262   }
    263   test_byte = (unsigned int) ((bin_func >> 16) & 0xFF);
    264   if ((0xA <= (test_byte & 0xF))
    265       || (0xA <= (test_byte >> 4)))
    266   {
    267     fflush (stdout);
    268     fprintf (stderr,
    269              "Invalid value in the second byte: %02X\n",
    270              test_byte);
    271     ret = 1;
    272   }
    273   test_byte = (unsigned int) ((bin_func >> 8) & 0xFF);
    274   if ((0xA <= (test_byte & 0xF))
    275       || (0xA <= (test_byte >> 4)))
    276   {
    277     fflush (stdout);
    278     fprintf (stderr,
    279              "Invalid value in the third byte: %02X\n",
    280              test_byte);
    281     ret = 1;
    282   }
    283   if (0 != ret)
    284   {
    285     fflush (stdout);
    286     fprintf (stderr,
    287              "The value (0x%08lX) returned by MHD_get_version_bin() "
    288              "function is invalid as it cannot be used as packed BCD form "
    289              "(its hexadecimal representation has at least one digit in "
    290              "A-F range).\n",
    291              (unsigned long) bin_func);
    292     return 1;
    293   }
    294   printf ("'0x%08lX' - success.\n", (unsigned long) bin_func);
    295   return 0;
    296 }
    297 
    298 
    299 /* 0 = success, 1 = error */
    300 static int
    301 test_func_str_format (void)
    302 {
    303   size_t ver_len;
    304   union MHD_LibInfoFixedData info_data;
    305 
    306   if (! tst_EXPECT_OK (MHD_lib_get_info_fixed ( \
    307                          MHD_LIB_INFO_FIXED_VERSION_STRING, \
    308                          &info_data)))
    309     return 1;
    310 
    311   printf ("Checking MHD_lib_get_info_fixed(MHD_LIB_INFO_FIXED_VERSION_STR) " \
    312           "function resulting value format.\n");
    313   ver_len = strlen (info_data.v_version_string.cstr);
    314 
    315   if (ver_len != info_data.v_version_string.len)
    316   {
    317     fflush (stdout);
    318     fprintf (stderr,
    319              "strlen(info_data.v_string.cstr) ('%lu') != "
    320              "info_data.v_string.len ('%lu') - FAILED.\n",
    321              (unsigned long) ver_len,
    322              (unsigned long) info_data.v_version_string.len);
    323     return 1;
    324   }
    325   printf ("strlen(info_data.v_string.cstr) ('%lu') == "
    326           "info_data.v_string.len ('%lu') - success.\n",
    327           (unsigned long) ver_len,
    328           (unsigned long) info_data.v_version_string.len);
    329   return 0;
    330 }
    331 
    332 
    333 int
    334 main (int argc, char *argv[])
    335 {
    336   int num_err;
    337 
    338   (void) argc; (void) argv; /* Unused. Silence compiler warning. */
    339 
    340   num_err = test_macro1_vs_macro2_str ();
    341   flush_std_all ();
    342   num_err += test_macro2_vs_func_str ();
    343   flush_std_all ();
    344   num_err += test_func_str_format ();
    345   flush_std_all ();
    346   num_err += test_func_str_vs_macro_bin ();
    347   flush_std_all ();
    348   num_err += test_macro_vs_func_bin ();
    349   flush_std_all ();
    350   num_err += test_func_bin_format ();
    351   flush_std_all ();
    352 
    353   if (0 != num_err)
    354   {
    355     fflush (stdout);
    356     fprintf (stderr, "Number of failed checks: %d\n", num_err);
    357     return 2;
    358   }
    359   printf ("All checks succeed.\n");
    360   return 0;
    361 }