4 * Copyright (c) 1999-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 for reading command line arguments.
15 #include "general.h" /* must always come first */
26 * FUNCTION DEFINITIONS
29 static char *nextStringArg (const char** const next
)
34 Assert (*next
!= NULL
);
35 for (start
= *next
; isspace ((int) *start
) ; ++start
)
44 for (end
= start
; *end
!= '\0' && ! isspace ((int) *end
) ; ++end
)
48 result
= xMalloc (length
+ 1, char);
49 strncpy (result
, start
, length
);
50 result
[length
] = '\0';
56 static char* nextStringLine (const char** const next
)
62 Assert (*next
!= NULL
);
63 for (end
= *next
; *end
!= '\n' && *end
!= '\0' ; ++end
)
68 result
= xMalloc (length
+ 1, char);
69 strncpy (result
, *next
, length
);
70 result
[length
] = '\0';
74 else if (*end
== '\r')
84 static char* nextString (const Arguments
* const current
, const char** const next
)
87 if (current
->lineMode
)
88 result
= nextStringLine (next
);
90 result
= nextStringArg (next
);
94 static char* nextFileArg (FILE* const fp
)
100 vString
* vs
= vStringNew ();
112 } while (c
!= EOF
&& ! isspace (c
));
113 vStringTerminate (vs
);
114 Assert (vStringLength (vs
) > 0);
115 result
= xMalloc (vStringLength (vs
) + 1, char);
116 strcpy (result
, vStringValue (vs
));
123 static char* nextFileLine (FILE* const fp
)
128 vString
* vs
= vStringNew ();
135 if (c
!= '\n' && c
!= '\r')
137 else if (vStringLength (vs
) > 0)
141 if (c
!= EOF
|| vStringLength (vs
) > 0)
149 vStringTerminate (vs
);
150 result
= xMalloc (vStringLength (vs
) + 1, char);
151 strcpy (result
, vStringValue (vs
));
158 static char* nextFileString (const Arguments
* const current
, FILE* const fp
)
161 if (current
->lineMode
)
162 result
= nextFileLine (fp
);
164 result
= nextFileArg (fp
);
168 extern Arguments
* argNewFromString (const char* const string
)
170 Arguments
* result
= xMalloc (1, Arguments
);
171 memset (result
, 0, sizeof (Arguments
));
172 result
->type
= ARG_STRING
;
173 result
->u
.stringArgs
.string
= string
;
174 result
->u
.stringArgs
.item
= string
;
175 result
->u
.stringArgs
.next
= string
;
176 result
->item
= nextString (result
, &result
->u
.stringArgs
.next
);
180 extern Arguments
* argNewFromArgv (char* const* const argv
)
182 Arguments
* result
= xMalloc (1, Arguments
);
183 memset (result
, 0, sizeof (Arguments
));
184 result
->type
= ARG_ARGV
;
185 result
->u
.argvArgs
.argv
= argv
;
186 result
->u
.argvArgs
.item
= result
->u
.argvArgs
.argv
;
187 result
->item
= *result
->u
.argvArgs
.item
;
191 extern Arguments
* argNewFromFile (FILE* const fp
)
193 Arguments
* result
= xMalloc (1, Arguments
);
194 memset (result
, 0, sizeof (Arguments
));
195 result
->type
= ARG_FILE
;
196 result
->u
.fileArgs
.fp
= fp
;
197 result
->item
= nextFileString (result
, result
->u
.fileArgs
.fp
);
201 extern Arguments
* argNewFromLineFile (FILE* const fp
)
203 Arguments
* result
= xMalloc (1, Arguments
);
204 memset (result
, 0, sizeof (Arguments
));
205 result
->type
= ARG_FILE
;
206 result
->lineMode
= TRUE
;
207 result
->u
.fileArgs
.fp
= fp
;
208 result
->item
= nextFileString (result
, result
->u
.fileArgs
.fp
);
212 extern char *argItem (const Arguments
* const current
)
214 Assert (current
!= NULL
);
215 Assert (! argOff (current
));
216 return current
->item
;
219 extern boolean
argOff (const Arguments
* const current
)
221 Assert (current
!= NULL
);
222 return (boolean
) (current
->item
== NULL
);
225 extern void argSetWordMode (Arguments
* const current
)
227 Assert (current
!= NULL
);
228 current
->lineMode
= FALSE
;
231 extern void argSetLineMode (Arguments
* const current
)
233 Assert (current
!= NULL
);
234 current
->lineMode
= TRUE
;
237 extern void argForth (Arguments
* const current
)
239 Assert (current
!= NULL
);
240 Assert (! argOff (current
));
241 switch (current
->type
)
244 if (current
->item
!= NULL
)
245 eFree (current
->item
);
246 current
->u
.stringArgs
.item
= current
->u
.stringArgs
.next
;
247 current
->item
= nextString (current
, ¤t
->u
.stringArgs
.next
);
250 ++current
->u
.argvArgs
.item
;
251 current
->item
= *current
->u
.argvArgs
.item
;
254 if (current
->item
!= NULL
)
255 eFree (current
->item
);
256 current
->item
= nextFileString (current
, current
->u
.fileArgs
.fp
);
259 Assert ("Invalid argument type" == NULL
);
264 extern void argDelete (Arguments
* const current
)
266 Assert (current
!= NULL
);
267 if (current
->type
== ARG_STRING
&& current
->item
!= NULL
)
268 eFree (current
->item
);
269 memset (current
, 0, sizeof (Arguments
));
273 /* vi:set tabstop=4 shiftwidth=4: */