*** etags.c.orig Wed Aug 6 02:09:19 1997 --- etags.c Wed Nov 5 13:30:11 1997 *************** *** 31,37 **** * Francesco Potorti` (F.Potorti@cnuce.cnr.it) is the current maintainer. */ ! char pot_etags_version[] = "@(#) pot revision number is 12.11"; #define TRUE 1 #define FALSE 0 --- 31,37 ---- * Francesco Potorti` (F.Potorti@cnuce.cnr.it) is the current maintainer. */ ! char pot_etags_version[] = "@(#) pot revision number is 12.11/patched for Ada"; #define TRUE 1 #define FALSE 0 *************** *** 182,193 **** --- 182,195 ---- char *relative_filename (), *absolute_filename (), *absolute_dirname (); void grow_linebuffer (); long *xmalloc (), *xrealloc (); + char *basename_no_extension (); typedef void Lang_function (); /* Many compilers barf on this: Lang_function Asm_labels; so let's write it this way */ void Asm_labels (); + void Ada_funcs (); void C_entries (); void default_C_entries (); void plain_C_entries (); *************** *** 300,305 **** --- 302,309 ---- bool cxref_style; /* -x: create cxref style output */ bool cplusplus; /* .[hc] means C++, not C */ bool noindentypedefs; /* -I: ignore indentation in C */ + bool packages_only; /* -P: only ada packages */ + bool do_filename_tags; /* -F: insert a tag for the filename */ #ifdef LONG_OPTIONS struct option longopts[] = *************** *** 330,335 **** --- 334,341 ---- { "update", no_argument, NULL, 'u' }, { "version", no_argument, NULL, 'V' }, { "vgrind", no_argument, NULL, 'v' }, + { "packages-only", no_argument, NULL, 'P' }, + { "do-filename-tags", no_argument, NULL, 'F' }, { 0 } }; #endif /* LONG_OPTIONS */ *************** *** 371,376 **** --- 377,386 ---- NULL }; + /* Ada code */ + char *Ada_suffixes [] = + { "ads", "adb", "ada", NULL }; + /* Note that .c and .h can be considered C++, if the --c++ flag was given. That is why default_C_entries is called here. */ char *default_C_suffixes [] = *************** *** 445,450 **** --- 455,461 ---- struct lang_entry lang_names [] = { { "asm", Asm_labels, Asm_suffixes, NULL }, + { "Ada", Ada_funcs, Ada_suffixes, NULL }, { "c", default_C_entries, default_C_suffixes, NULL }, { "c++", Cplusplus_entries, Cplusplus_suffixes, NULL }, { "c*", Cstar_entries, Cstar_suffixes, NULL }, *************** *** 609,614 **** --- 620,631 ---- which you like."); } + puts ("-P, --packages-only\n\ + For Ada files, generates tags entries only for packages."); + + puts ("-F, --do-filename-tags\n\ + Generates a tag entry with tagname being file basename without suffix."); + puts ("-V, --version\n\ Print the version of the program.\n\ -h, --help\n\ *************** *** 816,824 **** char *optstring; #ifdef ETAGS_REGEXPS ! optstring = "-aCdDf:Il:o:r:RStTi:BuvxwVhH"; #else ! optstring = "-aCdDf:Il:o:StTi:BuvxwVhH"; #endif /* ETAGS_REGEXPS */ #ifndef LONG_OPTIONS --- 833,841 ---- char *optstring; #ifdef ETAGS_REGEXPS ! optstring = "-aCdDf:Il:o:r:RStTi:BuvxwVhHPF"; #else ! optstring = "-aCdDf:Il:o:StTi:BuvxwVhHPF"; #endif /* ETAGS_REGEXPS */ #ifndef LONG_OPTIONS *************** *** 892,897 **** --- 909,923 ---- case 'T': typedefs = typedefs_and_cplusplus = TRUE; break; + + case 'P': + packages_only++; + break; + + case 'F': + do_filename_tags++; + break; + #if (!CTAGS) /* Etags options */ case 'i': *************** *** 1169,1174 **** --- 1195,1201 ---- if (!CTAGS) { char *filename; + char *tagfilename; if (absolutefn (file)) { *************** *** 1181,1186 **** --- 1208,1220 ---- to the directory of the tags file. */ filename = relative_filename (file, tagfiledir); } + if (do_filename_tags) + { + tagfilename = basename_no_extension(filename); + pfnote(savestr(tagfilename), FALSE, tagfilename, 0, 1, 0); + free (tagfilename); + } + fprintf (tagf, "\f\n%s,%d\n", filename, total_size_of_entries (head)); free (filename); put_entries (head); *************** *** 2954,2959 **** --- 2988,3198 ---- C_entries (YACC, inf); } + /* ada parsing */ + + char *adbp; + int apfcnt; + + void + Ada_funcs(fi) + FILE *fi; + { + int inquote; + + inquote = 0; + lineno = 0; + charno = 0; + apfcnt = 0; + + while (!feof (fi)) + { + if (adbp == NULL || *adbp == 0) + { + lineno++; + linecharno = charno; + charno += readline (&lb, fi) + 1; + adbp = lb.buffer; + } + if (*adbp == '-') + { + adbp++ ; + if (*adbp == '-') + { + while (*adbp) + adbp++; + continue; + } + } + if (*adbp == '\'') + { + adbp++ ; + if (*adbp) adbp++; + continue; + } + if (inquote || (*adbp == '"')) + { + inquote = 1; + adbp++ ; + while (*adbp && *adbp != '"') + adbp++; + if (*adbp == '"') + { + adbp++; + inquote = 0; + } + continue; + } + while (*adbp && !begtoken(*adbp)) + { + if ((*adbp == '-') || (*adbp == '"') || (*adbp == '\'')) + break; + adbp++; + } + if ((*adbp == '-') || (*adbp == '"') || (*adbp == '\'')) + continue; + if (*adbp == 0) + continue; + switch (*adbp) + { + case 'f': + case 'F': + if (adatail("function") && !packages_only) + adagetit(fi, "/f"); + else + adaskip(); + continue; + case 'p': + case 'P': + if (adatail("procedure") && !packages_only) + adagetit(fi, "/p"); + else if (adatail("package")) + adagetit(fi, "/s"); + else + adaskip(); + continue; + case 't': + case 'T': + if (adatail("task") && !packages_only) + adagetit(fi, "/k"); + else if (typedefs && adatail("type") && !packages_only) + adagetit(fi, "/t"); + else + adaskip(); + continue; + + default: + adaskip(); + continue; + } + } + } + adaskip() + { + while (*adbp && !endtoken(*adbp)) + adbp++; + while (*adbp && !begtoken(*adbp)) + { + if ((*adbp == '"') || (*adbp == '\'') || (*adbp == '-')) + return; + adbp++; + } + } + + adatail(cp) + char *cp; + { + register int len = 0; + + while (*cp && (*cp == tolower(*(adbp+len)))) + cp++, len++; + if (*cp == 0) + { + adbp += len; + if (intoken(*adbp)) + return (0); + else + return (1); + } + return (0); + } + + adagetit(fi, name_qualifier) + FILE *fi; + char *name_qualifier; + + { + register char *cp; + char c; + char nambuf[BUFSIZ]; + char * local_name_qualifier; + + local_name_qualifier = name_qualifier; + + while (!feof (fi)) + { + if (*adbp == '\0') + { + lineno++; + linecharno = charno; + charno += readline (&lb, fi) + 1; + adbp = lb.buffer; + } + if (*adbp == '-') + { + adbp++ ; + if (*adbp == '-') + { + while (*adbp) + adbp++; + continue; + } + } + while (isspace(*adbp)) + adbp++; + if (*adbp == 0) + continue; + if (*adbp == '-') + continue; + switch(*adbp) + { + case 'b': + case 'B': + if (adatail("body")) + { + local_name_qualifier = "/b"; + continue; + } + break; + + case 't': + case 'T': + if (adatail("type")) + continue; + break; + } + if (*adbp == '"') + { + for (cp = adbp+1; *cp && *cp != '"'; cp++) + continue; + } + else + for (cp = adbp+1; + *cp && (isalpha(*cp) || isdigit(*cp) || *cp == '_'); + cp++) + continue; + c = cp[0]; + cp[0] = 0; + strcpy(nambuf, adbp); + strcat(nambuf, local_name_qualifier); + cp[0] = c; + pfnote(savenstr (nambuf, strlen(nambuf)), TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno); + /* I am not really sure what the name is used for. */ + /* probably to be used to add a qualifier like /f /p /b /s /k /t */ + apfcnt++; + return; + } + } + /* Fortran parsing */ char *dbp; *************** *** 4684,4689 **** --- 4923,4968 ---- return path.buffer; #endif /* not MSDOS */ #endif /* not HAVE_GETCWD */ + } + + /* Returna newly allocated string containing the filename + of FILE without any precending directory and without + extension. */ + char * + basename_no_extension (file) + char *file; + { + char *begin = file + strlen(file); + char *end = begin; + char *res, *rescp; + bool in_extension; + + + /* position begin at the begining of the basename + end will point to the end of the basename + without extension */ + in_extension = TRUE; + + while (begin > file && *begin != '/') + { + if (*begin == '.' && in_extension) + { + end = begin; + in_extension = FALSE; + } + begin--; + } + if (*begin == '/') + begin++; + + res = xnew(strlen(begin) - strlen(end) + 1, char); + rescp = res; + while (begin != end) + { + *rescp++ = *begin++; + } + *rescp = '\0'; + return res; } /* Return a newly allocated string containing the file name