1806f296cSHadriel Kaplan# 2806f296cSHadriel Kaplan# cmake.ctags --- multitable regex parser for CMake's files 3806f296cSHadriel Kaplan# 4806f296cSHadriel Kaplan# Copyright (c) 2018, 128 Technology, Inc. 5806f296cSHadriel Kaplan# 6806f296cSHadriel Kaplan# Author: Hadriel Kaplan (hadrielk@yahoo.com) 7806f296cSHadriel Kaplan# 8806f296cSHadriel Kaplan# This source code is released for free distribution under the terms of the 9806f296cSHadriel Kaplan# GNU General Public License version 2 or (at your option) any later version. 10806f296cSHadriel Kaplan# 11806f296cSHadriel Kaplan# 12806f296cSHadriel Kaplan# Overview: 13806f296cSHadriel Kaplan# 14806f296cSHadriel Kaplan# This universal-ctags optlib option file defines the parser for tagging 15806f296cSHadriel Kaplan# CMake files. It supports tagging the following: 16806f296cSHadriel Kaplan# 17806f296cSHadriel Kaplan# - cmake function and macro names 18806f296cSHadriel Kaplan# - build target, executable, and library target names 19806f296cSHadriel Kaplan# - cmake variables and options 20806f296cSHadriel Kaplan# - cmake project names 21806f296cSHadriel Kaplan# 22806f296cSHadriel Kaplan# Caveats: 23806f296cSHadriel Kaplan# 24806f296cSHadriel Kaplan# Names that are ${} references to variables are not tagged. 25806f296cSHadriel Kaplan# 26806f296cSHadriel Kaplan# For example, given the following: 27806f296cSHadriel Kaplan# 28806f296cSHadriel Kaplan# set(PROJECT_NAME_STR ${PROJECT_NAME}) 29806f296cSHadriel Kaplan# add_executable( ${PROJECT_NAME_STR} ... ) 30806f296cSHadriel Kaplan# add_custom_target( ${PROJECT_NAME_STR}_tests ... ) 31806f296cSHadriel Kaplan# add_library( sharedlib ... ) 32806f296cSHadriel Kaplan# 33806f296cSHadriel Kaplan# the variable 'PROJECT_NAME_STR' and target 'sharedlib' will both be tagged, 34806f296cSHadriel Kaplan# but the other targets will not be. 35806f296cSHadriel Kaplan# 36806f296cSHadriel Kaplan# 37806f296cSHadriel Kaplan# References: 38806f296cSHadriel Kaplan# 39806f296cSHadriel Kaplan# - https://cmake.org/cmake/help/latest/manual/cmake-language.7.html 40806f296cSHadriel Kaplan# 41806f296cSHadriel Kaplan 42806f296cSHadriel Kaplan--langdef=CMake 43806f296cSHadriel Kaplan--map-CMake=+.cmake 44806f296cSHadriel Kaplan--map-CMake=+(CMakeLists.txt) 45806f296cSHadriel Kaplan 46806f296cSHadriel Kaplan# 47806f296cSHadriel Kaplan# Kinds 48806f296cSHadriel Kaplan# 49806f296cSHadriel Kaplan--kinddef-CMake=f,function,functions 50806f296cSHadriel Kaplan--kinddef-CMake=m,macro,macros 51806f296cSHadriel Kaplan--kinddef-CMake=t,target,targets 52806f296cSHadriel Kaplan--kinddef-CMake=v,variable,variable definitions 53806f296cSHadriel Kaplan--kinddef-CMake=D,option,options specified with -D 54806f296cSHadriel Kaplan--kinddef-CMake=p,project,projects 55806f296cSHadriel Kaplan 56806f296cSHadriel Kaplan# 57806f296cSHadriel Kaplan# Tables 58806f296cSHadriel Kaplan# 59806f296cSHadriel Kaplan--_tabledef-CMake=main 60806f296cSHadriel Kaplan--_tabledef-CMake=variable 61*3e144175SHadriel Kaplan--_tabledef-CMake=variableScoped 62806f296cSHadriel Kaplan--_tabledef-CMake=function 63806f296cSHadriel Kaplan--_tabledef-CMake=macro 64806f296cSHadriel Kaplan--_tabledef-CMake=target 65806f296cSHadriel Kaplan--_tabledef-CMake=option 66806f296cSHadriel Kaplan--_tabledef-CMake=project 67806f296cSHadriel Kaplan 68806f296cSHadriel Kaplan# 69806f296cSHadriel Kaplan# comment 70806f296cSHadriel Kaplan# 71806f296cSHadriel Kaplan--_tabledef-CMake=commentBegin 72806f296cSHadriel Kaplan--_tabledef-CMake=commentMultiline 73806f296cSHadriel Kaplan 74806f296cSHadriel Kaplan--_mtable-regex-CMake=commentBegin/\[\[//{tjump=commentMultiline} 75806f296cSHadriel Kaplan--_mtable-regex-CMake=commentBegin/[^\n]*[ \t\n]*//{tleave} 76806f296cSHadriel Kaplan 77806f296cSHadriel Kaplan--_mtable-regex-CMake=commentMultiline/\]\][ \t\n]*//{tleave} 78806f296cSHadriel Kaplan--_mtable-regex-CMake=commentMultiline/.[^]]*// 79806f296cSHadriel Kaplan 80806f296cSHadriel Kaplan--_tabledef-CMake=skipComment 81806f296cSHadriel Kaplan--_mtable-regex-CMake=skipComment/#//{tenter=commentBegin} 82806f296cSHadriel Kaplan 83806f296cSHadriel Kaplan# 84806f296cSHadriel Kaplan# Utilities 85806f296cSHadriel Kaplan# 86806f296cSHadriel Kaplan--_tabledef-CMake=skipWhiteSpace 87806f296cSHadriel Kaplan--_tabledef-CMake=skipToName 88806f296cSHadriel Kaplan--_tabledef-CMake=nextToken 89806f296cSHadriel Kaplan 90806f296cSHadriel Kaplan--_mtable-regex-CMake=skipWhiteSpace/[ \t\n]+// 91806f296cSHadriel Kaplan 92806f296cSHadriel Kaplan--_mtable-extend-CMake=skipToName+skipWhiteSpace 93806f296cSHadriel Kaplan--_mtable-extend-CMake=skipToName+skipComment 94806f296cSHadriel Kaplan 95806f296cSHadriel Kaplan--_mtable-regex-CMake=nextToken/[^ \t\n]+[ \t\n]*// 96806f296cSHadriel Kaplan 97806f296cSHadriel Kaplan# 98806f296cSHadriel Kaplan# main 99806f296cSHadriel Kaplan# 100806f296cSHadriel Kaplan# This first regex entry may seem odd - it's purely for improving performance, by 101806f296cSHadriel Kaplan# matching tokens with leading characters that could not possibly match a later regex, 102806f296cSHadriel Kaplan# and just skipping the whole token (and trailing whitespace). This one regex line 103806f296cSHadriel Kaplan# improved performance by an order of magnitude. 104806f296cSHadriel Kaplan--_mtable-regex-CMake=main/[^sSfFmMaAoOpP# \t\n][^ #\t\n]*[ \t\n]+// 105806f296cSHadriel Kaplan--_mtable-extend-CMake=main+skipComment 106806f296cSHadriel Kaplan--_mtable-regex-CMake=main/set[ \t]*\(//{icase}{tenter=variable} 107806f296cSHadriel Kaplan--_mtable-regex-CMake=main/function[ \t]*\(//{icase}{tenter=function} 108806f296cSHadriel Kaplan--_mtable-regex-CMake=main/macro[ \t]*\(//{icase}{tenter=macro} 109806f296cSHadriel Kaplan--_mtable-regex-CMake=main/add_(custom_target|executable|library)[ \t]*\(//{icase}{tenter=target} 110806f296cSHadriel Kaplan--_mtable-regex-CMake=main/option[ \t]*\(//{icase}{tenter=option} 111806f296cSHadriel Kaplan--_mtable-regex-CMake=main/project[ \t]*\(//{icase}{tenter=project} 112806f296cSHadriel Kaplan--_mtable-extend-CMake=main+nextToken 113806f296cSHadriel Kaplan--_mtable-extend-CMake=main+skipWhiteSpace 114806f296cSHadriel Kaplan 115*3e144175SHadriel Kaplan# 116*3e144175SHadriel Kaplan# For performance reasons, this is a separate table from 'main', mostly to avoid 117*3e144175SHadriel Kaplan# matching tokens starting with 'e' in the main table - such tokens are very 118*3e144175SHadriel Kaplan# common in CMake, due to 'endif()' and such 119*3e144175SHadriel Kaplan# 120*3e144175SHadriel Kaplan--_tabledef-CMake=inFunction 121*3e144175SHadriel Kaplan--_mtable-regex-CMake=inFunction/([^eEsSfFmMaAoO# \t\n]|[eE][^nN]|[eE][nN][^dD]|[eE][nN][dD][^fF#])[^ #\t\n]*[ \t\n]+// 122*3e144175SHadriel Kaplan--_mtable-extend-CMake=inFunction+skipComment 123*3e144175SHadriel Kaplan--_mtable-regex-CMake=inFunction/set[ \t]*\(//{icase}{tenter=variableScoped} 124*3e144175SHadriel Kaplan--_mtable-regex-CMake=inFunction/function[ \t]*\(//{icase}{tenter=function} 125*3e144175SHadriel Kaplan--_mtable-regex-CMake=inFunction/macro[ \t]*\(//{icase}{tenter=macro} 126*3e144175SHadriel Kaplan--_mtable-regex-CMake=inFunction/endfunction[ \t]*\([^)]*\)//{icase}{tleave}{scope=pop} 127*3e144175SHadriel Kaplan--_mtable-regex-CMake=inFunction/add_(custom_target|executable|library)[ \t]*\(//{icase}{tenter=target} 128*3e144175SHadriel Kaplan--_mtable-regex-CMake=inFunction/option[ \t]*\(//{icase}{tenter=option} 129*3e144175SHadriel Kaplan--_mtable-extend-CMake=inFunction+nextToken 130*3e144175SHadriel Kaplan--_mtable-extend-CMake=inFunction+skipWhiteSpace 131806f296cSHadriel Kaplan 132806f296cSHadriel Kaplan# 133806f296cSHadriel Kaplan# Each of the following basically work the same way, and only differ in the 134806f296cSHadriel Kaplan# exact pattern allowed to be their name, and the Kind they add. Note that they 135806f296cSHadriel Kaplan# capture a required trailing '[ \t\n\)]' or '#', to verify the full name token 136806f296cSHadriel Kaplan# matched the name's pattern, but then we advanceTo=2start for the next round, 137806f296cSHadriel Kaplan# so that we don't go past a potential '#' comment token but instead match it 138806f296cSHadriel Kaplan# again in the main table as a comment. The odds of a comment '#' immediately 139806f296cSHadriel Kaplan# following the name is very low, so we split it into its own check and do it 140806f296cSHadriel Kaplan# last in each table - this improves real-world performance ~10%, because in 141806f296cSHadriel Kaplan# the common case we can capture the whitespace at the same time as the name, 142806f296cSHadriel Kaplan# and not have to skip it again in the 'main' table. 143806f296cSHadriel Kaplan# 144806f296cSHadriel Kaplan 145806f296cSHadriel Kaplan# 146806f296cSHadriel Kaplan# variable 147806f296cSHadriel Kaplan# 148806f296cSHadriel Kaplan--_mtable-regex-CMake=variable/([A-Za-z0-9_.-]+)[ \t\n\)]+/\1/v/{tleave} 149806f296cSHadriel Kaplan--_mtable-extend-CMake=variable+skipToName 150806f296cSHadriel Kaplan--_mtable-regex-CMake=variable/([A-Za-z0-9_.-]+)(#)/\1/v/{tleave}{_advanceTo=2start} 151806f296cSHadriel Kaplan 152*3e144175SHadriel Kaplan# when a variable is defined inside a function, we reference its scope unless it 153*3e144175SHadriel Kaplan# has a PARENT_SCOPE argument; unfortunately the regex for this can backtrack a 154*3e144175SHadriel Kaplan# lot and the current ctags regex engine doesn't do lazy or atomic/possessive 155*3e144175SHadriel Kaplan# captures to avoid it, but in practice this should be ok 156*3e144175SHadriel Kaplan--_tabledef-CMake=inVariable 157*3e144175SHadriel Kaplan--_mtable-regex-CMake=inVariable/[^")]+(("(\\"|[^"])*")([^")]+("(\\"|[^"])*"))*)[ \t\n]PARENT_SCOPE[# \t\n)]//{tjump=variable}{_advanceTo=0start} 158*3e144175SHadriel Kaplan--_mtable-regex-CMake=inVariable/([A-Za-z0-9_.-]+)[ \t\n\)]+/\1/v/{tleave}{scope=ref} 159*3e144175SHadriel Kaplan--_mtable-regex-CMake=inVariable/([A-Za-z0-9_.-]+)(#)/\1/v/{tleave}{scope=ref}{_advanceTo=2start} 160*3e144175SHadriel Kaplan 161*3e144175SHadriel Kaplan--_mtable-regex-CMake=variableScoped/[A-Za-z0-9_.-]+[# \t\n\)]//{tjump=inVariable}{_advanceTo=0start} 162*3e144175SHadriel Kaplan--_mtable-extend-CMake=variableScoped+skipToName 163*3e144175SHadriel Kaplan 164*3e144175SHadriel Kaplan 165806f296cSHadriel Kaplan# 166806f296cSHadriel Kaplan# function 167806f296cSHadriel Kaplan# 168*3e144175SHadriel Kaplan--_mtable-regex-CMake=function/([A-Za-z_][A-Za-z0-9_]*)([# \t\n\)])/\1/f/{_advanceTo=2start}{tjump=inFunction}{scope=push} 169806f296cSHadriel Kaplan--_mtable-extend-CMake=function+skipToName 170806f296cSHadriel Kaplan 171806f296cSHadriel Kaplan# 172*3e144175SHadriel Kaplan# macro: unlike functions, technically macros don't create scopes for any 173*3e144175SHadriel Kaplan# variables set in them - the scope is whatever it is when the macro is invoked. 174*3e144175SHadriel Kaplan# So we're not going to push a scope nor go into the 'inFunction' table. 175806f296cSHadriel Kaplan# 176806f296cSHadriel Kaplan--_mtable-regex-CMake=macro/([A-Za-z_][A-Za-z0-9_]*)[ \t\n\)]+/\1/m/{tleave} 177806f296cSHadriel Kaplan--_mtable-extend-CMake=macro+skipToName 178806f296cSHadriel Kaplan--_mtable-regex-CMake=macro/([A-Za-z_][A-Za-z0-9_]*)(#)/\1/m/{tleave}{_advanceTo=2start} 179806f296cSHadriel Kaplan 180806f296cSHadriel Kaplan# 181806f296cSHadriel Kaplan# target 182806f296cSHadriel Kaplan# 183806f296cSHadriel Kaplan--_mtable-regex-CMake=target/([A-Za-z0-9_.-]+)[ \t\n\)]+/\1/t/{tleave} 184806f296cSHadriel Kaplan--_mtable-extend-CMake=target+skipToName 185806f296cSHadriel Kaplan--_mtable-regex-CMake=target/([A-Za-z0-9_.-]+)(#)/\1/t/{tleave}{_advanceTo=2start} 186806f296cSHadriel Kaplan 187806f296cSHadriel Kaplan# 188806f296cSHadriel Kaplan# option 189806f296cSHadriel Kaplan# 190806f296cSHadriel Kaplan--_mtable-regex-CMake=option/([A-Za-z0-9_.-]+)[ \t\n\)]+/\1/D/{tleave} 191806f296cSHadriel Kaplan--_mtable-extend-CMake=option+skipToName 192806f296cSHadriel Kaplan--_mtable-regex-CMake=option/([A-Za-z0-9_.-]+)(#)/\1/D/{tleave}{_advanceTo=2start} 193806f296cSHadriel Kaplan 194806f296cSHadriel Kaplan# 195806f296cSHadriel Kaplan# project 196806f296cSHadriel Kaplan# 197806f296cSHadriel Kaplan--_mtable-regex-CMake=project/([A-Za-z0-9_.-]+)([# \t\n\)])/\1/p/{tleave}{_advanceTo=2start} 198806f296cSHadriel Kaplan--_mtable-extend-CMake=project+skipToName 199