Files
OpenCL-CTS/test_conformance/printf/util_printf.c
Wenju He f10ee34dd8 Fix verifyOutputBuffer return value in printf (#102)
Function verifyOutputBuffer returns non-zero value in case of mismatch.
Return value 'false' means some mismatches are treated as matches. This
commit fix this problem.
2019-03-19 09:33:07 +00:00

879 lines
19 KiB
C

//
// 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]);
}