EPICS base macLib库解析与测试

文件: macLib.h

简述:文本宏替换的例程 
这个通用宏替换库用于EPICS base中所有宏替换。大部分例程成功返回0(OK),出错返回-1(ERROR),或者对应其它信息的小整数。macGetValue() 和 macExpandString()是这个的例外,并且返回有关成功/失败的和有关value长度的信息。使用errlogPrintf()报告出错和警告。
 

简述: 宏名和值的最大尺寸

#define MAC_SIZE 256

简述: 宏替换的上下文,仅由macLib例程使用 . 如果需要, 一个程序可以有多个活动的上下文.

typedef struct {
    long        magic;          /**< 用于验证的魔术值  */
    int         dirty;          /**< 需要从原始值展开的值? */
    int         level;          /**< 作用域 */
    int         debug;          /**< 调试级别 */
    ELLLIST     list;           /**< 宏名/值列表 */
    int         flags;          /**< 操作模式标志 */
} MAC_HANDLE;

 核心库:核心库提供了一个基本操作的最小集合。

 简述:创建一个新的宏替换上下文 .
 返回: 0 = OK; <0 = ERROR

LIBCOM_API long epicsStdCall macCreateHandle(
    MAC_HANDLE  **handle,       /**< 指向一个变量的指针,此变量接收一个指向新的宏替换上下文的指针 */
    const char * pairs[]        /**< 指向{name,value}对字符串的NULL结尾数组的指针。一个NULL值隐含未被定义,一个NULL对参数隐含没有宏 */
);



禁用或启用警告消息 .
当macExpandString()不能展开一个宏时,例程打印警告。这个程序可以用于静默那些消息。对于相同的句柄,一个非0值将禁止来自后续库例程的警告消息。

LIBCOM_API void epicsStdCall macSuppressWarning(
    MAC_HANDLE  *handle,        /**< 不透明句柄 */
    int         falseTrue       /**< 0表示发出, 1表示禁止*/
);


 简述:展开一个可能包含宏引用的字符串 .

 返回:返回被展开字符串的长度,如果宏未被定义,<0。这个例程解析src字符串,查找宏引用并且传递它找到的任何宏给macGetValue()来翻译。
 注意: 返回值类似于macGetValue()的返回值。它的绝对值时被复制到dest的字符数目。如果返回值是负数,至少一个未被定义的宏被留下未被展开。

LIBCOM_API long epicsStdCall macExpandString(
    MAC_HANDLE  *handle,        /**< 不透明句柄 */
    const char  *src,           /**< 源字符串 */
    char        *dest,          /**< 目标字符串 */
    long        capacity        /**< 目标缓存的容量(dest) */
);


 简述:设置一个特定的宏的值 .
 返回: 返回这个value字符串的长度。
 如果value是NULL,解除定义所有作用域的name的所有实例。(指定名称的宏在这种情况中不是必须存在的)。在value中引用的宏不需要在此处被定义。

LIBCOM_API long epicsStdCall macPutValue(
    MAC_HANDLE  *handle,        /**< 不透明句柄 */
    const char  *name,          /**< 宏名 */
    const char  *value          /**< 宏值 */
);

 
 简述:返回一个宏的值
 返回: 返回这个value字符串的长度,如果未定义,<0

如果这个值的长度少于capacity,value将是0结尾的。 返回值是被复制到value的字符数目(如果宏未被定义, 行为见以下)。
如果capacity是0, 没有字符将被复制到value(其可以是NULL),并且调用可以用于检查这个宏是否被定义。 注意: 不报告这个value的截断,程序应该认为如果返回值等于capacity,截断已经发生。
如果宏未被定义,(如果maxlen允许)宏引用将在value字符串中被返回,并且这个函数值将时被复制的最少字符。注意: capacity用于保持与strncpy()例程保持一致。如果这个值包含宏引用,这些引用将被递归地展开。这个展开将探测一个直接或间接的自引用。
 宏引用以一个"$"后面紧跟一个"("或一个"{"开始。宏名接着出现,并且能够可选地后跟一个"="和一个默认值,  一个引用是以一个匹配的")"或"}"字符结束。

