上一篇博客我分析了linenoise中的数据结构linenoiseCompletions和abuf,这篇我分析一下linenoise的历史命令取回和linenoiseState结构体。linenoiseState结构体即是这个库核心的部分,起到控制当前用户输入状态的功能。而history部分并不复杂,只是仅仅操作一个char** history数组,这个数组是固定大小的“双端队列”。
一、history模块:这部分功能都写在linenoise.c文件,以下是几个主要的全局变量,用于控制:
static int history_max_len = LINENOISE_DEFAULT_HISTORY_MAX_LEN;
static int history_len = 0;
static char **history = NULL;
history_max_len,所能记录的history条数; history_len ,目前history变量中装填的history数量; history, 用于历史记录存储,每个历史记录是一个char*。
history提供四个导出函数,一个内部函数:
int linenoiseHistoryAdd(const char *line);
int linenoiseHistorySetMaxLen(int len);
int linenoiseHistorySave(const char *filename);
int linenoiseHistoryLoad(const char *filename);
static void freeHistory(void);
单看名字应该能猜到这些函数的用途了。
(1)linenoiseHistoryAdd ():将字符串存入history中,这其中说一点,history变量的初始化是通过Load函数或者Add函数完成的,当用户有history文件时,调用Load函数直接加载到history变量,history即完成了初始化,并且填充了元素。若用户没有调用Load函数,在使用Add时,会检测history是否已经初始化,若没有初始化,则malloc(),元素个数就是history_max_len。接着完成添加任务,上一次的历史若与这一次欲添加的历史相同,则直接返回,不添加。若不同,检测history是否已经装满,若装满,将history[0]释放,用memmove腾出最后一个元素空间,把欲添加的字符串strdup()后赋值。
/* This is the API call to add a new entry in the linenoise history.
* It uses a fixed array of char pointers that are shifted (memmoved)
* when the history max length is reached in order to remove the older
* entry and make room for the new one, so it is not exactly suitable for huge
* histories, but will work well for a few hundred of