linenoise源码解析

原创 2016年06月01日 20:59:36

一、简介:

linenoise是一个命令行编辑库(line editing library),readline的替代品,可以用于tab自动补全方法的实现。目前linenoise已经在Redis, MongoDB,Android中使用。其支持特性如下:


1) 尽可能简小,无配置,支持BSD授权。

2) 单行或多行编辑模式,实现常用的快捷键绑定。

3)支持历史键入文本查询。

4)兼容性。

5)大约只有1100行代码。

6)只使用VT100 escapes键码的子集。

注:readline是一个提供了交互式的文本编辑功能的开源跨平台程序库,它最早由Brian Fox使用C语言开发,于1989年发布。


二、文件构成:

linenoise库核心文件仅仅是linenoise.c和linenoise.h,在linenoise.h中定义了一个数据结构linenoiseCompletions,用于记录一行行完整的匹配输入。

typedef struct linenoiseCompletions {
  size_t len;
  char **cvec;
} linenoiseCompletions;

其中:

a)len表示完整的匹配输入的数目。

b)cvec相当于一个二维字符数组char[len][ ],用于记录len条匹配输入。

注意:真正的匹配输入需要在自己的注册函数中完成,也就是linenoise中的completionCallback。


三、函数调用:

linenoise.c中定义了很多函数,下面几个图方便大家理清各函数之间的关系:

图3.1 函数调用图
1、其中completionCallback是定义的函数指针。
static linenoiseCompletionCallback *completionCallback = NULL;
再来看看linenoise.h文件中的函数定义:
typedef void(linenoiseCompletionCallback)(const char *, linenoiseCompletions *);
void linenoiseSetCompletionCallback(linenoiseCompletionCallback *);
2、completionCallback就是需要用户自己去定义和实现的匹配自动补全方法。
3、函数char *linenoise(const char *prompt);是提供给用户去调用的API接口。


图3.2 History函数调用

4、函数通过linenoiseHistoryLoad提供用户加载文件中的history记录,需要用户自己调用。

其实linenoiseHistoryLoad也是通过linenoiseHistoryAdd来添加history历史记录的,linenoiseHistoryAdd也可以供用户自己调用。

5、对于与linenoise edit相关度函数都是在completeEdit()函数中调用的,具体代码就不再赘述。


四、示例代码:

由于completionCallback函数需要用户自己去定义的自动补全方法,下面是一个示例代码,仅供参考。

SYS_CMD cmd[SYS_CMD_NUM] = {
    {"enable",      ENABLE},
    {"disable",     DISABLE},
    {"log",         LOG},
    {"dump",        DUMP},
    {"all",         ALL},
    {"status",      0},
    {"help",        0},
    {"exit",        0},
};
list<MENU_PAIR> componentList;

void tabCompletion(const char *buf, linenoiseCompletions *lc) {
    unsigned int  index =0, uLen = 0;
    const char *pLastWord = NULL;
    char *completion = NULL;

    if (buf) {
        pLastWord = buf;
        if (strlen(buf) > 0) {
            pLastWord += strlen(buf) - 1;
            while (uLen < strlen(buf) && *pLastWord != ' ') {
                pLastWord--; uLen++;
            }
            pLastWord++;
            uLen = strlen(pLastWord);
        }
        uLen = strlen(buf) - uLen;
        completion = (char *)malloc(sizeof(char) * (uLen + MAX_CMD_LEN));
        if (completion == NULL) {
            return;
        }
        memset(completion, 0, sizeof(char) * (uLen + MAX_CMD_LEN));
        strncpy(completion, buf, uLen);
        for(index = 0; index < SYS_CMD_NUM; index++) {
            if(strncmp(cmd[index].cmd, pLastWord, strlen(pLastWord)) == 0){
                strcpy(&completion[uLen],cmd[index].cmd);
                linenoiseAddCompletion(lc,completion);
            }
        }
        free(completion);
    }
}


相关文章推荐

linenoise 源码分析(一)

linenoise,一个命令行编辑库(line editing library)的源码分析

linenoise 源码分析(二)

linenoise 命令行编辑库源码分析,linenoiseState结构体,history模块。

多线程同步机制的几种方法

Critical Section Critical section(临界区)用来实现“排他性占有”。适用范围是单一进程 的各线程之间。它是:  一个局部性对象,不是一个核心对象。  快速而有效...

【NOSQL】非关系型数据库MongoDB ( 通过samus驱动实现基本数据操作 )

传统的关系数据库一般由数据库(database)、表(table)、记录(record)三个层次概念组成,MongoDB是由(database)、集合(collection)、文档对象(documen...

高性能搜索引擎sphinx源码解析之搜索过程和评分公式

sphinx搜索(select)逻辑 用输入的查询词在索引文件中挨个进行比较,找到满足关系的文档的过程,并读出文档,给每个文件打分,最后打分完成后进行排序,随后获取到排序后的文档列表的过程。 sp...

【特征匹配】RANSAC算法原理与源码解析

随机抽样一致性(RANSAC)算法,可以在一组包含“外点”的数据集中,采用不断迭代的方法,寻找最优参数模型,不符合最优模型的点,被定义为“外点”。在图像配准以及拼接上得到广泛的应用,本文将对RANSA...

基于rt-thread+lwip分析数据是怎么从网卡芯片接收数据到pbuf的(lwip源码解析一)

LWIP是嵌入式设备的网络微协议,基本上实现了标准的TCP/IP的功能,它没有项标准的TCP/IP协议那样有很严格的分层。主要原因是由于嵌入式设别的资源有限,所以避免了每层的COPY动作,在不同层之间...
  • bobbat
  • bobbat
  • 2015年03月30日 23:36
  • 1693

Android线程池(七)ExecutorService接口、Executor接口和ScheduledExecutorService接口的源码解析

ThreadPoolExecutor继承自AbstractExecutorService类,AbstractExecutorService类实现了ExecutorService接口,而Executor...

Java源码解析(附录)(2) —— TypeVariable

TypeVariable —— 类型变量  TypeVariable,类型变量,描述类型,表示泛指任意或相关一类类型,也可以说狭义上的泛型(泛指某一类类型),一般用大写字母作为变量,比如K、V、E等。...

Volley 图片加载相关源码解析

转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/47721631; 本文出自:【张鸿洋的博客】 一 概述在使用Voll...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:linenoise源码解析
举报原因:
原因补充:

(最多只允许输入30个字)