Updated Spanish translation
[anjuta-git-plugin.git] / tagmanager / sort.c
blobce855204ebe5fe4306469d79406f0589a69a6eaa
1 /*
2 * $Id$
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.
13 * INCLUDE FILES
15 #include "general.h" /* must always come first */
17 #if defined (HAVE_STDLIB_H)
18 # include <stdlib.h> /* to declare malloc () */
19 #endif
20 #include <string.h>
21 #include <stdio.h>
23 #include "debug.h"
24 #include "entry.h"
25 #include "options.h"
26 #include "read.h"
27 #include "routines.h"
28 #include "sort.h"
30 #ifdef TRAP_MEMORY_CALLS
31 # include "safe_malloc.h"
32 #endif
35 * FUNCTION DEFINITIONS
38 extern void catFile (const char *const name)
40 FILE *const fp = fopen (name, "r");
42 if (fp != NULL)
44 int c;
45 while ((c = getc (fp)) != EOF)
46 putchar (c);
47 fflush (stdout);
48 fclose (fp);
52 #ifdef EXTERNAL_SORT
54 #ifdef NON_CONST_PUTENV_PROTOTYPE
55 # define PE_CONST
56 #else
57 # define PE_CONST const
58 #endif
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);
71 int ret = -1;
73 if (cmd != NULL)
75 /* Ensure ASCII value sort order.
77 #ifdef HAVE_SETENV
78 setenv ("LC_COLLATE", "C", 1);
79 setenv ("LC_ALL", "C", 1);
80 sprintf (cmd, "%s %s %s", sortCommand, tagFileName (), tagFileName ());
81 #else
82 # ifdef HAVE_PUTENV
83 putenv (sortOrder1);
84 putenv (sortOrder2);
85 sprintf (cmd, "%s %s %s", sortCommand, tagFileName (), tagFileName ());
86 # else
87 sprintf (cmd, "%s %s %s %s %s", sortOrder1, sortOrder2, sortCommand,
88 tagFileName (), tagFileName ());
89 # endif
90 #endif
91 verbose ("system (\"%s\")\n", cmd);
92 ret = system (cmd);
93 free (cmd);
96 if (ret != 0)
97 error (FATAL | PERROR, "cannot sort tag file");
98 else if (toStdout)
99 catFile (tagFileName ());
102 #else
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";
113 if (fp != NULL)
114 fclose (fp);
115 if (msg == NULL)
116 error (FATAL | PERROR, cannotSort);
117 else
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)
140 FILE *fp;
141 size_t i;
143 /* Write the sorted lines back into the tag file.
145 if (toStdout)
146 fp = stdout;
147 else
149 fp = fopen (tagFileName (), "w");
150 if (fp == NULL)
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);
162 if (toStdout)
163 fflush (fp);
164 else
165 fclose (fp);
168 extern void internalSortTags (const boolean toStdout)
170 vString *vLine = vStringNew ();
171 FILE *fp = NULL;
172 const char *line;
173 size_t i;
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;
185 if (table == NULL)
186 failedSort (fp, "out of memory");
188 /* Open the tag file and place its lines into allocated buffers.
190 fp = fopen (tagFileName (), "r");
191 if (fp == NULL)
192 failedSort (fp, NULL);
193 for (i = 0 ; i < numTags && ! feof (fp) ; )
195 line = readLine (vLine, fp);
196 if (line == NULL)
198 if (! feof (fp))
199 failedSort (fp, NULL);
200 break;
202 else if (*line == '\0' || strcmp (line, "\n") == 0)
203 ; /* ignore blank lines */
204 else
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);
213 ++i;
216 numTags = i;
217 fclose (fp);
218 vStringDelete (vLine);
220 /* Sort the lines.
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)
228 free (table [i]);
229 free (table);
232 #endif
234 /* vi:set tabstop=4 shiftwidth=4: */