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