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.
13 #include "general.h" /* must always come first */
24 * FUNCTION DEFINITIONS
27 static char *nextStringArg (const char** const next
)
32 Assert (*next
!= NULL
);
33 for (start
= *next
; isspace ((int) *start
) ; ++start
)
42 for (end
= start
; *end
!= '\0' && ! isspace ((int) *end
) ; ++end
)
46 result
= xMalloc (length
+ 1, char);
47 strncpy (result
, start
, length
);
48 result
[length
] = '\0';
54 static char* nextStringLine (const char** const next
)
60 Assert (*next
!= NULL
);
61 for (end
= *next
; *end
!= '\n' && *end
!= '\0' ; ++end
)
66 result
= xMalloc (length
+ 1, char);
67 strncpy (result
, *next
, length
);
68 result
[length
] = '\0';
72 else if (*end
== '\r')
82 static char* nextString (const Arguments
* const current
, const char** const next
)
85 if (current
->lineMode
)
86 result
= nextStringLine (next
);
88 result
= nextStringArg (next
);
92 static char* nextFileArg (FILE* const fp
)
98 vString
* vs
= vStringNew ();
110 } while (c
!= EOF
&& ! isspace (c
));
111 Assert (vStringLength (vs
) > 0);
112 result
= xMalloc (vStringLength (vs
) + 1, char);
113 strcpy (result
, vStringValue (vs
));
120 static char* nextFileLine (FILE* const fp
)
126 vString
* vs
= vStringNew ();
132 if (c
!= '\n' && c
!= '\r')
134 else if (vStringLength (vs
) > 0)
138 if (c
!= EOF
|| vStringLength (vs
) > 0)
146 vStringStripTrailing (vs
);
147 result
= xMalloc (vStringLength (vs
) + 1, char);
148 vStringStripLeading (vs
);
149 strcpy (result
, vStringValue (vs
));
156 static bool isCommentLine (char* line
)
158 while (isspace(*line
))
160 return (*line
== '#');
163 static char* nextFileLineSkippingComments (FILE* const fp
)
170 result
= nextFileLine (fp
);
171 comment
= (result
&& isCommentLine (result
));
178 static char* nextFileString (const Arguments
* const current
, FILE* const fp
)
181 if (current
->lineMode
)
182 result
= nextFileLineSkippingComments (fp
);
184 result
= nextFileArg (fp
);
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
);
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
;
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
);
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
);
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
)
262 if (current
->item
!= NULL
)
263 eFree (current
->item
);
264 current
->item
= nextString (current
, ¤t
->u
.stringArgs
.next
);
267 ++current
->u
.argvArgs
.item
;
268 current
->item
= *current
->u
.argvArgs
.item
;
271 if (current
->item
!= NULL
)
272 eFree (current
->item
);
273 current
->item
= nextFileString (current
, current
->u
.fileArgs
.fp
);
276 Assert ("Invalid argument type" == NULL
);
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
));