来源于OpenCL CTS中的test_conformance/vectors
函数模板定义:
static const char* patterns[] = {
".PRAGMA..STATE.\n"
"__kernel void test_vec_align_array(.SRC_SCOPE. .TYPE..NUM. *source, "
".DST_SCOPE. uint *dest)\n"
"{\n"
" int tid = get_global_id(0);\n"
" dest[tid] = (uint)((.SRC_SCOPE. uchar *)(source+tid));\n"
"}\n",
".PRAGMA..STATE.\n"
"typedef struct myUnpackedStruct { \n"
".PRE."
" .TYPE..NUM. vec;\n"
".POST."
"} testStruct;\n"
"__kernel void test_vec_align_struct(__constant .TYPE..NUM. *source, "
".DST_SCOPE. uint *dest)\n"
"{\n"
" .SRC_SCOPE. testStruct test;\n"
" int tid = get_global_id(0);\n"
" dest[tid] = (uint)((.SRC_SCOPE. uchar *)&(test.vec));\n"
"}\n",
".PRAGMA..STATE.\n"
"typedef struct __attribute__ ((packed)) myPackedStruct { \n"
".PRE."
" .TYPE..NUM. vec;\n"
".POST."
"} testStruct;\n"
"__kernel void test_vec_align_packed_struct(__constant .TYPE..NUM. "
"*source, .DST_SCOPE. uint *dest)\n"
"{\n"
" .SRC_SCOPE. testStruct test;\n"
" int tid = get_global_id(0);\n"
" dest[tid] = (uint)((.SRC_SCOPE. uchar *)&(test.vec) - (.SRC_SCOPE. "
"uchar *)&test);\n"
"}\n",
".PRAGMA..STATE.\n"
"typedef struct myStruct { \n"
".PRE."
" .TYPE..NUM. vec;\n"
".POST."
"} testStruct;\n"
"__kernel void test_vec_align_struct_arr(.SRC_SCOPE. testStruct *source, "
".DST_SCOPE. uint *dest)\n"
"{\n"
" int tid = get_global_id(0);\n"
" dest[tid] = (uint)((.SRC_SCOPE. uchar *)&(source[tid].vec));\n"
"}\n",
".PRAGMA..STATE.\n"
"typedef struct __attribute__ ((packed)) myPackedStruct { \n"
".PRE."
" .TYPE..NUM. vec;\n"
".POST."
"} testStruct;\n"
"__kernel void test_vec_align_packed_struct_arr(.SRC_SCOPE. testStruct "
"*source, .DST_SCOPE. uint *dest)\n"
"{\n"
" int tid = get_global_id(0);\n"
" dest[tid] = (uint)((.SRC_SCOPE. uchar *)&(source[tid].vec) - "
"(.SRC_SCOPE. uchar *)&(source[0]));\n"
"}\n",
// __attribute__ ((packed))
};
通过替换代码中的.SRC_SCOPE. / .TYPE. / .NUM.等关键字,就可以生成针对不同类型数据的函数代码。具体替换函数如下:
size_t doReplace(char* dest, size_t destLength, const char* source,
const char* stringToReplace1, const char* replaceWith1,
const char* stringToReplace2, const char* replaceWith2)
{
size_t copyCount = 0;
const char* sourcePtr = source;
char* destPtr = dest;
const char* ptr1;
const char* ptr2;
size_t nJump;
size_t len1, len2;
size_t lenReplace1, lenReplace2;
len1 = strlen(stringToReplace1);
len2 = strlen(stringToReplace2);
lenReplace1 = strlen(replaceWith1);
lenReplace2 = strlen(replaceWith2);
for (; copyCount < destLength && *sourcePtr;)
{
ptr1 = strstr(sourcePtr, stringToReplace1);
ptr2 = strstr(sourcePtr, stringToReplace2);
if (ptr1 != NULL && (ptr2 == NULL || ptr2 > ptr1))
{
nJump = ptr1 - sourcePtr;
if (((uintptr_t)ptr1 - (uintptr_t)sourcePtr)
> destLength - copyCount)
{
return -1;
}
copyCount += nJump;
strncpy(destPtr, sourcePtr, nJump);
destPtr += nJump;
sourcePtr += nJump + len1;
strcpy(destPtr, replaceWith1);
destPtr += lenReplace1;
}
else if (ptr2 != NULL && (ptr1 == NULL || ptr1 >= ptr2))
{
nJump = ptr2 - sourcePtr;
if (nJump > destLength - copyCount)
{
return -2;
}
copyCount += nJump;
strncpy(destPtr, sourcePtr, nJump);
destPtr += nJump;
sourcePtr += nJump + len2;
strcpy(destPtr, replaceWith2);
destPtr += lenReplace2;
}
else
{
nJump = strlen(sourcePtr);
if (nJump > destLength - copyCount)
{
return -3;
}
copyCount += nJump;
strcpy(destPtr, sourcePtr);
destPtr += nJump;
sourcePtr += nJump;
}
}
*destPtr = '\0';
return copyCount;
}
size_t doSingleReplace(char* dest, size_t destLength, const char* source,
const char* stringToReplace, const char* replaceWith)
{
size_t copyCount = 0;
const char* sourcePtr = source;
char* destPtr = dest;
const char* ptr;
size_t nJump;
size_t len;
size_t lenReplace;
len = strlen(stringToReplace);
lenReplace = strlen(replaceWith);
for (; copyCount < destLength && *sourcePtr;)
{
ptr = strstr(sourcePtr, stringToReplace);
if (ptr != NULL)
{
nJump = ptr - sourcePtr;
if (((uintptr_t)ptr - (uintptr_t)sourcePtr)
> destLength - copyCount)
{
return -1;
}
copyCount += nJump;
strncpy(destPtr, sourcePtr, nJump);
destPtr += nJump;
sourcePtr += nJump + len;
strcpy(destPtr, replaceWith);
destPtr += lenReplace;
}
else
{
nJump = strlen(sourcePtr);
if (nJump > destLength - copyCount)
{
return -3;
}
copyCount += nJump;
strcpy(destPtr, sourcePtr);
destPtr += nJump;
sourcePtr += nJump;
}
}
*destPtr = '\0';
return copyCount;
}
替换完成后,我们可以把生成的函数字符串写到文件,就是一个个函数代码了。
文件操作使用fwrite/fread/fopen/fclose等函数,使用示例如下:
#include<stdio.h>
int main ()
{
FILE *fp;
char str[] = "This is runoob.com";
fp = fopen( "file.txt" , "w" );
fwrite(str, sizeof(str) , 1, fp );
fclose(fp);
return(0);
}