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 }