2012年2月17日金曜日

[PostgreSQL] WAL 文件解析 (xlogdump)

1. 解压 xlogdump 到 PG 源文件的 contrib 目录
?/src/postgresql-9.1.2/contrib/xlogdump-0.5.1

2. 设置 PG 环境变量

3. 安装
$ cd xlogdump-0.5.1
$ make
$ sudo make install

4. 使用
$ xlogdump --help

2012年2月14日火曜日

[C 语言] C 语言编程技巧

1. 按位与操作
1-1. 保留低 8 位, 其余置 0
0xaaaa & 0xff -> 0x00aa

2. 按位移动
用左/右移做快速的乘/除运算
左移, 丢弃最高位, 0 补最低位
右移, 正数的话补 0, 负数补 1, 保持符号位不变

3. fgets(buf, len, stdin)
3-1. 从标准输入读取时, 最后的回车 '\n' 也包含在 buf 中
3-2. buf 长度应是要保存的字符串长度 + 1

2012年2月12日日曜日

[LINUX 基础] Linux 静态库与共享库

1. 静态库
静态库在编译时静态组入程序中

2. 动态库
2-1. 运行时动态链接
程序运行时, 如果动态库没有在内存中, 则加载它

2-2. 程序控制动态加载
加载器加载动态库并调用程序所用到的函数

3. 创建动态库

3-1. 动态库头文件
$ cat sharedlib.h
#ifndef SHAREDLIB_H
#define SHAREDLIB_H
void print_hoge (int num);
#endif

3-2. 动态库源文件
$ cat sharedlib.c
#include <stdio.h>
#include "sharedlib.h"
void print_hoge (int num)
{
    int i;
    for (i = 0; i < num; i++) {
        printf("hoge\n");
    }
}

3-3. 测试源文件
$ cat run.c
#include "sharedlib.h"
int main (void)
{
    print_hoge(5);
    return 0;
}

3-4. 编译
$ gcc -fPIC -c sharedlib.c -o sharedlib.o (编译)
$ gcc -shared -Wl,-soname,libsharedlib.so.1 -o libsharedlib.so.1.0 sharedlib.o (生成共享库)
$ sudo /sbin/ldconfig /path/to/somewhere (生成 libsharedlib.so.1 链接, 同时更新 /etc/ld.so.cache)
$ sudo ln -s /usr/lib/libsharedlib.so.1 /usr/lib/libsharedlib.so (生成 libsharedlib.so 链接)
$ ll
libsharedlib.so -> libsharedlib.so.1
libsharedlib.so.1 -> libsharedlib.so.1.0
libsharedlib.so.1.0
$ gcc run.c -I./ -L./ -o run -lsharedlib (生成测试程序)
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. (设置共享库查找路径)
$ ./run

4. 创建静态库
$ gcc -c staticlib.c -o staticlib.o
$ ar rv libstaticlib.a staticlib.o
$ gcc run.c -o run ./libstaticlib.a
$ ./run

[LINUX 基础] tmpfs 的使用

1. 概念
tmpfs 是 Linux/Unix 系统上的基于内存的文件系统, 创建时不需要使用 mkfs 等初始化
tmpfs 可以使用物理内存或 swap 分区来暂时存储文件, 重启后数据丢失
/dev/shm 是设备文件, 默认分配为物理内存的一半

2.
改变 tmpfs 大小

2-1. 永久修改
# vi /etc/fstab
-tmpfs /dev/shm tmpfs defaults           0   0
+tmpfs /dev/shm tmpfs defaults,size=512m 0   0

# mount -o remount /dev/shm

2-2. 暂时修改
$ sudo mount tmpfs /dev/shm -t tmpfs -o remount,size=512M

3. 使用
可以直接使用 /dev/shm 目录来创建高速文件 (实际是在内存中)
$ dd if=/dev/zero of=/dev/shm/aaa bs=1M count=256
256+0 records in
256+0 records out
268435456 bytes (268 MB) copied, 0.153053 seconds, 1.8 GB/s

[LINUX 基础] SWAP

