📄 main.c
字号:
DebugStatement( debugPrintf(DEBUG_STATUS,
"%s: formatting error; retrying\n", fileName); )
Option.braceFormat = TRUE;
createTagsForFile(filePath, language);
Option.braceFormat = FALSE;
resize = TRUE;
}
return resize;
}
# if defined(MSDOS) || defined(WIN32)
static boolean createTagsForMatchingEntries __ARGS((char *const pattern));
static boolean createTagsForMatchingEntries( pattern )
char *const pattern;
{
boolean resize = FALSE;
const size_t tailIndex = baseFilename(pattern) - (const char *)pattern;
char *const tail = pattern + tailIndex;
#ifdef HAVE_FINDFIRST
struct ffblk fileInfo;
int result = findfirst(pattern, &fileInfo, FA_DIREC);
while (result == 0)
{
const char *const entryName = fileInfo.ff_name;
/* We must not recurse into the directories "." or "..".
*/
if (strcmp(entryName, ".") != 0 && strcmp(entryName, "..") != 0)
{
strcpy(tail, entryName);
resize |= createTagsForEntry(pattern);
}
result = findnext(&fileInfo);
}
#else
# ifdef HAVE__FINDFIRST
struct _finddata_t fileInfo;
long hFile = _findfirst(pattern, &fileInfo);
if (hFile != -1L)
{
do
{
const char *const entryName = fileInfo.name;
/* We must not recurse into the directories "." or "..".
*/
if (strcmp(entryName, ".") != 0 && strcmp(entryName, "..") != 0)
{
strcpy(tail, entryName);
resize |= createTagsForEntry(pattern);
}
} while (_findnext(hFile, &fileInfo) == 0);
_findclose(hFile);
}
# endif /* HAVE__FINDFIRST */
#endif /* HAVE_FINDFIRST */
return resize;
}
#else
# ifdef AMIGA
static boolean createTagsForMatchingEntries __ARGS((char *const pattern));
static boolean createTagsForMatchingEntries( pattern )
char *const pattern;
{
boolean resize = FALSE;
struct AnchorPath *const anchor = (struct AnchorPath *)
calloc((size_t)1, (size_t)ANCHOR_SIZE);
if (anchor != NULL)
{
LONG result;
anchor->ap_Strlen = ANCHOR_BUF_SIZE; /* ap_Length no longer supported */
/* Allow '.' for current directory.
*/
#ifdef APF_DODOT
anchor->ap_Flags = APF_DODOT | APF_DOWILD;
#else
anchor->ap_Flags = APF_DoDot | APF_DoWild;
#endif
result = MatchFirst((UBYTE *)pattern, anchor);
while (result == 0)
{
resize |= createTagsForEntry((char *)anchor->ap_Buf);
result = MatchNext(anchor);
}
MatchEnd(anchor);
free(anchor);
}
return resize;
}
# endif /* AMIGA */
#endif /* MSDOS || WIN32 */
static boolean createTagsForDirectory( dirName )
const char *const dirName;
{
#ifdef HAVE_OPENDIR
boolean resize = FALSE;
DIR *const dir = opendir(dirName);
if (dir == NULL)
error(WARNING, "");
else
{
struct dirent *entry;
DebugStatement( debugPrintf(DEBUG_STATUS, "RECURSING into %s%c\n",
dirName, PATH_SEPARATOR); )
while ((entry = readdir(dir)) != NULL)
{
const char *const entryName = entry->d_name;
if (strcmp(entryName, ".") != 0 &&
strcmp(entryName, "..") != 0 &&
strcmp(entryName, "SCCS") != 0 )
{
char filePath[PATH_MAX + 1];
combinePathAndFile(filePath, dirName, entryName);
resize |= createTagsForEntry(filePath);
}
}
closedir(dir);
}
return resize;
#else
# if defined(MSDOS) || defined(WIN32)
char pattern[PATH_MAX + 1];
boolean resize;
DebugStatement( debugPrintf(DEBUG_STATUS, "RECURSING into %s%c\n",
dirName, PATH_SEPARATOR); )
strcpy(pattern, dirName);
strcat(pattern, "\\*.*");
resize = createTagsForMatchingEntries(pattern);
return resize;
# else
# ifdef AMIGA
char pattern[PATH_MAX + 1];
boolean resize = FALSE;
DebugStatement( debugPrintf(DEBUG_STATUS, "RECURSING into %s%c\n",
dirName, PATH_SEPARATOR); )
strcpy(pattern, dirName);
if (pattern[0] != '\0')
strcat(pattern, "/"); /* "/#?" searches one directory upwards */
strcat(pattern, "#?");
resize = createTagsForMatchingEntries(pattern);
return resize;
# else /* !AMIGA */
return FALSE;
# endif
# endif
#endif /* HAVE_OPENDIR */
}
static boolean createTagsForEntry( entryName )
const char *const entryName;
{
boolean resize = FALSE;
langType language;
if (! doesFileExist(entryName))
error(WARNING | PERROR, "cannot open \"%s\"", entryName);
else if (isDirectory(entryName))
{
if (Option.recurse)
resize = createTagsForDirectory(entryName);
else
{
DebugStatement( debugPrintf(DEBUG_STATUS," no recurse into %s%c\n",
entryName, PATH_SEPARATOR) );
resize = FALSE;
}
}
else if (! isNormalFile(entryName))
{
DebugStatement( if (debug(DEBUG_STATUS))
printf(" ignoring %s (special file)\n", entryName) );
}
else if ((language = getFileLanguage(entryName)) == LANG_IGNORE)
DebugStatement( debugOpen(entryName, FALSE, language) );
else
{
resize = createTagsWithFallback(entryName, language);
addTotals(1, 0L, 0L);
}
return resize;
}
static boolean createTagsForArgs( argList )
const char *const *const argList;
{
boolean resize = FALSE;
const char *const *pArg;
/* Generate tags for each argument on the command line.
*/
for (pArg = argList ; *pArg != NULL ; ++pArg)
{
const char *arg = *pArg;
#if defined(MSDOS) || defined(WIN32)
char pattern[PATH_MAX + 1];
strcpy(pattern, arg);
/* We must transform the "." and ".." forms into something that can
* be expanded by the MSDOS/Windows functions.
*/
if (Option.recurse &&
(strcmp(pattern, ".") == 0 || strcmp(pattern, "..") == 0))
{
strcat(pattern, "\\*.*");
}
resize |= createTagsForMatchingEntries(pattern);
#else
resize |= createTagsForEntry(arg);
#endif
}
return resize;
}
/* Create tags for the source files listed in the file specified by
* "listFile".
*/
static boolean createTagsForList( listFile )
const char *const listFile;
{
boolean resize = FALSE;
FILE *const fp = (strcmp(listFile,"-") == 0) ? stdin : fopen(listFile, "r");
if (fp == NULL)
error(FATAL | PERROR, "cannot open \"%s\"", listFile);
else
{
const char *fileName = getNextListFile(fp);
while (fileName != NULL && fileName[0] != '\0')
{
resize |= createTagsForEntry(fileName);
fileName = getNextListFile(fp);
}
if (fp != stdin)
fclose(fp);
}
return resize;
}
#ifdef HAVE_CLOCK
# define CLOCK_AVAILABLE
# ifndef CLOCKS_PER_SEC
# define CLOCKS_PER_SEC 1000000
# endif
#else
# ifdef HAVE_TIMES
# define CLOCK_AVAILABLE
# define CLOCKS_PER_SEC 60
static clock_t clock __ARGS((void));
static clock_t clock()
{
struct tms buf;
times(&buf);
return (buf.tms_utime + buf.tms_stime);
}
# else
# define clock() (clock_t)0
# endif
#endif
static void printTotals( timeStamps )
const clock_t *const timeStamps;
{
const unsigned long totalTags = TagFile.numTags.added +
TagFile.numTags.prev;
fprintf(errout, "%ld file%s, %ld line%s (%ld kB) scanned",
Totals.files, plural(Totals.files),
Totals.lines, plural(Totals.lines),
Totals.bytes/1024L);
#ifdef CLOCK_AVAILABLE
{
const double interval = ((double)(timeStamps[1] - timeStamps[0])) /
CLOCKS_PER_SEC;
fprintf(errout, " in %.01f seconds", interval);
if (interval != (double)0.0)
fprintf(errout, " (%lu kB/s)",
(unsigned long)(Totals.bytes / interval) / 1024L);
}
#endif
fputc('\n', errout);
fprintf(errout, "%lu tag%s added to tag file",
TagFile.numTags.added, plural(TagFile.numTags.added));
if (Option.append)
fprintf(errout, " (now %lu tags)", totalTags);
fputc('\n', errout);
if (totalTags > 0 && Option.sorted)
{
fprintf(errout, "%lu tag%s sorted", totalTags, plural(totalTags));
#ifdef CLOCK_AVAILABLE
fprintf(errout, " in %.02f seconds",
((double)(timeStamps[3] - timeStamps[2])) / CLOCKS_PER_SEC);
#endif
fputc('\n', errout);
}
#ifdef DEBUG
fprintf(errout, "longest tag line = %lu\n",
(unsigned long)TagFile.max.line);
#endif
}
static void makeTags( argList )
const char *const *const argList;
{
boolean toStdout = FALSE;
boolean resize = FALSE;
clock_t timeStamps[4];
if (Option.xref || strcmp(Option.tagFileName, "-") == 0
#if !defined(MSDOS) && !defined(WIN32) && !defined(OS2)
|| strcmp(Option.tagFileName, "/dev/stdout") == 0
#endif
)
toStdout = TRUE;
openTagFile(toStdout);
if (Option.printTotals) timeStamps[0] = clock();
if (Option.fileList != NULL)
resize = createTagsForList(Option.fileList);
resize = (boolean)(createTagsForArgs(argList) || resize);
if (Option.printTotals) timeStamps[1] = clock();
closeTagFile(resize);
freeIgnoreList();
if (TagFile.numTags.added + TagFile.numTags.prev > 0L)
{
if (Option.sorted)
{
if (Option.printTotals) timeStamps[2] = clock();
#ifdef EXTERNAL_SORT
externalSortTags(toStdout);
#else
internalSortTags(toStdout);
#endif
if (Option.printTotals) timeStamps[3] = clock();
}
else if (toStdout)
catFile(TagFile.name);
}
if (toStdout)
remove(TagFile.name); /* remove temporary file */
if (Option.printTotals)
printTotals(timeStamps);
}
/*----------------------------------------------------------------------------
* Start up code
*--------------------------------------------------------------------------*/
static void setExecutableName( path )
const char *const path;
{
ExecutableName = baseFilename(path);
}
extern const char *getExecutableName()
{
return ExecutableName;
}
static void setDefaultTagFileName()
{
if (Option.tagFileName != NULL)
; /* accept given name */
else if (Option.etags)
Option.tagFileName = ETAGS_FILE;
else
Option.tagFileName = CTAGS_FILE;
}
static void setOptionDefaults()
{
if (Option.xref)
Option.include.sourceFiles = FALSE;
setDefaultTagFileName();
}
static void testEtagsInvocation()
{
if (strncmp(getExecutableName(), ETAGS, strlen(ETAGS)) == 0)
{
Option.startedAsEtags = TRUE;
Option.etags = TRUE;
Option.sorted = FALSE;
}
}
extern int main( argc, argv )
int __unused__ argc;
char **argv;
{
char **envArgList;
const char *const *fileList;
#ifdef __EMX__
_wildcard(&argc, &argv); /* expand wildcards in argument list */
#endif
setExecutableName(*argv++);
testEtagsInvocation();
/* Parse options.
*/
envArgList = parseEnvironmentOptions();
fileList = (const char *const *)parseOptions(argv);
setOptionDefaults();
buildKeywordHash();
/* Generate tags if there is at least one source file or a file list.
*/
if (*fileList == NULL && Option.fileList == NULL)
{
if (! Option.recurse)
error(FATAL, "No files specified. Try \"%s --help\".",
getExecutableName());
else
{
static const char *defaultRecursionDir[] = { ".", NULL };
fileList = defaultRecursionDir;
}
}
makeTags(fileList);
/* Post tag generation clean-up.
*/
freeLineBuffer(&TagFile.line);
if (envArgList != NULL)
free(envArgList);
exit(0);
return 0;
}
/* vi:set tabstop=8 shiftwidth=4: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -