Merge branch '1.37'
[geany-mirror.git] / ctags / main / args.c
blob4ab49134fb5bf12c1826ee96bee0442468e266b1
1 /*
2 * Copyright (c) 1999-2002, Darren Hiebert
4 * This source code is released for free distribution under the terms of the
5 * GNU General Public License version 2 or (at your option) any later version.
7 * This module contains functions for reading command line arguments.
8 */
11 * INCLUDE FILES
13 #include "general.h" /* must always come first */
15 #include <stdio.h>
16 #include <string.h>
17 #include <ctype.h>
19 #include "args.h"
20 #include "debug.h"
21 #include "routines.h"
24 * FUNCTION DEFINITIONS
27 static char *nextStringArg (const char** const next)
29 char* result = NULL;
30 const char* start;
32 Assert (*next != NULL);
33 for (start = *next ; isspace ((int) *start) ; ++start)
35 if (*start == '\0')
36 *next = start;
37 else
39 size_t length;
40 const char* end;
42 for (end = start ; *end != '\0' && ! isspace ((int) *end) ; ++end)
44 length = end - start;
45 Assert (length > 0);
46 result = xMalloc (length + 1, char);
47 strncpy (result, start, length);
48 result [length] = '\0';
49 *next = end;
51 return result;
54 static char* nextStringLine (const char** const next)
56 char* result = NULL;
57 size_t length;
58 const char* end;
60 Assert (*next != NULL);
61 for (end = *next ; *end != '\n' && *end != '\0' ; ++end)
63 length = end - *next;
64 if (length > 0)
66 result = xMalloc (length + 1, char);
67 strncpy (result, *next, length);
68 result [length] = '\0';
70 if (*end == '\n')
71 ++end;
72 else if (*end == '\r')
74 ++end;
75 if (*end == '\n')
76 ++end;
78 *next = end;
79 return result;
82 static char* nextString (const Arguments* const current, const char** const next)
84 char* result;
85 if (current->lineMode)
86 result = nextStringLine (next);
87 else
88 result = nextStringArg (next);
89 return result;
92 static char* nextFileArg (FILE* const fp)
94 char* result = NULL;
95 Assert (fp != NULL);
96 if (! feof (fp))
98 vString* vs = vStringNew ();
99 int c;
101 c = fgetc (fp);
102 while (isspace (c));
104 if (c != EOF)
108 vStringPut (vs, c);
109 c = fgetc (fp);
110 } while (c != EOF && ! isspace (c));
111 Assert (vStringLength (vs) > 0);
112 result = xMalloc (vStringLength (vs) + 1, char);
113 strcpy (result, vStringValue (vs));
115 vStringDelete (vs);
117 return result;
120 static char* nextFileLine (FILE* const fp)
122 char* result = NULL;
123 Assert (fp != NULL);
124 if (! feof (fp))
126 vString* vs = vStringNew ();
127 int c;
129 c = fgetc (fp);
130 while (c != EOF)
132 if (c != '\n' && c != '\r')
133 vStringPut (vs, c);
134 else if (vStringLength (vs) > 0)
135 break;
136 c = fgetc (fp);
138 if (c != EOF || vStringLength (vs) > 0)
140 if (c == '\r')
142 c = fgetc (fp);
143 if (c != '\n')
144 c = ungetc (c, fp);
146 vStringStripTrailing (vs);
147 result = xMalloc (vStringLength (vs) + 1, char);
148 vStringStripLeading (vs);
149 strcpy (result, vStringValue (vs));
151 vStringDelete (vs);
153 return result;
156 static bool isCommentLine (char* line)
158 while (isspace(*line))
159 ++line;
160 return (*line == '#');
163 static char* nextFileLineSkippingComments (FILE* const fp)
165 char* result;
166 bool comment;
170 result = nextFileLine (fp);
171 comment = (result && isCommentLine (result));
172 if (comment)
173 eFree (result);
174 } while (comment);
175 return result;
178 static char* nextFileString (const Arguments* const current, FILE* const fp)
180 char* result;
181 if (current->lineMode)
182 result = nextFileLineSkippingComments (fp);
183 else
184 result = nextFileArg (fp);
185 return result;
188 extern Arguments* argNewFromString (const char* const string)
190 Arguments* result = xMalloc (1, Arguments);
191 memset (result, 0, sizeof (Arguments));
192 result->type = ARG_STRING;
193 result->u.stringArgs.next = string;
194 result->item = nextString (result, &result->u.stringArgs.next);
195 return result;
198 extern Arguments* argNewFromArgv (char* const* const argv)
200 Arguments* result = xMalloc (1, Arguments);
201 memset (result, 0, sizeof (Arguments));
202 result->type = ARG_ARGV;
203 result->u.argvArgs.argv = argv;
204 result->u.argvArgs.item = result->u.argvArgs.argv;
205 result->item = *result->u.argvArgs.item;
206 return result;
209 extern Arguments* argNewFromFile (FILE* const fp)
211 Arguments* result = xMalloc (1, Arguments);
212 memset (result, 0, sizeof (Arguments));
213 result->type = ARG_FILE;
214 result->u.fileArgs.fp = fp;
215 result->item = nextFileString (result, result->u.fileArgs.fp);
216 return result;
219 extern Arguments* argNewFromLineFile (FILE* const fp)
221 Arguments* result = xMalloc (1, Arguments);
222 memset (result, 0, sizeof (Arguments));
223 result->type = ARG_FILE;
224 result->lineMode = true;
225 result->u.fileArgs.fp = fp;
226 result->item = nextFileString (result, result->u.fileArgs.fp);
227 return result;
230 extern char *argItem (const Arguments* const current)
232 Assert (current != NULL);
233 Assert (! argOff (current));
234 return current->item;
237 extern bool argOff (const Arguments* const current)
239 Assert (current != NULL);
240 return (bool) (current->item == NULL);
243 extern void argSetWordMode (Arguments* const current)
245 Assert (current != NULL);
246 current->lineMode = false;
249 extern void argSetLineMode (Arguments* const current)
251 Assert (current != NULL);
252 current->lineMode = true;
255 extern void argForth (Arguments* const current)
257 Assert (current != NULL);
258 Assert (! argOff (current));
259 switch (current->type)
261 case ARG_STRING:
262 if (current->item != NULL)
263 eFree (current->item);
264 current->item = nextString (current, &current->u.stringArgs.next);
265 break;
266 case ARG_ARGV:
267 ++current->u.argvArgs.item;
268 current->item = *current->u.argvArgs.item;
269 break;
270 case ARG_FILE:
271 if (current->item != NULL)
272 eFree (current->item);
273 current->item = nextFileString (current, current->u.fileArgs.fp);
274 break;
275 default:
276 Assert ("Invalid argument type" == NULL);
277 break;
281 extern void argDelete (Arguments* const current)
283 Assert (current != NULL);
284 if (current->type == ARG_STRING && current->item != NULL)
285 eFree (current->item);
286 memset (current, 0, sizeof (Arguments));
287 eFree (current);