LIBCOM_API long epicsStdCall macGetValue(
    MAC_HANDLE  *handle,        /**< 不透明的句柄  */
    const char  *name,          /**< 宏名或引用 */
    char        *value,         /**< 如果宏未被定义, 接收宏值或名称参数的字符串。*/
    long        capacity        /**< 目标缓存(value)的容量*/
);


 简述: 标记一个句柄无效,并且释放与它相关联的所有存储 
 返回: 0 = OK; <0 = ERROR
 注意: 这个不释放已经返回宏值所在的任何字符串。宏值总是被返回到由调用者先前分配的字符串。

LIBCOM_API long epicsStdCall macDeleteHandle(
    MAC_HANDLE  *handle         /**< 不透明的句柄 */
);


 标记一个新的作用域的开始
 返回: 0 = OK; <0 = ERROR
 标记在这个调用之后的所有宏定义属于另一个作用域。这些宏将在一个macPopScope()时丢失,
 而在当前作用域的那些宏将被重新安装。

LIBCOM_API long epicsStdCall macPushScope(
    MAC_HANDLE  *handle         /**< 不透明的句柄 */
);


 简述: 获取上次被压栈的作用域(像栈操作)
 返回:0 = OK; <0 = ERROR
 见 macPushScope()

LIBCOM_API long epicsStdCall macPopScope(
    MAC_HANDLE  *handle         /**< 不透明的句柄 */
);


简述:报告当前定义细节 

返回: 0 = OK; <0 = ERROR
这发送当前定义的细节到标准输出,并且仅用于调试目的 

LIBCOM_API long epicsStdCall macReportMacros(
    MAC_HANDLE  *handle         /**< opaque handle */
);

工具库

 这些便捷函数是用于程序,出于某些目的,使用和提供一个更方便的接口。
 
 简述: 解析宏定义未一个{name, value}对的数组。
 返回:找到的宏的数目; <0 = ERROR 
 这接收"a=xxx,b=yyy"格式的宏定义集合,并且转换它们未一个指向字符串的指针的数组,
 这个数组以两个NULL指针终结,并且所有存储区是被连续分配的,因而,可以用单个free()调用释放它们。这个例程独立于任何句柄, 并且提供了可以在别处使用的通用有用的服务。在值中任何宏引用在宏实际必须被转换前可以被定义或者重新定义。
 支持shell风格转义和引号,如像"A=B,B=$(C$(A)),CA=CA,CB=CB" (设置 B 为 "CB")的定义。
 空白在值中是重要的,但在别处被忽略(即: 在"="和','字符周围)
 这个函数返回遇到的定义数目,如果提供的字符串无效,为-1

LIBCOM_API long epicsStdCall macParseDefns(
    MAC_HANDLE  *handle,        /**< 不透明的句柄,如果不需要调试消息,可以是NULL。*/
    const char  *defns,         /**< "a=xxx,b=yyy"格式的宏定义 */
    char        **pairs[]       /**< 接收指向{name, value}对字符串的NULL终结的数组的指针的变量地址所有存储是连续分配的  */
);


 简述: 安装{name, value}对的集合作为定义
 返回: 定义的宏的数目,<0=ERROR 
 这接收一个以上定义的对的数组,并且通过调用macPutValue()安装它们作为定义。
 对数组是由一个NULL指针终结。

LIBCOM_API long epicsStdCall macInstallMacros(
    MAC_HANDLE  *handle,        /**< 不透明的句柄 */
    char        *pairs[]        /**<  指向{name,value}对字符串的NULL结尾的数组的指针,一个NULL值表示解除定义,
                                一个NULL参数表示没有宏 */
);


简述:展开在字符串中的环境变量 
返回: 展开的字符串,如果使用任何未定义的宏,NULL。
这个里车工展开一个字符串,它可能包含了宏引用引用。它解析这个字符串,查找这些引用并且传递它们给macGetValue来转换。它使用malloc()来为被展开字符串分配空间,并且返回一个指向这个null结尾的字符串的指针。如果这个源字符串包含任何未定义的引用,它返回NULL。

