1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /********************************************************************
5 * Copyright (c) 1997-2015, International Business Machines Corporation and
6 * others. All Rights Reserved.
7 ********************************************************************/
8 /********************************************************************************
12 * Modification History:
14 * Madhu Katragadda Creation
15 *********************************************************************************
18 /*The main root for C API tests*/
23 #include "unicode/utypes.h"
24 #include "unicode/putil.h"
29 #include "unicode/uchar.h"
30 #include "unicode/ustring.h"
31 #include "unicode/ucnv.h"
32 #include "unicode/ures.h"
33 #include "unicode/uclean.h"
34 #include "unicode/ucal.h"
36 #include "putilimp.h" /* for uprv_getRawUTCtime() */
38 #include "uresimp.h" /* for ures_dumpCacheContents() */
45 #define CTST_MAX_ALLOC 8192
46 /* Array used as a queue */
47 static void * ctst_allocated_stuff
[CTST_MAX_ALLOC
] = {0};
48 static int ctst_allocated
= 0;
49 static UBool ctst_free
= FALSE
;
50 static int ctst_allocated_total
= 0;
52 #define CTST_LEAK_CHECK 1
54 #ifdef CTST_LEAK_CHECK
55 static void ctst_freeAll(void);
58 static char* _testDataPath
=NULL
;
61 * Forward Declarations
63 void ctest_setICU_DATA(void);
67 #if UCONFIG_NO_LEGACY_CONVERSION
68 # define TRY_CNV_1 "iso-8859-1"
69 # define TRY_CNV_2 "ibm-1208"
71 # define TRY_CNV_1 "iso-8859-7"
72 # define TRY_CNV_2 "sjis"
76 static const char* const * gOrigArgv
;
78 #ifdef UNISTR_COUNT_FINAL_STRING_LENGTHS
79 U_CAPI
void unistr_printLengths();
82 int main(int argc
, const char* const argv
[])
85 UBool defaultDataFound
;
87 const char *warnOrErr
= "Failure";
88 UDate startTime
, endTime
;
91 /* initial check for the default converter */
92 UErrorCode errorCode
= U_ZERO_ERROR
;
96 U_MAIN_INIT_ARGS(argc
, argv
);
98 startTime
= uprv_getRawUTCtime();
102 if (!initArgs(argc
, argv
, NULL
, NULL
)) {
103 /* Error already displayed. */
107 /* Check whether ICU will initialize without forcing the build data directory into
108 * the ICU_DATA path. Success here means either the data dll contains data, or that
109 * this test program was run with ICU_DATA set externally. Failure of this check
110 * is normal when ICU data is not packaged into a shared library.
112 * Whether or not this test succeeds, we want to cleanup and reinitialize
113 * with a data path so that data loading from individual files can be tested.
115 defaultDataFound
= TRUE
;
117 if (U_FAILURE(errorCode
)) {
119 "#### Note: ICU Init without build-specific setDataDirectory() failed. %s\n", u_errorName(errorCode
));
120 defaultDataFound
= FALSE
;
124 fprintf(stderr
, "After initial u_cleanup: RB cache %s empty.\n", ures_dumpCacheContents()?"WAS NOT":"was");
127 while (getTestOption(REPEAT_TESTS_OPTION
) > 0) { /* Loop runs once per complete execution of the tests
128 * used for -r (repeat) test option. */
129 if (!initArgs(argc
, argv
, NULL
, NULL
)) {
130 /* Error already displayed. */
133 errorCode
= U_ZERO_ERROR
;
136 if (!defaultDataFound
) {
137 ctest_setICU_DATA(); /* u_setDataDirectory() must happen Before u_init() */
140 if (U_FAILURE(errorCode
)) {
142 "#### ERROR! %s: u_init() failed with status = \"%s\".\n"
143 "*** Check the ICU_DATA environment variable and \n"
144 "*** check that the data files are present.\n", argv
[0], u_errorName(errorCode
));
145 if(!getTestOption(WARN_ON_MISSING_DATA_OPTION
)) {
146 fprintf(stderr
, "*** Exiting. Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n");
155 cnv
= ucnv_open(TRY_CNV_2
, &errorCode
);
161 "*** %s! The converter for " TRY_CNV_2
" cannot be opened.\n"
162 "*** Check the ICU_DATA environment variable and \n"
163 "*** check that the data files are present.\n", warnOrErr
);
164 if(!getTestOption(WARN_ON_MISSING_DATA_OPTION
)) {
165 fprintf(stderr
, "*** Exitting. Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n");
171 rb
= ures_open(NULL
, "en", &errorCode
);
172 if(U_SUCCESS(errorCode
)) {
177 "*** %s! The \"en\" locale resource bundle cannot be opened.\n"
178 "*** Check the ICU_DATA environment variable and \n"
179 "*** check that the data files are present.\n", warnOrErr
);
180 if(!getTestOption(WARN_ON_MISSING_DATA_OPTION
)) {
181 fprintf(stderr
, "*** Exitting. Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n");
187 errorCode
= U_ZERO_ERROR
;
188 rb
= ures_open(NULL
, NULL
, &errorCode
);
189 if(U_SUCCESS(errorCode
)) {
191 if (errorCode
== U_USING_DEFAULT_WARNING
|| errorCode
== U_USING_FALLBACK_WARNING
) {
193 "#### Note: The default locale %s is not available\n", uloc_getDefault());
198 "*** %s! Can not open a resource bundle for the default locale %s\n", warnOrErr
, uloc_getDefault());
199 if(!getTestOption(WARN_ON_MISSING_DATA_OPTION
)) {
200 fprintf(stderr
, "*** Exitting. Use the '-w' option if data files were\n"
201 "*** purposely removed, to continue test anyway.\n");
206 fprintf(stdout
, "Default locale for this run is %s\n", uloc_getDefault());
208 /* Build a tree of all tests.
209 * Subsequently will be used to find / iterate the tests to run */
213 /* Tests acutally run HERE. TODO: separate command line option parsing & setting from test execution!! */
214 nerrors
= runTestRequest(root
, argc
, argv
);
216 setTestOption(REPEAT_TESTS_OPTION
, DECREMENT_OPTION_VALUE
);
217 if (getTestOption(REPEAT_TESTS_OPTION
) > 0) {
218 printf("Repeating tests %d more time(s)\n", getTestOption(REPEAT_TESTS_OPTION
));
220 cleanUpTestTree(root
);
222 #ifdef CTST_LEAK_CHECK
224 /* To check for leaks */
225 u_cleanup(); /* nuke the hashtable.. so that any still-open cnvs are leaked */
227 if(getTestOption(VERBOSITY_OPTION
) && ctst_allocated_total
>0) {
228 fprintf(stderr
,"ctst_freeAll(): cleaned up after %d allocations (queue of %d)\n", ctst_allocated_total
, CTST_MAX_ALLOC
);
231 if(ures_dumpCacheContents()) {
232 fprintf(stderr
, "Error: After final u_cleanup, RB cache was not empty.\n");
235 fprintf(stderr
,"OK: After final u_cleanup, RB cache was empty.\n");
240 } /* End of loop that repeats the entire test, if requested. (Normally doesn't loop) */
242 #ifdef UNISTR_COUNT_FINAL_STRING_LENGTHS
243 unistr_printLengths();
246 endTime
= uprv_getRawUTCtime();
247 diffTime
= (int32_t)(endTime
- startTime
);
248 printf("Elapsed Time: %02d:%02d:%02d.%03d\n",
249 (int)((diffTime%U_MILLIS_PER_DAY
)/U_MILLIS_PER_HOUR
),
250 (int)((diffTime%U_MILLIS_PER_HOUR
)/U_MILLIS_PER_MINUTE
),
251 (int)((diffTime%U_MILLIS_PER_MINUTE
)/U_MILLIS_PER_SECOND
),
252 (int)(diffTime%U_MILLIS_PER_SECOND
));
254 return nerrors
? 1 : 0;
258 static void ctest_appendToDataDirectory(const char *toAppend)
260 const char *oldPath ="";
262 char *newPath = newBuf;
266 if((toAppend == NULL) || (*toAppend == 0)) {
270 oldPath = u_getDataDirectory();
271 if( (oldPath==NULL) || (*oldPath == 0)) {
272 u_setDataDirectory(toAppend);
274 oldLen = strlen(oldPath);
275 newLen = strlen(toAppend)+1+oldLen;
279 newPath = (char *)ctst_malloc(newLen);
282 strcpy(newPath, oldPath);
283 strcpy(newPath+oldLen, U_PATH_SEP_STRING);
284 strcpy(newPath+oldLen+1, toAppend);
286 u_setDataDirectory(newPath);
288 if(newPath != newBuf)
296 /* returns the path to icu/source/data */
297 const char * ctest_dataSrcDir()
299 static const char *dataSrcDir
= NULL
;
305 /* U_TOPSRCDIR is set by the makefiles on UNIXes when building cintltst and intltst
306 // to point to the top of the build hierarchy, which may or
307 // may not be the same as the source directory, depending on
308 // the configure options used. At any rate,
309 // set the data path to the built data from this directory.
310 // The value is complete with quotes, so it can be used
311 // as-is as a string constant.
313 #if defined (U_TOPSRCDIR)
315 dataSrcDir
= U_TOPSRCDIR U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
;
319 /* On Windows, the file name obtained from __FILE__ includes a full path.
320 * This file is "wherever\icu\source\test\cintltst\cintltst.c"
321 * Change to "wherever\icu\source\data"
324 static char p
[sizeof(__FILE__
) + 20];
329 /* We want to back over three '\' chars. */
330 /* Only Windows should end up here, so looking for '\' is safe. */
331 for (i
=1; i
<=3; i
++) {
332 pBackSlash
= strrchr(p
, U_FILE_SEP_CHAR
);
333 if (pBackSlash
!= NULL
) {
334 *pBackSlash
= 0; /* Truncate the string at the '\' */
338 if (pBackSlash
!= NULL
) {
339 /* We found and truncated three names from the path.
340 * Now append "source\data" and set the environment
342 strcpy(pBackSlash
, U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
);
346 /* __FILE__ on MSVC7 does not contain the directory */
347 FILE *file
= fopen(".."U_FILE_SEP_STRING
".."U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
"Makefile.in", "r");
350 dataSrcDir
= ".."U_FILE_SEP_STRING
".."U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
;
353 dataSrcDir
= ".."U_FILE_SEP_STRING
".."U_FILE_SEP_STRING
".."U_FILE_SEP_STRING
".."U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
;
363 /* returns the path to icu/source/data/out */
364 const char *ctest_dataOutDir()
366 static const char *dataOutDir
= NULL
;
372 /* U_TOPBUILDDIR is set by the makefiles on UNIXes when building cintltst and intltst
373 // to point to the top of the build hierarchy, which may or
374 // may not be the same as the source directory, depending on
375 // the configure options used. At any rate,
376 // set the data path to the built data from this directory.
377 // The value is complete with quotes, so it can be used
378 // as-is as a string constant.
380 #if defined (U_TOPBUILDDIR)
382 dataOutDir
= U_TOPBUILDDIR
"data"U_FILE_SEP_STRING
"out"U_FILE_SEP_STRING
;
386 /* On Windows, the file name obtained from __FILE__ includes a full path.
387 * This file is "wherever\icu\source\test\cintltst\cintltst.c"
388 * Change to "wherever\icu\source\data"
391 static char p
[sizeof(__FILE__
) + 20];
396 /* We want to back over three '\' chars. */
397 /* Only Windows should end up here, so looking for '\' is safe. */
398 for (i
=1; i
<=3; i
++) {
399 pBackSlash
= strrchr(p
, U_FILE_SEP_CHAR
);
400 if (pBackSlash
!= NULL
) {
401 *pBackSlash
= 0; /* Truncate the string at the '\' */
405 if (pBackSlash
!= NULL
) {
406 /* We found and truncated three names from the path.
407 * Now append "source\data" and set the environment
409 strcpy(pBackSlash
, U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
);
413 /* __FILE__ on MSVC7 does not contain the directory */
414 FILE *file
= fopen(".."U_FILE_SEP_STRING
".."U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
"Makefile.in", "r");
417 dataOutDir
= ".."U_FILE_SEP_STRING
".."U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
;
420 dataOutDir
= ".."U_FILE_SEP_STRING
".."U_FILE_SEP_STRING
".."U_FILE_SEP_STRING
".."U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
;
429 /* ctest_setICU_DATA - if the ICU_DATA environment variable is not already
430 * set, try to deduce the directory in which ICU was built,
431 * and set ICU_DATA to "icu/source/data" in that location.
432 * The intent is to allow the tests to have a good chance
433 * of running without requiring that the user manually set
434 * ICU_DATA. Common data isn't a problem, since it is
435 * picked up via a static (build time) reference, but the
436 * tests dynamically load some data.
438 void ctest_setICU_DATA() {
440 /* No location for the data dir was identifiable.
441 * Add other fallbacks for the test data location here if the need arises
443 if (getenv("ICU_DATA") == NULL
) {
444 /* If ICU_DATA isn't set, set it to the usual location */
445 u_setDataDirectory(ctest_dataOutDir());
449 /* These tests do cleanup and reinitialize ICU in the course of their operation.
450 * The ICU data directory must be preserved across these operations.
451 * Here is a helper function to assist with that.
453 static char *safeGetICUDataDirectory() {
454 const char *dataDir
= u_getDataDirectory(); /* Returned string vanashes with u_cleanup */
456 if (dataDir
!= NULL
) {
457 retStr
= (char *)malloc(strlen(dataDir
)+1);
458 strcpy(retStr
, dataDir
);
463 UBool
ctest_resetICU() {
464 UErrorCode status
= U_ZERO_ERROR
;
465 char *dataDir
= safeGetICUDataDirectory();
468 if (!initArgs(gOrigArgc
, gOrigArgv
, NULL
, NULL
)) {
469 /* Error already displayed. */
472 u_setDataDirectory(dataDir
);
475 if (U_FAILURE(status
)) {
476 log_err_status(status
, "u_init failed with %s\n", u_errorName(status
));
482 UChar
* CharsToUChars(const char* str
) {
483 /* Might be faster to just use uprv_strlen() as the preflight len - liu */
484 int32_t len
= u_unescape(str
, 0, 0); /* preflight */
485 /* Do NOT use malloc() - we are supposed to be acting like user code! */
486 UChar
*buf
= (UChar
*) malloc(sizeof(UChar
) * (len
+ 1));
487 u_unescape(str
, buf
, len
+ 1);
491 char *austrdup(const UChar
* unichars
)
496 length
= u_strlen ( unichars
);
497 /*newString = (char*)malloc ( sizeof( char ) * 4 * ( length + 1 ) );*/ /* this leaks for now */
498 newString
= (char*)ctst_malloc ( sizeof( char ) * 4 * ( length
+ 1 ) ); /* this shouldn't */
500 if ( newString
== NULL
)
503 u_austrcpy ( newString
, unichars
);
508 char *aescstrdup(const UChar
* unichars
,int32_t length
){
509 char *newString
,*targetLimit
,*target
;
510 UConverterFromUCallback cb
;
512 UErrorCode errorCode
= U_ZERO_ERROR
;
513 #if U_CHARSET_FAMILY==U_EBCDIC_FAMILY
514 # if U_PLATFORM == U_PF_OS390
515 static const char convName
[] = "ibm-1047";
517 static const char convName
[] = "ibm-37";
520 static const char convName
[] = "US-ASCII";
522 UConverter
* conv
= ucnv_open(convName
, &errorCode
);
524 length
= u_strlen( unichars
);
526 newString
= (char*)ctst_malloc ( sizeof(char) * 8 * (length
+1));
528 targetLimit
= newString
+sizeof(char) * 8 * (length
+1);
529 ucnv_setFromUCallBack(conv
, UCNV_FROM_U_CALLBACK_ESCAPE
, UCNV_ESCAPE_C
, &cb
, &p
, &errorCode
);
530 ucnv_fromUnicode(conv
,&target
,targetLimit
, &unichars
, (UChar
*)(unichars
+length
),NULL
,TRUE
,&errorCode
);
536 const char* loadTestData(UErrorCode
* err
){
537 if( _testDataPath
== NULL
){
538 const char* directory
=NULL
;
539 UResourceBundle
* test
=NULL
;
541 const char* tdrelativepath
;
542 #if defined (U_TOPBUILDDIR)
543 #if defined (APPLE_XCODE_BUILD)
544 tdrelativepath
= "."U_FILE_SEP_STRING
;
545 directory
= U_TOPBUILDDIR
;
547 tdrelativepath
= "test"U_FILE_SEP_STRING
"testdata"U_FILE_SEP_STRING
"out"U_FILE_SEP_STRING
;
548 directory
= U_TOPBUILDDIR
;
549 #endif // APPLE_XCODE_BUILD
551 tdrelativepath
= ".."U_FILE_SEP_STRING
".."U_FILE_SEP_STRING
"test"U_FILE_SEP_STRING
"testdata"U_FILE_SEP_STRING
"out"U_FILE_SEP_STRING
;
552 directory
= ctest_dataOutDir();
553 #endif // U_TOPBUILDDIR
555 tdpath
= (char*) ctst_malloc(sizeof(char) *(( strlen(directory
) * strlen(tdrelativepath
)) + 10));
558 /* u_getDataDirectory shoul return \source\data ... set the
559 * directory to ..\source\data\..\test\testdata\out\testdata
561 * Fallback: When Memory mapped file is built
562 * ..\source\data\out\..\..\test\testdata\out\testdata
564 strcpy(tdpath
, directory
);
565 strcat(tdpath
, tdrelativepath
);
566 strcat(tdpath
,"testdata");
569 test
=ures_open(tdpath
, "testtypes", err
);
571 /* Fall back did not succeed either so return */
573 *err
= U_FILE_ACCESS_ERROR
;
574 log_data_err("Could not load testtypes.res in testdata bundle with path %s - %s\n", tdpath
, u_errorName(*err
));
578 _testDataPath
= tdpath
;
579 return _testDataPath
;
581 return _testDataPath
;
584 #define CTEST_MAX_TIMEZONE_SIZE 256
585 static UChar gOriginalTimeZone
[CTEST_MAX_TIMEZONE_SIZE
] = {0};
588 * Call this once to get a consistent timezone. Use ctest_resetTimeZone to set it back to the original value.
589 * @param optionalTimeZone Set this to a requested timezone.
590 * Set to NULL to use the standard test timezone (Pacific Time)
592 U_CFUNC
void ctest_setTimeZone(const char *optionalTimeZone
, UErrorCode
*status
) {
593 #if !UCONFIG_NO_FORMATTING
594 UChar zoneID
[CTEST_MAX_TIMEZONE_SIZE
];
596 if (optionalTimeZone
== NULL
) {
597 optionalTimeZone
= "America/Los_Angeles";
599 if (gOriginalTimeZone
[0]) {
600 log_data_err("*** Error: time zone saved twice. New value will be %s (Are you missing data?)\n",
603 ucal_getDefaultTimeZone(gOriginalTimeZone
, CTEST_MAX_TIMEZONE_SIZE
, status
);
604 if (U_FAILURE(*status
)) {
605 log_err("*** Error: Failed to save default time zone: %s\n",
606 u_errorName(*status
));
607 *status
= U_ZERO_ERROR
;
610 u_uastrncpy(zoneID
, optionalTimeZone
, CTEST_MAX_TIMEZONE_SIZE
-1);
611 zoneID
[CTEST_MAX_TIMEZONE_SIZE
-1] = 0;
612 ucal_setDefaultTimeZone(zoneID
, status
);
613 if (U_FAILURE(*status
)) {
614 log_err("*** Error: Failed to set default time zone to \"%s\": %s\n",
615 optionalTimeZone
, u_errorName(*status
));
621 * Call this once get back the original timezone
623 U_CFUNC
void ctest_resetTimeZone(void) {
624 #if !UCONFIG_NO_FORMATTING
625 UErrorCode status
= U_ZERO_ERROR
;
627 ucal_setDefaultTimeZone(gOriginalTimeZone
, &status
);
628 if (U_FAILURE(status
)) {
629 log_err("*** Error: Failed to reset default time zone: %s\n",
630 u_errorName(status
));
632 /* Set to an empty state */
633 gOriginalTimeZone
[0] = 0;
638 void *ctst_malloc(size_t size
) {
639 ctst_allocated_total
++;
640 if(ctst_allocated
>= CTST_MAX_ALLOC
- 1) {
644 if(ctst_allocated_stuff
[ctst_allocated
]) {
645 free(ctst_allocated_stuff
[ctst_allocated
]);
647 return ctst_allocated_stuff
[ctst_allocated
++] = malloc(size
);
650 #ifdef CTST_LEAK_CHECK
651 static void ctst_freeAll() {
653 if(ctst_free
== FALSE
) { /* only free up to the allocated mark */
654 for(i
=0; i
<ctst_allocated
; i
++) {
655 free(ctst_allocated_stuff
[i
]);
656 ctst_allocated_stuff
[i
] = NULL
;
658 } else { /* free all */
659 for(i
=0; i
<CTST_MAX_ALLOC
; i
++) {
660 free(ctst_allocated_stuff
[i
]);
661 ctst_allocated_stuff
[i
] = NULL
;
668 #define VERBOSE_ASSERTIONS
670 U_CFUNC UBool
assertSuccessCheck(const char* msg
, UErrorCode
* ec
, UBool possibleDataError
) {
672 if (U_FAILURE(*ec
)) {
673 if (possibleDataError
) {
674 log_data_err("FAIL: %s (%s)\n", msg
, u_errorName(*ec
));
676 log_err_status(*ec
, "FAIL: %s (%s)\n", msg
, u_errorName(*ec
));
683 U_CFUNC UBool
assertSuccess(const char* msg
, UErrorCode
* ec
) {
685 return assertSuccessCheck(msg
, ec
, FALSE
);
688 /* if 'condition' is a UBool, the compiler complains bitterly about
689 expressions like 'a > 0' which it evaluates as int */
690 U_CFUNC UBool
assertTrue(const char* msg
, int /*not UBool*/ condition
) {
692 log_err("FAIL: assertTrue() failed: %s\n", msg
);
694 #ifdef VERBOSE_ASSERTIONS
696 log_verbose("Ok: %s\n", msg
);
699 return (UBool
)condition
;
702 U_CFUNC UBool
assertEquals(const char* message
, const char* expected
,
703 const char* actual
) {
704 if (uprv_strcmp(expected
, actual
) != 0) {
705 log_err("FAIL: %s; got \"%s\"; expected \"%s\"\n",
706 message
, actual
, expected
);
709 #ifdef VERBOSE_ASSERTIONS
711 log_verbose("Ok: %s; got \"%s\"\n", message
, actual
);
717 U_CFUNC UBool
assertUEquals(const char* message
, const UChar
* expected
,
718 const UChar
* actual
) {
719 for (int32_t i
=0;; i
++) {
720 if (expected
[i
] != actual
[i
]) {
721 log_err("FAIL: %s; got \"%s\"; expected \"%s\"\n",
722 message
, austrdup(actual
), austrdup(expected
));
725 UChar curr
= expected
[i
];
726 U_ASSERT(curr
== actual
[i
]);
731 #ifdef VERBOSE_ASSERTIONS
732 log_verbose("Ok: %s; got \"%s\"\n", message
, austrdup(actual
));
737 U_CFUNC UBool
assertIntEquals(const char* message
, int64_t expected
, int64_t actual
) {
738 if (expected
!= actual
) {
739 log_err("FAIL: %s; got \"%d\"; expected \"%d\"\n",
740 message
, actual
, expected
);
743 #ifdef VERBOSE_ASSERTIONS
745 log_verbose("Ok: %s; got \"%d\"\n", message
, actual
);
751 U_CFUNC UBool
assertPtrEquals(const char* message
, const void* expected
, const void* actual
) {
752 if (expected
!= actual
) {
753 log_err("FAIL: %s; got 0x%llx; expected 0x%llx\n",
754 message
, actual
, expected
);
757 #ifdef VERBOSE_ASSERTIONS
759 log_verbose("Ok: %s; got 0x%llx\n", message
, actual
);