Mention that indentation settings can be overridden per-project.
[geany-mirror.git] / tagmanager / sort.c
blob6f4357776172c5b5de6c999e59b135524fffb2e5
1 /*
3 * Copyright (c) 1996-2001, Darren Hiebert
5 * This source code is released for free distribution under the terms of the
6 * GNU General Public License.
8 * This module contains functions to sort the tag entries.
9 */
12 * INCLUDE FILES
14 #include "general.h" /* must always come first */
16 #if defined (HAVE_STDLIB_H)
17 # include <stdlib.h> /* to declare malloc () */
18 #endif
19 #include <string.h>
20 #include <stdio.h>
21 #include <glib.h>
22 #include <glib/gstdio.h>
24 #include "entry.h"
25 #include "main.h"
26 #include "options.h"
27 #include "read.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 = g_fopen (name, "r");
42 if (fp != NULL)
44 int c;
46 while ((c = getc (fp)) != EOF)
47 putchar (c);
48 fflush (stdout);
49 fclose (fp);
53 #ifdef EXTERNAL_SORT
55 #ifdef NON_CONST_PUTENV_PROTOTYPE
56 # define PE_CONST
57 #else
58 # define PE_CONST const
59 #endif
61 extern void externalSortTags (const boolean toStdout)
63 const char *const sortCommand = "sort -u -o";
64 PE_CONST char *const sortOrder1 = "LC_COLLATE=C";
65 PE_CONST char *const sortOrder2 = "LC_ALL=C";
66 const size_t length = 4 + strlen (sortOrder1) + strlen (sortOrder2) +
67 strlen (sortCommand) + (2 * strlen (tagFileName ()));
68 char *const cmd = (char *) g_malloc (length + 1);
69 int ret = -1;
71 if (cmd != NULL)
73 /* Ensure ASCII value sort order.
75 #ifdef HAVE_SETENV
76 setenv ("LC_COLLATE", "C", 1);
77 setenv ("LC_ALL", "C", 1);
78 sprintf (cmd, "%s %s %s", sortCommand, tagFileName (), tagFileName ());
79 #else
80 # ifdef HAVE_PUTENV
81 putenv (sortOrder1);
82 putenv (sortOrder2);
83 sprintf (cmd, "%s %s %s", sortCommand, tagFileName (), tagFileName ());
84 # else
85 sprintf (cmd, "%s %s %s %s %s", sortOrder1, sortOrder2, sortCommand,
86 tagFileName (), tagFileName ());
87 # endif
88 #endif
89 verbose ("system (\"%s\")\n", cmd);
90 ret = system (cmd);
91 g_free (cmd);
94 if (ret != 0)
95 error (FATAL | PERROR, "cannot sort tag file");
96 else if (toStdout)
97 catFile (tagFileName ());
100 #else
103 * These functions provide a basic internal sort. No great memory
104 * optimization is performed (e.g. recursive subdivided sorts),
105 * so have lots of memory if you have large tag files.
108 static void failedSort (FILE *const fp, const char* msg)
110 const char* const cannotSort = "cannot sort tag file";
111 if (fp != NULL)
112 fclose (fp);
113 if (msg == NULL)
114 error (FATAL | PERROR, "%s", cannotSort);
115 else
116 error (FATAL, "%s: %s", msg, cannotSort);
119 static int compareTags (const void *const one, const void *const two)
121 const char *const line1 = *(const char* const*) one;
122 const char *const line2 = *(const char* const*) two;
124 return strcmp (line1, line2);
127 static void writeSortedTags (char **const table, const size_t numTags,
128 const boolean toStdout)
130 FILE *fp;
131 size_t i;
133 /* Write the sorted lines back into the tag file.
135 if (toStdout)
136 fp = stdout;
137 else
139 fp = g_fopen (tagFileName (), "w");
140 if (fp == NULL)
141 failedSort (fp, NULL);
143 for (i = 0 ; i < numTags ; ++i)
145 /* Here we filter out identical tag *lines* (including search
146 * pattern) if this is not an xref file.
148 if (i == 0 || Option.xref || strcmp (table [i], table [i-1]) != 0)
149 if (fputs (table [i], fp) == EOF)
150 failedSort (fp, NULL);
152 if (toStdout)
153 fflush (fp);
154 else
155 fclose (fp);
158 extern void internalSortTags (const boolean toStdout)
160 vString *vLine = vStringNew ();
161 FILE *fp = NULL;
162 const char *line;
163 size_t i;
165 /* Allocate a table of line pointers to be sorted.
167 size_t numTags = TagFile.numTags.added + TagFile.numTags.prev;
168 const size_t tableSize = numTags * sizeof (char *);
169 char **const table = (char **) g_malloc (tableSize); /* line pointers */
170 DebugStatement ( size_t mallocSize = tableSize; ) /* cumulative total */
172 if (table == NULL)
173 failedSort (fp, "out of memory");
175 /* Open the tag file and place its lines into allocated buffers.
177 fp = g_fopen (tagFileName (), "r");
178 if (fp == NULL)
179 failedSort (fp, NULL);
180 for (i = 0 ; i < numTags && ! feof (fp) ; )
182 line = readLine (vLine, fp);
183 if (line == NULL)
185 if (! feof (fp))
186 failedSort (fp, NULL);
187 break;
189 else if (*line == '\0' || strcmp (line, "\n") == 0)
190 ; /* ignore blank lines */
191 else
193 const size_t stringSize = strlen (line) + 1;
195 table [i] = (char *) g_malloc (stringSize);
196 if (table [i] == NULL)
197 failedSort (fp, "out of memory");
198 DebugStatement ( mallocSize += stringSize; )
199 strcpy (table [i], line);
200 ++i;
203 numTags = i;
204 fclose (fp);
205 vStringDelete (vLine);
207 /* Sort the lines.
209 qsort (table, numTags, sizeof (*table), compareTags);
211 writeSortedTags (table, numTags, toStdout);
213 PrintStatus (("sort memory: %ld bytes\n", (long) mallocSize));
214 for (i = 0 ; i < numTags ; ++i)
215 free (table [i]);
216 free (table);
219 #endif
221 /* vi:set tabstop=8 shiftwidth=4: */