LIBCOM_API char * epicsStdCall macEnvExpand(
    const char *str             /**< 待被展开的字符串 */
);


 简述: 展开在字符串中的宏和环境变量 
 返回: 展开的字符串,如果使用任何未定义的宏,NULL。
 这个例程类似于macEnvExpand(),但它允许传入一个可选的句柄,其可能包含更多的宏定义。
 在展开这个字符串时, 从环境变量追加这些宏到宏的集合。

LIBCOM_API char * epicsStdCall macDefExpand(
    const char *str,            /**< 待被展开的字符串 */
    MAC_HANDLE *macros          /**< 不透明的句柄, 如果仅使用环境变量,可以是NULL */
);

测试macLib.h中每个函数的测试程序,如下:

#include 
#include 
#include 
#include "macLib.h"

int main()
{
        MAC_HANDLE * handle = NULL;
        char ** ppairs;

        printf("Test function: macCreateHandle\n");
        macCreateHandle(&handle, NULL);

        if (handle == NULL){
                printf("can not create handle\n");
                return -1;
        }

        char  defns[] = "name=greatwall,location=beijing";

        int len;

        printf("Test function: macParseDefns\n");
        //len = macParseDefns(handle, defns, &ppairs);
        len = macParseDefns(NULL , defns, &ppairs);
        printf("The length of %s is %d\n", defns, len);
        int i;
        for (i = 0; i < 2; i++){
                printf("%d: key:%s, value: %s\n", i+1, ppairs[i * 2], ppairs[i * 2 + 1] );
        }

        printf("Test function: macInstallMacros\n");
        len = macInstallMacros(handle, ppairs);
        printf("The number of macros : %d\n", len);

        printf("Call funtion: macPutValue\n");
        macPutValue(handle, "sport", "walk");
        char name[100];
        memset(name, 0, sizeof(name));
        char value[100];
        memset(value, 0, sizeof(value));


        printf("Test function: macGetValue\n");
        strcpy(name, "name");
        len = macGetValue(handle, name, value, sizeof(value));

        printf("len = %d\n", len);
        printf("name: %s expanded to value: %s\n", name, value);


        printf("Test function : macExpandString\n");
        memset(name, 0, sizeof(name));
        memset(value, 0, sizeof(value));
        strcpy(name, "name: ${name} location: ${location} sport: ${sport}");
        macExpandString(handle, name, value, sizeof(value));
        printf("%s is expanded to %s\n", name, value);

        printf("Call macEnvExpand:\n");
        char * pvalue = macEnvExpand("${EPICS_CA_ADDR_LIST}");
        printf("EPICS_CA_ADDR_LIST: %s\n", pvalue);
        free(pvalue);

        printf("Call function:  macReportMacros\n");
        macReportMacros(handle);

        printf("Call function: macDeleteHandle\n");
        macDeleteHandle( handle );
        free(ppairs);

        return 0;
}

测试结果如下:

orangepi@orangepi5:~/C_program/host_program/hostApp$ O.linux-aarch64/testMacLib
Test function: macCreateHandle
Test function: macParseDefns
The length of name=greatwall,location=beijing is 2
1: key:name, value: greatwall
2: key:location, value: beijing
Test function: macInstallMacros
The number of macros : 2
Call funtion: macPutValue
Test function: macGetValue
len = 9
name: name expanded to value: greatwall
Test function : macExpandString
name: ${name} location: ${location} sport: ${sport} is expanded to name: greatwall location: beijing sport: walk
Call macEnvExpand:
EPICS_CA_ADDR_LIST: 192.168.50.25 192.168.50.234:5092 192.168.50.234:5100
Call function:  macReportMacros
e name             rawval           value
- ----             ------           -----
  name             greatwall        greatwall
  location         beijing          beijing
  sport            walk             walk
Call function: macDeleteHandle

你可能感兴趣的:(EPICS教程,Linux,C,EPICS,C语言)