長らく readline との API の非互換が手間だったのが、Juniper Networks のスポンサーの元 realine との互換 API が開発された。FreeBSD にコミットされたのは既に一年以上も前で、現時点では、FreeBSD 9.0 と FreeBSD 8.3 以降で恩恵を受けることができる。
その恩恵はと言うと、C++ 言語での readline の使い方がそのまま動く。まあ、互換 API なので当然のこと。
// c++ rl.cpp -lreadline -lcurses
// c++ -I /usr/include/edit rl.cpp -ledit // FreeBSD 8.3/9.0
#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
#include <string>
#include <iostream>
int main()
{
using namespace std;
char *ptr;
string line;
using_history();
read_history(NULL);
while(ptr = readline("rl++:"))
{
add_history(ptr);
line = ptr;
cout << line << endl;
free(ptr);
}
write_history(NULL);
}
肝の部分はコンパイル時のオプション。editline の readline 互換 API は /usr/include/edit
に入る。例えば、/usr/include/edit/readline/readline.h
といった感じだ。
ldd を用いて実際にリンクされているライブラリを調べる。こちらは libedit を用いた場合。
% c++ -I /usr/include/edit rl.cpp -ledit
% ldd a.out
a.out:
libedit.so.7 => /lib/libedit.so.7 (0x28098000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x280b7000)
libm.so.5 => /lib/libm.so.5 (0x281ab000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x281c5000)
libc.so.7 => /lib/libc.so.7 (0x281d0000)
libncurses.so.8 => /lib/libncurses.so.8 (0x282ec000)
そして、こちらは realine を用いた場合。
% c++ rl.cpp -l readline
% ldd a.out
a.out:
libreadline.so.8 => /lib/libreadline.so.8 (0x28098000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x280ca000)
libm.so.5 => /lib/libm.so.5 (0x281be000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x281d8000)
libc.so.7 => /lib/libc.so.7 (0x281e3000)
libncurses.so.8 => /lib/libncurses.so.8 (0x282ff000)
セコメントをする