| // |
| // Copyright (c) 2017 The Khronos Group Inc. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| #include "../../test_common/harness/compat.h" |
| |
| #include "test_printf.h" |
| |
| |
| #if defined (_WIN32) |
| #define strtoull _strtoi64 |
| #endif |
| |
| const char* strType[] = {"int","float","octal","unsigned","hexadecimal","char","string","vector","address space"}; |
| |
| |
| |
| //================================== |
| |
| // int |
| |
| //================================== |
| |
| //------------------------------------------------------ |
| |
| // [string] format | [string] int-data representation | |
| |
| //------------------------------------------------------ |
| |
| struct printDataGenParameters printIntGenParameters[] = { |
| |
| //(Minimum)Five-wide,default(right)-justified |
| |
| {"%5d","10"}, |
| |
| //(Minimum)Five-wide,left-justified |
| |
| {"%-5d","10"}, |
| |
| //(Minimum)Five-wide,default(right)-justified,zero-filled |
| |
| {"%05d","10"}, |
| |
| //(Minimum)Five-wide,default(right)-justified,with sign |
| |
| {"%+5d","10"}, |
| |
| //(Minimum)Five-wide ,left-justified,with sign |
| |
| {"%-+5d","10"}, |
| |
| //(Minimum)Five-digit(zero-filled in absent digits),default(right)-justified |
| |
| {"%.5i","100"}, |
| |
| //(Minimum)Six-wide,Five-digit(zero-filled in absent digits),default(right)-justified |
| |
| {"%6.5i","100"}, |
| |
| //0 and - flag both apper ==>0 is ignored,left-justified,capital I |
| |
| {"%-06i","100"}, |
| |
| //(Minimum)Six-wide,Five-digit(zero-filled in absent digits),default(right)-justified |
| |
| {"%06.5i","100"} |
| |
| }; |
| |
| //------------------------------------------------ |
| |
| // Lookup table - [string]int-correct buffer | |
| |
| //------------------------------------------------ |
| |
| const char *correctBufferInt[] = { |
| |
| " 10", |
| |
| "10 ", |
| |
| "00010", |
| |
| " +10", |
| |
| "+10 ", |
| |
| "00100", |
| |
| " 00100", |
| |
| "100 ", |
| |
| " 00100" |
| |
| }; |
| |
| |
| |
| |
| |
| //----------------------------------------------- |
| |
| //test case for int | |
| |
| //----------------------------------------------- |
| |
| testCase testCaseInt = { |
| |
| sizeof(correctBufferInt)/sizeof(char*), |
| |
| TYPE_INT, |
| |
| correctBufferInt, |
| |
| printIntGenParameters |
| |
| }; |
| |
| |
| |
| |
| |
| //============================================== |
| |
| // float |
| |
| //============================================== |
| |
| |
| |
| //-------------------------------------------------------- |
| |
| // [string] format | [string] float-data representation | |
| |
| //-------------------------------------------------------- |
| |
| struct printDataGenParameters printFloatGenParameters[] = { |
| |
| //Default(right)-justified |
| |
| {"%f","10.3456"}, |
| |
| //One position after the decimal,default(right)-justified |
| |
| {"%.1f","10.3456"}, |
| |
| //Two positions after the decimal,default(right)-justified |
| |
| {"%.2f","10.3456"}, |
| |
| //(Minimum)Eight-wide,three positions after the decimal,default(right)-justified |
| |
| {"%8.3f","10.3456"}, |
| |
| //(Minimum)Eight-wide,two positions after the decimal,zero-filled,default(right)-justified |
| |
| {"%08.2f","10.3456"}, |
| |
| //(Minimum)Eight-wide,two positions after the decimal,left-justified |
| |
| {"%-8.2f","10.3456"}, |
| |
| //(Minimum)Eight-wide,two positions after the decimal,with sign,default(right)-justified |
| |
| {"%+8.2f","-10.3456"}, |
| |
| //Zero positions after the decimal([floor]rounding),default(right)-justified |
| |
| {"%.0f","0.1"}, |
| |
| //Zero positions after the decimal([ceil]rounding),default(right)-justified |
| |
| {"%.0f","0.6"}, |
| |
| //Zero-filled,default positions number after the decimal,default(right)-justified |
| |
| {"%0f","0.6"}, |
| |
| //Double argument representing floating-point,used by f style,default(right)-justified |
| |
| {"%4g","12345.6789"}, |
| |
| //Double argument representing floating-point,used by e style,default(right)-justified |
| |
| {"%4.2g","12345.6789"}, |
| |
| //Double argument representing floating-point,used by f style,default(right)-justified |
| |
| {"%4G","0.0000023"}, |
| |
| //Double argument representing floating-point,used by e style,default(right)-justified |
| |
| {"%4G","0.023"}, |
| |
| //Double argument representing floating-point,with exponent,left-justified,default(right)-justified |
| |
| {"%-#20.15e","789456123.0"}, |
| |
| //Double argument representing floating-point,with exponent,left-justified,with sign,capital E,default(right)-justified |
| |
| {"%+#21.15E","789456123.0"}, |
| |
| //Double argument representing floating-point,in [-]xh.hhhhpAd style |
| |
| {"%.6a","0.1"}, |
| |
| //(Minimum)Ten-wide,Double argument representing floating-point,in xh.hhhhpAd style,default(right)-justified |
| |
| {"%10.2a","9990.235"}, |
| |
| //Infinity (1.0/0.0) |
| |
| {"%f","1.0f/0.0f"}, |
| |
| //NaN |
| |
| {"%f","sqrt(-1.0f)"}, |
| |
| //NaN |
| {"%f","acospi(2.0f)"} |
| }; |
| //-------------------------------------------------------- |
| |
| // Lookup table - [string]float-correct buffer | |
| |
| //-------------------------------------------------------- |
| |
| const char* correctBufferFloat[] = { |
| |
| "10.345600", |
| |
| "10.3", |
| |
| "10.35", |
| |
| " 10.346", |
| |
| "00010.35", |
| |
| "10.35 ", |
| |
| " -10.35", |
| |
| "0", |
| |
| "1", |
| |
| "0.600000", |
| |
| "12345.7", |
| |
| "1.2e+4", |
| |
| "2.3E-6", |
| |
| "0.023", |
| |
| "7.894561230000000e+8", |
| |
| "+7.894561230000000E+8", |
| |
| "0x1.99999ap-4", |
| |
| "0x1.38p+13", |
| |
| "inf", |
| |
| "-nan", |
| |
| "nan" |
| }; |
| |
| //--------------------------------------------------------- |
| |
| //Test case for float | |
| |
| //--------------------------------------------------------- |
| |
| testCase testCaseFloat = { |
| |
| sizeof(correctBufferFloat)/sizeof(char*), |
| |
| TYPE_FLOAT, |
| |
| correctBufferFloat, |
| |
| printFloatGenParameters |
| |
| }; |
| |
| |
| |
| //========================================================= |
| |
| // octal |
| |
| //========================================================= |
| |
| |
| |
| //--------------------------------------------------------- |
| |
| // [string] format | [string] octal-data representation | |
| |
| //--------------------------------------------------------- |
| |
| struct printDataGenParameters printOctalGenParameters[] = { |
| |
| //Default(right)-justified |
| |
| {"%o","10"}, |
| |
| //Five-digit,default(right)-justified |
| |
| {"%.5o","10"}, |
| |
| //Default(right)-justified,increase precision |
| |
| {"%#o","100000000"}, |
| |
| //(Minimum)Four-wide,Five-digit,0-flag ignored(because of precision),default(right)-justified |
| |
| {"%04.5o","10"} |
| |
| }; |
| |
| //------------------------------------------------------- |
| |
| // Lookup table - [string] octal-correct buffer | |
| |
| //------------------------------------------------------- |
| |
| |
| |
| const char* correctBufferOctal[] = { |
| |
| "12", |
| |
| "00012", |
| |
| "0575360400", |
| |
| "00012" |
| |
| }; |
| |
| //------------------------------------------------------- |
| |
| //Test case for octal | |
| |
| //------------------------------------------------------- |
| |
| testCase testCaseOctal = { |
| |
| sizeof(correctBufferOctal)/sizeof(char*), |
| |
| TYPE_OCTAL, |
| |
| correctBufferOctal, |
| |
| printOctalGenParameters |
| |
| }; |
| |
| |
| |
| //========================================================= |
| |
| // unsigned |
| |
| //========================================================= |
| |
| |
| |
| //--------------------------------------------------------- |
| |
| // [string] format | [string] unsined-data representation | |
| |
| //--------------------------------------------------------- |
| |
| struct printDataGenParameters printUnsignedGenParameters[] = { |
| |
| //Default(right)-justified |
| |
| {"%u","10"}, |
| |
| //Zero precision for zero,default(right)-justified |
| |
| {"%.0u","0"}, |
| |
| }; |
| |
| //------------------------------------------------------- |
| |
| // Lookup table - [string] octal-correct buffer | |
| |
| //------------------------------------------------------- |
| |
| |
| |
| const char* correctBufferUnsigned[] = { |
| |
| "10", |
| |
| "" |
| |
| }; |
| |
| //------------------------------------------------------- |
| |
| //Test case for octal | |
| |
| //------------------------------------------------------- |
| |
| testCase testCaseUnsigned = { |
| |
| sizeof(correctBufferUnsigned)/sizeof(char*), |
| |
| TYPE_UNSIGNED, |
| |
| correctBufferUnsigned, |
| |
| printUnsignedGenParameters |
| |
| }; |
| |
| |
| |
| //======================================================= |
| |
| // hexadecimal |
| |
| //======================================================= |
| |
| |
| |
| //-------------------------------------------------------------- |
| |
| // [string] format | [string] hexadecimal-data representation | |
| |
| //-------------------------------------------------------------- |
| |
| struct printDataGenParameters printHexadecimalGenParameters[] = { |
| |
| //Add 0x,low x,default(right)-justified |
| |
| {"%#x","0xABCDEF"}, |
| |
| //Add 0x,capital X,default(right)-justified |
| |
| {"%#X","0xABCDEF"}, |
| |
| //Not add 0x,if zero,default(right)-justified |
| |
| {"%#X","0"}, |
| |
| //(Minimum)Eight-wide,default(right)-justified |
| |
| {"%8x","399"}, |
| |
| //(Minimum)Four-wide,zero-filled,default(right)-justified |
| |
| {"%04x","399"} |
| |
| }; |
| |
| //-------------------------------------------------------------- |
| |
| // Lookup table - [string]hexadecimal-correct buffer | |
| |
| //-------------------------------------------------------------- |
| |
| |
| |
| const char* correctBufferHexadecimal[] = { |
| |
| "0xabcdef", |
| |
| "0XABCDEF", |
| |
| "0", |
| |
| " 18f", |
| |
| "018f" |
| |
| }; |
| |
| //-------------------------------------------------------------- |
| |
| //Test case for hexadecimal | |
| |
| //-------------------------------------------------------------- |
| |
| testCase testCaseHexadecimal = { |
| |
| sizeof(correctBufferHexadecimal)/sizeof(char*), |
| |
| TYPE_HEXADEC, |
| |
| correctBufferHexadecimal, |
| |
| printHexadecimalGenParameters |
| |
| }; |
| |
| |
| |
| //============================================================= |
| |
| // char |
| |
| //============================================================= |
| |
| |
| |
| //----------------------------------------------------------- |
| |
| // [string] format | [string] string-data representation | |
| |
| //----------------------------------------------------------- |
| |
| struct printDataGenParameters printCharGenParameters[] = { |
| |
| //Four-wide,zero-filled,default(right)-justified |
| |
| {"%4c","\'1\'"}, |
| |
| //Four-wide,left-justified |
| |
| {"%-4c","\'1\'"}, |
| |
| //(unsigned) int argument,default(right)-justified |
| |
| {"%c","66"} |
| |
| }; |
| |
| //--------------------------------------------------------- |
| |
| // Lookup table -[string] char-correct buffer | |
| |
| //--------------------------------------------------------- |
| |
| const char * correctBufferChar[] = { |
| |
| " 1", |
| |
| "1 ", |
| |
| "B", |
| |
| }; |
| |
| |
| |
| //---------------------------------------------------------- |
| |
| //Test case for char | |
| |
| //---------------------------------------------------------- |
| |
| testCase testCaseChar = { |
| |
| sizeof(correctBufferChar)/sizeof(char*), |
| |
| TYPE_CHAR, |
| |
| correctBufferChar, |
| |
| printCharGenParameters |
| |
| }; |
| |
| |
| |
| //========================================================== |
| |
| // string |
| |
| //========================================================== |
| |
| |
| |
| //-------------------------------------------------------- |
| |
| // [string]format | [string] string-data representation | |
| |
| //-------------------------------------------------------- |
| |
| struct printDataGenParameters printStringGenParameters[] = { |
| |
| //(Minimum)Four-wide,zero-filled,default(right)-justified |
| |
| {"%4s","\"foo\""}, |
| |
| //One-digit(precision ignored),left-justified |
| |
| {"%.1s","\"foo\""}, |
| |
| //%% specification |
| |
| {"%s","\"%%\""}, |
| }; |
| |
| //--------------------------------------------------------- |
| |
| // Lookup table -[string] string-correct buffer | |
| |
| //--------------------------------------------------------- |
| |
| const char * correctBufferString[] = { |
| |
| " foo", |
| |
| "f", |
| |
| "%%", |
| }; |
| |
| //--------------------------------------------------------- |
| |
| //Test case for string | |
| |
| //--------------------------------------------------------- |
| |
| testCase testCaseString = { |
| |
| sizeof(correctBufferString)/sizeof(char*), |
| |
| TYPE_STRING, |
| |
| correctBufferString, |
| |
| printStringGenParameters |
| |
| }; |
| |
| |
| |
| //========================================================= |
| |
| // vector |
| |
| //========================================================= |
| |
| |
| |
| //------------------------------------------------------------------------------------------------------------------- |
| |
| //[string] flag | [string] specifier | [string] type | [string] vector-data representation | [string] vector size | |
| |
| //------------------------------------------------------------------------------------------------------------------- |
| |
| struct printDataGenParameters printVectorGenParameters[]={ |
| |
| //(Minimum)Two-wide,two positions after decimal |
| |
| {NULL,"(1.0f,2.0f,3.0f,4.0f)","%2.2","hlf","float","4"}, |
| |
| //Alternative form,uchar argument |
| |
| {NULL,"(0xFA,0xFB)","%#","hhx","uchar","2"}, |
| |
| //Alternative form,ushort argument |
| |
| {NULL,"(0x1234,0x8765)","%#","hx","ushort","2"}, |
| |
| //Alternative form,uint argument |
| |
| {NULL,"(0x12345678,0x87654321)","%#","hlx","uint","2"}, |
| |
| //Alternative form,long argument |
| |
| {NULL,"(12345678,98765432)","%","ld","long","2"} |
| |
| }; |
| |
| //------------------------------------------------------------ |
| |
| // Lookup table -[string] vector-correct buffer | |
| |
| //------------------------------------------------------------ |
| |
| const char * correctBufferVector[] = { |
| |
| "1.00,2.00,3.00,4.00", |
| |
| "0xfa,0xfb", |
| |
| "0x1234,0x8765", |
| |
| "0x12345678,0x87654321", |
| |
| "12345678,98765432" |
| |
| }; |
| |
| //----------------------------------------------------------- |
| |
| //Test case for vector | |
| |
| //----------------------------------------------------------- |
| |
| testCase testCaseVector = { |
| |
| sizeof(correctBufferVector)/(sizeof(char *)), |
| |
| TYPE_VECTOR, |
| |
| correctBufferVector, |
| |
| printVectorGenParameters |
| |
| }; |
| |
| |
| |
| //================================================================== |
| |
| // address space |
| |
| //================================================================== |
| |
| |
| |
| //------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| |
| // [string] argument type qualifier |[string] variable type qualifier + initialization | [string] format | [string] parameter |[string]%p indicator/additional code | |
| |
| //------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| |
| |
| |
| struct printDataGenParameters printAddrSpaceGenParameters[]={ |
| |
| //Global memory region |
| |
| {"\"%d\\n\"",NULL,NULL,NULL,NULL,NULL,"__global int* x","","*x",""}, |
| |
| //Global,constant, memory region |
| |
| {"\"%d\\n\"",NULL,NULL,NULL,NULL,NULL,"constant int* x","","*x",""}, |
| |
| //Local memory region |
| |
| {"\"%+d\\n\"",NULL,NULL,NULL,NULL,NULL,"","local int x;\n x= (int)3;\n","x",""}, |
| |
| //Private memory region |
| |
| {"\"%i\\n\"",NULL,NULL,NULL,NULL,NULL,"","private int x;\n x = (int)-1;\n","x",""}, |
| |
| //Address of void * from global memory region |
| |
| {"\"%p\\n\"",NULL,NULL,NULL,NULL,NULL,"__global void* x,__global intptr_t* xAddr","","x","*xAddr = (intptr_t)x;\n"} |
| |
| }; |
| |
| //------------------------------------------------------------------------------- |
| |
| // Lookup table -[string] address space -correct buffer | |
| |
| //------------------------------------------------------------------------------- |
| |
| const char * correctAddrSpace[] = { |
| |
| "2","2","+3","-1","" |
| |
| }; |
| |
| //------------------------------------------------------------------------------- |
| |
| //Test case for address space | |
| |
| //------------------------------------------------------------------------------- |
| |
| testCase testCaseAddrSpace = { |
| |
| sizeof(correctAddrSpace)/(sizeof(char *)), |
| |
| TYPE_ADDRESS_SPACE, |
| |
| correctAddrSpace, |
| |
| printAddrSpaceGenParameters |
| |
| }; |
| |
| |
| |
| //------------------------------------------------------------------------------- |
| |
| //All Test cases | |
| |
| //------------------------------------------------------------------------------- |
| |
| testCase* allTestCase[] = {&testCaseInt,&testCaseFloat,&testCaseOctal,&testCaseUnsigned,&testCaseHexadecimal,&testCaseChar,&testCaseString,&testCaseVector,&testCaseAddrSpace}; |
| |
| |
| //----------------------------------------- |
| |
| // Check functions |
| |
| //----------------------------------------- |
| |
| size_t verifyOutputBuffer(char *analysisBuffer,testCase* pTestCase,size_t testId,cl_ulong pAddr) |
| { |
| int terminatePos = strlen(analysisBuffer); |
| if(terminatePos > 0) |
| { |
| analysisBuffer[terminatePos - 1] = '\0'; |
| } |
| |
| //Convert analysis buffer to long for address space |
| if(pTestCase->_type == TYPE_ADDRESS_SPACE && strcmp(pTestCase->_genParameters[testId].addrSpacePAdd,"")) |
| |
| { |
| char analysisBufferTmp[ANALYSIS_BUFFER_SIZE]; |
| |
| if(strstr(analysisBuffer,"0x") == NULL) |
| // Need to prepend 0x to ASCII number before calling strtol. |
| strcpy(analysisBufferTmp,"0x"); |
| |
| else analysisBufferTmp[0]='\0'; |
| strcat(analysisBufferTmp,analysisBuffer); |
| if (sizeof(long) == 8) { |
| if(strtoul(analysisBufferTmp,NULL,0) == pAddr) return 0; |
| } |
| else { |
| if(strtoull(analysisBufferTmp,NULL,0) == pAddr) return 0; |
| } |
| return 1; |
| |
| } |
| |
| char* exp; |
| //Exponenent representation |
| if((exp = strstr(analysisBuffer,"E+")) != NULL || (exp = strstr(analysisBuffer,"e+")) != NULL || (exp = strstr(analysisBuffer,"E-")) != NULL || (exp = strstr(analysisBuffer,"e-")) != NULL) |
| { |
| char correctExp[3]={0}; |
| strncpy(correctExp,exp,2); |
| |
| |
| char* eCorrectBuffer = strstr((char*)pTestCase->_correctBuffer[testId],correctExp); |
| if(eCorrectBuffer == NULL) |
| return 1; |
| |
| eCorrectBuffer+=2; |
| exp += 2; |
| |
| //Exponent always contains at least two digits |
| if(strlen(exp) < 2) |
| return 1; |
| //Scip leading zeros in the exponent |
| while(*exp == '0') |
| ++exp; |
| return strcmp(eCorrectBuffer,exp); |
| } |
| if(!strcmp(pTestCase->_correctBuffer[testId],"inf")) |
| return strcmp(analysisBuffer,"inf")&&strcmp(analysisBuffer,"infinity")&&strcmp(analysisBuffer,"1.#INF00")&&strcmp(analysisBuffer,"Inf"); |
| if(!strcmp(pTestCase->_correctBuffer[testId],"nan") || !strcmp(pTestCase->_correctBuffer[testId],"-nan")) { |
| return strcmp(analysisBuffer,"nan")&&strcmp(analysisBuffer,"-nan")&&strcmp(analysisBuffer,"1.#IND00")&&strcmp(analysisBuffer,"-1.#IND00")&&strcmp(analysisBuffer,"NaN")&&strcmp(analysisBuffer,"nan(ind)")&&strcmp(analysisBuffer,"nan(snan)")&&strcmp(analysisBuffer,"-nan(ind)"); |
| } |
| return strcmp(analysisBuffer,pTestCase->_correctBuffer[testId]); |
| } |
| |