1. 增加 SWAP 空间的方法

1-1. 增加独立磁盘分区

1-1-1. 创建新分区
$ fdisk /dev/sda6

1-1-2. 制作 SWAP 分区
$ mkswap /dev/sda6

1-1-3. 启动时加载
$ vim /etc/fstab
/dev/sda6 swap swap defaults 0 0

1-1-4. 使 SWAP 分区生效
swapon -a


1-2. 创建 SWAP 文件

1-2-1. 制作 2G SWAP 文件
$ dd if=/dev/zero of=/swapfile bs=1M count=2048

1-2-2. 转化为 SWAP 文件
mkswap /mnt/swapfile

1-2-3. 启动时加载
$ vim /etc/fstab
/mnt/swapfile swap swap defaults 0 0

1-2-4. 使 SWAP 分区生效
swapon /mnt/swapfile


1-3. 采用 LVM

1-3-1. 确定 swap 使用的逻辑卷
# cat /proc/swaps

1-3-2. 将 swap 离线
# swapoff /dev/VolGroup00/LogVol01

1-3-3. 扩展(收缩) swap 对应的逻辑卷
# lvextend [lvreduce] -L 2G /dev/VolGroup00/LogVol01

1-3-4. 创建 swap 文件系统
$ mkswap /dev/VolGroup00/LogVol01

1-3-5. 使 swap 生效
# swapoon /dev/VolGroup00/LogVol01

2. 观察 SWAP
# top (之后按 f 来调节 SWAP 列的现实与否)
# free -m
# cat /proc/swaps
# swapon -s
# vmstat
# cat /etc/fstab

[C 语言] CUnit 的使用

1. 安装

$ cd CUnit-x.x-x
$ ./configure --prefix /usr/local/cunit
$ make
$ sudo make install
$ sudo /sbin/ldconfig
--------------------------------------------------------------------------------
2. 测试用例

/*
 * file: func.c
 */

int maxi(int i, int j)
{
    return i>j?i:j;
}


/*
 * file: test_func.c
 */
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "CUnit/CUnit.h"
#include "CUnit/Automated.h"

/*---- functions to be tested ------*/
extern int maxi(int i, int j);

/*---- test cases ------------------*/
void testIQJ()
{
    CU_ASSERT_EQUAL(maxi(1,1),2);
    CU_ASSERT_EQUAL(maxi(0,-0),0);
}

void testIGJ()
{
    CU_ASSERT_EQUAL(maxi(2,1),2);
    CU_ASSERT_EQUAL(maxi(0,-1),0);
    CU_ASSERT_EQUAL(maxi(-1,-2),-1);
}

void testILJ()
{
    CU_ASSERT_EQUAL(maxi(1,2),2);
    CU_ASSERT_EQUAL(maxi(-1,0),0);
    CU_ASSERT_EQUAL(maxi(-2,-1),-1);
}

CU_TestInfo testcases[] = {
    {"Testing i equals j:", testIQJ},
    {"Testing i greater than j:", testIGJ},
    {"Testing i less than j:", testILJ},
    CU_TEST_INFO_NULL
};


/*---- test suites ------------------*/
int suite_success_init(void)
{
    return 0;
}
int suite_success_clean(void)
{
    return 0;
}

CU_SuiteInfo suites[] = {
    {"Testing the function maxi:", suite_success_init, suite_success_clean, testcases},
    CU_SUITE_INFO_NULL
};


/*---- setting enviroment -----------*/
void AddTests(void)
{
    assert(NULL != CU_get_registry());
    assert(!CU_is_test_running());
    /* shortcut regitry */

    if(CUE_SUCCESS != CU_register_suites(suites)) {
        fprintf(stderr, "Register suites failed - %s ", CU_get_error_msg());
        exit(EXIT_FAILURE);
    }
}


/*
 * file: run_test.c
 */

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

int main( int argc, char *argv[] )
{
    if(CU_initialize_registry()) {
        fprintf(stderr, " Initialization of Test Registry failed. ");
        exit(EXIT_FAILURE);
    } else {
        AddTests();
        CU_set_output_filename("TestMax");
        CU_list_tests_to_file();
        CU_automated_run_tests();
        CU_cleanup_registry();
    }
    return 0;
}


