cTags源码分析(1) – 概要


本文分析的是cTags5.8源代码,http://sourceforge.net/projects/ctags/ 可以从这里获得

main.c开始。

一开始cTags维护了一个自己的cookedArgs类型的参数列表,args。之后根据不同系统的情况,重新定义了argcargv

第一个函数setCurrentDirectory()定义在routines.c中,根据系统不同,定义了CurrentDirectory一个全局变量(使用getcwd()),并在最后增加了OUTPUT_PATH_SEPARATOR

第二个函数setExecutableName (*argv++)定义了ExecutableProgram(主文件路径)和ExecutableName(主文件名)两个全局变量。

第三个函数checkRegex()regex库的内部函数,检查regex能否正常工作.

之后,args = cArgNewFromArgv (argv)将默认的选项格式加以处理转换到args中.

previewFirstOption (args)处理-v和没有选项的情况(直接退出)。

testEtagsInvocation ()检测是否有-e选项,若有,则初始化etags

initializeParsing()是重要的一步,它检查每一个内建的语言,它们的名称是否合法,它们的regex是否存在,如果是,则将它们插入LanguageTable[]数组中。这个数组的成员类型是parserDefinition*,而parserDefinition的定义如下:

之后initializeParsing调用initializeParsers (),即循环调用每个LanguageTable[]中语言的LanguageTable[i]->initialize(),进行语言初始化工作(建立hash表等)。

接下来的一大步是initOptions(),设置默认选项,建立默认语言映射,自动添加.git等控制文件到--exclude选项中。

readOptionConfiguration ()读取目录下的.ctags配置文件与环境变量。

parseOptions (args)把之前简单分拆的选项细分成longOptionsshortOptions,并设置Options结构的相应位。

checkOptions()是对选项的静态检查。

makeTags(args),是最重要的部分,代码如下:

简而言之,就是以下几步:

  1. openTagFile (resize)打开Tag文件;
  2. 根据选项不同,分别调用createTagsForArgs (args)createTagsFromListFile (Option.fileList)createTagsFromFileInput (stdin, TRUE)recurseIntoDirectory ("."),而它们都调用了createTagsForEntry(filename),经过检查后,最终调用了parse.c中的parseFile(filename);
  3. closeTagFile (resize)关闭Tag文件。

最终,通过如下几步,free掉前几步申请的动态内存,防止内存泄漏: