geany  1.38
About: Geany is a text editor (using GTK2) with basic features of an integrated development environment (syntax highlighting, code folding, symbol name auto-completion, ...). F: office T: editor programming GTK+ IDE
  Fossies Dox: geany-1.38.tar.bz2  ("unofficial" and yet experimental doxygen-generated source code documentation)  

args.c
Go to the documentation of this file.
1/*
2* Copyright (c) 1999-2002, Darren Hiebert
3*
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.
6*
7* This module contains functions for reading command line arguments.
8*/
9
10/*
11* INCLUDE FILES
12*/
13#include "general.h" /* must always come first */
14
15#include <stdio.h>
16#include <string.h>
17#include <ctype.h>
18
19#include "args_p.h"
20#include "debug.h"
21#include "routines.h"
22#include "vstring.h"
23
24/*
25* FUNCTION DEFINITIONS
26*/
27
28static char *nextStringArg (const char** const next)
29{
30 char* result = NULL;
31 const char* start;
32
33 Assert (*next != NULL);
34 for (start = *next ; isspace ((int) *start) ; ++start)
35 ;
36 if (*start == '\0')
37 *next = start;
38 else
39 {
40 size_t length;
41 const char* end;
42
43 for (end = start ; *end != '\0' && ! isspace ((int) *end) ; ++end)
44 ;
45 length = end - start;
46 Assert (length > 0);
47 result = xMalloc (length + 1, char);
48 strncpy (result, start, length);
49 result [length] = '\0';
50 *next = end;
51 }
52 return result;
53}
54
55static char* nextStringLine (const char** const next)
56{
57 char* result = NULL;
58 size_t length;
59 const char* end;
60
61 Assert (*next != NULL);
62 for (end = *next ; *end != '\n' && *end != '\0' ; ++end)
63 ;
64 length = end - *next;
65 if (length > 0)
66 {
67 result = xMalloc (length + 1, char);
68 strncpy (result, *next, length);
69 result [length] = '\0';
70 }
71 if (*end == '\n')
72 ++end;
73 else if (*end == '\r')
74 {
75 ++end;
76 if (*end == '\n')
77 ++end;
78 }
79 *next = end;
80 return result;
81}
82
83static char* nextString (const Arguments* const current, const char** const next)
84{
85 char* result;
86 if (current->lineMode)
87 result = nextStringLine (next);
88 else
89 result = nextStringArg (next);
90 return result;
91}
92
93static char* nextFileArg (FILE* const fp)
94{
95 char* result = NULL;
96 Assert (fp != NULL);
97 if (! feof (fp))
98 {
99 vString* vs = vStringNew ();
100 int c;
101 do
102 c = fgetc (fp);
103 while (isspace (c));
104
105 if (c != EOF)
106 {
107 do
108 {
109 vStringPut (vs, c);
110 c = fgetc (fp);
111 } while (c != EOF && ! isspace (c));
112 Assert (vStringLength (vs) > 0);
113 result = xMalloc (vStringLength (vs) + 1, char);
114 strcpy (result, vStringValue (vs));
115 }
116 vStringDelete (vs);
117 }
118 return result;
119}
120
121static char* nextFileLine (FILE* const fp)
122{
123 char* result = NULL;
124 Assert (fp != NULL);
125 if (! feof (fp))
126 {
127 vString* vs = vStringNew ();
128 int c;
129
130 c = fgetc (fp);
131 while (c != EOF)
132 {
133 if (c != '\n' && c != '\r')
134 vStringPut (vs, c);
135 else if (vStringLength (vs) > 0)
136 break;
137 c = fgetc (fp);
138 }
139 if (c != EOF || vStringLength (vs) > 0)
140 {
141 if (c == '\r')
142 {
143 c = fgetc (fp);
144 if (c != '\n')
145 c = ungetc (c, fp);
146 }
148 result = xMalloc (vStringLength (vs) + 1, char);
150 strcpy (result, vStringValue (vs));
151 }
152 vStringDelete (vs);
153 }
154 return result;
155}
156
157static bool isCommentLine (char* line)
158{
159 while (isspace(*line))
160 ++line;
161 return (*line == '#');
162}
163
164static char* nextFileLineSkippingComments (FILE* const fp)
165{
166 char* result;
167 bool comment;
168
169 do
170 {
171 result = nextFileLine (fp);
172 comment = (result && isCommentLine (result));
173 if (comment)
174 eFree (result);
175 } while (comment);
176 return result;
177}
178
179static char* nextFileString (const Arguments* const current, FILE* const fp)
180{
181 char* result;
182 if (current->lineMode)
183 result = nextFileLineSkippingComments (fp);
184 else
185 result = nextFileArg (fp);
186 return result;
187}
188
189extern Arguments* argNewFromString (const char* const string)
190{
191 Arguments* result = xMalloc (1, Arguments);
192 memset (result, 0, sizeof (Arguments));
193 result->type = ARG_STRING;
194 result->u.stringArgs.next = string;
195 result->item = nextString (result, &result->u.stringArgs.next);
196 return result;
197}
198
199extern Arguments* argNewFromArgv (char* const* const argv)
200{
201 Arguments* result = xMalloc (1, Arguments);
202 memset (result, 0, sizeof (Arguments));
203 result->type = ARG_ARGV;
204 result->u.argvArgs.argv = argv;
205 result->u.argvArgs.item = result->u.argvArgs.argv;
206 result->item = *result->u.argvArgs.item;
207 return result;
208}
209
210extern Arguments* argNewFromFile (FILE* const fp)
211{
212 Arguments* result = xMalloc (1, Arguments);
213 memset (result, 0, sizeof (Arguments));
214 result->type = ARG_FILE;
215 result->u.fileArgs.fp = fp;
216 result->item = nextFileString (result, result->u.fileArgs.fp);
217 return result;
218}
219
220extern Arguments* argNewFromLineFile (FILE* const fp)
221{
222 Arguments* result = xMalloc (1, Arguments);
223 memset (result, 0, sizeof (Arguments));
224 result->type = ARG_FILE;
225 result->lineMode = true;
226 result->u.fileArgs.fp = fp;
227 result->item = nextFileString (result, result->u.fileArgs.fp);
228 return result;
229}
230
231extern char *argItem (const Arguments* const current)
232{
233 Assert (current != NULL);
234 Assert (! argOff (current));
235 return current->item;
236}
237
238extern bool argOff (const Arguments* const current)
239{
240 Assert (current != NULL);
241 return (bool) (current->item == NULL);
242}
243
244extern void argSetWordMode (Arguments* const current)
245{
246 Assert (current != NULL);
247 current->lineMode = false;
248}
249
250extern void argSetLineMode (Arguments* const current)
251{
252 Assert (current != NULL);
253 current->lineMode = true;
254}
255
256extern void argForth (Arguments* const current)
257{
258 Assert (current != NULL);
259 Assert (! argOff (current));
260 switch (current->type)
261 {
262 case ARG_STRING:
263 if (current->item != NULL)
264 eFree (current->item);
265 current->item = nextString (current, &current->u.stringArgs.next);
266 break;
267 case ARG_ARGV:
268 ++current->u.argvArgs.item;
269 current->item = *current->u.argvArgs.item;
270 break;
271 case ARG_FILE:
272 if (current->item != NULL)
273 eFree (current->item);
274 current->item = nextFileString (current, current->u.fileArgs.fp);
275 break;
276 default:
277 Assert ("Invalid argument type" == NULL);
278 break;
279 }
280}
281
282extern void argDelete (Arguments* const current)
283{
284 Assert (current != NULL);
285 if ((current->type == ARG_STRING
286 || current->type == ARG_FILE) && current->item != NULL)
287 eFree (current->item);
288 memset (current, 0, sizeof (Arguments));
289 eFree (current);
290}
void argDelete(Arguments *const current)
Definition: args.c:282
static char * nextFileArg(FILE *const fp)
Definition: args.c:93
Arguments * argNewFromLineFile(FILE *const fp)
Definition: args.c:220
void argForth(Arguments *const current)
Definition: args.c:256
static bool isCommentLine(char *line)
Definition: args.c:157
static char * nextFileString(const Arguments *const current, FILE *const fp)
Definition: args.c:179
static char * nextStringLine(const char **const next)
Definition: args.c:55
void argSetLineMode(Arguments *const current)
Definition: args.c:250
static char * nextFileLineSkippingComments(FILE *const fp)
Definition: args.c:164
bool argOff(const Arguments *const current)
Definition: args.c:238
void argSetWordMode(Arguments *const current)
Definition: args.c:244
char * argItem(const Arguments *const current)
Definition: args.c:231
static char * nextString(const Arguments *const current, const char **const next)
Definition: args.c:83
Arguments * argNewFromString(const char *const string)
Definition: args.c:189
Arguments * argNewFromFile(FILE *const fp)
Definition: args.c:210
Arguments * argNewFromArgv(char *const *const argv)
Definition: args.c:199
static char * nextFileLine(FILE *const fp)
Definition: args.c:121
static char * nextStringArg(const char **const next)
Definition: args.c:28
@ ARG_ARGV
Definition: args_p.h:23
@ ARG_STRING
Definition: args_p.h:23
@ ARG_FILE
Definition: args_p.h:23
#define Assert(c)
Definition: debug.h:47
vString * line
Definition: geany_cobol.c:133
#define NULL
Definition: rbtree.h:150
void eFree(void *const ptr)
Definition: routines.c:252
#define xMalloc(n, Type)
Definition: routines.h:23
Definition: args_p.h:25
argType type
Definition: args_p.h:26
struct sArgs::@2::sStringArgs stringArgs
bool lineMode
Definition: args_p.h:40
char *const * item
Definition: args_p.h:33
struct sArgs::@2::sArgvArgs argvArgs
struct sArgs::@2::sFileArgs fileArgs
union sArgs::@2 u
void vStringStripTrailing(vString *const string)
Definition: vstring.c:186
vString * vStringNew(void)
Definition: vstring.c:70
void vStringDelete(vString *const string)
Definition: vstring.c:60
void vStringStripLeading(vString *const string)
Definition: vstring.c:171
#define vStringLength(vs)
Definition: vstring.h:31
#define vStringValue(vs)
Definition: vstring.h:28
static void vStringPut(vString *const string, const int c)
Definition: vstring.h:101