aboutsummaryrefslogtreecommitdiffstats
path: root/lib-src
diff options
context:
space:
mode:
authorPaul Eggert2016-01-30 13:56:23 -0800
committerPaul Eggert2016-01-30 13:56:23 -0800
commit99fa8c3dbf333f1e3fa7d6449d4b4428ce439ce1 (patch)
treefc459c16ca5f7204aa5a21529f8a189bfb45f831 /lib-src
parent3005605776955593e0b416de9e1ebf158114343e (diff)
parent875577bcc8d6139d61f91118d0907b847912b3e1 (diff)
downloademacs-99fa8c3dbf333f1e3fa7d6449d4b4428ce439ce1.tar.gz
emacs-99fa8c3dbf333f1e3fa7d6449d4b4428ce439ce1.zip
-
Diffstat (limited to 'lib-src')
-rw-r--r--lib-src/etags.c133
1 files changed, 128 insertions, 5 deletions
diff --git a/lib-src/etags.c b/lib-src/etags.c
index 2192627c7e0..ff75de45659 100644
--- a/lib-src/etags.c
+++ b/lib-src/etags.c
@@ -354,6 +354,7 @@ static void Cstar_entries (FILE *);
354static void Erlang_functions (FILE *); 354static void Erlang_functions (FILE *);
355static void Forth_words (FILE *); 355static void Forth_words (FILE *);
356static void Fortran_functions (FILE *); 356static void Fortran_functions (FILE *);
357static void Go_functions (FILE *);
357static void HTML_labels (FILE *); 358static void HTML_labels (FILE *);
358static void Lisp_functions (FILE *); 359static void Lisp_functions (FILE *);
359static void Lua_functions (FILE *); 360static void Lua_functions (FILE *);
@@ -641,6 +642,10 @@ static const char *Fortran_suffixes [] =
641static const char Fortran_help [] = 642static const char Fortran_help [] =
642"In Fortran code, functions, subroutines and block data are tags."; 643"In Fortran code, functions, subroutines and block data are tags.";
643 644
645static const char *Go_suffixes [] = {"go", NULL};
646static const char Go_help [] =
647 "In Go code, functions, interfaces and packages are tags.";
648
644static const char *HTML_suffixes [] = 649static const char *HTML_suffixes [] =
645 { "htm", "html", "shtml", NULL }; 650 { "htm", "html", "shtml", NULL };
646static const char HTML_help [] = 651static const char HTML_help [] =
@@ -727,7 +732,7 @@ static const char *Ruby_suffixes [] =
727 { "rb", "ruby", NULL }; 732 { "rb", "ruby", NULL };
728static const char Ruby_help [] = 733static const char Ruby_help [] =
729 "In Ruby code, 'def' or 'class' or 'module' at the beginning of\n\ 734 "In Ruby code, 'def' or 'class' or 'module' at the beginning of\n\
730a line generate a tag."; 735a line generate a tag. Constants also generate a tag.";
731 736
732/* Can't do the `SCM' or `scm' prefix with a version number. */ 737/* Can't do the `SCM' or `scm' prefix with a version number. */
733static const char *Scheme_suffixes [] = 738static const char *Scheme_suffixes [] =
@@ -794,6 +799,7 @@ static language lang_names [] =
794 { "erlang", Erlang_help, Erlang_functions, Erlang_suffixes }, 799 { "erlang", Erlang_help, Erlang_functions, Erlang_suffixes },
795 { "forth", Forth_help, Forth_words, Forth_suffixes }, 800 { "forth", Forth_help, Forth_words, Forth_suffixes },
796 { "fortran", Fortran_help, Fortran_functions, Fortran_suffixes }, 801 { "fortran", Fortran_help, Fortran_functions, Fortran_suffixes },
802 { "go", Go_help, Go_functions, Go_suffixes },
797 { "html", HTML_help, HTML_labels, HTML_suffixes }, 803 { "html", HTML_help, HTML_labels, HTML_suffixes },
798 { "java", Cjava_help, Cjava_entries, Cjava_suffixes }, 804 { "java", Cjava_help, Cjava_entries, Cjava_suffixes },
799 { "lisp", Lisp_help, Lisp_functions, Lisp_suffixes }, 805 { "lisp", Lisp_help, Lisp_functions, Lisp_suffixes },
@@ -4210,6 +4216,73 @@ Fortran_functions (FILE *inf)
4210 4216
4211 4217
4212/* 4218/*
4219 * Go language support
4220 * Original code by Xi Lu <lx@shellcodes.org> (2016)
4221 */
4222static void
4223Go_functions(FILE *inf)
4224{
4225 char *cp, *name;
4226
4227 LOOP_ON_INPUT_LINES(inf, lb, cp)
4228 {
4229 cp = skip_spaces (cp);
4230
4231 if (LOOKING_AT (cp, "package"))
4232 {
4233 name = cp;
4234 while (!notinname (*cp) && *cp != '\0')
4235 cp++;
4236 make_tag (name, cp - name, false, lb.buffer,
4237 cp - lb.buffer + 1, lineno, linecharno);
4238 }
4239 else if (LOOKING_AT (cp, "func"))
4240 {
4241 /* Go implementation of interface, such as:
4242 func (n *Integer) Add(m Integer) ...
4243 skip `(n *Integer)` part.
4244 */
4245 if (*cp == '(')
4246 {
4247 while (*cp != ')')
4248 cp++;
4249 cp = skip_spaces (cp+1);
4250 }
4251
4252 if (*cp)
4253 {
4254 name = cp;
4255
4256 while (!notinname (*cp))
4257 cp++;
4258
4259 make_tag (name, cp - name, true, lb.buffer,
4260 cp - lb.buffer + 1, lineno, linecharno);
4261 }
4262 }
4263 else if (members && LOOKING_AT (cp, "type"))
4264 {
4265 name = cp;
4266
4267 /* Ignore the likes of the following:
4268 type (
4269 A
4270 )
4271 */
4272 if (*cp == '(')
4273 return;
4274
4275 while (!notinname (*cp) && *cp != '\0')
4276 cp++;
4277
4278 make_tag (name, cp - name, false, lb.buffer,
4279 cp - lb.buffer + 1, lineno, linecharno);
4280 }
4281 }
4282}
4283
4284
4285/*
4213 * Ada parsing 4286 * Ada parsing
4214 * Original code by 4287 * Original code by
4215 * Philippe Waroquiers (1998) 4288 * Philippe Waroquiers (1998)
@@ -4551,18 +4624,68 @@ Ruby_functions (FILE *inf)
4551 4624
4552 LOOP_ON_INPUT_LINES (inf, lb, cp) 4625 LOOP_ON_INPUT_LINES (inf, lb, cp)
4553 { 4626 {
4627 bool is_class = false;
4628 bool is_method = false;
4629 char *name;
4630
4554 cp = skip_spaces (cp); 4631 cp = skip_spaces (cp);
4555 if (LOOKING_AT (cp, "def") 4632 if (c_isalpha (*cp) && c_isupper (*cp)) /* constants */
4556 || LOOKING_AT (cp, "class")
4557 || LOOKING_AT (cp, "module"))
4558 { 4633 {
4559 char *name = cp; 4634 char *bp, *colon = NULL;
4635
4636 name = cp;
4637
4638 for (cp++; c_isalnum (*cp) || *cp == '_' || *cp == ':'; cp++)
4639 {
4640 if (*cp == ':')
4641 colon = cp;
4642 }
4643 if (cp > name + 1)
4644 {
4645 bp = skip_spaces (cp);
4646 if (*bp == '=' && c_isspace (bp[1]))
4647 {
4648 if (colon && !c_isspace (colon[1]))
4649 name = colon + 1;
4650 make_tag (name, cp - name, false,
4651 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4652 }
4653 }
4654 }
4655 else if ((is_method = LOOKING_AT (cp, "def")) /* module/class/method */
4656 || (is_class = LOOKING_AT (cp, "class"))
4657 || LOOKING_AT (cp, "module"))
4658 {
4659 const char self_name[] = "self.";
4660 const size_t self_size1 = sizeof ("self.") - 1;
4661
4662 name = cp;
4560 4663
4561 /* Ruby method names can end in a '='. Also, operator overloading can 4664 /* Ruby method names can end in a '='. Also, operator overloading can
4562 define operators whose names include '='. */ 4665 define operators whose names include '='. */
4563 while (!notinname (*cp) || *cp == '=') 4666 while (!notinname (*cp) || *cp == '=')
4564 cp++; 4667 cp++;
4565 4668
4669 /* Remove "self." from the method name. */
4670 if (cp - name > self_size1
4671 && strneq (name, self_name, self_size1))
4672 name += self_size1;
4673
4674 /* Remove the class/module qualifiers from method names. */
4675 if (is_method)
4676 {
4677 char *q;
4678
4679 for (q = name; q < cp && *q != '.'; q++)
4680 ;
4681 if (q < cp - 1) /* punt if we see just "FOO." */
4682 name = q + 1;
4683 }
4684
4685 /* Don't tag singleton classes. */
4686 if (is_class && strneq (name, "<<", 2) && cp == name + 2)
4687 continue;
4688
4566 make_tag (name, cp - name, true, 4689 make_tag (name, cp - name, true,
4567 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 4690 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4568 } 4691 }