comparison lib-src/etags.c @ 45950:74a2581262b0

(F_getit, Fortran_functions, Ada_getit, Asm_labels) (Python_functions, PHP_functions, PHP_functions, PHP_functions) (PHP_functions, PHP_functions, Cobol_paragraphs) (Makefile_targets, Postscript_functions, Texinfo_nodes) (prolog_pr, erlang_func, erlang_attribute) (Perl_functions, Perl_functions, Pascal_functions) (TeX_commands, get_tag): Use make_tag instead of pfnote. (get_tag): Prototype changed, all callers changed.
author Francesco Potortì <pot@gnu.org>
date Fri, 21 Jun 2002 12:36:12 +0000
parents 5425e4687a4e
children 9c058ffb550b
comparison
equal deleted inserted replaced
45949:38d7d01adff1 45950:74a2581262b0
33 * 33 *
34 * Francesco Potort́ <pot@gnu.org> has maintained and improved it since 1993. 34 * Francesco Potort́ <pot@gnu.org> has maintained and improved it since 1993.
35 * 35 *
36 */ 36 */
37 37
38 char pot_etags_version[] = "@(#) pot revision number is 16.29"; 38 char pot_etags_version[] = "@(#) pot revision number is 16.32";
39 39
40 #define TRUE 1 40 #define TRUE 1
41 #define FALSE 0 41 #define FALSE 0
42 42
43 #ifdef DEBUG 43 #ifdef DEBUG
351 static language *get_language_from_interpreter __P((char *)); 351 static language *get_language_from_interpreter __P((char *));
352 static language *get_language_from_filename __P((char *, bool)); 352 static language *get_language_from_filename __P((char *, bool));
353 static void readline __P((linebuffer *, FILE *)); 353 static void readline __P((linebuffer *, FILE *));
354 static long readline_internal __P((linebuffer *, FILE *)); 354 static long readline_internal __P((linebuffer *, FILE *));
355 static bool nocase_tail __P((char *)); 355 static bool nocase_tail __P((char *));
356 static char *get_tag __P((char *)); 356 static void get_tag __P((char *, char **));
357 357
358 #ifdef ETAGS_REGEXPS 358 #ifdef ETAGS_REGEXPS
359 static void analyse_regex __P((char *)); 359 static void analyse_regex __P((char *));
360 static void free_patterns __P((void)); 360 static void free_patterns __P((void));
361 static void regex_tag_multiline __P((void)); 361 static void regex_tag_multiline __P((void));
1774 regex_tag_multiline (); 1774 regex_tag_multiline ();
1775 #endif /* ETAGS_REGEXPS */ 1775 #endif /* ETAGS_REGEXPS */
1776 } 1776 }
1777 1777
1778 1778
1779 /* Record a tag. */
1780 static void
1781 pfnote (name, is_func, linestart, linelen, lno, cno)
1782 char *name; /* tag name, or NULL if unnamed */
1783 bool is_func; /* tag is a function */
1784 char *linestart; /* start of the line where tag is */
1785 int linelen; /* length of the line where tag is */
1786 int lno; /* line number */
1787 long cno; /* character number */
1788 {
1789 register node *np;
1790
1791 if (CTAGS && name == NULL)
1792 return;
1793
1794 np = xnew (1, node);
1795
1796 /* If ctags mode, change name "main" to M<thisfilename>. */
1797 if (CTAGS && !cxref_style && streq (name, "main"))
1798 {
1799 register char *fp = etags_strrchr (curfdp->taggedfname, '/');
1800 np->name = concat ("M", fp == NULL ? curfdp->taggedfname : fp + 1, "");
1801 fp = etags_strrchr (np->name, '.');
1802 if (fp != NULL && fp[1] != '\0' && fp[2] == '\0')
1803 fp[0] = '\0';
1804 }
1805 else
1806 np->name = name;
1807 np->valid = TRUE;
1808 np->been_warned = FALSE;
1809 np->fdp = curfdp;
1810 np->is_func = is_func;
1811 np->lno = lno;
1812 if (np->fdp->usecharno)
1813 /* Our char numbers are 0-base, because of C language tradition?
1814 ctags compatibility? old versions compatibility? I don't know.
1815 Anyway, since emacs's are 1-base we expect etags.el to take care
1816 of the difference. If we wanted to have 1-based numbers, we would
1817 uncomment the +1 below. */
1818 np->cno = cno /* + 1 */ ;
1819 else
1820 np->cno = invalidcharno;
1821 np->left = np->right = NULL;
1822 if (CTAGS && !cxref_style)
1823 {
1824 if (strlen (linestart) < 50)
1825 np->pat = concat (linestart, "$", "");
1826 else
1827 np->pat = savenstr (linestart, 50);
1828 }
1829 else
1830 np->pat = savenstr (linestart, linelen);
1831
1832 add_node (np, &nodehead);
1833 }
1834
1835 /* 1779 /*
1836 * Check whether an implicitly named tag should be created, 1780 * Check whether an implicitly named tag should be created,
1837 * then call `pfnote'. 1781 * then call `pfnote'.
1838 * NAME is a string that is internally copied by this function. 1782 * NAME is a string that is internally copied by this function.
1839 * 1783 *
1840 * TAGS format specification 1784 * TAGS format specification
1841 * Idea by Sam Kendall <kendall@mv.mv.com> (1997) 1785 * Idea by Sam Kendall <kendall@mv.mv.com> (1997)
1786 * The following is explained in some more detail in etc/ETAGS.EBNF.
1842 * 1787 *
1843 * make_tag creates tags with "implicit tag names" (unnamed tags) 1788 * make_tag creates tags with "implicit tag names" (unnamed tags)
1844 * if the following are all true, assuming NONAM=" \f\t\n\r()=,;": 1789 * if the following are all true, assuming NONAM=" \f\t\n\r()=,;":
1845 * 1. NAME does not contain any of the characters in NONAM; 1790 * 1. NAME does not contain any of the characters in NONAM;
1846 * 2. LINESTART contains name as either a rightmost, or rightmost but 1791 * 2. LINESTART contains name as either a rightmost, or rightmost but
1864 int lno; /* line number */ 1809 int lno; /* line number */
1865 long cno; /* character number */ 1810 long cno; /* character number */
1866 { 1811 {
1867 bool named = TRUE; 1812 bool named = TRUE;
1868 1813
1869 if (!CTAGS) 1814 if (!CTAGS && name != NULL && namelen > 0)
1870 { 1815 {
1871 int i; 1816 int i;
1872 register char *cp = name; 1817 register char *cp = name;
1873 1818
1874 for (i = 0; i < namelen; i++) 1819 for (i = 0; i < namelen; i++)
1890 if (named) 1835 if (named)
1891 name = savenstr (name, namelen); 1836 name = savenstr (name, namelen);
1892 else 1837 else
1893 name = NULL; 1838 name = NULL;
1894 pfnote (name, is_func, linestart, linelen, lno, cno); 1839 pfnote (name, is_func, linestart, linelen, lno, cno);
1840 }
1841
1842 /* Record a tag. */
1843 static void
1844 pfnote (name, is_func, linestart, linelen, lno, cno)
1845 char *name; /* tag name, or NULL if unnamed */
1846 bool is_func; /* tag is a function */
1847 char *linestart; /* start of the line where tag is */
1848 int linelen; /* length of the line where tag is */
1849 int lno; /* line number */
1850 long cno; /* character number */
1851 {
1852 register node *np;
1853
1854 if (CTAGS && name == NULL)
1855 return;
1856
1857 np = xnew (1, node);
1858
1859 /* If ctags mode, change name "main" to M<thisfilename>. */
1860 if (CTAGS && !cxref_style && streq (name, "main"))
1861 {
1862 register char *fp = etags_strrchr (curfdp->taggedfname, '/');
1863 np->name = concat ("M", fp == NULL ? curfdp->taggedfname : fp + 1, "");
1864 fp = etags_strrchr (np->name, '.');
1865 if (fp != NULL && fp[1] != '\0' && fp[2] == '\0')
1866 fp[0] = '\0';
1867 }
1868 else
1869 np->name = name;
1870 np->valid = TRUE;
1871 np->been_warned = FALSE;
1872 np->fdp = curfdp;
1873 np->is_func = is_func;
1874 np->lno = lno;
1875 if (np->fdp->usecharno)
1876 /* Our char numbers are 0-base, because of C language tradition?
1877 ctags compatibility? old versions compatibility? I don't know.
1878 Anyway, since emacs's are 1-base we expect etags.el to take care
1879 of the difference. If we wanted to have 1-based numbers, we would
1880 uncomment the +1 below. */
1881 np->cno = cno /* + 1 */ ;
1882 else
1883 np->cno = invalidcharno;
1884 np->left = np->right = NULL;
1885 if (CTAGS && !cxref_style)
1886 {
1887 if (strlen (linestart) < 50)
1888 np->pat = concat (linestart, "$", "");
1889 else
1890 np->pat = savenstr (linestart, 50);
1891 }
1892 else
1893 np->pat = savenstr (linestart, linelen);
1894
1895 add_node (np, &nodehead);
1895 } 1896 }
1896 1897
1897 /* 1898 /*
1898 * free_tree () 1899 * free_tree ()
1899 * recurse on left children, iterate on right children. 1900 * recurse on left children, iterate on right children.
3896 } 3897 }
3897 if (!ISALPHA (*dbp) && *dbp != '_' && *dbp != '$') 3898 if (!ISALPHA (*dbp) && *dbp != '_' && *dbp != '$')
3898 return; 3899 return;
3899 for (cp = dbp + 1; *cp != '\0' && intoken (*cp); cp++) 3900 for (cp = dbp + 1; *cp != '\0' && intoken (*cp); cp++)
3900 continue; 3901 continue;
3901 pfnote (savenstr (dbp, cp-dbp), TRUE, 3902 make_tag (dbp, cp-dbp, TRUE,
3902 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 3903 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3903 } 3904 }
3904 3905
3905 3906
3906 static void 3907 static void
3907 Fortran_functions (inf) 3908 Fortran_functions (inf)
3964 case 'b': 3965 case 'b':
3965 if (nocase_tail ("blockdata") || nocase_tail ("block data")) 3966 if (nocase_tail ("blockdata") || nocase_tail ("block data"))
3966 { 3967 {
3967 dbp = skip_spaces (dbp); 3968 dbp = skip_spaces (dbp);
3968 if (*dbp == '\0') /* assume un-named */ 3969 if (*dbp == '\0') /* assume un-named */
3969 pfnote (savestr ("blockdata"), TRUE, 3970 make_tag ("blockdata", 9, TRUE,
3970 lb.buffer, dbp - lb.buffer, lineno, linecharno); 3971 lb.buffer, dbp - lb.buffer, lineno, linecharno);
3971 else 3972 else
3972 F_getit (inf); /* look for name */ 3973 F_getit (inf); /* look for name */
3973 } 3974 }
3974 continue; 3975 continue;
3975 } 3976 }
4041 } 4042 }
4042 c = *cp; 4043 c = *cp;
4043 *cp = '\0'; 4044 *cp = '\0';
4044 name = concat (dbp, name_qualifier, ""); 4045 name = concat (dbp, name_qualifier, "");
4045 *cp = c; 4046 *cp = c;
4046 pfnote (name, TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 4047 make_tag (name, strlen (name), TRUE,
4048 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4049 free (name);
4047 if (c == '"') 4050 if (c == '"')
4048 dbp = cp + 1; 4051 dbp = cp + 1;
4049 return; 4052 return;
4050 } 4053 }
4051 } 4054 }
4160 /* Read past label. */ 4163 /* Read past label. */
4161 cp++; 4164 cp++;
4162 while (ISALNUM (*cp) || *cp == '_' || *cp == '.' || *cp == '$') 4165 while (ISALNUM (*cp) || *cp == '_' || *cp == '.' || *cp == '$')
4163 cp++; 4166 cp++;
4164 if (*cp == ':' || iswhite (*cp)) 4167 if (*cp == ':' || iswhite (*cp))
4165 { 4168 /* Found end of label, so copy it and add it to the table. */
4166 /* Found end of label, so copy it and add it to the table. */ 4169 make_tag (lb.buffer, cp - lb.buffer, TRUE,
4167 pfnote (savenstr(lb.buffer, cp-lb.buffer), TRUE,
4168 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 4170 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4169 }
4170 } 4171 }
4171 } 4172 }
4172 } 4173 }
4173 4174
4174 4175
4192 skip_spaces(cp); 4193 skip_spaces(cp);
4193 4194
4194 if (LOOKING_AT (cp, "package")) 4195 if (LOOKING_AT (cp, "package"))
4195 { 4196 {
4196 free (package); 4197 free (package);
4197 package = get_tag (cp); 4198 get_tag (cp, &package);
4198 if (package == NULL) /* can't parse package name */
4199 package = savestr ("");
4200 else
4201 package = savestr(package); /* make a copy */
4202 } 4199 }
4203 else if (LOOKING_AT (cp, "sub")) 4200 else if (LOOKING_AT (cp, "sub"))
4204 { 4201 {
4205 char *name, *fullname, *pos; 4202 char *pos;
4206 char *sp = cp; 4203 char *sp = cp;
4207 4204
4208 while (!notinname (*cp)) 4205 while (!notinname (*cp))
4209 cp++; 4206 cp++;
4210 if (cp == sp) 4207 if (cp == sp)
4211 continue; 4208 continue; /* nothing found */
4212 name = savenstr (sp, cp-sp); 4209 if ((pos = etags_strchr (sp, ':')) != NULL
4213 if ((pos = etags_strchr (name, ':')) != NULL && pos[1] == ':') 4210 && pos < cp && pos[1] == ':')
4214 fullname = name; 4211 /* The name is already qualified. */
4212 make_tag (sp, cp - sp, TRUE,
4213 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4215 else 4214 else
4216 fullname = concat (package, "::", name); 4215 /* Qualify it. */
4217 pfnote (fullname, TRUE, 4216 {
4218 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 4217 char savechar, *name;
4219 if (name != fullname) 4218
4220 free (name); 4219 savechar = *cp;
4220 *cp = '\0';
4221 name = concat (package, "::", sp);
4222 *cp = savechar;
4223 make_tag (name, strlen(name), TRUE,
4224 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4225 free (name);
4226 }
4221 } 4227 }
4222 else if (globals /* only if tagging global vars is enabled */ 4228 else if (globals) /* only if we are tagging global vars */
4223 && (LOOKING_AT (cp, "my") || LOOKING_AT (cp, "local")))
4224 { 4229 {
4230 /* Skip a qualifier, if any. */
4231 bool qual = LOOKING_AT (cp, "my") || LOOKING_AT (cp, "local");
4225 /* After "my" or "local", but before any following paren or space. */ 4232 /* After "my" or "local", but before any following paren or space. */
4226 char *varname = NULL; 4233 char *varstart = cp;
4227 4234
4228 if (*cp == '$' || *cp == '@' || *cp == '%') 4235 if (qual /* should this be removed? If yes, how? */
4236 && (*cp == '$' || *cp == '@' || *cp == '%'))
4229 { 4237 {
4230 char* varstart = ++cp; 4238 varstart += 1;
4231 while (ISALNUM (*cp) || *cp == '_') 4239 do
4232 cp++; 4240 cp++;
4233 varname = savenstr (varstart, cp-varstart); 4241 while (ISALNUM (*cp) || *cp == '_');
4234 } 4242 }
4235 else 4243 else if (qual)
4236 { 4244 {
4237 /* Should be examining a variable list at this point; 4245 /* Should be examining a variable list at this point;
4238 could insist on seeing an open parenthesis. */ 4246 could insist on seeing an open parenthesis. */
4239 while (*cp != '\0' && *cp != ';' && *cp != '=' && *cp != ')') 4247 while (*cp != '\0' && *cp != ';' && *cp != '=' && *cp != ')')
4240 cp++; 4248 cp++;
4241 } 4249 }
4242 4250 else
4243 /* Perhaps I should back cp up one character, so the TAGS table 4251 continue;
4244 doesn't mention (and so depend upon) the following char. */ 4252
4245 pfnote (varname, FALSE, 4253 make_tag (varstart, cp - varstart, FALSE,
4246 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 4254 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4247 } 4255 }
4248 } 4256 }
4249 } 4257 }
4250 4258
4251 4259
4267 if (LOOKING_AT (cp, "def") || LOOKING_AT (cp, "class")) 4275 if (LOOKING_AT (cp, "def") || LOOKING_AT (cp, "class"))
4268 { 4276 {
4269 char *name = cp; 4277 char *name = cp;
4270 while (!notinname (*cp) && *cp != ':') 4278 while (!notinname (*cp) && *cp != ':')
4271 cp++; 4279 cp++;
4272 pfnote (savenstr (name, cp-name), TRUE, 4280 make_tag (name, cp - name, TRUE,
4273 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 4281 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4274 } 4282 }
4275 } 4283 }
4276 } 4284 }
4277 4285
4278 4286
4300 if (search_identifier 4308 if (search_identifier
4301 && *cp != '\0') 4309 && *cp != '\0')
4302 { 4310 {
4303 while (!notinname (*cp)) 4311 while (!notinname (*cp))
4304 cp++; 4312 cp++;
4305 pfnote (savenstr (name, cp-name), TRUE, 4313 make_tag (name, cp - name, TRUE,
4306 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 4314 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4307 search_identifier = FALSE; 4315 search_identifier = FALSE;
4308 } 4316 }
4309 else if (LOOKING_AT (cp, "function")) 4317 else if (LOOKING_AT (cp, "function"))
4310 { 4318 {
4311 if(*cp == '&') 4319 if(*cp == '&')
4313 if(*cp != '\0') 4321 if(*cp != '\0')
4314 { 4322 {
4315 name = cp; 4323 name = cp;
4316 while (!notinname (*cp)) 4324 while (!notinname (*cp))
4317 cp++; 4325 cp++;
4318 pfnote (savenstr (name, cp-name), TRUE, 4326 make_tag (name, cp - name, TRUE,
4319 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 4327 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4320 } 4328 }
4321 else 4329 else
4322 search_identifier = TRUE; 4330 search_identifier = TRUE;
4323 } 4331 }
4324 else if (LOOKING_AT (cp, "class")) 4332 else if (LOOKING_AT (cp, "class"))
4326 if (*cp != '\0') 4334 if (*cp != '\0')
4327 { 4335 {
4328 name = cp; 4336 name = cp;
4329 while (*cp != '\0' && !iswhite (*cp)) 4337 while (*cp != '\0' && !iswhite (*cp))
4330 cp++; 4338 cp++;
4331 pfnote (savenstr (name, cp-name), FALSE, 4339 make_tag (name, cp - name, FALSE,
4332 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 4340 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4333 } 4341 }
4334 else 4342 else
4335 search_identifier = TRUE; 4343 search_identifier = TRUE;
4336 } 4344 }
4337 else if (strneq (cp, "define", 6) 4345 else if (strneq (cp, "define", 6)
4341 { 4349 {
4342 char quote = *cp++; 4350 char quote = *cp++;
4343 name = cp; 4351 name = cp;
4344 while (*cp != quote && *cp != '\0') 4352 while (*cp != quote && *cp != '\0')
4345 cp++; 4353 cp++;
4346 pfnote (savenstr (name, cp-name), FALSE, 4354 make_tag (name, cp - name, FALSE,
4347 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 4355 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4348 } 4356 }
4349 else if (members 4357 else if (members
4350 && LOOKING_AT (cp, "var") 4358 && LOOKING_AT (cp, "var")
4351 && *cp == '$') 4359 && *cp == '$')
4352 { 4360 {
4353 name = cp; 4361 name = cp;
4354 while (!notinname(*cp)) 4362 while (!notinname(*cp))
4355 cp++; 4363 cp++;
4356 pfnote (savenstr (name, cp-name), FALSE, 4364 make_tag (name, cp - name, FALSE,
4357 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 4365 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4358 } 4366 }
4359 } 4367 }
4360 } 4368 }
4361 4369
4362 4370
4383 continue; 4391 continue;
4384 4392
4385 for (ep = bp; ISALNUM (*ep) || *ep == '-'; ep++) 4393 for (ep = bp; ISALNUM (*ep) || *ep == '-'; ep++)
4386 continue; 4394 continue;
4387 if (*ep++ == '.') 4395 if (*ep++ == '.')
4388 pfnote (savenstr (bp, ep-bp), TRUE, 4396 make_tag (bp, ep - bp, TRUE,
4389 lb.buffer, ep - lb.buffer + 1, lineno, linecharno); 4397 lb.buffer, ep - lb.buffer + 1, lineno, linecharno);
4390 } 4398 }
4391 } 4399 }
4392 4400
4393 4401
4394 /* 4402 /*
4406 if (*bp == '\t' || *bp == '#') 4414 if (*bp == '\t' || *bp == '#')
4407 continue; 4415 continue;
4408 while (*bp != '\0' && *bp != '=' && *bp != ':') 4416 while (*bp != '\0' && *bp != '=' && *bp != ':')
4409 bp++; 4417 bp++;
4410 if (*bp == ':' || (globals && *bp == '=')) 4418 if (*bp == ':' || (globals && *bp == '='))
4411 pfnote (savenstr (lb.buffer, bp - lb.buffer), TRUE, 4419 make_tag (lb.buffer, bp - lb.buffer, TRUE,
4412 lb.buffer, bp - lb.buffer + 1, lineno, linecharno); 4420 lb.buffer, bp - lb.buffer + 1, lineno, linecharno);
4413 } 4421 }
4414 } 4422 }
4415 4423
4416 4424
4417 /* 4425 /*
4427 Pascal_functions (inf) 4435 Pascal_functions (inf)
4428 FILE *inf; 4436 FILE *inf;
4429 { 4437 {
4430 linebuffer tline; /* mostly copied from C_entries */ 4438 linebuffer tline; /* mostly copied from C_entries */
4431 long save_lcno; 4439 long save_lcno;
4432 int save_lineno, save_len; 4440 int save_lineno, namelen, taglen;
4433 char c, *cp, *namebuf; 4441 char c, *name;
4434 4442
4435 bool /* each of these flags is TRUE iff: */ 4443 bool /* each of these flags is TRUE iff: */
4436 incomment, /* point is inside a comment */ 4444 incomment, /* point is inside a comment */
4437 inquote, /* point is inside '..' string */ 4445 inquote, /* point is inside '..' string */
4438 get_tagname, /* point is after PROCEDURE/FUNCTION 4446 get_tagname, /* point is after PROCEDURE/FUNCTION
4442 verify_tag; /* point has passed the parm-list, so the 4450 verify_tag; /* point has passed the parm-list, so the
4443 next token will determine whether this 4451 next token will determine whether this
4444 is a FORWARD/EXTERN to be ignored, or 4452 is a FORWARD/EXTERN to be ignored, or
4445 whether it is a real tag */ 4453 whether it is a real tag */
4446 4454
4447 save_lcno = save_lineno = save_len = 0; /* keep compiler quiet */ 4455 save_lcno = save_lineno = namelen = taglen = 0; /* keep compiler quiet */
4448 namebuf = NULL; /* keep compiler quiet */ 4456 name = NULL; /* keep compiler quiet */
4449 dbp = lb.buffer; 4457 dbp = lb.buffer;
4450 *dbp = '\0'; 4458 *dbp = '\0';
4451 initbuffer (&tline); 4459 initbuffer (&tline);
4452 4460
4453 incomment = inquote = FALSE; 4461 incomment = inquote = FALSE;
4454 found_tag = FALSE; /* have a proc name; check if extern */ 4462 found_tag = FALSE; /* have a proc name; check if extern */
4455 get_tagname = FALSE; /* have found "procedure" keyword */ 4463 get_tagname = FALSE; /* found "procedure" keyword */
4456 inparms = FALSE; /* found '(' after "proc" */ 4464 inparms = FALSE; /* found '(' after "proc" */
4457 verify_tag = FALSE; /* check if "extern" is ahead */ 4465 verify_tag = FALSE; /* check if "extern" is ahead */
4458 4466
4459 4467
4460 while (!feof (inf)) /* long main loop to get next char */ 4468 while (!feof (inf)) /* long main loop to get next char */
4519 } 4527 }
4520 continue; 4528 continue;
4521 } 4529 }
4522 if (found_tag && verify_tag && (*dbp != ' ')) 4530 if (found_tag && verify_tag && (*dbp != ' '))
4523 { 4531 {
4524 /* check if this is an "extern" declaration */ 4532 /* Check if this is an "extern" declaration. */
4525 if (*dbp == '\0') 4533 if (*dbp == '\0')
4526 continue; 4534 continue;
4527 if (lowcase (*dbp == 'e')) 4535 if (lowcase (*dbp == 'e'))
4528 { 4536 {
4529 if (nocase_tail ("extern")) /* superfluous, really! */ 4537 if (nocase_tail ("extern")) /* superfluous, really! */
4542 } 4550 }
4543 if (found_tag && verify_tag) /* not external proc, so make tag */ 4551 if (found_tag && verify_tag) /* not external proc, so make tag */
4544 { 4552 {
4545 found_tag = FALSE; 4553 found_tag = FALSE;
4546 verify_tag = FALSE; 4554 verify_tag = FALSE;
4547 pfnote (namebuf, TRUE, 4555 make_tag (name, namelen, TRUE,
4548 tline.buffer, save_len, save_lineno, save_lcno); 4556 tline.buffer, taglen, save_lineno, save_lcno);
4549 continue; 4557 continue;
4550 } 4558 }
4551 } 4559 }
4552 if (get_tagname) /* grab name of proc or fn */ 4560 if (get_tagname) /* grab name of proc or fn */
4553 { 4561 {
4562 char *cp;
4563
4554 if (*dbp == '\0') 4564 if (*dbp == '\0')
4555 continue; 4565 continue;
4556 4566
4557 /* save all values for later tagging */ 4567 /* Find block name. */
4568 for (cp = dbp + 1; *cp != '\0' && !endtoken (*cp); cp++)
4569 continue;
4570
4571 /* Save all values for later tagging. */
4558 linebuffer_setlen (&tline, lb.len); 4572 linebuffer_setlen (&tline, lb.len);
4559 strcpy (tline.buffer, lb.buffer); 4573 strcpy (tline.buffer, lb.buffer);
4560 save_lineno = lineno; 4574 save_lineno = lineno;
4561 save_lcno = linecharno; 4575 save_lcno = linecharno;
4562 4576 name = tline.buffer + (dbp - lb.buffer);
4563 /* grab block name */ 4577 namelen = cp - dbp;
4564 for (cp = dbp + 1; *cp != '\0' && !endtoken (*cp); cp++) 4578 taglen = cp - lb.buffer + 1;
4565 continue; 4579
4566 namebuf = savenstr (dbp, cp-dbp);
4567 dbp = cp; /* set dbp to e-o-token */ 4580 dbp = cp; /* set dbp to e-o-token */
4568 save_len = dbp - lb.buffer + 1;
4569 get_tagname = FALSE; 4581 get_tagname = FALSE;
4570 found_tag = TRUE; 4582 found_tag = TRUE;
4571 continue; 4583 continue;
4572 4584
4573 /* and proceed to check for "extern" */ 4585 /* And proceed to check for "extern". */
4574 } 4586 }
4575 else if (!incomment && !inquote && !found_tag) 4587 else if (!incomment && !inquote && !found_tag)
4576 { 4588 {
4577 /* check for proc/fn keywords */ 4589 /* Check for proc/fn keywords. */
4578 switch (lowcase (c)) 4590 switch (lowcase (c))
4579 { 4591 {
4580 case 'p': 4592 case 'p':
4581 if (nocase_tail ("rocedure")) /* c = 'p', dbp has advanced */ 4593 if (nocase_tail ("rocedure")) /* c = 'p', dbp has advanced */
4582 get_tagname = TRUE; 4594 get_tagname = TRUE;
4585 if (nocase_tail ("unction")) 4597 if (nocase_tail ("unction"))
4586 get_tagname = TRUE; 4598 get_tagname = TRUE;
4587 continue; 4599 continue;
4588 } 4600 }
4589 } 4601 }
4590 } /* while not eof */ 4602 } /* while not eof */
4591 4603
4592 free (tline.buffer); 4604 free (tline.buffer);
4593 } 4605 }
4594 4606
4595 4607
4611 /* Try to skip "(quote " */ 4623 /* Try to skip "(quote " */
4612 if (!LOOKING_AT (dbp, "quote") && !LOOKING_AT (dbp, "QUOTE")) 4624 if (!LOOKING_AT (dbp, "quote") && !LOOKING_AT (dbp, "QUOTE"))
4613 /* Ok, then skip "(" before name in (defstruct (foo)) */ 4625 /* Ok, then skip "(" before name in (defstruct (foo)) */
4614 dbp = skip_spaces (dbp); 4626 dbp = skip_spaces (dbp);
4615 } 4627 }
4616 get_tag (dbp); 4628 get_tag (dbp, NULL);
4617 } 4629 }
4618 4630
4619 static void 4631 static void
4620 Lisp_functions (inf) 4632 Lisp_functions (inf)
4621 FILE *inf; 4633 FILE *inf;
4675 { 4687 {
4676 for (ep = bp+1; 4688 for (ep = bp+1;
4677 *ep != '\0' && *ep != ' ' && *ep != '{'; 4689 *ep != '\0' && *ep != ' ' && *ep != '{';
4678 ep++) 4690 ep++)
4679 continue; 4691 continue;
4680 pfnote (savenstr (bp, ep-bp), TRUE, 4692 make_tag (bp, ep - bp, TRUE,
4681 lb.buffer, ep - lb.buffer + 1, lineno, linecharno); 4693 lb.buffer, ep - lb.buffer + 1, lineno, linecharno);
4682 } 4694 }
4683 else if (LOOKING_AT (bp, "defineps")) 4695 else if (LOOKING_AT (bp, "defineps"))
4684 get_tag (bp); 4696 get_tag (bp, NULL);
4685 } 4697 }
4686 } 4698 }
4687 4699
4688 4700
4689 /* 4701 /*
4707 { 4719 {
4708 bp = skip_non_spaces (bp+4); 4720 bp = skip_non_spaces (bp+4);
4709 /* Skip over open parens and white space */ 4721 /* Skip over open parens and white space */
4710 while (notinname (*bp)) 4722 while (notinname (*bp))
4711 bp++; 4723 bp++;
4712 get_tag (bp); 4724 get_tag (bp, NULL);
4713 } 4725 }
4714 if (LOOKING_AT (bp, "(SET!") || LOOKING_AT (bp, "(set!")) 4726 if (LOOKING_AT (bp, "(SET!") || LOOKING_AT (bp, "(set!"))
4715 get_tag (bp); 4727 get_tag (bp, NULL);
4716 } 4728 }
4717 } 4729 }
4718 4730
4719 4731
4720 /* Find tags in TeX and LaTeX input files. */ 4732 /* Find tags in TeX and LaTeX input files. */
4772 4784
4773 for (key = TEX_toktab; key->buffer != NULL; key++) 4785 for (key = TEX_toktab; key->buffer != NULL; key++)
4774 if (strneq (cp, key->buffer, key->len)) 4786 if (strneq (cp, key->buffer, key->len))
4775 { 4787 {
4776 register char *p; 4788 register char *p;
4777 char *name; 4789 int namelen, linelen;
4778 int linelen;
4779 bool opgrp = FALSE; 4790 bool opgrp = FALSE;
4780 4791
4781 cp = skip_spaces (cp + key->len); 4792 cp = skip_spaces (cp + key->len);
4782 if (*cp == TEX_opgrp) 4793 if (*cp == TEX_opgrp)
4783 { 4794 {
4787 for (p = cp; 4798 for (p = cp;
4788 (!iswhite (*p) && *p != '#' && 4799 (!iswhite (*p) && *p != '#' &&
4789 *p != TEX_opgrp && *p != TEX_clgrp); 4800 *p != TEX_opgrp && *p != TEX_clgrp);
4790 p++) 4801 p++)
4791 continue; 4802 continue;
4792 name = savenstr (cp, p-cp); 4803 namelen = p - cp;
4793 linelen = lb.len; 4804 linelen = lb.len;
4794 if (!opgrp || *p == TEX_clgrp) 4805 if (!opgrp || *p == TEX_clgrp)
4795 { 4806 {
4796 while (*p != '\0' && *p != TEX_opgrp && *p != TEX_clgrp) 4807 while (*p != '\0' && *p != TEX_opgrp && *p != TEX_clgrp)
4797 *p++; 4808 *p++;
4798 linelen = p - lb.buffer + 1; 4809 linelen = p - lb.buffer + 1;
4799 } 4810 }
4800 pfnote (name, TRUE, lb.buffer, linelen, lineno, linecharno); 4811 make_tag (cp, namelen, TRUE,
4812 lb.buffer, linelen, lineno, linecharno);
4801 goto tex_next_line; /* We only tag a line once */ 4813 goto tex_next_line; /* We only tag a line once */
4802 } 4814 }
4803 } 4815 }
4804 tex_next_line: 4816 tex_next_line:
4805 ; 4817 ;
4905 if (LOOKING_AT (cp, "@node")) 4917 if (LOOKING_AT (cp, "@node"))
4906 { 4918 {
4907 start = cp; 4919 start = cp;
4908 while (*cp != '\0' && *cp != ',') 4920 while (*cp != '\0' && *cp != ',')
4909 cp++; 4921 cp++;
4910 pfnote (savenstr (start, cp - start), TRUE, 4922 make_tag (start, cp - start, TRUE,
4911 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 4923 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4912 } 4924 }
4913 } 4925 }
4914 4926
4915 4927
4916 /* 4928 /*
5009 || (s[pos] == ':' && s[pos + 1] == '-' && (pos += 2))) 5021 || (s[pos] == ':' && s[pos + 1] == '-' && (pos += 2)))
5010 && (last == NULL /* save only the first clause */ 5022 && (last == NULL /* save only the first clause */
5011 || len != strlen (last) 5023 || len != strlen (last)
5012 || !strneq (s, last, len))) 5024 || !strneq (s, last, len)))
5013 { 5025 {
5014 pfnote (savenstr (s, len), TRUE, s, pos, lineno, linecharno); 5026 make_tag (s, len, TRUE, s, pos, lineno, linecharno);
5015 return len; 5027 return len;
5016 } 5028 }
5017 else 5029 else
5018 return 0; 5030 return 0;
5019 } 5031 }
5163 if (s[pos++] == '(' 5175 if (s[pos++] == '('
5164 && (last == NULL 5176 && (last == NULL
5165 || len != (int)strlen (last) 5177 || len != (int)strlen (last)
5166 || !strneq (s, last, len))) 5178 || !strneq (s, last, len)))
5167 { 5179 {
5168 pfnote (savenstr (s, len), TRUE, s, pos, lineno, linecharno); 5180 make_tag (s, len, TRUE, s, pos, lineno, linecharno);
5169 return len; 5181 return len;
5170 } 5182 }
5171 5183
5172 return 0; 5184 return 0;
5173 } 5185 }
5191 if ((LOOKING_AT (cp, "-define") || LOOKING_AT (cp, "-record")) 5203 if ((LOOKING_AT (cp, "-define") || LOOKING_AT (cp, "-record"))
5192 && *cp++ == '(') 5204 && *cp++ == '(')
5193 { 5205 {
5194 int len = erlang_atom (skip_spaces (cp)); 5206 int len = erlang_atom (skip_spaces (cp));
5195 if (len > 0) 5207 if (len > 0)
5196 pfnote (savenstr (cp, len), TRUE, 5208 make_tag (cp, len, TRUE, s, cp + len - s, lineno, linecharno);
5197 s, cp + len - s, lineno, linecharno);
5198 } 5209 }
5199 return; 5210 return;
5200 } 5211 }
5201 5212
5202 5213
5608 while (charno < pp->regs.end[0]) 5619 while (charno < pp->regs.end[0])
5609 if (buffer[charno++] == '\n') 5620 if (buffer[charno++] == '\n')
5610 lineno++, linecharno = charno; 5621 lineno++, linecharno = charno;
5611 if (pp->name_pattern[0] != '\0') 5622 if (pp->name_pattern[0] != '\0')
5612 { 5623 {
5613 /* Make a named tag. */ 5624 /* Make a named tag.
5625 Do not use make_tag here, as it would make the name
5626 implicit if possible, while we want to respect the user's
5627 request to create an explicit tag name. */
5614 char *name = substitute (buffer, 5628 char *name = substitute (buffer,
5615 pp->name_pattern, &pp->regs); 5629 pp->name_pattern, &pp->regs);
5616 if (name != NULL) 5630 if (name != NULL)
5617 pfnote (name, TRUE, buffer + linecharno, 5631 pfnote (name, TRUE, buffer + linecharno,
5618 charno - linecharno + 1, lineno, linecharno); 5632 charno - linecharno + 1, lineno, linecharno);
5646 return TRUE; 5660 return TRUE;
5647 } 5661 }
5648 return FALSE; 5662 return FALSE;
5649 } 5663 }
5650 5664
5651 static char * 5665 static void
5652 get_tag (bp) 5666 get_tag (bp, namepp)
5653 register char *bp; 5667 register char *bp;
5654 { 5668 char **namepp;
5655 register char *cp, *name; 5669 {
5656 5670 register char *cp = bp;
5657 if (*bp == '\0') 5671
5658 return NULL; 5672 if (*bp != '\0')
5659 /* Go till you get to white space or a syntactic break */ 5673 {
5660 for (cp = bp + 1; !notinname (*cp); cp++) 5674 /* Go till you get to white space or a syntactic break */
5661 continue; 5675 for (cp = bp + 1; !notinname (*cp); cp++)
5662 name = savenstr (bp, cp-bp); 5676 continue;
5663 pfnote (name, TRUE, 5677 make_tag (bp, cp - bp, TRUE,
5664 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 5678 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
5665 return name; 5679 }
5680
5681 if (namepp != NULL)
5682 *namepp = savenstr (bp, cp - bp);
5666 } 5683 }
5667 5684
5668 /* Initialize a linebuffer for use */ 5685 /* Initialize a linebuffer for use */
5669 static void 5686 static void
5670 initbuffer (lbp) 5687 initbuffer (lbp)
5941 break; 5958 break;
5942 default: 5959 default:
5943 /* Match occurred. Construct a tag. */ 5960 /* Match occurred. Construct a tag. */
5944 if (pp->name_pattern[0] != '\0') 5961 if (pp->name_pattern[0] != '\0')
5945 { 5962 {
5946 /* Make a named tag. */ 5963 /* Make a named tag.
5964 Do not use make_tag here, as it would make the name
5965 implicit if possible, while we want to respect the user's
5966 request to create an explicit tag name. */
5947 char *name = substitute (lbp->buffer, 5967 char *name = substitute (lbp->buffer,
5948 pp->name_pattern, &pp->regs); 5968 pp->name_pattern, &pp->regs);
5949 if (name != NULL) 5969 if (name != NULL)
5950 pfnote (name, TRUE, lbp->buffer, match, lineno, linecharno); 5970 pfnote (name, TRUE, lbp->buffer, match, lineno, linecharno);
5951 } 5971 }