ctags 工具介紹

轉載自易水博客 [ http://easwy.com/blog/ ]http://easwy.com/blog/archives/exuberant-ctags-chinese-manual


[譯序]

(Easwy) First of all, I would like to thank the author of Exuberate Ctags, Darren Hiebert,
without his help, I cannot finish the work.

翻譯這個手冊的想法,最初源於我在寫“使用VIM開發軟件項目”系列文章(現在改名爲”vim使用進階“時。當時看到大家在使用 ctags 時,
基本都是用 "ctags -R"。其實 ctags 所擁有的能力並不止這些。它的衆多選項可以讓你方便的控制標籤文件的
內容,甚至你可以自己定義一種語言,由 ctags 爲它生成標籤文件 (這方面的例子,可見下面的鏈接:
http://ctags.sourceforge.net/EXTENDING.html)

你可以在我的BLOG上找到最新版本的譯文: http://easwy.com/blog/
譯文可自由使用,轉載請保留譯序部分。
======

NAME
ctags – 爲源代碼產生標籤文件

SYNOPSIS
ctags [options] [file(s)]

etags [options] [file(s)]

DESCRIPTION
ctags 和 etags 程序 (下文中統稱爲 ctags,除非特別指明) 爲文件中的各種語言對象生成一個索引
(或稱爲標籤) 文件。標籤文件允許這些項目能夠被一個文本編輯器或其它工具簡捷迅速的定位。一個
“標籤”是指一個語言對象,它對應着一個有效的索引項 (或者換言之,這個索引項爲這個對象而創建)。

可選的,ctags 能夠爲多種程序語言文件的語言對象信息生成可讀格式的交叉索引列表。

標籤索引文件被多種編輯器支持。這些編輯器允許用戶通過出現在源文件中的名字定位對象,並且跳轉到
定義這個名字的文件和行。在這個版本發佈時,我們所知的編輯器包括:

Vi(1)及其變種(例如,Elvis, Vim, Vile, Lemmy), CRiSP, Emacs, FTE (Folding Text Editor),
JED, jEdit, Mined, NEdit (Nirvana Edit), TSE (The SemWare Editor), UltraEdit, WorkSpace,
X2, Zeus

Ctags可以爲許多種不同的程序語言產生不同類型的標籤。要獲得完整的程序語言支持列表、它們被識別
的名字、爲它們所產生的標籤的的類型,請見 –list-languages 和 –list-kinds 選項。

SOURCE FILES
除非定義了 –language-force 選項,每個源文件的語言類型將根據文件名到程序語言名的映射自動選擇。
每種程序語言的映射可以通過 –list-maps 選項查看,並且可以通過 –langmap 選項修改。在支持的平
臺上,如果文件的名字沒有映射到一種程序語言並且這個文件是可執行的,將檢查文件的第一行,看該文
件是不是一種可識別編程語言的 "#!" 腳本。
缺省的,所有其它文件都被忽略。這允許在一個目錄的所有文件上執行 ctags (例如,"ctags *" ),或
在整個源代碼目錄樹的所有文件上執行 ctags (例如,"ctags -R")。因爲只有那些文件名被映射到一種
程序語言的文件纔會被掃描。

[ .h 擴展名的文件被映射爲 C++ 文件而不是 C 文件的原因是 .h 擴展名也應用於 C++ 語言,並且把它
當做 C++ 文件對待並沒有害處]

OPTIONS
儘管擁有大量的選項,ctags 設置了缺省值 (適合多數情況),因此通常不帶任何選項來執行 ctags (例
如,ctags *,或ctags -R),這將爲當前目錄下所有可識別的源文件生成一個標籤文件。下面提供的選項
僅僅爲了在有特殊需要時允許用戶自定義。

需注意,用來分隔單字母選項和它們參數的空格是可選的。

同樣需注意,長格式選項的布爾型參數 (那些以 "–" 開頭並且帶 "[=yes|no]" 參數的選項) 可以被省
略,在這種情況下隱含爲 "=yes" ,而 "=0" 和 "=off" 被認爲是 "=no" 。

某些選項在以 etags 模式運行時或被忽略,或會起作用 (見 -e 選項)。這樣的選項會特殊註明。

絕大多數選項可以出現在命令行的任意位置,隻影響在該選項後面的文件。然而,少數選項必須出現在第
一個文件名之前,這樣的選項也會特殊註明。
帶程序語言名字的選項允許名字是大寫或小寫。見 –list-languages 選項,以獲得內建程序語言名的完
整列表。

-a 等同於 –append

-B 使用向上查找的模式 (例如 ?pattern?)。 [在 etags 模式中忽略]

-e 使能 etags 模式,這將創建 Emacs 編輯器使用的標籤文件。可選的,如果包含 "etags" 調用
ctags 時 (通過重命名,或者創建符號鏈接到可執行文件的方式),會使能 etags 模式。這個選項
必須出現在第一個文件名之前。

-f tagfile
使用所指定的 tagfile 做爲標籤文件的名字 (缺省是 "tags",或 "TAGS" 當以etags模式運行時)。
如果 tagfile 被定義成 "-",那麼標籤文件被輸出到標準輸出。如果 tagfile 存在並且它的第一
行不是有效的標籤行時,ctags 將拒絕執行。如果你錯誤的輸入了 "ctags -f *.c",這會救你一命,
不然它會把其它文件所產生的標籤覆蓋到你的第一個 C 文件! ctags 也會拒絕接受以一個 "-" (減
號)開頭的文件名,因爲這很可能是你忘記輸入標籤文件的名字,而本選項試圖把它後面的選項做爲
文件名。如果你真的想把你的輸出標籤文件名命名爲 "-ugly",把它定義成 "./-ugly"。這個選項
必須出現在第一個文件名之前。如果這個選項出現多次,只有最後一個生效。

-F 使用向下查找的模式 (例如 /pattern/) (缺省)。 [在 etags 模式中忽略]

-h list
定義一個文件擴展名列表,以句號分隔,這些文件將做爲包含文件(或頭文件)被解析。要指定沒有
擴展名的文件,用一個句號,後面不跟句號以外的字符 (例如,".","..x",".x.")。這個選項只
影響如何解析一種特定類型的標籤的作用域 (也就是說,這些標籤是全局可見,還是這些標籤只在
定義它們的文件中可見);它並不把這些擴展名映射到任何特定的程序語言。任何位於非頭文件中的
標籤,如果不能被另外一個文件可見 (例如,鏈接到另外一個文件),那麼它的作用域被認爲侷限於
該文件 (例如,static)。在頭文件中的所有類型的標籤,它的作用域都不會被認爲侷限於該文件。
如果列表中的第一個字符是加號,那麼該列表中的擴展名將被加到現有列表之後;否則,該列表將
替換現有列表。另外,參見 –file-scope 選項。缺省的列表是 ".h.H.hh.hpp.hxx.h++.inc.def"。
要恢復缺省列表,使用 -h default。注意,如果此選項指定的一個擴展名還沒有被映射到一種特定
的程序語言 (見上面的 SOURCE FILES),你也需要使用 –langmap 或 –language-force 選項。

-I identifier-list
定義一個標識符列表,在解析 C 和 C++ 源文件時會對這些標識符進行特殊的處理。這個選項主要
用來處理由於編譯預處理宏的使用而引發的特殊情況。當列出的標識符是簡單的標識符時,這些標
識符在解析源文件時會被忽略。如果一個標識符以 "+" 字符做爲結尾,ctags 將忽略源文件中緊跟
在此標識符後的被括號括起來的參數列表。如果兩個標識符以 "=" 字符分隔,在解析時,第一個標
識符將被第二個標識符所替代。標識符列表可以直接在命令行上提供,也可以從一個單獨的文件中
讀出。如果 identifier-list 的第一個字符是 "@",".",或目錄分隔符 ("/" 或 ""), 或前兩個
字符是驅動器的盤符 (例如,"C:"),identifier-list 參數將被解釋爲一個文件名,從這個文件中
讀取標識符列表,每行一個標識符。否則,identifier-list 是需要被特殊處理的標識符的列表
(或一組標識符對的列表),每一個標識符被逗號或空格分開,(如果以空格分隔,需要用引號把整個
列表括起來,以使整個列表做爲一個命令行參數)。可以使用多個 -I 選項。要清除已定義的標識符
列表,以 "-" 做爲 identifier-list 參數。

這個特性在編譯預處理宏的出現會導致句法混淆的時候非常有用。實際上,這是解決源文件中干擾
語法的宏所引發的問題的最好辦法 (見下面的 CAVEATS)。下面的例子詳細描述這點。

int foo ARGDECL4(void *, ptr, long int, nbytes)

在上面的例子中,宏 "ARGDECL4" 將被錯誤的解釋爲函數的名字,而不是正確的名字 "foo"。定義
-I ARGDECL4 會獲得正確的結果。

/* creates an RCS version string in module */
MODULE_VERSION("$Revision: 1.41 $")

在上面的例子,宏定義看起來非常像一個函數的定義,因爲它沒有以分號結尾 (實際上,它後面甚
至還可以跟一個全局變量定義,這樣看起來更像一個 K&R 風格的函數參數定義)。實際上,在試圖
完成這個看起來像函數的定義時,可能會導致文件的其它部分被跳過。定義 -I MODULE_VERSION+
可以避免這樣的問題。

CLASS Example {
// your content here
};

上面的例子使用了 "CLASS" 做爲預處理宏,它在不同的平臺上被擴展爲不同的東西。例如,在
Win32 平臺上它可能被定義爲 "class __declspec(dllexport)",而在 UNIX 上簡單的被定義爲
"class"。通常,沒有 C++ 的 "class" 關鍵字將導致源文件被錯誤的解析。定義 -I CLASS=class
能夠得到正確的結果。

-L file
在文件 file 中讀取需要產生標籤文件的文件列表。如果 file 被指定爲 "-",那麼文件列表由標
準輸入上讀取。通過這個選項讀到的文件將在命令行上給出的文件之後被處理。輸入中的選項也會
被接受 (*1)。如果此選項被定義多次,只使用最後一個。注意:file 以行的方式被讀取,只以換
行符做爲分隔符,空格被認爲是有意義的,這是爲了支持文件名中包含空格的情況;如果輸入中包
含選項,這會影響選項如何被解析 (*2)。

-n 同 –excmd=number。

-N 同 –excmd=pattern。

-o tagfile
同 -f tagfile。

-R 同 –recurse。

-u 同 –sort=no (也就是 "unsorted",不排序)。

-V 同 –verbose。

-w 此選項被悄悄忽略。僅爲兼容 SVR4 Unix 的 ctags。

-x 打印一個表格形式的、可讀的交叉索引 (xref) 文件到標準輸出,而不是產生一個標籤文件。輸出
的信息包括:標籤名字;標籤類型;行號,文件名和標籤所定義行的內容 (多餘的空格被壓縮)。不
會寫標籤文件,並且所有影響標籤文件輸出的選項都被忽略。這個特性的一個應用實例是爲源文件
中定義的函數生成一個列表 (例如,ctags -x –c-kinds=f file),或爲源文件中所有外部可見全
局變量生成一個列表 (例如,ctags -x –c-kinds=v –file-scope=no file)。這個選項必須出現
在第一個文件名之前。

–append[=yes|no]
指明爲指定文件生成的標籤是增加到標籤文件已存在內容的後面,還是替換它們。此選項缺省關閉。
這個選項必須出現在第一個文件名之前。

–etags-include=file
在標籤文件中包含一個到 file 的引用。此選項可以被指定任意多次。這個選項支持 Emacs 在一個
標籤文件中包含另外一個標籤文件的功能。[只在 etags 模式中有效]

–exclude=[pattern]
將 pattern 加到排除文件/目錄列表中。這個選項可以被指定任意多次。對每一個 ctags 處理的文
件名,都會把該文件的完整路徑 (例如,some/path/base.ext) 以及文件名 (例如,base.ext) 與
此選項定義的每個 pattern 進行比較,這允許 pattern 只匹配一個給定的文件名而不管其路徑,
或者只匹配一個指定的路徑。如果你所用的 C 編譯器的運行庫支持,那麼 pattern 中可以包含
Unix 上通用的 shell 通配符 (不是正則表達式) (確保把這個選項的參數用引號括起來,以保證通
配符在傳給 ctags 之前不會被 shell 擴展;另外,要知道通配符可以匹配 "/" 字符)。 你可以通
過檢查 –version 選項的輸出來確定在你的平臺上 shell 通配符是否可用,(如果可用,) 在編譯
的特性表中將包含 "+wildcards";否則將通過簡單的文本比較來檢查 pattern 與文件名的匹配。

如果 pattern 以字符 "@" 開始,那麼剩餘的字符串將被解釋成一個文件的名字,由此文件中讀取
排除模式字串,每行一個。如果 pattern 爲空,排除列表將被清空。注意,在程序啓動時,缺省的
排除列表包含"EIFGEN","SCCS","RCS",和"CVS",這些是在處理 –recurse 選項時不想意外進入
的目錄名。

–excmd=type
定義在源文件中定位標籤時所用的 EX 命令的類型。[在 etags 模式中忽略]

type 的有效值爲 (用整個單詞或用第一個字母都可以):

number 在標籤文件中只使用行號來定位標籤。這有4個優點:
1. 明顯減小最終標籤文件的大小。
2. 消除因爲定義標籤的行被修改而導致使用 pattern 查找標籤失敗的情況,導致模式
匹配失敗 (注意,有些編輯器,例如vim, 夠在很多這樣的情況中恢復)。
3. 消除在查找雷同的匹配時,找到不正確的源碼行的情況 (見下面的 BUGS)。
4. 在標籤文件中爲內容相同的行保留多個不同的表項。在 pattern 模式,重複的表項
被丟棄,因爲它們產生的查找字串是相同的,保存重複的表項沒有意義。

但是,這個選項有一個顯著的缺點:對源文件的更改會導致標籤文件中的行號記錄不再對
應源文件的行號,導致跳轉到某些標籤時偏離標籤定義位置一行或多行。大體上講,這個
選項最好用在那些不打算更改的源文件上。選擇這個選項導致下面的選項被忽略:-BF。

pattern 對所有標籤只使用搜索字串,與行號不同,行號通常用於宏定義。優點是標籤文件產生後,
增加或刪除行不會引用 到舊的行號。

mixed 在這個模式,除少數例外,通常都使用搜索字串。對 C 語言,行號用於宏定義標籤。這
是原始的 ctags 生成的缺省格式,因此,保留這個選項的缺省值。對 Fortran,common
塊使用行號,因爲它們的源碼行通常都相同,使搜索模式在查找所有匹配時沒有用處。

–extra=[+|-]flags
指定是否爲特定類型的信息增加額外的標籤條目。flags 參數是一組單字母標記,每個代表標籤文
件中的一種額外的標籤條目。如果 flags 前帶 "+" 或 "-" 字符,會向當前生效的標記中加入,或
刪除這些標記。否則 flags 替代當前的設置。每個標記的含義如下:

f 爲每個源文件的文件名包含一個條目 (例如,"example.c"),它定位到文件的第一行。

q 爲每個類成員包含一個額外的類修飾符條目 (爲那些支持這類信息的編程語言;當前包括
C++, Eiffel 和 Java)。修飾符標籤的實際格式取決於定義該標籤的語言 (使用這種語言中
修飾符被定義的那種格式)。對 C++來說,格式爲 "class::member";對 Eiffel 和 Java,
格式爲 "class.member"。當標籤文件中一個標籤的名字出現多次時,這將更容易的定位到
特定的標籤。然而需注意,這有可能使標籤文件的大小不止增加一倍。

–fields=[+|-]flags
定義標籤文件表項中的有效擴展字段 (見下面的 TAG FILE FORMAT,以獲得更多信息)。flags 參數
是一組單個字母標記, 每一個代表一種類型的擴展字段,具有如下含義 (缺省爲禁用,除非下面有
註明):

a 類成員的訪問控制信息
f 作用域局部於文件 [使能]
i (關於)繼承的信息
k 使用一個字符表示的標籤類型 [使能]
K 標籤類型的完整名稱
l 包含該標籤的源文件的編程語言類型
m (關於)實現的信息
n 標籤出現的行號
s 標籤的範圍 [使能]
S 函數的指紋 (例如,原型或參數列表)
z 在 kind 字段中包含 "kind:" 關鍵字
t 把變量或 typedef 的類型和名字做爲 "typeref:" 字段 [使能] (*3)

每個字母或字母組合的前面可以爲 "+" ,表示將它加到缺省集合,或者爲 "-",表示排除它。如果
既沒有 "+" 前綴也沒有 "-"前綴,只有在 flags 中明確列出的類型被包含在輸出中 (也就是說,
覆蓋缺省集合)。如果 –format=1 選項定義了,此選項被忽略。此選項缺省值爲 "fkst"。

–file-scope[=yes|no]
指明作用域只在一個文件的標籤 (即只在定義它們的文件中可見,不能被其它文件見到的標籤,例
如 "static" 的標籤) 是否被包含在輸出中。又見 -h 選項。這個選項缺省使能。

–filter[=yes|no]
使 ctags 表現的像一個過濾器,由標準輸入讀取文件的名字,並一個文件接一個文件的輸出它們的
標籤。如果 –sorted 選項使能,只對文件內定義的標籤排序。文件由標準輸入上按行讀入 (見 -L
選項的備註 ),並且這些文件在命令行及 -L 選項指定的文件之後處理。本選項使能時, -f,-o
和 –totals 選項被忽略。這個選項太過高深,缺省爲禁用。這個選項必須出現在第一個文件名之前。

–filter-terminator=string
在 –filter 選項使能時,定義一個字符串,在一個文件的標籤解析完後,會打印這個字符串到標
準輸出。這允許讀取 ctags 輸出的應用程序能夠確定一個文件的輸出在什麼時候結束。注意,如果
讀入文件名是一個目錄,並且 –recurse 選項使能,這個字符串只在該目錄中的所有標籤之後輸出
一次。這個字符串總是被文件的最後一個標籤的換行符隔開。這個選項太過高深,缺省爲空。這個
選項必須出現在第一個文件名之前。

–format=level
改變輸出標籤文件的格式。當前有效的 level 只有 1 或 2。級別1指定原始的標籤文件格式,級別2
指定一種新的擴展格式,裏面包含擴展字段 (但使用了一種手段,使之仍後向兼容原始的 vi(1)
現)。缺省的級別爲 2。這個選項必須出現在第一個文件名之前。 [在 etags 模式中忽略]

–help
向標準輸出打印一個詳細用法描述,然後退出。

–if0[=yes|no]
指定是否對於 "#if 0" 編譯預處理分支中的非宏標籤進行檢查 (宏標籤總被包含)。因爲這種構造
是爲了禁用代碼,所以此選項的缺省值爲 no。注意,這只是指明一種偏好,並不能保證在 "#if 0"
分支中的代碼真的被跳過,因爲產生標籤的算法會在編譯預處理條件太複雜時會解析條件編譯的每
一個分支。

–<LANG>-kinds=[+|-]kinds
爲特定的編程語言指定一個與語言相關的標籤種類 (或類型) 的列表,這些內容會被包含在輸出文
件中,在這裏 <LANG> 不區分大小寫,並且是內建語言名的一種 (見 –list-languages 選項以獲
得完整列表)。kinds 參數是一組單字母標記,用來指明 (特定於這種語言的) 標籤類型是包含在輸
出中,還是不包含。這些特定標記集基於每種程序語言被識別,它們的含義以及缺省值可以由
–list-kinds 選項列出。每個字母或組合可以以 "+" 做前綴,表示在缺省值中加入它,或者以 "-"
做前綴,表示在缺省值中排除它。如果不以 "+" 或 "-" 爲前綴,只有在 kinds 中明確列出的類型
被包含在輸出中 (就是說,覆蓋這種編程語言的缺省值)。

做爲 C 語言的一個例子,要想在缺省標籤類型中加入函數原型和外部變量定義,但是排除宏定義,
使用 –c-kinds=+px-d;要想只包含函數的標籤,使用 –c-kinds=f。

–langdef=name
定義一種新的用戶自定義語言,name,使用正則表達式進行解析。一旦被定義,name 可以在其它使
用程序語言名字的選項中被使用。這個選項的典型用法是,先定義這種語言,然後使用 –langmap
把文件名映射到它,最後使用 –regex-<LANG> 定義它的標籤如何被解析。

–langmap=map[,map[...]]
控制文件名如何被映射到程序語言 (見 –list-maps 選項)。每個以逗號分隔的映射中,包含語言
的名字 (內建語言或用戶自定義語言),一個冒號,以及一個文件擴展名和/或文件名模式的列表。
要定義一個文件擴展名,在此擴展名前加上句號 (例如,".c")。要定義一個文件名模式,把這個模
式用括號括起來 (例如,"([Mm]ake-file)")。如果你的 C 編譯器的運行庫支持,那麼文件名模式
中可以包含 Unix 中通用的 shell 通配符 (確保用引號把參數括起來,以保護通配符在傳給 ctags
之前不會被 shell 擴展)。 你可以通過檢查 –version 選項的輸出來確定在你的平臺上 shell 通
配符是否可用,(如果可用,) 在編譯的特性表中將包含 "+wildcards";否則將通過簡單的文本比
較來檢查文件名模式與文件名的匹配。要映射一個 (已經使用的) 文件擴展名,首先要取消它與其
它語言的映射關係。

如果映射的第一個字符是一個 "+",那麼這個映射中的擴展名和文件名模式將加到這種語言的當前
映射中;否則,這個映射將替換當前映射。例如,爲了指定只有擴展名爲 .c 和 .x 的文件被當做
C 語言文件,使用 "–langmap=c:.c.x";想同時把擴展名爲 .j 的文件加到 Java 語言文件,定義
"–langmap=c:.c.x,java:+.j"。爲了把 makefiles (例如,文件名爲 "Makefile","makefile",
或具有擴展名 ".mak") 映射到一種稱爲 "make" 的語言,定義 "–langmap=make:([Mm]akefile).mak"。
想映射沒有擴展名的文件,定義一個句號,後面不包含句號以外字符 (例如,".","..x",".x.")。
想要爲一種特定的語言清除映射 (這會防止自動爲這個語言生成標籤),定義一個空的擴展名列表
(例如, "–langmap=fortran:")。想爲特定的語言恢復缺省的映射,將映射定義爲default。想爲
所有的語言恢復缺省的映射,定義 "–langmap=default"。
注意,在判別文件的程序語言時,文件擴展名先於文件名模式被判斷。

–language-force=language
缺省的,ctags 自動爲一個源文件選擇語言,忽略那些不能確定程序語言的文件 (見上面的 SOURCE
FILES)。這個選項強制把每個文件做爲指定程序語言 (不區分大小寫;內建或用戶自定義) 的文件,
而不是根據它們的擴展名自動爲其選擇語言類型。另外,特殊值 auto 表示語言類型應該被自動選
擇 (這否決的本選項的有效方法)。

–languages=[+|-]list
定義一個語言列表,將爲這些語言產生標籤,list 包含一個逗號分隔的語言名列表 (不區分大小寫;
內建或用戶自定義)。如果列表的第一個語言前面不是 "+" 或 "-" 字符,在向列表增加或從列表刪
除語言前,會先清空當前列表。列表的每個語言都將加入列表,直到遇到一個 "-"。因爲 "+" 或
"-" 都可以在列表中出現,在這兩個符號後面的語言就相應被加到列表,或從列表中去掉。這樣,
使用一個新的列表替換當前列表,或者從當前列表中增加或刪除語言都變得很簡單。實際會生成標
籤的文件列表取決於生效的語言擴展名映射 (見 –langmap 選項)。注意,所有的語言,包括用戶
自定義的語言,(缺省)都是使能的,除非使用本選項禁止。列表中的語言名可以是任何內建語言或
一個先前被 –langdef 選項定義的語言。缺省值爲 "all",這也是一個可被接受的參數。見
–list-languages 選項以獲得一個完整的內建語言名稱。

–license
向標準輸出打印軟件許可證信息,然後退出。

–line-directives[=yes|no]
定義 "#line" 操作符是否應該被識別。它們存在於預處理器的輸出中,包括行號,可能還包括生成
這個預處理輸出的源文件的名字。當選項使能時,ctags 會生成標籤項目,將使用源文件的文件名
和行號,而不是它們在預處理器輸出中的位置。標籤文件中的實際文件名將和預處理器輸出文件具
有同樣的路徑,這是因爲它假設原始文件的位置相對於預處理器輸出文件 (當然,除非 #line 操作
符定義的是絕對路徑)。這個選項缺省關閉。注意:這個選項通常在和 –excmd-number (-n) 選項
一起使用才比較有用。你也需要使用 –langmap 或 –language-force 選項,如果 ctags 不能識
別預處理器輸出文件的擴展名的話。

–links[=yes|no]
指示是否跟蹤符號鏈接 (如果系統支持符號鏈接的話)。在禁止時,符號鏈接被忽略。這個選項缺省
打開。

–list-kinds[=language|all]
列出指定語言或全部語言所能夠識別的標籤種類,然後退出。在標籤文件中,每個種類的標籤都用
一個單字母的標記來表示,它也用於 –<LANG>-kinds 選項,用以過濾在輸出中所包含的標籤種類。
注意,有些語言和/或標籤種類可能用正則表達式來實現,如果正則表達式支持沒有編譯到 ctags
中,可能無法支持 (見 –regex-<LANG> 選項)。列出的每個種類都是使能的,除非後面跟有 "[off]"。

–list-maps[=language|all]
列出指定的語言或全部語言的文件擴展名和文件名模式,然後退出。這些擴展名以及文件名模式把
一個文件與特定程序語言相關聯。見上面的 –langmap 選項,以及 SOURCE FILES。

–list-languages
列出 ctags 能夠識別的程序語言名,然後退出。這些程序語言名稱不區分大小寫,可以用在
–language-force,–languages,–<LANG>-kinds 和–regex-<LANG> 選項。

–options=file
從 file 中讀取附加選項。做爲一種特殊情形,如果 –options=NONE 做爲命令行的第一個選項,
它將禁止自動從文件或環境變量 (見 FILES) 中讀取任何配置選項。

–recurse[=yes|no]
遞歸進入文件列表中所遇到的目錄。如果給出的文件列表爲空,並且沒有使用 -L 指定文件列表,
那麼當前目錄被使用 (也就是 ".")。符號鏈接將被跟蹤。如果你不喜歡這樣的處理,或者顯式的指
定文件列表,或者通過管道將 find(1) 的輸出傳給 "ctags -L-"。注意,這個選項當前並不能支持
所有的平臺。如果 –help 選項的輸出中包含本選項,說明它可用。又見 –exclude 選項,以限制
遞歸行爲。

–regex-<LANG>=/regexp/replacement/[kind-spec/][flags]
/regexp/replacement/ 定義一個正則表達式的替換串,與 sed 的 substitution 命令風格類似,
使用它爲映射到 <LANG> 語言 (不區分大小寫;內建程序語言,或用戶自定義程序語言) 的源文件
產生標籤。正則表達式 regexp 定義一個擴展正則表達式 (主要爲 egrep(1) 所用),它用來定位包
含標籤的一個源碼行,使用 t 來定義 tab 字符。當一個匹配行被發現,將會生成一個名爲
replacement 的標籤,replacement 通常會包含特殊的前向引用 1 到 9,以引用 regexp 中的子
表達式。選項參數中的 "/" 分隔字符實際上可以換成任何字符。注意,不管使用哪個分隔符,如果
它在參數中不做分隔用,必須使用 "" 字符對其進行轉義。
本選項定義的正則表達式會被添加到這種語言當前的正則表達式列表中,除非省略選項參數,這種
情況當前列表會被清空。
除非由 flags 做出更改,否則 regexp 被作爲 Posix 擴展正則表達式解析。對於每個匹配行,
replacement 應該被擴展爲一個非空字符串,不然的話會產生一條告警信息。一個可選的標籤類型
定義可以跟在 replacement 後面,它用來指定在標籤的 "kind" 擴展字段裏寫入的類型 (見下面的
TAG FILE FORMAT)。kind-spec 的完整格式是一個單個字母,一個逗號,一個名字 (不包含空格),
一個逗號,一個描述,後面跟分隔符,這個格式定義了類型及其文本描述的長、短形式 (使用
–list-kinds 可以顯示出來)。類型的名字和/或類型的描述可以被省略。如果 kind-spec 被省略,
它的缺省值爲 "r,regex"。最後,flags 是一個或多個單字母字符,對 regexp 的解析有下列影響:

b 此模式被解析爲 Posix 的基本正則表達式

e 此模式被解析爲 Posix 的擴展正則表達式 (缺省)

i 此模式以忽略大小寫的方式被應用

注意,這個選項只在 ctags 編譯時加入正則表達式支持時纔有效,這取決於你所用的平臺。你可通
過檢查 –version 選項的輸出,以確定編譯時是否加入正則表達式支持,(如果支持),輸出的編譯
特性列表中將包含 "+regex"。

欲獲得 ctags 使用的正則表達式的詳細信息,見 regex(5,7) 的手冊頁,或見 regex 的 GUU info
文檔 (例如,"info regex")。

–sort[=yes|no|foldcase]
指明標籤文件是否按標籤名排序 (缺省爲排序)。注意,原始的 vi(1) 要求排序標籤。foldcase 指
定不區分大小寫排序 (或大小寫合併排序)。
對大小寫合併排序進行快速二叉樹查找需要由使用標籤文件的工具提供特殊支持,例如 ctags 的
readtags 庫,或 Vim 6.2 以上版本 (使用 "set ignorecase")。這個選項必須出現在第一個文件
名之前。[在 etags 模式中忽略]

–tag-relative[=yes|no]
指明標籤文件中記錄的名字路徑應該相對於標籤文件所在的目錄,而不是相對於當前目錄,除非命
令行所指定的文件名使用絕對路徑。這個選項必須出現在第一個文件名之前。當運行在 etags 模式
時,缺省爲 yes (見 -e 選項),否則缺省值爲 no。

–totals[=yes|no]
打印在本次 ctags 運行期間所讀入源文件以及所寫標籤的統計信息。這個選項缺省關閉。這個選項
必須出現在第一個文件名之前。

–verbose[=yes|no]
使能詳細模式。打印處理選項的信息,以及在 ctags 處理每個文件時打印一條簡潔的消息,描述採
取什麼樣的動作。通常,ctags 在配置文件中的選項 (見下面的 FILES) 以及 CTAGS 環境變量被讀
入前,不會讀取命令行參數。然而,如果本選項是命令行的第一個選項,它將在配置文件、CTAGS
環境變量,以及命令行上的每個選項被讀入前生效。缺省值爲 no。

–version
打印 ctags 的版本信息,然後退出。信息中始終包含字符串 "Exuberant Ctags"。

OPERATIONAL DETAILS
在 ctags 依次處理每個文件時,它試圖挨順序進行以下三步測試來確定文件的程序語言類型:是否文件
的擴展名被映射到一種程序語言,是否文件名匹配一個映射到程序語言的 shell 模式,最後判斷是否該
文件可執行並且它的第一行使用 Unix 風格的 "#!" 定義了一個解釋器 (如果平臺支持的話)。如果程序
語言確定了,這個文件會被打開,接下來相應的語言解析器被調用,以解析當前打開的文件。解析器解析
整個文件,並且在標籤文件中爲每個語言對象增加一個條目。見下面的 TAG FILE FORMAT,以獲得這些條
目的詳細信息。

這個 ctags 實現不像舊有的實現那樣,對 C 代碼的格式有要求。舊的實現往往依賴特殊的預定格式來幫
助它解決編譯預處理條件引發的困難。

通常,ctags 試圖更巧妙的處理翻譯預處理操作符。如果在一條定義了標籤的語句中遇到一個編譯預處理
條件,ctags 只跟隨此條件的第一個分支 (除非第一分支是 "#if 0" ,在這種情況下,只跟隨剩下的唯
一一條分支)。這樣做的原因是 (如果) 跟隨不只一條分支會導致語法不明確,就像下面例子:

#ifdef TWO_ALTERNATIVES
struct {
#else
union {
#endif
short a;
long b;
}

不能同時跟隨兩個分支,否則括號會不匹配,ctags 將不能識別語法。

由於這些條件很複雜,並且 (分支) 相互排斥,如果這種辦法不能正確的解析一個文件,ctags 將重新嘗
試另一種不同的方法,這種方法不併選擇性的跟隨條件預處理分支,而是在 #if 條件分支導致大括號不
匹配時,通過位於第 1 列的大括號 ("}") 來做爲一個代碼塊結束的指示。

Ctags 也嘗試對括在兩個圓括號中的參數列表進行特殊處理,以接受下面這樣的條件結構:

extern void foo __ARGS((int one, char two));

任何緊挨着 "((" 的名字都被自動忽略,而使用在它之前的名字。

C++ 的運算符定義會被特殊處理。爲了對所有種類的運算符 (重載或轉換) 保持一致,在標籤文件中,所
有運算符的名字總是以 "operator " 爲前綴 (也就是說,即使實際的運算符定義被寫成 "operator<<")。

在創建標籤文件,或向標籤文件中添加標籤後,將根據標籤的名字進行排序,刪除相同的標籤行。

TAG FILE FORMAT
在不以 etags 模式運行時,標籤文件中的每個表項佔單獨的一行,通常每個看起來都如同這樣:

tag_name<TAB>file_name<TAB>ex_cmd;"<TAB>extension_fields

字段以及分隔符定義如下:

1. 標籤名
2. 單個 tab 字符
3. 文件名,這個標籤對應的對象在此文件中定義
4. 單個 tab 字符
5. 在文件中定位此標籤的 EX 命令;通常是一個搜索模式 (/pattern/ 或 ?pattern?) 或行號 (見
–excmd)。標籤文件格式 2 (見 –format)
在某些情況下擴展了這個 EX 命令,在緊挨着此 EX 命令後面的 EX 命令註釋裏嵌入了一套擴展
字段 (在下面描述),這樣使它仍能向下兼容原始的 vi(1) 實現。

基於內部使用的目的,會向標籤文件中寫入一些特殊的標籤。這些標籤的構成使它們始終被排序到文件的
最前面。因此,這些標籤的前兩個字符被用做標籤文件的幻數,以確定正在寫入的是一個有效的標籤文件,
而不是一個源文件。

注意,記錄在標籤文件的每個源文件名,和命令行上定義的完全相同。因此,如果你在命令行上指定的是
相對於當前目錄的路徑的話,它們在標籤文件中以同樣的方式被記錄。然而,見 –tag-relative 選項,
以更改此設置。

如上所說,擴展字段作爲註釋增加在 EX 命令之後,是以 tab 字符分隔的 "關鍵字-值" 組合。這些 "關
鍵字-值" 組合一般爲 "key:value" 的格式。它們是否在標籤文件中出現,由 –fields 選項控制。可能
的關鍵字以及它們值的含義見下:

access 指明類成員的可見範圍,它的值特定於程序語言。

file 指明此標籤只在文件中可見。這個關鍵字沒有相應的值。

kind 指明標籤的類型,或種類。它的值要麼是上面 –<LANG>-kinds 選項所描述的相應單字母標
志,要麼是全名。此字段的關鍵字部分允許被省略 (實際上,這是缺省設置)。由 –fields
選項控制它的表現。

implementation
如果存在,它指明一個函數或類具有實現的限制 (抽象與具體),它的值特定於程序語言
(對 C++ 而言是 "virtual" 或 "pure virtual";對 Java 而言是 "abstract").

inherits 如果存在,值爲一個逗號分隔的類列表,這個類源於列表中的類 (也就是說,它由列表中的
類繼承而來)。

signature 如果存在,它的值是函數指紋,表示方法與程序語言相關。完整的函數指紋定義了此函數的
返回類型及它的參數列表格式。這個擴展字段當前只支持基於 C 的程序語言,並且不包括
返回類型。

另外,標籤作用域有關的信息也 (在標籤文件中) 可用,它的關鍵字部分是程序語言中的構造名稱,它的
值是程序中此構造的名字。作用域表項指明定義此標籤的範圍。例如,C 語言的結構成員所生成的標籤,
會包含一個作用域,看起來像這樣 "struct:myStruct"。

HOW TO USE WITH VI
Vi 缺省的期望當前工作目錄中有一個名爲 "tags" 的標籤文件。一旦生成了標籤文件,下面的命令執行
按標籤索引的特性:

vi -t tag 啓動 vi 並且把光標定位在 "tag" 定義所在的文件和行上。

:ta tag 查找一個標籤。

Ctrl-] 查找光標下的標籤

Ctrl-T 返回跳轉到標籤前的前一次位置 (不是所有實現都支持)。

HOW TO USE WITH GNU EMACS
Emacs 缺省的期望當前工作目錄中有一個名爲 "TAGS" 的標籤文件。一旦生成了標籤文件,下面的命令執
行按標籤索引的特性:

M-x visit-tags-table <RET> FILE <RET>
選擇所使用的標籤文件 "FILE"。

M-. [TAG] <RET>
查找第一個 TAG 定義。缺省的標籤是光標下的標識符。

M-* 跳回你先前調用 "M-." 的位置

C-u M-. 查找前一次所查找的標籤的下一個定義

閱讀 Emacs info 文檔的 Tags 主題,以瞭解更多命令。

HOW TO USE WITH NEDIT
NEdit 的 5.1 及以後版本可以處理新的擴展標籤文件格式 (見 –format)。要使 NEdit 使用標籤文件,
選擇 "File->Load Tags File"。要跳轉到一個標籤的定義,高亮這個標籤,然後按 Ctrl-D。NEdit 5.1
可以從不同的目錄讀取多個標籤文件。設置 X 資源中的 nedit.tagFile 爲標籤文件的名字,可以使
NEdit 在啓動時自動加載這個標籤文件。

CAVEATS
由於 ctags 既不是一個預處理器也不是一個編譯器,使用預處理宏會使 ctags 漏掉標籤或者錯誤的生成
不正確的標籤。雖然 ctags 已經被設計成處理一些的通用情況,但這依舊是提交最多的問題。特別是使
用預處理構造改變 C 的語法結構時,會欺騙 ctags。你可以通過使用 -I 選項避開很多這樣的問題。

(*4)
White space is treated as a separator for file names and options read from list files,
specified using the -L option, and in filter mode (specified using the –filter option).
Therefore, it is not currently possible to supply file names or other options contain-ing
embedded white space (spaces, etc.) through these options.

注意,當 ctags 使用模式字串來定位標籤時 (見 –excmd 選項),如果另外一個源碼行和包含這個標籤
的行完全相同,你的編輯器完全有可以跳到錯誤的行上。下面的例子說明這種情況:

int variable;

/* … */
void foo(variable)
int variable;
{
/* … */
}

取決於你所使用的編輯器,以及你在代碼中位置,搜索模式可能會在查找到真正的全局變量定義之前,查
找到 foo() 的局部參數聲明,因爲這兩行完全相同 (因此它們的搜索模式也相同)。這可以通過使用
–excmd=n 來避免。

BUGS
Ctags 具有比 ls(1) 更多的選項.

當解析一個 C++ 成員函數定義時 (例如,"className::function"),ctags 不能確定域分隔符是一個類
名分隔符還是一個 namespace 分隔符,總是把它做一個類名放在擴展字段的作用域部分。另外,如果一
個 C++ 函數定義在類定義外面 (通常都是這樣),函數定義中包含的訪問限定符 (即 public,protected
或 private) 以及實現信息 (例如 virtual,pure virtual) 在爲這個函數生成標籤時無法知道。然而,
對於原型,這些信息可用 (例如,–c++-kinds+=p)。

沒有爲繼承自一個類的語言對象產生標籤。

ENVIRONMENT VARIABLES
CTAGS 如果這個環境變量存在,在 ctags 啓動時會從此環境變量中讀取缺省選項,讀取發生在下面
FILES 一節中列出的配置文件之後,但在命令行選項之前。命令行中出現的選項會覆蓋此環境變
量中的選項。只從這個環境變量中讀取選項值。注意,環境變量中的所有空格都被認爲是分隔符,
這樣傳遞一個包含空格的選項參數是不可能的。如果這會導致問題,改用配置文件。

ETAGS 與上面的 CTAGS 類似,如果存在,它會在 etags 啓動時讀取。如果這個環境變量未找到,etags
將嘗試改用 CTAGS 環境變量。

TMPDIR 在支持 mkstemp() 的類 Unix 主機上,這個環境變量的值定義了存放臨時文件的目錄。這在臨
時文件太大導致缺省臨時文件目錄所在的分區無法裝下它時比較有用。ctags 只在下列情況時創
建臨時文件: (1) 生成一個 emacs 格式的標籤文件, (2) 標籤文件被輸出到標準輸出,
(3) 它被編譯成使用內部的排序算法來排序標籤文件,而不是使用操作系統的 sort 工具。如果
使用系統的 sort 工具,它通常也會使用這個變量。如果 ctags 是 setuid 的,TMPDIR 的值將
被忽略。

FILES
/ctags.cnf (只在 MSDOS,MSWindows)
/etc/ctags.conf
/usr/local/etc/ctags.conf
$HOME/.ctags (在 MSDOS, MSWindows 上是 $HOME/ctags.cnf)
.ctags (在 MSDOS,MSWindows上是 ctags.cnf)
如果這些配置文件中任一個存在,每個都應該包含一個缺省的選項集合,在 ctags 啓動時會按列
出的順序讀入這些選項,讀入的時刻發生在讀取 CTAGS 環境變量以及命令行選項之前。這使得設
置適用於整個系統、每個人或基於項目的缺省選項值成爲可能。在編譯 ctags 時爲它指定一個額
外的配置文件是可能的,它會在上面列出文件被讀入之前讀取,在 –version 選項輸出中的
"custom-conf" 指示這個特性可用。CTAGS 環境變量及命令行中選項會覆蓋這些文件中定義的選
項。只從這些文件中讀入選項值。注意,選項文件按行讀入,行內的空格有效 (因爲不能像 shell
那樣使用引號)。文件的每行被當做一個命令行參數 (就像它們被單引號括起來一樣)。因此,使
用換行符做爲命令行參數的分隔標誌。

tags ctags 生成的缺省標籤文件。

TAGS etags 生成的缺省標籤文件。

SEE ALSO
Exuberant Ctags 的官方網站在:

http://ctags.sourceforge.net

參閱 ex(1),vi(1),elvis,或更好的,vim,ctags 的正式編輯器。欲獲得 vim 的更多信息,請到
VIM 的 web 網站:

http://www.vim.org/

AUTHOR
Darren Hiebert <dhiebert at users.sourceforge.net>
http://DarrenHiebert.com/

MOTIVATION
"Think ye at all times of rendering some service to every member of the human race."

"All effort and exertion put forth by man from the fullness of his heart is worship, if it
is prompted by the highest motives and the will to do service to humanity."

— From the Baha’i Writings

CREDITS
這個版本的 ctags 最初繼承了 Steve Kirkendall <[email protected]> 的 ctags 並從中獲取靈感,
他的 ctags 伴隨 Elvis vi 變種發行 (雖然事實上沒有使用一行原來的代碼)。

榮譽也要歸於 Bram Moolenaar <[email protected]>,vim 的作者,他花費如此多的時間和精力開發這個編輯
器 (服務於他人) 以及幫助烏干達的孤兒。

名爲 "HOW TO USE WITH GNU EMACS" 的一節是從 GNU etags 的 info 文檔中 "偷來" 的。

Darren Hiebert Version 5.6 CTAGS(1)

譯者注:

(*1) 原文爲 "Options all also accepted in this input" 。經過與作者溝通,本句應爲 "Options also
accepted in this input"。意思是“在輸入中的選項也會被接受”,也就是說,可以在 file 中加入選項,
這些選項將會應用在其後出現的文件上。這提供了一種非常便捷的方式,允許用戶爲不同的文件指定不同的
選項。

(*2) 這句話意思是,因爲行內的空格被視爲有意義的,所以不能再以空格來分隔各個選項,而應該以換行符來分
隔多個選項。

(*3) 按譯者的理解,在使用類如 struct,union 這樣的複雜數據類型進行類型定義 (typedef) 或直接定義變量
時,會爲之增加 "typeref:" 字段。下面兩個例子中的代碼生成的標籤文件就包含此字段:
/* 定義類型 */
typedef struct abc
{
int a;
char b;
} abc;

/* 直接定義變量 */
union {
TEST1,
TEST2
} test;

(*4) 這段話與前面的選項解釋相牴觸,正在與作者溝通。

[譯文版本]
27Apr07, easwy, initial version
28Apr07, easwy, reformat it



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章