C/C++通过程序模板生成函数

来源于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);
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

denglin12315

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值