Monday, August 25, 2008

为自己的程序添加GNU readline

1.引言:什么是readline
http://www.javvin.net/Software-Terms/GNU-readline.php

GNU readline 是由 GNU 工程创建和维护的一个软件包。它提供行编辑功能。例如,在 readline 授权的应用程序中,按下 C-b (CTRL-B) 将指针向后移到一个位置,然而 C-f 向前移动这个指针到一个位置;C-r 在历史纪录中搜索;这些组合键(这些是默认的,尽管像组合 vi's 是选择性的)来自于 GNU 的最早和最流行的工程,文本编辑器 Emacs 。Readline 支持多种高级特征,包括一个 kill ring( 复制/粘贴剪切板的一种更灵活的版本)和 tab completion 。作为一个跨平台的库,readline 允许多种系统上很多应用程序来展示行编辑行为。它是在 GNU 通用公共许可证(GPL)下的分发的一个自由包。

2.表现与使用
emacs,bash,vi,lftp等许多unix工具都使用了readline。readline支持组合键操作,历史记录搜寻,文件自动补全等功能。

3.例子
下面是一个例子,程序输出"Enter 'exit' to return:" 并且等待输入,知道输入'exit'为止。
支持热键编辑,文件名匹配,历史记录搜寻等。
文件readline.c的内容:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <readline/readline.h>  // readline 库头文件
#include <readline/history.h>  // readline 的历史命令功能

// 下面的一段例程摘自: http://www.ascc.sinica.edu.tw/pd-man/readline-2.0/rlman_2.html#SEC23
// start
/* A static variable for holding the line. */
static char *line_read = (char *)NULL;

/* Read a string, and return a pointer to it.  Returns NULL on EOF. */
char * rl_gets ()
{
    /* If the buffer has already been allocated, return the memory
     *      to the free pool. */
    if (line_read)
    {
        free (line_read);
        line_read = (char *)NULL;
    }

    /* Get a line from the user. */
    line_read = readline ("Enter 'exit' to return:");

    /* If the line has any text in it, save it on the history. */
    if (line_read && *line_read)
        add_history (line_read);

    return (line_read);
}

// end

void main()
{
    do
    {
        rl_gets();
    }while( strcmp("exit",line_read) != 0);
    exit(0);
}

其中rl_get这个例程摘自这里,有非常简明易懂的readline使用说明。
事实上实现最简单的readline其实只需用readline代替gets/fgets即可。

使用以下命令进行编译:
gcc readline.c -lreadline -o readline

No comments: