Mercurial > emacs
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 } |