--- ctags/entry.c +++ ctags/entry.c @@ -550,8 +550,15 @@ extern void beginEtagsFile (void) extern void endEtagsFile (const char *const name) { const char *line; + const char *file = name; + size_t buildRootLen = Option.buildRoot ? strlen (Option.buildRoot) : 0; - fprintf (TagFile.fp, "\f\n%s,%ld\n", name, (long) TagFile.etags.byteCount); + if (Option.buildRoot && + strncmp (file, Option.buildRoot, buildRootLen) == 0 && + isPathSeparator (name[buildRootLen])) + file += buildRootLen; + + fprintf (TagFile.fp, "\f\n%s,%ld\n", file, (long) TagFile.etags.byteCount); if (TagFile.etags.fp != NULL) { rewind (TagFile.etags.fp); @@ -834,14 +841,21 @@ extern void makeTagEntry (const tagEntryInfo *const tag) extern void initTagEntry (tagEntryInfo *const e, const char *const name) { + const char *file = getSourceFileTagPath (); + size_t buildRootLen = Option.buildRoot ? strlen (Option.buildRoot) : 0; + Assert (File.source.name != NULL); memset (e, 0, sizeof (tagEntryInfo)); e->lineNumberEntry = (boolean) (Option.locate == EX_LINENUM); e->lineNumber = getSourceLineNumber (); e->language = getSourceLanguageName (); e->filePosition = getInputFilePosition (); - e->sourceFileName = getSourceFileTagPath (); + if (Option.buildRoot && + strncmp (file, Option.buildRoot, buildRootLen) == 0 && + isPathSeparator (file[buildRootLen])) + file += buildRootLen; + e->sourceFileName = file; e->name = name; } --- ctags/options.c +++ ctags/options.c @@ -148,6 +148,7 @@ optionValues Option = { FALSE, /* --tag-relative */ FALSE, /* --totals */ FALSE, /* --line-directives */ + NULL, /* --buildroot */ #ifdef DEBUG 0, 0 /* -D, -b */ #endif @@ -270,6 +271,8 @@ static optionDescription LongOptionDescription [] = { {0," Should paths be relative to location of tag file [no; yes when -e]?"}, {1," --totals=[yes|no]"}, {1," Print statistics about source and tag files [no]."}, + {1," --buildroot=path"}, + {1," Base directory to strip from file names."}, {1," --verbose=[yes|no]"}, {1," Enable verbose messages describing actions on each source file."}, {1," --version"}, @@ -866,6 +869,15 @@ static void processFieldsOption ( } } +static void processBuildrootOption ( + const char *const option, const char *const parameter) +{ + freeString (&Option.buildRoot); + if (! isAbsolutePath(parameter)) + error (FATAL, "Value for \"%s\" must be absolute path",option); + Option.buildRoot = stringCopy (parameter); +} + static void processFilterTerminatorOption ( const char *const option __unused__, const char *const parameter) { @@ -1370,6 +1382,7 @@ static void processVersionOption ( */ static parametricOption ParametricOptions [] = { + { "buildroot", processBuildrootOption, TRUE }, { "etags-include", processEtagsInclude, FALSE }, { "exclude", processExcludeOption, FALSE }, { "excmd", processExcmdOption, FALSE }, @@ -1818,6 +1831,7 @@ extern void freeOptionResources (void) freeString (&Option.tagFileName); freeString (&Option.fileList); freeString (&Option.filterTerminator); + freeString (&Option.buildRoot); freeList (&Excluded); freeList (&Option.ignore); --- ctags/options.h +++ ctags/options.h @@ -108,6 +108,7 @@ typedef struct sOptionValues { boolean tagRelative; /* --tag-relative file paths relative to tag file */ boolean printTotals; /* --totals print cumulative statistics */ boolean lineDirectives; /* --linedirectives process #line directives */ + char *buildRoot; /* --buildroot file prefix */ #ifdef DEBUG long debugLevel; /* -D debugging output */ unsigned long breakLine;/* -b source line at which to call lineBreak() */ --- ctags/routines.c +++ ctags/routines.c @@ -513,7 +513,7 @@ extern int fsetpos (FILE *stream, fpos_t const *pos) * Pathname manipulation (O/S dependent!!!) */ -static boolean isPathSeparator (const int c) +extern boolean isPathSeparator (const int c) { boolean result; #if defined (MSDOS_STYLE_PATH) || defined (VMS) --- ctags/routines.h +++ ctags/routines.h @@ -120,6 +120,7 @@ extern boolean isSameFile (const char *const name1, const char *const name2); extern int fgetpos (FILE *stream, fpos_t *pos); extern int fsetpos (FILE *stream, fpos_t *pos); #endif +extern boolean isPathSeparator (const int c); extern const char *baseFilename (const char *const filePath); extern const char *fileExtension (const char *const fileName); extern boolean isAbsolutePath (const char *const path);