xref: /Universal-ctags/optlib/cmake.ctags (revision 3e144175b9049ff87b6eb5a369fd02d5542f8a23)
1#
2#  cmake.ctags --- multitable regex parser for CMake's files
3#
4#  Copyright (c) 2018, 128 Technology, Inc.
5#
6#  Author: Hadriel Kaplan (hadrielk@yahoo.com)
7#
8#  This source code is released for free distribution under the terms of the
9#  GNU General Public License version 2 or (at your option) any later version.
10#
11#
12# Overview:
13#
14#  This universal-ctags optlib option file defines the parser for tagging
15#  CMake files. It supports tagging the following:
16#
17#    - cmake function and macro names
18#    - build target, executable, and library target names
19#    - cmake variables and options
20#    - cmake project names
21#
22# Caveats:
23#
24#  Names that are ${} references to variables are not tagged.
25#
26#  For example, given the following:
27#
28#    set(PROJECT_NAME_STR ${PROJECT_NAME})
29#    add_executable( ${PROJECT_NAME_STR} ... )
30#    add_custom_target( ${PROJECT_NAME_STR}_tests ... )
31#    add_library( sharedlib ... )
32#
33#  the variable 'PROJECT_NAME_STR' and target 'sharedlib' will both be tagged,
34#  but the other targets will not be.
35#
36#
37# References:
38#
39# - https://cmake.org/cmake/help/latest/manual/cmake-language.7.html
40#
41
42--langdef=CMake
43--map-CMake=+.cmake
44--map-CMake=+(CMakeLists.txt)
45
46#
47# Kinds
48#
49--kinddef-CMake=f,function,functions
50--kinddef-CMake=m,macro,macros
51--kinddef-CMake=t,target,targets
52--kinddef-CMake=v,variable,variable definitions
53--kinddef-CMake=D,option,options specified with -D
54--kinddef-CMake=p,project,projects
55
56#
57# Tables
58#
59--_tabledef-CMake=main
60--_tabledef-CMake=variable
61--_tabledef-CMake=variableScoped
62--_tabledef-CMake=function
63--_tabledef-CMake=macro
64--_tabledef-CMake=target
65--_tabledef-CMake=option
66--_tabledef-CMake=project
67
68#
69# comment
70#
71--_tabledef-CMake=commentBegin
72--_tabledef-CMake=commentMultiline
73
74--_mtable-regex-CMake=commentBegin/\[\[//{tjump=commentMultiline}
75--_mtable-regex-CMake=commentBegin/[^\n]*[ \t\n]*//{tleave}
76
77--_mtable-regex-CMake=commentMultiline/\]\][ \t\n]*//{tleave}
78--_mtable-regex-CMake=commentMultiline/.[^]]*//
79
80--_tabledef-CMake=skipComment
81--_mtable-regex-CMake=skipComment/#//{tenter=commentBegin}
82
83#
84# Utilities
85#
86--_tabledef-CMake=skipWhiteSpace
87--_tabledef-CMake=skipToName
88--_tabledef-CMake=nextToken
89
90--_mtable-regex-CMake=skipWhiteSpace/[ \t\n]+//
91
92--_mtable-extend-CMake=skipToName+skipWhiteSpace
93--_mtable-extend-CMake=skipToName+skipComment
94
95--_mtable-regex-CMake=nextToken/[^ \t\n]+[ \t\n]*//
96
97#
98# main
99#
100# This first regex entry may seem odd - it's purely for improving performance, by
101# matching tokens with leading characters that could not possibly match a later regex,
102# and just skipping the whole token (and trailing whitespace). This one regex line
103# improved performance by an order of magnitude.
104--_mtable-regex-CMake=main/[^sSfFmMaAoOpP# \t\n][^ #\t\n]*[ \t\n]+//
105--_mtable-extend-CMake=main+skipComment
106--_mtable-regex-CMake=main/set[ \t]*\(//{icase}{tenter=variable}
107--_mtable-regex-CMake=main/function[ \t]*\(//{icase}{tenter=function}
108--_mtable-regex-CMake=main/macro[ \t]*\(//{icase}{tenter=macro}
109--_mtable-regex-CMake=main/add_(custom_target|executable|library)[ \t]*\(//{icase}{tenter=target}
110--_mtable-regex-CMake=main/option[ \t]*\(//{icase}{tenter=option}
111--_mtable-regex-CMake=main/project[ \t]*\(//{icase}{tenter=project}
112--_mtable-extend-CMake=main+nextToken
113--_mtable-extend-CMake=main+skipWhiteSpace
114
115#
116# For performance reasons, this is a separate table from 'main', mostly to avoid
117# matching tokens starting with 'e' in the main table - such tokens are very
118# common in CMake, due to 'endif()' and such
119#
120--_tabledef-CMake=inFunction
121--_mtable-regex-CMake=inFunction/([^eEsSfFmMaAoO# \t\n]|[eE][^nN]|[eE][nN][^dD]|[eE][nN][dD][^fF#])[^ #\t\n]*[ \t\n]+//
122--_mtable-extend-CMake=inFunction+skipComment
123--_mtable-regex-CMake=inFunction/set[ \t]*\(//{icase}{tenter=variableScoped}
124--_mtable-regex-CMake=inFunction/function[ \t]*\(//{icase}{tenter=function}
125--_mtable-regex-CMake=inFunction/macro[ \t]*\(//{icase}{tenter=macro}
126--_mtable-regex-CMake=inFunction/endfunction[ \t]*\([^)]*\)//{icase}{tleave}{scope=pop}
127--_mtable-regex-CMake=inFunction/add_(custom_target|executable|library)[ \t]*\(//{icase}{tenter=target}
128--_mtable-regex-CMake=inFunction/option[ \t]*\(//{icase}{tenter=option}
129--_mtable-extend-CMake=inFunction+nextToken
130--_mtable-extend-CMake=inFunction+skipWhiteSpace
131
132#
133# Each of the following basically work the same way, and only differ in the
134# exact pattern allowed to be their name, and the Kind they add. Note that they
135# capture a required trailing '[ \t\n\)]' or '#', to verify the full name token
136# matched the name's pattern, but then we advanceTo=2start for the next round,
137# so that we don't go past a potential '#' comment token but instead match it
138# again in the main table as a comment. The odds of a comment '#' immediately
139# following the name is very low, so we split it into its own check and do it
140# last in each table - this improves real-world performance ~10%, because in
141# the common case we can capture the whitespace at the same time as the name,
142# and not have to skip it again in the 'main' table.
143#
144
145#
146# variable
147#
148--_mtable-regex-CMake=variable/([A-Za-z0-9_.-]+)[ \t\n\)]+/\1/v/{tleave}
149--_mtable-extend-CMake=variable+skipToName
150--_mtable-regex-CMake=variable/([A-Za-z0-9_.-]+)(#)/\1/v/{tleave}{_advanceTo=2start}
151
152# when a variable is defined inside a function, we reference its scope unless it
153# has a PARENT_SCOPE argument; unfortunately the regex for this can backtrack a
154# lot and the current ctags regex engine doesn't do lazy or atomic/possessive
155# captures to avoid it, but in practice this should be ok
156--_tabledef-CMake=inVariable
157--_mtable-regex-CMake=inVariable/[^")]+(("(\\"|[^"])*")([^")]+("(\\"|[^"])*"))*)[ \t\n]PARENT_SCOPE[# \t\n)]//{tjump=variable}{_advanceTo=0start}
158--_mtable-regex-CMake=inVariable/([A-Za-z0-9_.-]+)[ \t\n\)]+/\1/v/{tleave}{scope=ref}
159--_mtable-regex-CMake=inVariable/([A-Za-z0-9_.-]+)(#)/\1/v/{tleave}{scope=ref}{_advanceTo=2start}
160
161--_mtable-regex-CMake=variableScoped/[A-Za-z0-9_.-]+[# \t\n\)]//{tjump=inVariable}{_advanceTo=0start}
162--_mtable-extend-CMake=variableScoped+skipToName
163
164
165#
166# function
167#
168--_mtable-regex-CMake=function/([A-Za-z_][A-Za-z0-9_]*)([# \t\n\)])/\1/f/{_advanceTo=2start}{tjump=inFunction}{scope=push}
169--_mtable-extend-CMake=function+skipToName
170
171#
172# macro: unlike functions, technically macros don't create scopes for any
173# variables set in them - the scope is whatever it is when the macro is invoked.
174# So we're not going to push a scope nor go into the 'inFunction' table.
175#
176--_mtable-regex-CMake=macro/([A-Za-z_][A-Za-z0-9_]*)[ \t\n\)]+/\1/m/{tleave}
177--_mtable-extend-CMake=macro+skipToName
178--_mtable-regex-CMake=macro/([A-Za-z_][A-Za-z0-9_]*)(#)/\1/m/{tleave}{_advanceTo=2start}
179
180#
181# target
182#
183--_mtable-regex-CMake=target/([A-Za-z0-9_.-]+)[ \t\n\)]+/\1/t/{tleave}
184--_mtable-extend-CMake=target+skipToName
185--_mtable-regex-CMake=target/([A-Za-z0-9_.-]+)(#)/\1/t/{tleave}{_advanceTo=2start}
186
187#
188# option
189#
190--_mtable-regex-CMake=option/([A-Za-z0-9_.-]+)[ \t\n\)]+/\1/D/{tleave}
191--_mtable-extend-CMake=option+skipToName
192--_mtable-regex-CMake=option/([A-Za-z0-9_.-]+)(#)/\1/D/{tleave}{_advanceTo=2start}
193
194#
195# project
196#
197--_mtable-regex-CMake=project/([A-Za-z0-9_.-]+)([# \t\n\)])/\1/p/{tleave}{_advanceTo=2start}
198--_mtable-extend-CMake=project+skipToName
199