4 * Copyright (c) 1996-2002, Darren Hiebert
6 * This source code is released for free distribution under the terms of the
7 * GNU General Public License.
9 * This module contains functions to sort the tag entries.
15 #include "general.h" /* must always come first */
17 #if defined (HAVE_STDLIB_H)
18 # include <stdlib.h> /* to declare malloc () */
30 #ifdef TRAP_MEMORY_CALLS
31 # include "safe_malloc.h"
35 * FUNCTION DEFINITIONS
38 extern void catFile (const char *const name
)
40 FILE *const fp
= fopen (name
, "r");
45 while ((c
= getc (fp
)) != EOF
)
54 #ifdef NON_CONST_PUTENV_PROTOTYPE
57 # define PE_CONST const
60 extern void externalSortTags (const boolean toStdout
)
62 const char *const sortNormalCommand
= "sort -u -o";
63 const char *const sortFoldedCommand
= "sort -u -f -o";
64 const char *sortCommand
=
65 Option
.sorted
== SO_FOLDSORTED
? sortFoldedCommand
: sortNormalCommand
;
66 PE_CONST
char *const sortOrder1
= "LC_COLLATE=C";
67 PE_CONST
char *const sortOrder2
= "LC_ALL=C";
68 const size_t length
= 4 + strlen (sortOrder1
) + strlen (sortOrder2
) +
69 strlen (sortCommand
) + (2 * strlen (tagFileName ()));
70 char *const cmd
= (char *) malloc (length
+ 1);
75 /* Ensure ASCII value sort order.
78 setenv ("LC_COLLATE", "C", 1);
79 setenv ("LC_ALL", "C", 1);
80 sprintf (cmd
, "%s %s %s", sortCommand
, tagFileName (), tagFileName ());
85 sprintf (cmd
, "%s %s %s", sortCommand
, tagFileName (), tagFileName ());
87 sprintf (cmd
, "%s %s %s %s %s", sortOrder1
, sortOrder2
, sortCommand
,
88 tagFileName (), tagFileName ());
91 verbose ("system (\"%s\")\n", cmd
);
97 error (FATAL
| PERROR
, "cannot sort tag file");
99 catFile (tagFileName ());
105 * These functions provide a basic internal sort. No great memory
106 * optimization is performed (e.g. recursive subdivided sorts),
107 * so have lots of memory if you have large tag files.
110 static void failedSort (FILE *const fp
, const char* msg
)
112 const char* const cannotSort
= "cannot sort tag file";
116 error (FATAL
| PERROR
, cannotSort
);
118 error (FATAL
, "%s: %s", msg
, cannotSort
);
121 static int compareTagsFolded(const void *const one
, const void *const two
)
123 const char *const line1
= *(const char* const*) one
;
124 const char *const line2
= *(const char* const*) two
;
126 return struppercmp (line1
, line2
);
129 static int compareTags (const void *const one
, const void *const two
)
131 const char *const line1
= *(const char* const*) one
;
132 const char *const line2
= *(const char* const*) two
;
134 return strcmp (line1
, line2
);
137 static void writeSortedTags (
138 char **const table
, const size_t numTags
, const boolean toStdout
)
143 /* Write the sorted lines back into the tag file.
149 fp
= fopen (tagFileName (), "w");
151 failedSort (fp
, NULL
);
153 for (i
= 0 ; i
< numTags
; ++i
)
155 /* Here we filter out identical tag *lines* (including search
156 * pattern) if this is not an xref file.
158 if (i
== 0 || Option
.xref
|| strcmp (table
[i
], table
[i
-1]) != 0)
159 if (fputs (table
[i
], fp
) == EOF
)
160 failedSort (fp
, NULL
);
168 extern void internalSortTags (const boolean toStdout
)
170 vString
*vLine
= vStringNew ();
174 int (*cmpFunc
)(const void *, const void *);
176 /* Allocate a table of line pointers to be sorted.
178 size_t numTags
= TagFile
.numTags
.added
+ TagFile
.numTags
.prev
;
179 const size_t tableSize
= numTags
* sizeof (char *);
180 char **const table
= (char **) malloc (tableSize
); /* line pointers */
181 DebugStatement ( size_t mallocSize
= tableSize
; ) /* cumulative total */
184 cmpFunc
= Option
.sorted
== SO_FOLDSORTED
? compareTagsFolded
: compareTags
;
186 failedSort (fp
, "out of memory");
188 /* Open the tag file and place its lines into allocated buffers.
190 fp
= fopen (tagFileName (), "r");
192 failedSort (fp
, NULL
);
193 for (i
= 0 ; i
< numTags
&& ! feof (fp
) ; )
195 line
= readLine (vLine
, fp
);
199 failedSort (fp
, NULL
);
202 else if (*line
== '\0' || strcmp (line
, "\n") == 0)
203 ; /* ignore blank lines */
206 const size_t stringSize
= strlen (line
) + 1;
208 table
[i
] = (char *) malloc (stringSize
);
209 if (table
[i
] == NULL
)
210 failedSort (fp
, "out of memory");
211 DebugStatement ( mallocSize
+= stringSize
; )
212 strcpy (table
[i
], line
);
218 vStringDelete (vLine
);
222 qsort (table
, numTags
, sizeof (*table
), cmpFunc
);
224 writeSortedTags (table
, numTags
, toStdout
);
226 PrintStatus (("sort memory: %ld bytes\n", (long) mallocSize
));
227 for (i
= 0 ; i
< numTags
; ++i
)
234 /* vi:set tabstop=4 shiftwidth=4: */