Makefile:
INC=-I/usr/local/cunit/include
LIB=-L/usr/local/cunit/lib

all: func.c test_func.c run_test.c
    gcc $^ -o test $(INC) $(LIB) -lcunit -static
--------------------------------------------------------------------------------
3. 编译并运行测试程序
$ make
$ ./test
--------------------------------------------------------------------------------
4. 查看测试结果

将 {$prefix}/share/CUnit/ 下的

 CUnit-List.dtd
 CUnit-List.xsl
 CUnit-Run.dtd
 CUnit-Run.xsl

与测试所生成的

 TestMax-Listing.xml
 TestMax-Results.xml

文件放在同一文件夹并用浏览器打开

2012年2月11日土曜日

[工具使用] 代码排版 astyle

1. 安装
$ cd ../astyle/build/gcc
$ make
$ sudo make install

2. 编写 vim 插件文件
$ cat ~/.vim/plugin/astyle.vim
:if exists("g:loaded_astyle")
    :finish
:endif
:let g:loaded_astyle = 1
:let s:save_cpo = &cpo
:set cpo&vim

:function Astyle()
    :let l:pos = getpos(".")
    :%!astyle --style=k\&r --indent-switches --indent-cases
    :call setpos(".", pos)
:endfunction
:command F :call Astyle()

:let &cpo = s:save_cpo

3. 使用
$ vim filename
:F

2012年2月10日金曜日

[工具使用] VirtualBox 网络设置

1. NAT (网络地址转换模式)

1-1. 虚拟主机不真实存在于网络中
1-2. Host 和 Host 网络中的任何主机都不能直接访问虚拟主机, 各虚拟主机也互不相通
1-3. 虚拟主机能访问 Host, 以及 Host 能访问的任何主机
1-4. 虚拟主机访问网络是先通过 VBox 转换后再发送出去的, 数据接收也是先由 VBox 接收后再转换转发到虚拟主机
1-5. 虚拟主机网络参数默认从 VBox 的虚拟 DHCP 服务器获取
IP地址      10.0.x.15
子网掩码    255.255.255.0
网 关       10.0.x.2
DNS         10.0.x.3
1-6. VBox 端口转发
设置特定的端口供实体网络访问虚拟主机, 设置发送到 Host 的某些端口转发到虚拟主机
--------------------------------------------------------------------------------
2. Bridged Adapter (桥接模式)

2-1. 虚拟主机通过 VBox 桥接到 Host 的一个网卡中像真实存在的一台主机
2-2. 虚拟主机能与 Host 和 Host 网络中的主机完美互通
2-3. 被桥接的网卡会开启混杂模式
2-4. 配置成桥接的 Host 网卡的同一网段, 或通过宿主机网络中的 DHCP 服务器获取
2-5. 如果 Host 在一个受限制的网络虚拟主机不能访问互联网的, 如: Host 使用 ADSL, 使用使用代理或 VPN, Host 网关做了 MAC 地址限制等
--------------------------------------------------------------------------------
3. Internal (内部模式)

3-1. 虚拟机与外界完全分开, 虚拟机与 Host 网络不能互通
3-2. 只有虚拟网卡同名 (intnet 等) 的内部网络模式的虚拟机之间才能互访
3-3. 默认不分配 IP, 在同一网段内, IP 手动自由设置
3-4. 不同过宿主环境, 可以高速通信
--------------------------------------------------------------------------------
4. Host-only Adapter (宿主机模式)

4-1. Host 可以访问虚拟主机
4-2. VBox 在 Host 中虚拟一 host-only 网卡, 然后把虚拟主机桥接到 host-only 网卡上
4-3. 可以通过设置 host-only 网卡 (共享, 桥接) 来实现网络连接
4-4. 默认 IP 段为 192.168.56.X/24, 可以通过 VirtualBox 的文件->环境设置->网络来配置
--------------------------------------------------------------------------------
5. VBox 其它问题

