2 * $Id: sort.c 747 2009-11-06 02:33:37Z dhiebert $
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 () */
31 * FUNCTION DEFINITIONS
34 extern void catFile (const char *const name
)
36 FILE *const fp
= fopen (name
, "r");
41 while ((c
= getc (fp
)) != EOF
)
50 #ifdef NON_CONST_PUTENV_PROTOTYPE
53 # define PE_CONST const
56 extern void externalSortTags (const boolean toStdout
)
58 const char *const sortNormalCommand
= "sort -u -o";
59 const char *const sortFoldedCommand
= "sort -u -f -o";
60 const char *sortCommand
=
61 Option
.sorted
== SO_FOLDSORTED
? sortFoldedCommand
: sortNormalCommand
;
62 PE_CONST
char *const sortOrder1
= "LC_COLLATE=C";
63 PE_CONST
char *const sortOrder2
= "LC_ALL=C";
64 const size_t length
= 4 + strlen (sortOrder1
) + strlen (sortOrder2
) +
65 strlen (sortCommand
) + (2 * strlen (tagFileName ()));
66 char *const cmd
= (char *) malloc (length
+ 1);
71 /* Ensure ASCII value sort order.
74 setenv ("LC_COLLATE", "C", 1);
75 setenv ("LC_ALL", "C", 1);
76 sprintf (cmd
, "%s %s %s", sortCommand
, tagFileName (), tagFileName ());
81 sprintf (cmd
, "%s %s %s", sortCommand
, tagFileName (), tagFileName ());
83 sprintf (cmd
, "%s %s %s %s %s", sortOrder1
, sortOrder2
, sortCommand
,
84 tagFileName (), tagFileName ());
87 verbose ("system (\"%s\")\n", cmd
);
93 error (FATAL
| PERROR
, "cannot sort tag file");
95 catFile (tagFileName ());
101 * These functions provide a basic internal sort. No great memory
102 * optimization is performed (e.g. recursive subdivided sorts),
103 * so have lots of memory if you have large tag files.
106 static void failedSort (FILE *const fp
, const char* msg
)
108 const char* const cannotSort
= "cannot sort tag file";
112 error (FATAL
| PERROR
, "%s", cannotSort
);
114 error (FATAL
, "%s: %s", msg
, cannotSort
);
117 static int compareTagsFolded(const void *const one
, const void *const two
)
119 const char *const line1
= *(const char* const*) one
;
120 const char *const line2
= *(const char* const*) two
;
122 return struppercmp (line1
, line2
);
125 static int compareTags (const void *const one
, const void *const two
)
127 const char *const line1
= *(const char* const*) one
;
128 const char *const line2
= *(const char* const*) two
;
130 return strcmp (line1
, line2
);
133 static void writeSortedTags (
134 char **const table
, const size_t numTags
, const boolean toStdout
)
139 /* Write the sorted lines back into the tag file.
145 fp
= fopen (tagFileName (), "w");
147 failedSort (fp
, NULL
);
149 for (i
= 0 ; i
< numTags
; ++i
)
151 /* Here we filter out identical tag *lines* (including search
152 * pattern) if this is not an xref file.
154 if (i
== 0 || Option
.xref
|| strcmp (table
[i
], table
[i
-1]) != 0)
155 if (fputs (table
[i
], fp
) == EOF
)
156 failedSort (fp
, NULL
);
164 extern void internalSortTags (const boolean toStdout
)
166 vString
*vLine
= vStringNew ();
170 int (*cmpFunc
)(const void *, const void *);
172 /* Allocate a table of line pointers to be sorted.
174 size_t numTags
= TagFile
.numTags
.added
+ TagFile
.numTags
.prev
;
175 const size_t tableSize
= numTags
* sizeof (char *);
176 char **const table
= (char **) malloc (tableSize
); /* line pointers */
177 DebugStatement ( size_t mallocSize
= tableSize
; ) /* cumulative total */
180 cmpFunc
= Option
.sorted
== SO_FOLDSORTED
? compareTagsFolded
: compareTags
;
182 failedSort (fp
, "out of memory");
184 /* Open the tag file and place its lines into allocated buffers.
186 fp
= fopen (tagFileName (), "r");
188 failedSort (fp
, NULL
);
189 for (i
= 0 ; i
< numTags
&& ! feof (fp
) ; )
191 line
= readLine (vLine
, fp
);
195 failedSort (fp
, NULL
);
198 else if (*line
== '\0' || strcmp (line
, "\n") == 0)
199 ; /* ignore blank lines */
202 const size_t stringSize
= strlen (line
) + 1;
204 table
[i
] = (char *) malloc (stringSize
);
205 if (table
[i
] == NULL
)
206 failedSort (fp
, "out of memory");
207 DebugStatement ( mallocSize
+= stringSize
; )
208 strcpy (table
[i
], line
);
214 vStringDelete (vLine
);
218 qsort (table
, numTags
, sizeof (*table
), cmpFunc
);
220 writeSortedTags (table
, numTags
, toStdout
);
222 PrintStatus (("sort memory: %ld bytes\n", (long) mallocSize
));
223 for (i
= 0 ; i
< numTags
; ++i
)
230 /* vi:set tabstop=4 shiftwidth=4: */