Ctags intro

Any self-respecting IDE should implement click-and-jump functionality. You click on a function and automatically jump to its definition. You click on a variable and jump to its declaration. Stuff like that.

To achieve that in a multi-file C or C++ program, we need to build a database of all the names or symbols that have been declared. Ctags is a wondeful program doing exactly what we need.

 

Installing Ctags

I use Universal Ctags as it seems to be the best maintained branch of Ctags:
https://ctags.io/
You can download the latest Ctags Windows executables here:
https://github.com/universal-ctags/ctags-win32/releases
Unzip the folder and put the contents in a logical place, like:
C:\Program Files\ctags
Last but not least, add this location to your Windows PATH variable.

 

Generate a tag-file

Open your terminal and navigate to the folder where all your source code is:

    C:\Users\Kristof>cd C:\Users\Kristof\...\source
    
    C:\Users\Kristof\...\source>ctags -R --output-format=json > tag.tg
    
    C:\Users\Kristof\...\source>
    

In the top folder of your C-source code, you should execute the command ctags -R –output-format=json > tag.tg. Ctags will parse all the source code recursively and build an output json-file in the top folder named tag.tg.

This tag-file is a long list of entries, each encapsulated in { } curly braces. Every entry starts on a new line. This tag-file is essentially a database of names and symbols used in your C-code. Each entry has several fields, like:

  • _type
  • name
  • path
  • pattern
  • typeref
  • kind
  • scope
  • scopeKind

Here is an example of an entry:

{
    "_type": "tag",
    "name": "HAL_TIM_ActiveChannel",
    "path": "Drivers\\STM32F7xx_HAL_Driver\\Inc\\stm32f7xx_hal_tim.h",
    "pattern": "/^}HAL_TIM_ActiveChannel;$/",
    "typeref": "__anon0bc4ec500a03",
    "kind": "typedef"
}

Please note that I’ve presented this entry on multiple lines to make it more readable. But in the tag.tg file, every entry fills only one line!
Also note that the fields scope and scopeKind are not present for this particular entry.