www.pudn.com > vim53src.zip > sort.c
/***************************************************************************** * $Id: sort.c,v 6.2 1998/07/02 06:10:55 darren Exp $ * * Copyright (c) 1996-1998, Darren Hiebert * * This source code is released for free distribution under the terms of the * GNU General Public License. * * This module contains functions to sort the tag entries. *****************************************************************************/ /*============================================================================ = Include files ============================================================================*/ #ifdef HAVE_CONFIG_H # include#endif #include "ctags.h" /*============================================================================ = Function prototypes ============================================================================*/ /* Tag sorting functions. */ #ifndef EXTERNAL_SORT static void failedSort __ARGS((void)); static int compareTags __ARGS((const void *const one, const void *const two)); static void writeSortedTags __ARGS((char **const table, const size_t numTags, const boolean toStdout)); #endif /*============================================================================ = Function definitions ============================================================================*/ extern void catFile( name ) const char *const name; { FILE *const fp = fopen(name, "r"); if (fp != NULL) { int c; while ((c = getc(fp)) != EOF) putchar(c); fclose(fp); } } #ifdef EXTERNAL_SORT extern void externalSortTags( toStdout ) const boolean toStdout; { const char *const sortTemplate = "%ssort -u -o %s %s"; #ifndef NON_CONST_PUTENV_PROTOTYPE const #endif char *const sortOrder = "LC_COLLATE=C "; const char *env = ""; const size_t length = strlen(sortOrder) + strlen(sortTemplate) + 2 * strlen(TagFile.name); char *const cmd = (char *)malloc(length); if (cmd != NULL) { int ret; /* Ensure ASCII value sort order. */ #ifdef HAVE_PUTENV putenv(sortOrder); #else # ifdef HAVE_SETENV setenv("LC_COLLATE", "C", 1); # else env = sortOrder; # endif #endif sprintf(cmd, sortTemplate, env, TagFile.name, TagFile.name); ret = system(cmd); free(cmd); if (ret != 0) error(FATAL, "cannot sort tag file"); } if (toStdout) catFile(TagFile.name); } #else /*---------------------------------------------------------------------------- * These functions provide a basic internal sort. No great memory * optimization is performed (e.g. recursive subdivided sorts), * so have lots of memory if you have large tag files. *--------------------------------------------------------------------------*/ static void failedSort() { if (TagFile.fp != NULL) { fclose(TagFile.fp); TagFile.fp = NULL; } error(FATAL | PERROR, "cannot sort tag file"); } static int compareTags( one, two ) const void *const one; const void *const two; { const char *const line1 = *(const char *const *const)one; const char *const line2 = *(const char *const *const)two; return strcmp(line1, line2); } static void writeSortedTags( table, numTags, toStdout ) char **const table; const size_t numTags; const boolean toStdout; { size_t i; /* Write the sorted lines back into the tag file. */ if (toStdout) TagFile.fp = stdout; else { TagFile.fp = fopen(TagFile.name, "w"); if (TagFile.fp == NULL) failedSort(); } for (i = 0 ; i < numTags ; ++i) { /* Here we filter out identical tag *lines* (including search * pattern) if this is not an xref file. */ if (i == 0 || Option.xref || strcmp(table[i], table[i-1]) != 0) if (fputs(table[i], TagFile.fp) == EOF) failedSort(); } if (! toStdout) fclose(TagFile.fp); } extern void internalSortTags( toStdout ) const boolean toStdout; { size_t i; const char *line; /* Allocate a table of line pointers to be sorted. */ size_t numTags = TagFile.numTags.added + TagFile.numTags.prev; const size_t tableSize = numTags * sizeof(char *); char **const table = (char **)malloc(tableSize); /* line pointers */ DebugStatement( size_t mallocSize = tableSize; ) /* cumulative total */ if (table == NULL) failedSort(); /* Open the tag file and place its lines into allocated buffers. */ TagFile.fp = fopen(TagFile.name, "r"); if (TagFile.fp == NULL) failedSort(); for (i = 0 ; i < numTags && ! feof(TagFile.fp) ; ) { line = readLine(&TagFile.line, TagFile.fp); if (line == NULL) { if (! feof(TagFile.fp)) failedSort(); break; } else if (*line == '\0' || strcmp(line, "\n") == 0) ; /* ignore blank lines */ else { const size_t stringSize = strlen(line) + 1; table[i] = (char *)malloc(stringSize); if (table[i] == NULL) failedSort(); DebugStatement( mallocSize += stringSize; ) strcpy(table[i], line); ++i; } } numTags = i; fclose(TagFile.fp); /* Sort the lines. */ qsort(table, numTags, sizeof(*table), (int (*)__ARGS((const void *, const void *)))compareTags); writeSortedTags(table, numTags, toStdout); DebugStatement( if (debug(DEBUG_STATUS)) printf("sort memory: %ld bytes\n", (long)mallocSize); ) for (i = 0 ; i < numTags ; ++i) free(table[i]); free(table); } #endif /* vi:set tabstop=8 shiftwidth=4: */