@@ -2426,6 +2426,234 @@ static int test_mp_pack_unpack(void)
24262426 return EXIT_FAILURE ;
24272427}
24282428
2429+ #ifndef MP_NO_FILE
2430+
2431+ #define LTM_TEST_BUFSIZ 4096
2432+ #include <string.h>
2433+ static int test_mp_fprintf (void )
2434+ {
2435+ FILE * test_file = NULL ;
2436+
2437+ char line_buffer [LTM_TEST_BUFSIZ ] = {0 };
2438+ int i ;
2439+ bool write_only = false;
2440+ size_t slen = 0 ;
2441+ int characters_printed = 0 ;
2442+ char * fgets_return ;
2443+
2444+ const char * test_values [2 ] = {
2445+ "4DDCFDE0D20EF8663B34D19F829FDD" ,
2446+ "-51D9769BDAE5B38121F2A31D881E5F"
2447+ };
2448+
2449+ const char * test_strings [] = {
2450+ #ifdef LTM_HAVE_FLOAT_TYPE
2451+ "START 0x0000007b 123.123 -424986725583297217766029037085924959 0x4DDCFDE0D20EF8663B34D19F829FDD END\n" ,
2452+ #endif
2453+ "START -0b10100011101100101110110100110111101101011100101101100111000000100100001111100101010001100011101100010000001111001011111 END\n" ,
2454+ "START @ -KTbsczhbiu4XygCTY1vV @ END\n" ,
2455+ #if (MP_DIGIT_BIT == 60 )
2456+ "START 0x63b34d19f829fdd,0x4ddcfde0d20ef86 END\n" ,
2457+ #elif (MP_DIGIT_BIT == 31 )
2458+ "START 0x1f829fdd,0x4c7669a3,0x3483be1,0x26ee7ef END\n" ,
2459+ #elif (MP_DIGIT_BIT == 28 )
2460+ "START 0xf829fdd,0x3b34d19,0x20ef866,0xdcfde0d,0x4d END\n" ,
2461+ #elif (MP_DIGIT_BIT == 15 )
2462+ "START 0x1fdd,0x3f05,0x5346,0x31d9,0x6f86,0x1a41,0x3f78,0x26ee END\n" ,
2463+ #else
2464+ "undefined limb size\n" ,
2465+ #endif
2466+
2467+
2468+ #if (MP_DIGIT_BIT == 60 )
2469+ "START 0x000000000000063b34d19f829fdd END\n"
2470+ #elif (MP_DIGIT_BIT == 31 )
2471+ "START 0x000000000000000000001f829fdd END\n"
2472+ #elif (MP_DIGIT_BIT == 28 )
2473+ "START 0x000000000000000000000f829fdd END\n"
2474+ #elif (MP_DIGIT_BIT == 15 )
2475+ "START 0x0000000000000000000000001fdd END\n"
2476+ #else
2477+ "undefined limb size\n"
2478+ #endif
2479+ };
2480+
2481+ mp_int p , q ;
2482+ int n ;
2483+ /* Only stream printing available, no mp_sprintf or the like. File needs a path for repeated truncating */
2484+ test_file = fopen ("ltm_testing_mp_fprintf_88a43603fcfc2f7e7c6646cd4b89180a" , "w+" );
2485+ if (test_file == NULL ) {
2486+ /* use logfile instead to have at least sth. in case of an error */
2487+ test_file = stdout ;
2488+ write_only = true;
2489+ }
2490+
2491+ DOR (mp_init_multi (& p , & q , NULL ));
2492+
2493+ DO (mp_read_radix (& p , test_values [0 ], 16 ));
2494+ DO (mp_read_radix (& q , test_values [1 ], 16 ));
2495+
2496+ /* No loop here, too much hassle */
2497+ i = 0 ;
2498+ /* Defined by CMake and is not in any of the generic Makefiles */
2499+ #ifdef LTM_HAVE_FLOAT_TYPE
2500+ characters_printed = mp_fprintf (test_file , "START %#010x %12.12g %10Zd %#10Zx END\n" ,123 ,123.123 ,& q ,& p ,& q );
2501+ slen = strlen (test_strings [i ]);
2502+ if ((characters_printed - (int )slen ) != 0 ) {
2503+ fprintf (stderr , "0 test_mp_fprintf: failed to print o:%zu t:%d\n" , slen , characters_printed );
2504+ goto LBL_ERR ;
2505+ }
2506+ if (!write_only ) {
2507+ rewind (test_file );
2508+ fgets_return = fgets (line_buffer , LTM_TEST_BUFSIZ , test_file );
2509+ if (fgets_return == NULL ) {
2510+ fprintf (stderr , "1 test_mp_fprintf: failed to read from file\n" );
2511+ goto LBL_ERR ;
2512+ }
2513+ if (strcmp (line_buffer , test_strings [i ]) != 0 ) {
2514+ fprintf (stderr , "test_mp_fprintf: file content is not equal to test string #%d\n" ,i );
2515+ goto LBL_ERR ;
2516+ }
2517+ }
2518+ i ++ ;
2519+ /* Clear file content */
2520+ test_file = freopen ("ltm_testing_mp_fprintf_88a43603fcfc2f7e7c6646cd4b89180a" ,"w+" , test_file );
2521+ if (test_file == NULL ) {
2522+ /* use logfile instead to have at least sth. in case of an error */
2523+ test_file = stdout ;
2524+ write_only = true;
2525+ }
2526+ #endif
2527+
2528+ characters_printed = mp_fprintf (test_file , "START %#Zb END\n" ,& q );
2529+ slen = strlen (test_strings [i ]);
2530+ if ((characters_printed - (int )slen ) != 0 ) {
2531+ fprintf (stderr , "1 test_mp_fprintf: failed to print o:%zu t:%d\n" , slen , characters_printed );
2532+ goto LBL_ERR ;
2533+ }
2534+ if (!write_only ) {
2535+ rewind (test_file );
2536+ fgets_return = fgets (line_buffer , LTM_TEST_BUFSIZ , test_file );
2537+ if (fgets_return == NULL ) {
2538+ fprintf (stderr , "test_mp_fprintf: failed to read from file\n" );
2539+ goto LBL_ERR ;
2540+ }
2541+ if (strcmp (line_buffer , test_strings [i ]) != 0 ) {
2542+ fprintf (stderr , "test_mp_fprintf: file content is not equal to test string #%d\n" ,i );
2543+ goto LBL_ERR ;
2544+ }
2545+ }
2546+ i ++ ;
2547+ /* Clear file content */
2548+ test_file = freopen ("ltm_testing_mp_fprintf_88a43603fcfc2f7e7c6646cd4b89180a" ,"w+" , test_file );
2549+ if (test_file == NULL ) {
2550+ /* use logfile instead to have at least sth. in case of an error */
2551+ test_file = stdout ;
2552+ write_only = true;
2553+ }
2554+
2555+ characters_printed = mp_fprintf (test_file , "START @ %#Z@ @ END\n" ,& q );
2556+ slen = strlen (test_strings [i ]);
2557+ if ((characters_printed - (int )slen ) != 0 ) {
2558+ fprintf (stderr , "1 test_mp_fprintf: failed to print o:%zu t:%d\n" , slen , characters_printed );
2559+ goto LBL_ERR ;
2560+ }
2561+ if (!write_only ) {
2562+ rewind (test_file );
2563+ fgets_return = fgets (line_buffer , LTM_TEST_BUFSIZ , test_file );
2564+ if (fgets_return == NULL ) {
2565+ fprintf (stderr , "test_mp_fprintf: failed to read from file\n" );
2566+ goto LBL_ERR ;
2567+ }
2568+ if (strcmp (line_buffer , test_strings [i ]) != 0 ) {
2569+ fprintf (stderr , "test_mp_fprintf: file content is not equal to test string #%d\n" ,i );
2570+ goto LBL_ERR ;
2571+ }
2572+ }
2573+ i ++ ;
2574+ /* Clear file content */
2575+ test_file = freopen ("ltm_testing_mp_fprintf_88a43603fcfc2f7e7c6646cd4b89180a" ,"w+" , test_file );
2576+ if (test_file == NULL ) {
2577+ /* use logfile instead to have at least sth. in case of an error */
2578+ test_file = stdout ;
2579+ write_only = true;
2580+ }
2581+
2582+ /* TODO: add entries for the smaller mp_digits */
2583+ characters_printed = mp_fprintf (test_file ,"START %#Nx END\n" ,& p );
2584+ slen = strlen (test_strings [i ]);
2585+ if ((characters_printed - (int )slen ) != 0 ) {
2586+ fprintf (stderr , "2 test_mp_fprintf: failed to print o:%zu t:%d\n" , slen , characters_printed );
2587+ goto LBL_ERR ;
2588+ }
2589+ if (!write_only ) {
2590+ rewind (test_file );
2591+ fgets_return = fgets (line_buffer , LTM_TEST_BUFSIZ , test_file );
2592+ if (fgets_return == NULL ) {
2593+ fprintf (stderr , "test_mp_fprintf: failed to read from file\n" );
2594+ goto LBL_ERR ;
2595+ }
2596+ if (strcmp (line_buffer , test_strings [i ]) != 0 ) {
2597+ fprintf (stderr , "test_mp_fprintf: file content is not equal to test string #%d\n" ,i );
2598+ goto LBL_ERR ;
2599+ }
2600+ }
2601+ i ++ ;
2602+ /* Clear file content */
2603+ test_file = freopen ("ltm_testing_mp_fprintf_88a43603fcfc2f7e7c6646cd4b89180a" ,"w+" , test_file );
2604+ if (test_file == NULL ) {
2605+ /* use logfile instead to have at least sth. in case of an error */
2606+ test_file = stdout ;
2607+ write_only = true;
2608+ }
2609+
2610+ characters_printed = mp_fprintf (test_file ,"START %0#30Mx END\n" ,p .dp [0 ]);
2611+ slen = strlen (test_strings [i ]);
2612+ if ((characters_printed - (int )slen ) != 0 ) {
2613+ fprintf (stderr , "3 test_mp_fprintf: failed to print o:%zu t:%d\n" , slen , characters_printed );
2614+ goto LBL_ERR ;
2615+ }
2616+ if (!write_only ) {
2617+ rewind (test_file );
2618+ fgets_return = fgets (line_buffer , LTM_TEST_BUFSIZ , test_file );
2619+ if (fgets_return == NULL ) {
2620+ fprintf (stderr , "test_mp_fprintf: failed to read from file\n" );
2621+ goto LBL_ERR ;
2622+ }
2623+ if (strcmp (line_buffer , test_strings [i ]) != 0 ) {
2624+ fprintf (stderr , "test_mp_fprintf: file content is not equal to test string #%d\n" ,i );
2625+ goto LBL_ERR ;
2626+ }
2627+ }
2628+
2629+ /* It's more or less implementation defined but must be the same. */
2630+ characters_printed = mp_fprintf (stdout ,"START %p END\n" ,& p );
2631+ i = fprintf (stdout ,"START %p END\n" ,& p );
2632+ if ((characters_printed - i ) != 0 ) {
2633+ fprintf (stderr , "test_mp_fprintf: failed to print pointer\n" );
2634+ goto LBL_ERR ;
2635+ }
2636+
2637+ characters_printed = mp_fprintf (stdout ,"START %n END\n" ,& n );
2638+ if (n != 6 ) {
2639+ fprintf (stderr , "test_mp_fprintf: failed to count 6 characters properly\n" );
2640+ goto LBL_ERR ;
2641+ }
2642+
2643+ mp_clear_multi (& p , & q , NULL );
2644+ fclose (test_file );
2645+ if (remove ("ltm_testing_mp_fprintf_88a43603fcfc2f7e7c6646cd4b89180a" ) != 0 ) {
2646+ fprintf (stderr , "Could not delete file ltm_testing_mp_fprintf_88a43603fcfc2f7e7c6646cd4b89180a\n" );
2647+ }
2648+ return EXIT_SUCCESS ;
2649+ LBL_ERR :
2650+ mp_clear_multi (& p , & q , NULL );
2651+ fclose (test_file );
2652+ /* We don't delete the testfile in case of error, conrtent might be helpful. */
2653+ return EXIT_FAILURE ;
2654+ }
2655+ #endif
2656+
24292657#ifndef LTM_TEST_DYNAMIC
24302658#define ONLY_PUBLIC_API_C
24312659#endif
@@ -2453,6 +2681,7 @@ static int unit_tests(int argc, char **argv)
24532681 T1 (mp_dr_reduce , MP_DR_REDUCE ),
24542682 T2 (mp_pack_unpack ,MP_PACK , MP_UNPACK ),
24552683 T2 (mp_fread_fwrite , MP_FREAD , MP_FWRITE ),
2684+ T1 (mp_fprintf , S_MP_FPRINTF ),
24562685 T1 (mp_get_u32 , MP_GET_I32 ),
24572686 T1 (mp_get_u64 , MP_GET_I64 ),
24582687 T1 (mp_get_ul , MP_GET_L ),
0 commit comments