sort.c
上传用户:gddssl
上传日期:2007-01-06
资源大小:1003k
文件大小:6k
源码类别:

编辑器/阅读器

开发平台:

DOS

  1. /*****************************************************************************
  2. *   $Id: sort.c,v 6.2 1998/07/02 06:10:55 darren Exp $
  3. *
  4. *   Copyright (c) 1996-1998, Darren Hiebert
  5. *
  6. *   This source code is released for free distribution under the terms of the
  7. *   GNU General Public License.
  8. *
  9. *   This module contains functions to sort the tag entries.
  10. *****************************************************************************/
  11. /*============================================================================
  12. =   Include files
  13. ============================================================================*/
  14. #ifdef HAVE_CONFIG_H
  15. # include <config.h>
  16. #endif
  17. #include "ctags.h"
  18. /*============================================================================
  19. =   Function prototypes
  20. ============================================================================*/
  21. /*  Tag sorting functions.
  22.  */
  23. #ifndef EXTERNAL_SORT
  24. static void failedSort __ARGS((void));
  25. static int compareTags __ARGS((const void *const one, const void *const two));
  26. static void writeSortedTags __ARGS((char **const table, const size_t numTags, const boolean toStdout));
  27. #endif
  28. /*============================================================================
  29. =   Function definitions
  30. ============================================================================*/
  31. extern void catFile( name )
  32.     const char *const name;
  33. {
  34.     FILE *const fp = fopen(name, "r");
  35.     if (fp != NULL)
  36.     {
  37. int c;
  38. while ((c = getc(fp)) != EOF)
  39.     putchar(c);
  40. fclose(fp);
  41.     }
  42. }
  43. #ifdef EXTERNAL_SORT
  44. extern void externalSortTags( toStdout )
  45.     const boolean toStdout;
  46. {
  47.     const char *const sortTemplate = "%ssort -u -o %s %s";
  48. #ifndef NON_CONST_PUTENV_PROTOTYPE
  49.     const
  50. #endif
  51.   char *const sortOrder = "LC_COLLATE=C ";
  52.     const char *env = "";
  53.     const size_t length = strlen(sortOrder) + strlen(sortTemplate) +
  54.      2 * strlen(TagFile.name);
  55.     char *const cmd = (char *)malloc(length);
  56.     if (cmd != NULL)
  57.     {
  58. int ret;
  59. /*  Ensure ASCII value sort order.
  60.  */
  61. #ifdef HAVE_PUTENV
  62. putenv(sortOrder);
  63. #else
  64. # ifdef HAVE_SETENV
  65. setenv("LC_COLLATE", "C", 1);
  66. # else
  67. env = sortOrder;
  68. # endif
  69. #endif
  70. sprintf(cmd, sortTemplate, env, TagFile.name, TagFile.name);
  71. ret = system(cmd);
  72. free(cmd);
  73. if (ret != 0)
  74.     error(FATAL, "cannot sort tag file");
  75.     }
  76.     if (toStdout)
  77. catFile(TagFile.name);
  78. }
  79. #else
  80. /*----------------------------------------------------------------------------
  81.  *  These functions provide a basic internal sort. No great memory
  82.  *  optimization is performed (e.g. recursive subdivided sorts),
  83.  *  so have lots of memory if you have large tag files.
  84.  *--------------------------------------------------------------------------*/
  85. static void failedSort()
  86. {
  87.     if (TagFile.fp != NULL)
  88.     {
  89. fclose(TagFile.fp);
  90. TagFile.fp = NULL;
  91.     }
  92.     error(FATAL | PERROR, "cannot sort tag file");
  93. }
  94. static int compareTags( one, two )
  95.     const void *const one;
  96.     const void *const two;
  97. {
  98.     const char *const line1 = *(const char *const *const)one;
  99.     const char *const line2 = *(const char *const *const)two;
  100.     return strcmp(line1, line2);
  101. }
  102. static void writeSortedTags( table, numTags, toStdout )
  103.     char **const table;
  104.     const size_t numTags;
  105.     const boolean toStdout;
  106. {
  107.     size_t i;
  108.     /* Write the sorted lines back into the tag file.
  109.      */
  110.     if (toStdout)
  111. TagFile.fp = stdout;
  112.     else
  113.     {
  114. TagFile.fp = fopen(TagFile.name, "w");
  115. if (TagFile.fp == NULL)
  116.     failedSort();
  117.     }
  118.     for (i = 0 ; i < numTags ; ++i)
  119.     {
  120. /*  Here we filter out identical tag *lines* (including search
  121.  *  pattern) if this is not an xref file.
  122.  */
  123. if (i == 0  ||  Option.xref  ||  strcmp(table[i], table[i-1]) != 0)
  124.     if (fputs(table[i], TagFile.fp) == EOF)
  125. failedSort();
  126.     }
  127.     if (! toStdout)
  128. fclose(TagFile.fp);
  129. }
  130. extern void internalSortTags( toStdout )
  131.     const boolean toStdout;
  132. {
  133.     size_t i;
  134.     const char *line;
  135.     /* Allocate a table of line pointers to be sorted.
  136.      */
  137.     size_t numTags = TagFile.numTags.added + TagFile.numTags.prev;
  138.     const size_t tableSize = numTags * sizeof(char *);
  139.     char **const table = (char **)malloc(tableSize); /* line pointers */
  140.     DebugStatement( size_t mallocSize = tableSize; ) /* cumulative total */
  141.     if (table == NULL)
  142. failedSort();
  143.     /* Open the tag file and place its lines into allocated buffers.
  144.      */
  145.     TagFile.fp = fopen(TagFile.name, "r");
  146.     if (TagFile.fp == NULL)
  147. failedSort();
  148.     for (i = 0  ;  i < numTags  &&  ! feof(TagFile.fp)  ;  )
  149.     {
  150. line = readLine(&TagFile.line, TagFile.fp);
  151. if (line == NULL)
  152. {
  153.     if (! feof(TagFile.fp))
  154. failedSort();
  155.     break;
  156. }
  157. else if (*line == ''  ||  strcmp(line, "n") == 0)
  158.     ; /* ignore blank lines */
  159. else
  160. {
  161.     const size_t stringSize = strlen(line) + 1;
  162.     table[i] = (char *)malloc(stringSize);
  163.     if (table[i] == NULL)
  164. failedSort();
  165.     DebugStatement( mallocSize += stringSize; )
  166.     strcpy(table[i], line);
  167.     ++i;
  168. }
  169.     }
  170.     numTags = i;
  171.     fclose(TagFile.fp);
  172.     /* Sort the lines.
  173.      */
  174.     qsort(table, numTags, sizeof(*table),
  175.   (int (*)__ARGS((const void *, const void *)))compareTags);
  176.     writeSortedTags(table, numTags, toStdout);
  177.     DebugStatement( if (debug(DEBUG_STATUS))
  178. printf("sort memory: %ld bytesn", (long)mallocSize); )
  179.     for (i = 0 ; i < numTags ; ++i)
  180. free(table[i]);
  181.     free(table);
  182. }
  183. #endif
  184. /* vi:set tabstop=8 shiftwidth=4: */