From da4af9c233cc01339f77ddc99d136f74f3f8ec09 Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Wed, 28 Dec 2022 07:28:59 +0900 Subject: [PATCH] Texinfo: new parser Signed-off-by: Masatake YAMATO --- Tmain/list-params.d/run.sh | 7 + Tmain/list-roles-with-kind-names.d/run.sh | 2 +- .../stdout-expected.txt | 40 +- Tmain/list-roles.d/run.sh | 11 +- .../lisp-param-elisp.d/args.ctags | 2 + .../lisp-param-elisp.d/expected.tags | 1 + .../lisp-param-elisp.d/features | 1 + .../lisp-param-elisp.d/input.texi | 4 + .../lisp-param-scheme.d/args.ctags | 3 + .../lisp-param-scheme.d/expected.tags | 1 + .../lisp-param-scheme.d/features | 1 + .../lisp-param-scheme.d/input.texi | 4 + docs/news.rst | 1 + main/parsers_p.h | 3 +- optlib/texinfo.c | 402 ++++++++++++++++++ optlib/texinfo.ctags | 282 ++++++++++++ source.mak | 1 + 17 files changed, 741 insertions(+), 25 deletions(-) create mode 100644 Units/parser-texinfo.r/lisp-param-elisp.d/args.ctags create mode 100644 Units/parser-texinfo.r/lisp-param-elisp.d/expected.tags create mode 100644 Units/parser-texinfo.r/lisp-param-elisp.d/features create mode 100644 Units/parser-texinfo.r/lisp-param-elisp.d/input.texi create mode 100644 Units/parser-texinfo.r/lisp-param-scheme.d/args.ctags create mode 100644 Units/parser-texinfo.r/lisp-param-scheme.d/expected.tags create mode 100644 Units/parser-texinfo.r/lisp-param-scheme.d/features create mode 100644 Units/parser-texinfo.r/lisp-param-scheme.d/input.texi create mode 100644 optlib/texinfo.c create mode 100644 optlib/texinfo.ctags diff --git a/Tmain/list-params.d/run.sh b/Tmain/list-params.d/run.sh index 3ccb98bbdb..dfc841957b 100644 --- a/Tmain/list-params.d/run.sh +++ b/Tmain/list-params.d/run.sh @@ -4,6 +4,12 @@ CTAGS=$1 C="${CTAGS} --quiet --options=NONE" +ignore_pcre2() +{ + grep -v Texinfo +} + +{ echo '# ALL' ${C} --with-list-header=yes --list-params echo @@ -31,3 +37,4 @@ echo echo '# CPP MACHINABLE NOHEADER + PARAM DEFINE WITH CMDLINE' ${C} --_paramdef-CPreProcessor='pragma,handle program' --with-list-header=no --machinable --list-params=CPreProcessor echo +} | ignore_pcre2 diff --git a/Tmain/list-roles-with-kind-names.d/run.sh b/Tmain/list-roles-with-kind-names.d/run.sh index b4472aab75..05bb98f83b 100644 --- a/Tmain/list-roles-with-kind-names.d/run.sh +++ b/Tmain/list-roles-with-kind-names.d/run.sh @@ -7,7 +7,7 @@ echo '{header}' ${CTAGS} --list-roles=all.'{header}' echo '{header}I' -${CTAGS} --list-roles=all.'{header}I' +${CTAGS} --machinable=yes --list-roles=all.'{header}I' | grep -v Texinfo echo 'd{header}' ${CTAGS} --list-roles=all.'d{header}' diff --git a/Tmain/list-roles-with-kind-names.d/stdout-expected.txt b/Tmain/list-roles-with-kind-names.d/stdout-expected.txt index 5df6e078be..8d82b92f93 100644 --- a/Tmain/list-roles-with-kind-names.d/stdout-expected.txt +++ b/Tmain/list-roles-with-kind-names.d/stdout-expected.txt @@ -15,26 +15,26 @@ OldC++ h/header system on system header Vera h/header local on local header Vera h/header system on system header {header}I -#LANGUAGE KIND(L/N) NAME ENABLED DESCRIPTION -C h/header local on local header -C h/header system on system header -C++ h/header local on local header -C++ h/header system on system header -CPreProcessor h/header local on local header -CPreProcessor h/header system on system header -CUDA h/header local on local header -CUDA h/header system on system header -Flex I/import import on imports -M4 I/macrofile included on included macro -M4 I/macrofile sincluded on silently included macro -Make I/makefile included on included -Make I/makefile optional on optionally included -OldC h/header local on local header -OldC h/header system on system header -OldC++ h/header local on local header -OldC++ h/header system on system header -Vera h/header local on local header -Vera h/header system on system header +#LANGUAGE KIND(L/N) NAME ENABLED DESCRIPTION +C h/header local on local header +C h/header system on system header +C++ h/header local on local header +C++ h/header system on system header +CPreProcessor h/header local on local header +CPreProcessor h/header system on system header +CUDA h/header local on local header +CUDA h/header system on system header +Flex I/import import on imports +M4 I/macrofile included on included macro +M4 I/macrofile sincluded on silently included macro +Make I/makefile included on included +Make I/makefile optional on optionally included +OldC h/header local on local header +OldC h/header system on system header +OldC++ h/header local on local header +OldC++ h/header system on system header +Vera h/header local on local header +Vera h/header system on system header d{header} #LANGUAGE KIND(L/N) NAME ENABLED DESCRIPTION Automake d/directory data on directory for DATA primary diff --git a/Tmain/list-roles.d/run.sh b/Tmain/list-roles.d/run.sh index febabbb946..faac8cc24d 100644 --- a/Tmain/list-roles.d/run.sh +++ b/Tmain/list-roles.d/run.sh @@ -33,17 +33,22 @@ ignore_old() grep -v '^Old' } +ignore_pcre2() +{ + grep -v '^Texinfo' +} + title '' -${CTAGS} --quiet --options=NONE --list-roles= | ignore_xml | ignore_old | ignore_yaml +${CTAGS} --quiet --options=NONE --list-roles= | ignore_xml | ignore_old | ignore_yaml | ignore_pcre2 title 'all.*' -${CTAGS} --quiet --options=NONE --list-roles='all.*' | ignore_xml | ignore_old | ignore_yaml +${CTAGS} --quiet --options=NONE --list-roles='all.*' | ignore_xml | ignore_old | ignore_yaml | ignore_pcre2 title 'C.*' ${CTAGS} --quiet --options=NONE --list-roles='C.*' title 'all.d' -${CTAGS} --quiet --options=NONE --list-roles='all.d' | ignore_xml | ignore_old | ignore_yaml +${CTAGS} --quiet --options=NONE --list-roles='all.d' | ignore_xml | ignore_old | ignore_yaml | ignore_pcre2 title 'Sh.s' ${CTAGS} --quiet --options=NONE --list-roles='Sh.s' diff --git a/Units/parser-texinfo.r/lisp-param-elisp.d/args.ctags b/Units/parser-texinfo.r/lisp-param-elisp.d/args.ctags new file mode 100644 index 0000000000..f371192148 --- /dev/null +++ b/Units/parser-texinfo.r/lisp-param-elisp.d/args.ctags @@ -0,0 +1,2 @@ +--sort=no +--extras=+g diff --git a/Units/parser-texinfo.r/lisp-param-elisp.d/expected.tags b/Units/parser-texinfo.r/lisp-param-elisp.d/expected.tags new file mode 100644 index 0000000000..9dc69cde18 --- /dev/null +++ b/Units/parser-texinfo.r/lisp-param-elisp.d/expected.tags @@ -0,0 +1 @@ +exec input.texi /^(defun exec (cmd)$/;" f diff --git a/Units/parser-texinfo.r/lisp-param-elisp.d/features b/Units/parser-texinfo.r/lisp-param-elisp.d/features new file mode 100644 index 0000000000..92d5e6de8e --- /dev/null +++ b/Units/parser-texinfo.r/lisp-param-elisp.d/features @@ -0,0 +1 @@ +pcre2 diff --git a/Units/parser-texinfo.r/lisp-param-elisp.d/input.texi b/Units/parser-texinfo.r/lisp-param-elisp.d/input.texi new file mode 100644 index 0000000000..bc8d50d6f3 --- /dev/null +++ b/Units/parser-texinfo.r/lisp-param-elisp.d/input.texi @@ -0,0 +1,4 @@ +@lisp +(defun exec (cmd) + ...) +@end lisp diff --git a/Units/parser-texinfo.r/lisp-param-scheme.d/args.ctags b/Units/parser-texinfo.r/lisp-param-scheme.d/args.ctags new file mode 100644 index 0000000000..0a22be40b1 --- /dev/null +++ b/Units/parser-texinfo.r/lisp-param-scheme.d/args.ctags @@ -0,0 +1,3 @@ +--sort=no +--extras=+g +--param-Texinfo.LispLang=Scheme diff --git a/Units/parser-texinfo.r/lisp-param-scheme.d/expected.tags b/Units/parser-texinfo.r/lisp-param-scheme.d/expected.tags new file mode 100644 index 0000000000..c642a360a6 --- /dev/null +++ b/Units/parser-texinfo.r/lisp-param-scheme.d/expected.tags @@ -0,0 +1 @@ +exec input.texi /^(define (exec cmd)$/;" f diff --git a/Units/parser-texinfo.r/lisp-param-scheme.d/features b/Units/parser-texinfo.r/lisp-param-scheme.d/features new file mode 100644 index 0000000000..92d5e6de8e --- /dev/null +++ b/Units/parser-texinfo.r/lisp-param-scheme.d/features @@ -0,0 +1 @@ +pcre2 diff --git a/Units/parser-texinfo.r/lisp-param-scheme.d/input.texi b/Units/parser-texinfo.r/lisp-param-scheme.d/input.texi new file mode 100644 index 0000000000..a9907366f9 --- /dev/null +++ b/Units/parser-texinfo.r/lisp-param-scheme.d/input.texi @@ -0,0 +1,4 @@ +@lisp +(define (exec cmd) + ...) +@end lisp diff --git a/docs/news.rst b/docs/news.rst index 37940b7dd5..83d3e3cd35 100644 --- a/docs/news.rst +++ b/docs/news.rst @@ -478,6 +478,7 @@ The following parsers have been added: * TerraformVariables *optlib* * Thrift *peg/packcc* * TTCN +* Texinfo *optlib pcre2* * Txt2tags * TypeScript * Varlink *peg/packcc* diff --git a/main/parsers_p.h b/main/parsers_p.h index 7ec20898db..a0ef978324 100644 --- a/main/parsers_p.h +++ b/main/parsers_p.h @@ -48,7 +48,8 @@ #ifdef HAVE_PCRE2 #define OPTLIB2C_PCRE2_PARSER_LIST \ - RDocParser + RDocParser, \ + TexinfoParser #else #define OPTLIB2C_PCRE2_PARSER_LIST #endif diff --git a/optlib/texinfo.c b/optlib/texinfo.c new file mode 100644 index 0000000000..7b548d6af8 --- /dev/null +++ b/optlib/texinfo.c @@ -0,0 +1,402 @@ +/* + * Generated by ./misc/optlib2c from optlib/texinfo.ctags, Don't edit this manually. + */ +#include "general.h" +#include "parse.h" +#include "routines.h" +#include "field.h" +#include "xtag.h" +#include "param.h" + + +typedef enum { + K_ANCHOR, + K_ALIAS, + K_FLAG, + K_MACRO, + K_MENU, + K_NODE, + K_MENTRY, + K_CHAPTER, + K_SECTION, + K_SUBSECTION, + K_SUBSUBSECTION, + K_TITLE, + K_SUBTITLE, + K_MACROPARAM, + K_INFO, + K_TEXINFO, +} TexinfoKind; + + +static void initializeTexinfoParser (const langType language) +{ + addLanguageOptscriptToHook (language, SCRIPT_HOOK_PRELUDE, + "{{ /LispLang /LispLang _param not {\n" + " (EmacsLisp)\n" + " } if def\n" + "\n" + " /kindTable [\n" + " /title /chapter /section /subsection /subsubsection\n" + " ] def\n" + "\n" + " % cork:int DEPTHFORCORK depth:int\n" + " /depthForCork {\n" + " :kind kindTable exch _aindex pop\n" + " } def\n" + "\n" + " % endline:int goal:int scopePopUpTo -\n" + " /scopePopUpTo {\n" + " {\n" + " _scopetop {\n" + " dup\n" + " % endline goal scope scope\n" + " depthForCork 2 index ge {\n" + " % endline goal scope\n" + " 2 index end:\n" + " _scopepop\n" + " } {\n" + " pop\n" + " exit\n" + " } ifelse\n" + " } {\n" + " exit\n" + " } ifelse\n" + " } loop\n" + " pop\n" + " pop\n" + " } def\n" + "\n" + " % - SCOPEACTION -\n" + " /scopeAction {\n" + " . :line 1 sub . depthForCork scopePopUpTo\n" + " _scopetop {\n" + " . exch scope: . _scopepush\n" + " } {\n" + " . _scopepush\n" + " } ifelse\n" + " } def\n" + "}}"); + + addLanguageRegexTable (language, "main"); + addLanguageRegexTable (language, "macro"); + addLanguageRegexTable (language, "macroparam"); + addLanguageRegexTable (language, "comment"); + addLanguageRegexTable (language, "menu"); + addLanguageRegexTable (language, "linecomment"); + addLanguageRegexTable (language, "blockcomment"); + addLanguageRegexTable (language, "blockcommentbody"); + + addLanguageTagMultiTableRegex (language, "main", + "^[^@]+", + "", "", "p", NULL); + addLanguageTagMultiTableRegex (language, "main", + "^@[^achilmnust][^@]*", + "", "", "p", NULL); + addLanguageTagMultiTableRegex (language, "main", + "^(?:@c|@comment)[[:space:]]+[^\n]*", + "", "", "p", NULL); + addLanguageTagMultiTableRegex (language, "main", + "^@ignore[[:space:]]*", + "", "", "p{tenter=blockcommentbody}", NULL); + addLanguageTagMultiTableRegex (language, "main", + "^@menu", + "", "M", "p{tenter=menu}{_anonymous=menu}{scope=push}", NULL); + addLanguageTagMultiTableRegex (language, "main", + "^@node[[:space:]]+([^,\n]+)(?:,[[:space:]]+(?:[^,\n]+),[[:space:]]+(?:[^,\n]+),[[:space:]]+([^,\n]+))?[[:space:]]*\n?", + "\\1", "n", "p" + "{{\n" + " \\2 false ne {\n" + " .\n" + " \\2 /node @2 _tag _commit dup /upper _assignrole\n" + " scope:\n" + " } if\n" + "}}", NULL); + addLanguageTagMultiTableRegex (language, "main", + "^@macro[[:space:]]+([^[:space:]\\{]+)[[:space:]]*", + "\\1", "m", "p{tenter=macro}{scope=push}" + "{{\n" + " . [ ({)\n" + "}}", NULL); + addLanguageTagMultiTableRegex (language, "main", + "^@(chapter|unnumbered|appendix|chapheading)[[:space:]]+([^\n]+)\n?", + "\\2", "c", "p" + "{{\n" + " scopeAction\n" + "}}", NULL); + addLanguageTagMultiTableRegex (language, "main", + "^@(section|unnumberedsec|appendixsec|heading)[[:space:]]+([^\n]+)\n?", + "\\2", "s", "p" + "{{\n" + " scopeAction\n" + "}}", NULL); + addLanguageTagMultiTableRegex (language, "main", + "^@(subsection|unnumberedsubsec|appendixsubsec|subheading)[[:space:]]+([^\n]+)\n?", + "\\2", "u", "p" + "{{\n" + " scopeAction\n" + "}}", NULL); + addLanguageTagMultiTableRegex (language, "main", + "^@(subsubsection|unnumberedsubsubsec|appendixsubsubsec|subsubheading)[[:space:]]+([^\n]+)\n?", + "\\2", "b", "p" + "{{\n" + " scopeAction\n" + "}}", NULL); + addLanguageTagMultiTableRegex (language, "main", + "^@setfilename[[:space:]]+([^\n]+)\n?", + "\\1", "I", "p", NULL); + addLanguageTagMultiTableRegex (language, "main", + "^@settitle[[:space:]]+([^\n]+)\n?", + "\\1", "T", "p" + "{{\n" + " scopeAction\n" + "}}", NULL); + addLanguageTagMultiTableRegex (language, "main", + "^@subtitle[[:space:]]+([^\n]+)\n?", + "\\1", "U", "p{scope=ref}", NULL); + addLanguageTagMultiTableRegex (language, "main", + "^@anchor[[:space:]]*\\{([^\\}]+)\\}", + "\\1", "a", "p{scope=ref}", NULL); + addLanguageTagMultiTableRegex (language, "main", + "^@set[[:space:]]+([-a-zA-Z_0-9][^[:space:]@^<>~`^+]*)", + "\\1", "f", "p{scope=ref}", NULL); + addLanguageTagMultiTableRegex (language, "main", + "^@include[[:space:]]+([^\n]+)[[:space:]]*\n?", + "\\1", "X", "p{_role=included}{scope=ref}", NULL); + addLanguageTagMultiTableRegex (language, "main", + "^@alias[[:space:]]+([^[:space:]=]+)[[:space:]]*=[^\n]*\n", + "\\1", "A", "p{scope=ref}", NULL); + addLanguageTagMultiTableRegex (language, "main", + "^@tex[[:space:]]*\n(.*)\n@end[[:space:]]+tex", + "", "", "p{_guest=Tex,1start,1end}", NULL); + addLanguageTagMultiTableRegex (language, "main", + "^@lisp[[:space:]]*\n(.*)\n@end[[:space:]]+lisp", + "", "", "p" + "{{\n" + " LispLang @1 1@ _makepromise { pop } if\n" + "}}", NULL); + addLanguageTagMultiTableRegex (language, "main", + "^.", + "", "", "p", NULL); + addLanguageTagMultiTableRegex (language, "macro", + "^\\{[[:space:]]*", + "", "", "p{tenter=macroparam}", NULL); + addLanguageTagMultiTableRegex (language, "macro", + "^(?:@c|@comment)[[:space:]]+[^\n]*", + "", "", "p", NULL); + addLanguageTagMultiTableRegex (language, "macro", + "^@ignore[[:space:]]*", + "", "", "p{tenter=blockcommentbody}", NULL); + addLanguageTagMultiTableRegex (language, "macro", + "^@end[[:space:]]+macro", + "", "", "p{tleave}{scope=pop}" + "{{\n" + " % drop the last (,)\n" + " dup (,) eq {\n" + " pop\n" + " } if\n" + " % does the macro take parameters?\n" + " dup ({) eq {\n" + " % No.\n" + " % pop . [ ({)\n" + " pop pop pop\n" + " } {\n" + " % Yes. build signature string and assign it to thet tag for macro.\n" + " (}) _buildstring signature:\n" + " } ifelse\n" + "}}", NULL); + addLanguageTagMultiTableRegex (language, "macro", + "^[^\n]+", + "", "", "p", NULL); + addLanguageTagMultiTableRegex (language, "macro", + "^.", + "", "", "p", NULL); + addLanguageTagMultiTableRegex (language, "macroparam", + "^\\}", + "", "", "p{tleave}", NULL); + addLanguageTagMultiTableRegex (language, "macroparam", + "^([^[:space:],\\}]+)(?:[[:space:],]*)", + "\\1", "z", "p{scope=ref}" + "{{\n" + " \\1 (,)\n" + "}}", NULL); + addLanguageTagMultiTableRegex (language, "macroparam", + "^.", + "", "", "p", NULL); + addLanguageTagMultiTableRegex (language, "comment", + "^(?:@c|@comment)[[:space:]]+[^\n]*", + "", "", "p", NULL); + addLanguageTagMultiTableRegex (language, "comment", + "^@ignore[[:space:]]*", + "", "", "p{tenter=blockcommentbody}", NULL); + addLanguageTagMultiTableRegex (language, "menu", + "^[*][[:space:]]*(?:\\(([^\\)]+)\\))?[[:space:]]*([^[:space:]\\(:][^:]*):(?:([:])|[[:space:]]*(?:\\(([^\\)]+)\\))?[[:space:]]*([^[:space:]\\(:.][^.]*)[.])[[:space:]]*[^\n]*\n", + "\\2", "e", "p{scope=ref}" + "{{\n" + " \\1 false ne {\n" + " \\1 /info @1 _tag _commit dup /referenced _assignrole true\n" + " } {\n" + " \\4 false ne {\n" + " \\4 /info @4 _tag _commit dup /referenced _assignrole true\n" + " } {\n" + " false\n" + " } ifelse\n" + " } ifelse\n" + " \\3 false eq {\n" + " \\5 /node @5 _tag _commit\n" + " } {\n" + " \\2 /node @2 _tag _commit\n" + " } ifelse\n" + " dup /menu _assignrole\n" + " % scope true index\n" + " % false cork\n" + " exch {\n" + " exch scope:\n" + " } {\n" + " pop\n" + " } ifelse\n" + "}}", NULL); + addLanguageTagMultiTableRegex (language, "menu", + "^[*][[:space:]]*([^[[:space:]\\(:]+):[[:space:]]*\\(([^\\)]+)\\)[.][^\n]*\n", + "\\1", "e", "p{scope=ref}" + "{{\n" + " \\2 /info @2 _tag _commit dup /referenced _assignrole\n" + "}}", NULL); + addLanguageTagMultiTableRegex (language, "menu", + "^[*][[:space:]]*\\(([^\\)]+)\\)::[^\n]*\n", + "\\1", "I", "p{scope=ref}{_role=referenced}", NULL); + addLanguageTagMultiTableRegex (language, "menu", + "^@detailmenu", + "", "M", "p{tenter=menu}{_anonymous=menu}{scope=push}", NULL); + addLanguageTagMultiTableRegex (language, "menu", + "^@end[[:space:]]+(menu|detailmenu)", + "", "", "p{tleave}{scope=pop}", NULL); + addLanguageTagMultiTableRegex (language, "menu", + "^[^\n]*\n", + "", "", "p", NULL); + addLanguageTagMultiTableRegex (language, "menu", + "^.", + "", "", "p", NULL); + addLanguageTagMultiTableRegex (language, "linecomment", + "^(?:@c|@comment)[[:space:]]+[^\n]*", + "", "", "p", NULL); + addLanguageTagMultiTableRegex (language, "blockcomment", + "^@ignore[[:space:]]*", + "", "", "p{tenter=blockcommentbody}", NULL); + addLanguageTagMultiTableRegex (language, "blockcommentbody", + "^[^@]+", + "", "", "p", NULL); + addLanguageTagMultiTableRegex (language, "blockcommentbody", + "^@end[[:space:]]+ignore[[:space:]]*", + "", "", "p{tleave}", NULL); + addLanguageTagMultiTableRegex (language, "blockcommentbody", + "^.", + "", "", "p", NULL); +} + +extern parserDefinition* TexinfoParser (void) +{ + static const char *const extensions [] = { + "texi", + "texinfo", + NULL + }; + + static const char *const aliases [] = { + NULL + }; + + static const char *const patterns [] = { + NULL + }; + + static roleDefinition TexinfoNodeRoleTable [] = { + { true, "menu", "node name referenced in @menu...@end" }, + { true, "upper", "node name referenced @node ..., UP" }, + }; + static roleDefinition TexinfoInfoRoleTable [] = { + { true, "referenced", "referenced" }, + }; + static roleDefinition TexinfoTexinfoRoleTable [] = { + { true, "included", "included with @include command" }, + }; + static kindDefinition TexinfoKindTable [] = { + { + true, 'a', "anchor", "anchors", + }, + { + true, 'A', "alias", "aliases", + }, + { + true, 'f', "flag", "flags", + }, + { + true, 'm', "macro", "macros", + }, + { + true, 'M', "menu", "menus", + }, + { + true, 'n', "node", "nodes", + ATTACH_ROLES(TexinfoNodeRoleTable), + }, + { + true, 'e', "mentry", "menu entries", + }, + { + true, 'c', "chapter", "chapters", + }, + { + true, 's', "section", "sections", + }, + { + true, 'u', "subsection", "subsections", + }, + { + true, 'b', "subsubsection", "subsubsections", + }, + { + true, 'T', "title", "titles", + }, + { + true, 'U', "subtitle", "subtitles", + }, + { + false, 'z', "macroparam", "macro parameters", + }, + { + true, 'I', "info", "info file names", + ATTACH_ROLES(TexinfoInfoRoleTable), + }, + { + true, 'X', "texinfo", "texinfo files", + ATTACH_ROLES(TexinfoTexinfoRoleTable), + }, + }; + static paramDefinition TexinfoParamTable [] = { + { + .name = "LispLang", + .desc = "a guest parser running on @lisp...@end areas [EmacsLisp]", + .handleParam = NULL, + }, + }; + + parserDefinition* const def = parserNew ("Texinfo"); + + def->versionCurrent= 0; + def->versionAge = 0; + def->enabled = true; + def->extensions = extensions; + def->patterns = patterns; + def->aliases = aliases; + def->method = METHOD_NOT_CRAFTED|METHOD_REGEX; + def->useCork = CORK_QUEUE; + def->kindTable = TexinfoKindTable; + def->kindCount = ARRAY_SIZE(TexinfoKindTable); + def->paramTable = TexinfoParamTable; + def->paramCount = ARRAY_SIZE(TexinfoParamTable); + def->defaultScopeSeparator = "\"\""; + def->initialize = initializeTexinfoParser; + + return def; +} diff --git a/optlib/texinfo.ctags b/optlib/texinfo.ctags new file mode 100644 index 0000000000..3599136a08 --- /dev/null +++ b/optlib/texinfo.ctags @@ -0,0 +1,282 @@ +# +# Copyright (c) 2022, Red Hat, Inc. +# Copyright (c) 2022, Masatake YAMATO +# +# Author: Masatake YAMATO +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. +# +# Reference +# https://www.gnu.org/software/texinfo/manual/texinfo/texinfo.html +# +# TODO +# ---- +# * @def... +# * index commands like @cindex +# * @part +# * @verbatiminclude +# * @direntry +# + +--langdef=Texinfo +--map-Texinfo=+.texi +--map-Texinfo=+.texinfo + +--_paramdef-Texinfo=LispLang,a guest parser running on @lisp...@end areas [EmacsLisp] + +# +# kind definitions +# +--kinddef-Texinfo=a,anchor,anchors +--kinddef-Texinfo=A,alias,aliases +--kinddef-Texinfo=f,flag,flags +--kinddef-Texinfo=m,macro,macros +--kinddef-Texinfo=M,menu,menus +--kinddef-Texinfo=n,node,nodes + --_roledef-Texinfo.{node}=menu,node name referenced in @menu...@end + --_roledef-Texinfo.{node}=upper,node name referenced @node ..., UP +--kinddef-Texinfo=e,mentry,menu entries +--kinddef-Texinfo=c,chapter,chapters +--kinddef-Texinfo=s,section,sections +--kinddef-Texinfo=u,subsection,subsections +--kinddef-Texinfo=b,subsubsection,subsubsections +--kinddef-Texinfo=T,title,titles +--kinddef-Texinfo=U,subtitle,subtitles +--kinddef-Texinfo=z,macroparam,macro parameters +--kinddef-Texinfo=I,info,info file names + --_roledef-Texinfo.{info}=referenced,referenced +--kinddef-Texinfo=X,texinfo,texinfo files + --_roledef-Texinfo.{texinfo}=included,included with @include command +--kinds-Texinfo=-z + +# +# separators +# +# Separator definitions must come after kind definitions. +# This is the limitation of optlib2c. +--_scopesep-Texinfo=*/*:"" + +# +# table declarations +# +--_tabledef-Texinfo=main +--_tabledef-Texinfo=macro +--_tabledef-Texinfo=macroparam +--_tabledef-Texinfo=comment +--_tabledef-Texinfo=menu + +# +# scripts +# +--_prelude-Texinfo={{ + /LispLang /LispLang _param not { + (EmacsLisp) + } if def + + /kindTable [ + /title /chapter /section /subsection /subsubsection + ] def + + % cork:int DEPTHFORCORK depth:int + /depthForCork { + :kind kindTable exch _aindex pop + } def + + % endline:int goal:int scopePopUpTo - + /scopePopUpTo { + { + _scopetop { + dup + % endline goal scope scope + depthForCork 2 index ge { + % endline goal scope + 2 index end: + _scopepop + } { + pop + exit + } ifelse + } { + exit + } ifelse + } loop + pop + pop + } def + + % - SCOPEACTION - + /scopeAction { + . :line 1 sub . depthForCork scopePopUpTo + _scopetop { + . exch scope: . _scopepush + } { + . _scopepush + } ifelse + } def +}} + +# +# tables: comment +# +--_tabledef-Texinfo=linecomment +--_tabledef-Texinfo=blockcomment +--_tabledef-Texinfo=blockcommentbody + +--_mtable-regex-Texinfo=linecomment/(?:@c|@comment)[[:space:]]+[^\n]*//p + +--_mtable-regex-Texinfo=blockcommentbody/[^@]+//p +--_mtable-regex-Texinfo=blockcommentbody/@end[[:space:]]+ignore[[:space:]]*//p{tleave} +--_mtable-regex-Texinfo=blockcommentbody/.//p +--_mtable-regex-Texinfo=blockcomment/@ignore[[:space:]]*//p{tenter=blockcommentbody} + +--_mtable-extend-Texinfo=comment+linecomment +--_mtable-extend-Texinfo=comment+blockcomment + +# +# tables: main +# +--_mtable-regex-Texinfo=main/[^@]+//p +--_mtable-regex-Texinfo=main/@[^achilmnust][^@]*//p +--_mtable-extend-Texinfo=main+comment +--_mtable-regex-Texinfo=main/@menu//M/p{tenter=menu}{_anonymous=menu}{scope=push} +--_mtable-regex-Texinfo=main/@node[[:space:]]+([^,\n]+)(?:,[[:space:]]+(?:[^,\n]+),[[:space:]]+(?:[^,\n]+),[[:space:]]+([^,\n]+))?[[:space:]]*\n?/\1/n/p{{ + \2 false ne { + . + \2 /node @2 _tag _commit dup /upper _assignrole + scope: + } if +}} +--_mtable-regex-Texinfo=main/@macro[[:space:]]+([^[:space:]\{]+)[[:space:]]*/\1/m/p{tenter=macro}{scope=push}{{ + . [ ({) +}} +--_mtable-regex-Texinfo=main/@(chapter|unnumbered|appendix|chapheading)[[:space:]]+([^\n]+)\n?/\2/c/p{{ + scopeAction +}} +--_mtable-regex-Texinfo=main/@(section|unnumberedsec|appendixsec|heading)[[:space:]]+([^\n]+)\n?/\2/s/p{{ + scopeAction +}} +--_mtable-regex-Texinfo=main/@(subsection|unnumberedsubsec|appendixsubsec|subheading)[[:space:]]+([^\n]+)\n?/\2/u/p{{ + scopeAction +}} +--_mtable-regex-Texinfo=main/@(subsubsection|unnumberedsubsubsec|appendixsubsubsec|subsubheading)[[:space:]]+([^\n]+)\n?/\2/b/p{{ + scopeAction +}} +--_mtable-regex-Texinfo=main/@setfilename[[:space:]]+([^\n]+)\n?/\1/I/p +--_mtable-regex-Texinfo=main/@settitle[[:space:]]+([^\n]+)\n?/\1/T/p{{ + scopeAction +}} +--_mtable-regex-Texinfo=main/@subtitle[[:space:]]+([^\n]+)\n?/\1/U/p{scope=ref} +--_mtable-regex-Texinfo=main/@anchor[[:space:]]*\{([^\}]+)\}/\1/a/p{scope=ref} +--_mtable-regex-Texinfo=main/@set[[:space:]]+([-a-zA-Z_0-9][^[:space:]@^<>~`^+]*)/\1/f/p{scope=ref} +--_mtable-regex-Texinfo=main/@include[[:space:]]+([^\n]+)[[:space:]]*\n?/\1/X/p{_role=included}{scope=ref} +--_mtable-regex-Texinfo=main/@alias[[:space:]]+([^[:space:]=]+)[[:space:]]*=[^\n]*\n/\1/A/p{scope=ref} +--_mtable-regex-Texinfo=main/@tex[[:space:]]*\n(.*)\n@end[[:space:]]+tex//p{_guest=Tex,1start,1end} +--_mtable-regex-Texinfo=main/@lisp[[:space:]]*\n(.*)\n@end[[:space:]]+lisp//p{{ + LispLang @1 1@ _makepromise { pop } if +}} +--_mtable-regex-Texinfo=main/.//p + +# +# tables: menu +# +# * MENU-ENTRY-NAME: NODE-NAME. DESCRIPTION +# The parser extracts MENU-ENTRY-NAME with /entry kind, and +# NODE-NAME with /node kind. +# +# * NAME. DESCRIPTION +# The parser extracts NAME twice, once with /entry kind, and +# once with /node kind. +# +# * FIRST-ENTRY-NAME:(FILENAME)NODENAME. DESCRIPTION +# The parser extracts FIRST-ENTRY-NAME with /entry kind, +# FILENAME with /info kind + /referred role, and NODENAME with /node kind + +# FILENAME as scope. +# +# * (FILENAME)SECOND-NODE:: DESCRIPTION +# The parser extracts FILENAME with /info kind + /referred role. +# The parser extracts SECOND-NODE twice, once with /entry kind, and once with /node kind. +# For SECOND-NODE of /node kind, FILENAME is attached as scope. +# +--_mtable-regex-Texinfo=menu/[*][[:space:]]*(?:\(([^\)]+)\))?[[:space:]]*([^[:space:]\(:][^:]*):(?:([:])|[[:space:]]*(?:\(([^\)]+)\))?[[:space:]]*([^[:space:]\(:.][^.]*)[.])[[:space:]]*[^\n]*\n/\2/e/p{scope=ref}{{ + \1 false ne { + \1 /info @1 _tag _commit dup /referenced _assignrole true + } { + \4 false ne { + \4 /info @4 _tag _commit dup /referenced _assignrole true + } { + false + } ifelse + } ifelse + \3 false eq { + \5 /node @5 _tag _commit + } { + \2 /node @2 _tag _commit + } ifelse + dup /menu _assignrole + % scope true index + % false cork + exch { + exch scope: + } { + pop + } ifelse +}} + +# * FIRST-ENTRY-NAME:(FILENAME). DESCRIPTION +--_mtable-regex-Texinfo=menu/[*][[:space:]]*([^[[:space:]\(:]+):[[:space:]]*\(([^\)]+)\)[.][^\n]*\n/\1/e/p{scope=ref}{{ + \2 /info @2 _tag _commit dup /referenced _assignrole +}} + +# * (FILENAME):: DESCRIPTION +--_mtable-regex-Texinfo=menu/[*][[:space:]]*\(([^\)]+)\)::[^\n]*\n/\1/I/p{scope=ref}{_role=referenced} + +--_mtable-regex-Texinfo=menu/@detailmenu//M/p{tenter=menu}{_anonymous=menu}{scope=push} + +--_mtable-regex-Texinfo=menu/@end[[:space:]]+(menu|detailmenu)//p{tleave}{scope=pop} +--_mtable-regex-Texinfo=menu/[^\n]*\n//p +--_mtable-regex-Texinfo=menu/.//p + +# +# tables: macroparam +# +--_mtable-regex-Texinfo=macroparam/\}//p{tleave} +--_mtable-regex-Texinfo=macroparam/([^[:space:],\}]+)(?:[[:space:],]*)/\1/z/p{scope=ref}{{ + \1 (,) +}} +--_mtable-regex-Texinfo=macroparam/.//p + +# +# tables: macro +# +--_mtable-regex-Texinfo=macro/\{[[:space:]]*//p{tenter=macroparam} +--_mtable-extend-Texinfo=macro+comment +--_mtable-regex-Texinfo=macro/@end[[:space:]]+macro//p{tleave}{scope=pop}{{ + % drop the last (,) + dup (,) eq { + pop + } if + % does the macro take parameters? + dup ({) eq { + % No. + % pop . [ ({) + pop pop pop + } { + % Yes. build signature string and assign it to thet tag for macro. + (}) _buildstring signature: + } ifelse +}} +--_mtable-regex-Texinfo=macro/[^\n]+//p +--_mtable-regex-Texinfo=macro/.//p diff --git a/source.mak b/source.mak index f131acedbe..56dde47a71 100644 --- a/source.mak +++ b/source.mak @@ -219,6 +219,7 @@ OPTSCRIPT_OBJS = $(OPTSCRIPT_SRCS:.c=.$(OBJEXT)) OPTLIB2C_PCRE2_INPUT = \ optlib/rdoc.ctags \ + optlib/texinfo.ctags \ \ $(NULL) OPTLIB2C_PCRE2_SRCS = $(OPTLIB2C_PCRE2_INPUT:.ctags=.c)