diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2016-01-30 13:56:23 -0800 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2016-01-30 13:56:23 -0800 |
commit | 99fa8c3dbf333f1e3fa7d6449d4b4428ce439ce1 (patch) | |
tree | fc459c16ca5f7204aa5a21529f8a189bfb45f831 /lib-src | |
parent | 3005605776955593e0b416de9e1ebf158114343e (diff) | |
parent | 875577bcc8d6139d61f91118d0907b847912b3e1 (diff) |
-
Diffstat (limited to 'lib-src')
-rw-r--r-- | lib-src/etags.c | 133 |
1 files changed, 128 insertions, 5 deletions
diff --git a/lib-src/etags.c b/lib-src/etags.c index 2192627c7e..ff75de4565 100644 --- a/lib-src/etags.c +++ b/lib-src/etags.c @@ -354,6 +354,7 @@ static void Cstar_entries (FILE *); static void Erlang_functions (FILE *); static void Forth_words (FILE *); static void Fortran_functions (FILE *); +static void Go_functions (FILE *); static void HTML_labels (FILE *); static void Lisp_functions (FILE *); static void Lua_functions (FILE *); @@ -641,6 +642,10 @@ static const char *Fortran_suffixes [] = static const char Fortran_help [] = "In Fortran code, functions, subroutines and block data are tags."; +static const char *Go_suffixes [] = {"go", NULL}; +static const char Go_help [] = + "In Go code, functions, interfaces and packages are tags."; + static const char *HTML_suffixes [] = { "htm", "html", "shtml", NULL }; static const char HTML_help [] = @@ -727,7 +732,7 @@ static const char *Ruby_suffixes [] = { "rb", "ruby", NULL }; static const char Ruby_help [] = "In Ruby code, 'def' or 'class' or 'module' at the beginning of\n\ -a line generate a tag."; +a line generate a tag. Constants also generate a tag."; /* Can't do the `SCM' or `scm' prefix with a version number. */ static const char *Scheme_suffixes [] = @@ -794,6 +799,7 @@ static language lang_names [] = { "erlang", Erlang_help, Erlang_functions, Erlang_suffixes }, { "forth", Forth_help, Forth_words, Forth_suffixes }, { "fortran", Fortran_help, Fortran_functions, Fortran_suffixes }, + { "go", Go_help, Go_functions, Go_suffixes }, { "html", HTML_help, HTML_labels, HTML_suffixes }, { "java", Cjava_help, Cjava_entries, Cjava_suffixes }, { "lisp", Lisp_help, Lisp_functions, Lisp_suffixes }, @@ -4210,6 +4216,73 @@ Fortran_functions (FILE *inf) /* + * Go language support + * Original code by Xi Lu <lx@shellcodes.org> (2016) + */ +static void +Go_functions(FILE *inf) +{ + char *cp, *name; + + LOOP_ON_INPUT_LINES(inf, lb, cp) + { + cp = skip_spaces (cp); + + if (LOOKING_AT (cp, "package")) + { + name = cp; + while (!notinname (*cp) && *cp != '\0') + cp++; + make_tag (name, cp - name, false, lb.buffer, + cp - lb.buffer + 1, lineno, linecharno); + } + else if (LOOKING_AT (cp, "func")) + { + /* Go implementation of interface, such as: + func (n *Integer) Add(m Integer) ... + skip `(n *Integer)` part. + */ + if (*cp == '(') + { + while (*cp != ')') + cp++; + cp = skip_spaces (cp+1); + } + + if (*cp) + { + name = cp; + + while (!notinname (*cp)) + cp++; + + make_tag (name, cp - name, true, lb.buffer, + cp - lb.buffer + 1, lineno, linecharno); + } + } + else if (members && LOOKING_AT (cp, "type")) + { + name = cp; + + /* Ignore the likes of the following: + type ( + A + ) + */ + if (*cp == '(') + return; + + while (!notinname (*cp) && *cp != '\0') + cp++; + + make_tag (name, cp - name, false, lb.buffer, + cp - lb.buffer + 1, lineno, linecharno); + } + } +} + + +/* * Ada parsing * Original code by * Philippe Waroquiers (1998) @@ -4551,18 +4624,68 @@ Ruby_functions (FILE *inf) LOOP_ON_INPUT_LINES (inf, lb, cp) { + bool is_class = false; + bool is_method = false; + char *name; + cp = skip_spaces (cp); - if (LOOKING_AT (cp, "def") - || LOOKING_AT (cp, "class") - || LOOKING_AT (cp, "module")) + if (c_isalpha (*cp) && c_isupper (*cp)) /* constants */ { - char *name = cp; + char *bp, *colon = NULL; + + name = cp; + + for (cp++; c_isalnum (*cp) || *cp == '_' || *cp == ':'; cp++) + { + if (*cp == ':') + colon = cp; + } + if (cp > name + 1) + { + bp = skip_spaces (cp); + if (*bp == '=' && c_isspace (bp[1])) + { + if (colon && !c_isspace (colon[1])) + name = colon + 1; + make_tag (name, cp - name, false, + lb.buffer, cp - lb.buffer + 1, lineno, linecharno); + } + } + } + else if ((is_method = LOOKING_AT (cp, "def")) /* module/class/method */ + || (is_class = LOOKING_AT (cp, "class")) + || LOOKING_AT (cp, "module")) + { + const char self_name[] = "self."; + const size_t self_size1 = sizeof ("self.") - 1; + + name = cp; /* Ruby method names can end in a '='. Also, operator overloading can define operators whose names include '='. */ while (!notinname (*cp) || *cp == '=') cp++; + /* Remove "self." from the method name. */ + if (cp - name > self_size1 + && strneq (name, self_name, self_size1)) + name += self_size1; + + /* Remove the class/module qualifiers from method names. */ + if (is_method) + { + char *q; + + for (q = name; q < cp && *q != '.'; q++) + ; + if (q < cp - 1) /* punt if we see just "FOO." */ + name = q + 1; + } + + /* Don't tag singleton classes. */ + if (is_class && strneq (name, "<<", 2) && cp == name + 2) + continue; + make_tag (name, cp - name, true, lb.buffer, cp - lb.buffer + 1, lineno, linecharno); } |