虽然 VBox 桥接模式非常好用, 但是受限制的网络你怎么办呢?
给虚拟主机添加两个网卡, 一个网卡使用 NAT 模式, 另一个网卡使用桥接模式,
然后给虚拟主机设置静态路由, 设置访问宿主机的数据从桥接模式的网卡送出,
而访问互联网的数据从 NAT 模式的网卡送去

[工具使用] quickfix & vimgdb 的使用

1. quickfix

1-1. 使用创建的 Makefile 或 makeprg 命令进行编译
$ vim hello.c
:set makeprg=gcc\ -Wall\ -ohello\ hello.c (空格用 \ 转义)
:make (编译)

1-2. 默认快捷键
:cc   显示详细错误信息 ( :help :cc )
:cp   跳到上一个错误 ( :help :cp )
:cn   跳到下一个错误 ( :help :cn )
:cl   列出所有错误 ( :help :cl )
:cw   如果有错误列表, 则打开quickfix窗口 ( :help :cw )
:col  到前一个旧的错误列表 ( :help :col )
:cnew 到后一个较新的错误列表 ( :help :cnew )

1-3. 自定义快捷键
$ cat ~/vimrc
autocmd FileType c,cpp  map <buffer> <leader><space> :w<cr>:make<cr>
nmap <leader>cn :cn<cr>
nmap <leader>cp :cp<cr>
nmap <leader>cw :cw 10<cr>
--------------------------------------------------------------------------------
2. vimgdb

2-1. 编译安装 vim 和 vimgdb
$ 移动到 vim72 vimgdb 上层目录
$ patch -d vim72 --backup -p0 < vimgdb/vim72.diff
$ cd vim72/src
$ make
$ sudo make install
$ tar zxvf vimgdb_runtime.tgz
$ 复制解压缩后的文件夹或文件到 ~/.vim 路径, 如下
.
|-- doc
|   |-- gdb.txt
|-- macros
|   `-- gdb_mappings.vim
`-- syntax
    |-- gdb.vim
    |-- gdbvar.vim
    `-- gdbvim.vim

$ vim
:helptags ~/.vim/doc
:help vimgdb

2-2. 安装 gdb
$ rpm -qa | grep gdb

2-3. 修改 vimgdb 绑定键

2-3-1. ~/.vim/macros/gdb_mappings.vim
在 nmap <F7> :call <SID>Toggle()<CR> 后添加
" ---------- add start ---------- "
nunmap <F7>
nmap <F4> :call <SID>Toggle()<CR>
" ---------- add end ---------- "

在 let s:gdb_k = 0 后添加
" ---------- add start ---------- "
if ! exists("g:vimgdb_debug_file")
    let g:vimgdb_debug_file = ""
elseif g:vimgdb_debug_file == ""
    call inputsave()
    let g:vimgdb_debug_file = input("File: ", "", "file")
    call inputrestore()
endif
call gdb("file " . g:vimgdb_debug_file)

map <Space> :call gdb("")<CR>
nmap <silent> <C-Z> :call gdb("\032")<CR>
" ---------- add end ---------- "

在 nmap <silent> <C-X> :call gdb("print *" . expand("<cword>"))<CR> 后面添加
" ---------- add start ---------- "
nunmap S
nunmap <C-N>
nunmap F
nunmap R
nunmap C
nmap <silent> <F5> :call gdb("step")<CR>
nmap <silent> <F6> :call gdb("next")<CR>
nmap <silent> <F7> :call gdb("finish")<CR>
nmap <silent> <F8> :call gdb("continue")<CR>
nmap <silent> <F9> :call gdb("run")<CR>
" ---------- add end ---------- "

在 nunmap <C-X> 后添加
" ---------- add start ---------- "
nunmap <F4>
nunmap <F5>
nunmap <F6>
nunmap <F7>
nunmap <F8>
nunmap <F9>
" ---------- add end ---------- "

在 map vimGdb keys 后修改
" ---------- edit start ---------- "
" call s:Toggle()
" ---------- edit end ---------- "

2-3-2. ~/.vimrc (添加)
" ---------- vimgdb settings start ---------- "
map <silent> <F2> :bel 25vsplit gdb-variables<CR>
set splitbelow
set nosplitright
set previewheight=50
let g:vimgdb_debug_file = ""
run macros/gdb_mappings.vim
" ---------- vimgdb settings end ---------- "

3. 使用
3-1. 带参数的程序调试时
<空格>, 在 gdb 命令窗口输入 run 参数1 参数2 的形式来启动程序

2012年2月9日木曜日

[LINUX 基础] yum 设置

1. 指定本地源
yum 命令直接指定 repo 文件, 或禁用其他 repo 直接使用 yum 命令
$ mount /dev/cdrom /mnt/dvd
$ yum -c /etc/yum.repo.d/local.repo install heartbeat
$ cat /etc/yum.repo.d/local.repo
[local]
name=CentOS DVD $releasever - $basearch
baseurl=file:///mnt/dvd
enable=1
gpgcheck=1
gpgkey=file:///mnt/dvd/RPM-GPG-KEY-CentOS-5

2. 只下载安装 64 位包
$ vim /etc/yum.conf
exclude=*.i?86

3. 删除已经安装上的 64 位包
$ yum remove \*.i\?86

4. 超时设置
$ vim /etc/yum.conf
timeout=60

5. yum 下载包保存位置
可以在每个源文件中设置
$ cat /etc/yum.conf
cachedir=/var/cache/yum #存放目录
keepcache=1 #1为保存, 0为不保存
metadata_expire=1800 #过期时间

6. 更新源设置
6-1. 导入 KEY
# rpm --import http://ftp.riken.jp/Linux/centos/5/os/i386/RPM-GPG-KEY-CentOS-5
保存在 /etc/pki/rpm-gpg/ 下

6-2. 编辑
# vi /etc/yum.repos.d/CentOS-Base.repo
--
[base]
name=CentOS-$releasever - Base
baseurl=http://ftp.riken.jp/Linux/centos/$releasever/os/$basearch/
gpgcheck=1

[updates]
name=CentOS-$releasever - Updates
baseurl=http://ftp.riken.jp/Linux/centos/$releasever/updates/$basearch/
gpgcheck=1

[addons]
name=CentOS-$releasever - Addons
baseurl=http://ftp.riken.jp/Linux/centos/$releasever/addons/$basearch/
gpgcheck=1

[extras]
name=CentOS-$releasever - Extras
baseurl=http://ftp.riken.jp/Linux/centos/$releasever/extras/$basearch/
gpgcheck=1

[centosplus]
name=CentOS-$releasever - Plus
baseurl=http://ftp.riken.jp/Linux/centos/$releasever/centosplus/$basearch/
gpgcheck=1

[contrib]
name=CentOS-$releasever - Contrib
baseurl=http://ftp.riken.jp/Linux/centos/$releasever/contrib/$basearch/
gpgcheck=1
--

6-3. 测试
# yum update kernel

[工具使用] 虚拟终端 tmux

http://d.hatena.ne.jp/kakurasan/20100310/p1
http://ameblo.jp/principia-ca/entry-10966932882.html

2012年2月8日水曜日

[LINUX 基础] 文件分割合并 split

1. 按行数分割文件 (默认 1000 行), 文件名为 out.aa out.ab ...
$ split -l 2 filename out.

2. 按大小分割文件 (默认 byte )
$ split -b 100 filename
$ split -b 100k filename

3. 合并文件
$ cat out.* > filename

[Shell 基础] shell 书写技巧

1. ls

1-1. 按文件扩展名排序 (升序)
$ ls -lX
$ ls -lXr

1-2. 按文件大小排序 (大到小)
$ ls -lS
$ ls -lSr
================================================================================
2. mv

2-1. 有同名文件存在则做备份 (finename~)
$ mv -b filename dir/
================================================================================
3. mkdir

3-1. 创建多层文件夹
$ mkdir -p aaa/bbb/ccc

3-2. 创建时指定访问权限
$ mkdir -m 755 dirname
================================================================================
4. cp

4-1. 保持文件权限更新时间等信息
$ cp -p filename filename.bak
$ cp -a filename filename.bak => -dpR

4-2. 保持文件夹构造和权限等信息
$ cp -p -r fromdir/ todir/
$ cp -a -r fromdir/ todir/ => -dpR

4-3. 复制多个文件
$ cp fromdir/{aaa,bbb} todir/

4-4. 服务器间复制
$ scp fromdir/filename to_server:todir/
$ scp from_server:fromdir/filename todir/

4-5. 复制文件
$ cp /tmp/file.log{.bak} # file.log.bak -> file.log
================================================================================
5. 创建空文件
$ echo -n > filename
$ mktemp filename.XXX (自动生成 XXX 随机字符串)
================================================================================
6. 创建指定大小的文件 (1M)
dd if=/dev/zero of=/tmp/yourfile bs=1024 count=1024
dd if=/dev/zero of=/tmp/yourfile bs=1 seek=1M count=0
dd if=/dev/random of=/tmp/yourfile bs=1 seek=1M count=0 (不容易被压缩的数据)
================================================================================
7. $() 与 ``
内部的字符串当工作命令来执行
$() : 其内部可以包含 ``
``  : 其内部不可以包含 ``
================================================================================
8. 引号区别
8-1. 单引号
为了保护文字不被转换, 除了他本身
就是说除去单引号外, 在单引号内的所有文字都是原样输出

8-1. 双引号
为了包含文字或者函数段, 除了本身, 反引号内的函数
$开头的变量和\开头反转换的字符外, 其余都是直接输出

8-1. 反单引号
函数转换, 但单引号内其无作用
================================================================================




--------------------------------------------------------------------------------
yes "123" | fmt -w 3 | head -n 10
--------------------------------------------------------------------------------

[Shell 基础] shell 注意事项

1. rm

1-1. 文件名带空格时加双引号
$ rm "file name"

1-2. -开头的文件名删除时加路径
$ rm ./-filename
$ rm /home/hoge/-filename

[LINUX 基础] 系统启动关闭

1. 系统重启

# shutdown -r now
# reboot
# fastboot (快速重启, 不检查文件系统)

2. 系统关闭

# shutdown -h now
# halt

# init 0
# fasthalt
# shutdown -h 0:0 (指定时间点关闭)

[LINUX 基础] 别名 alias 设置

1. 别名设定
1-1.
$ alias lsa='ls -a'

1-2.
$ vim ~/.bashrc
alias lsa='ls -a'

2. 显示左右别名
$ alias

3. 删除别名
$ vim ~/.bashrc
$ unalias lsa

2012年2月7日火曜日

[LINUX 基础] 程序前后台运行

1. 让程序在后台执行
$ command &

2. 查看当前后台运行的程序
$ jobs

3. 暂停当前程序, 转向后台
Ctrl + z

4. 将后台程序转到前台执行
$ fg %1

5. 让暂停后的程序在后台继续运行
$ bg %2

2012年2月5日日曜日

[工具使用] vim 代码自动补齐

http://easwy.com/blog/archives/advanced-vim-skills-omin-complete/

1. 安装 ctags
下载 : http://ctags.sourceforge.net/
$ ./configure --prefix=/usr/local/ctags-x.x
$ make && make install
$ /etc/bashrc (追加)
# ctags settings
export PATH=$PATH:/usr/local/ctags-x.x/bin

$ source /etc/bashrc
--------------------------------------------------------------------------------
2. 安装 taglist 插件
下载 : http://sourceforge.net/projects/vim-taglist/files/

解压后的文件路径
~/.vim/plugin/taglist.vim (taglist插件)
~/.vim/doc/taglist.txt    (taglist帮助文件)

在 vim 中生成帮助标签
:helptags ~/.vim/doc

在 vim 中查看 taglist 帮助
:help taglist.txt

在 taglist 窗口中的快捷键

<CR>    跳到光标下tag所定义的位置,用鼠标双击此tag功能也一样
o       在一个新打开的窗口中显示光标下tag
<Space> 显示光标下tag的原型定义
u       更新taglist窗口中的tag
s       更改排序方式,在按名字排序和按出现顺序排序间切换
x       taglist窗口放大和缩小,方便查看较长的tag
+       打开一个折叠,同zo
-       将tag折叠起来,同zc
*       打开所有的折叠,同zR
=       将所有tag折叠起来,同zM
[[      跳到前一个文件
]]      跳到后一个文件
q       关闭taglist窗口
<F1>    显示帮助
--------------------------------------------------------------------------------
3. 安装 OmniCppComplete 插件
下载 : http://www.vim.org/scripts/script.php?script_id=1520

$ unzip omnicppcomplete-x.x.zip
$ mv doc/omnicppcomplete.txt ~/.vim/doc/ -v
$ mv autoload after ~/.vim/ -v

$ cp /usr/share/vim/vim70/vimrc_example.vim ~/.vimrc
$ vim ~/.vimrc
" custom settings
set tabstop=4
set softtabstop=4
set shiftwidth=4
set expandtab
set number

" -- ctags --
" map <ctrl>+F12 to generate ctags for current folder:
" map <C-F12> :!ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .<CR><CR>
" add tags file to available tags
set tags+=/usr/local/src/postgresql-x.x.x/src/tags

" taglist settings
map <silent> <F12> :TlistToggle<CR>
let Tlist_Show_One_File = 1
let Tlist_Exit_OnlyWindow = 1
let Tlist_Use_Right_Window = 1
let Tlist_File_Fold_Auto_Close = 1
let Tlist_GainFocus_On_ToggleOpen = 1
let Tlist_Ctags_Cmd = "/usr/local/ctags-x.x/bin/ctags"
" let Tlist_Auto_Open = 1
" let Tlist_WinHeight = 20
" let Tlist_WinWidth = 20
" let Tlist_Use_Horiz_Window = 1

" --- OmniCppComplete Start ---
" -- required --
set nocp " non vi compatible mode
" filetype plugin on " enable plugins

" -- optional --
" auto close options when exiting insert mode
autocmd InsertLeave * if pumvisible() == 0|pclose|endif
set completeopt=menu,menuone

" -- configs --
let OmniCpp_MayCompleteDot = 1 " autocomplete with .
let OmniCpp_MayCompleteArrow = 1 " autocomplete with ->
let OmniCpp_MayCompleteScope = 1 " autocomplete with ::
let OmniCpp_SelectFirstItem = 2 " select first item (but don't insert)
let OmniCpp_NamespaceSearch = 2 " search namespaces in this and included files
let OmniCpp_ShowPrototypeInAbbr = 1 " show function prototype (i.e. parameters) in popup window
let OmniCpp_GlobalScopeSearch = 1
let OmniCpp_DisplayMode = 1
let OmniCpp_DefaultNamespaces = ["std"]

" --- OmniCppComplete End ---

" {{{ Autocompletion using the TAB key
" This function determines, wether we are on the start of the line text (then
" tab indents) or
" if we want to try autocompletion
function! InsertTabWrapper()
    let col = col('.') - 1
    if !col || getline('.')[col - 1] !~ '\k'
        return "\<TAB>"
    else
        if pumvisible()
            return "\<C-N>"
        else
            return "\<C-N>\<C-P>"
        endif
    endif
endfunction
" Remap the tab key to select action with InsertTabWrapper
inoremap <tab> <c-r>=InsertTabWrapper()<cr>
" }}} Autocompletion using the TAB key
--------------------------------------------------------------------------------
4. 使用

4-1. 跳转到定义
Ctrl + ']'

4-2. 返回
Ctrl + 't'

$ cd /usr/local/src/postgresql-9.1.2/src

$ ctags -R --langmap=c:+.h --languages=c,php --exclude=*.in (只包含*.c和*.h和*.php 文件, 不包含 *.in 文件)
$ ctags --list-maps (查看支持语言类型)
$ ll tags
-rw-rw-r-- 1 go go 4927781  2月  6 10:21 tags
$ vim bin/psql/startup.c