2 * $Id: args.c 536 2007-06-02 06:09:00Z elliotth $
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 vStringStripTrailing (vs
);
151 result
= xMalloc (vStringLength (vs
) + 1, char);
152 strcpy (result
, vStringValue (vs
));
159 static char* nextFileString (const Arguments
* const current
, FILE* const fp
)
162 if (current
->lineMode
)
163 result
= nextFileLine (fp
);
165 result
= nextFileArg (fp
);
169 extern Arguments
* argNewFromString (const char* const string
)
171 Arguments
* result
= xMalloc (1, Arguments
);
172 memset (result
, 0, sizeof (Arguments
));
173 result
->type
= ARG_STRING
;
174 result
->u
.stringArgs
.string
= string
;
175 result
->u
.stringArgs
.item
= string
;
176 result
->u
.stringArgs
.next
= string
;
177 result
->item
= nextString (result
, &result
->u
.stringArgs
.next
);
181 extern Arguments
* argNewFromArgv (char* const* const argv
)
183 Arguments
* result
= xMalloc (1, Arguments
);
184 memset (result
, 0, sizeof (Arguments
));
185 result
->type
= ARG_ARGV
;
186 result
->u
.argvArgs
.argv
= argv
;
187 result
->u
.argvArgs
.item
= result
->u
.argvArgs
.argv
;
188 result
->item
= *result
->u
.argvArgs
.item
;
192 extern Arguments
* argNewFromFile (FILE* const fp
)
194 Arguments
* result
= xMalloc (1, Arguments
);
195 memset (result
, 0, sizeof (Arguments
));
196 result
->type
= ARG_FILE
;
197 result
->u
.fileArgs
.fp
= fp
;
198 result
->item
= nextFileString (result
, result
->u
.fileArgs
.fp
);
202 extern Arguments
* argNewFromLineFile (FILE* const fp
)
204 Arguments
* result
= xMalloc (1, Arguments
);
205 memset (result
, 0, sizeof (Arguments
));
206 result
->type
= ARG_FILE
;
207 result
->lineMode
= TRUE
;
208 result
->u
.fileArgs
.fp
= fp
;
209 result
->item
= nextFileString (result
, result
->u
.fileArgs
.fp
);
213 extern char *argItem (const Arguments
* const current
)
215 Assert (current
!= NULL
);
216 Assert (! argOff (current
));
217 return current
->item
;
220 extern boolean
argOff (const Arguments
* const current
)
222 Assert (current
!= NULL
);
223 return (boolean
) (current
->item
== NULL
);
226 extern void argSetWordMode (Arguments
* const current
)
228 Assert (current
!= NULL
);
229 current
->lineMode
= FALSE
;
232 extern void argSetLineMode (Arguments
* const current
)
234 Assert (current
!= NULL
);
235 current
->lineMode
= TRUE
;
238 extern void argForth (Arguments
* const current
)
240 Assert (current
!= NULL
);
241 Assert (! argOff (current
));
242 switch (current
->type
)
245 if (current
->item
!= NULL
)
246 eFree (current
->item
);
247 current
->u
.stringArgs
.item
= current
->u
.stringArgs
.next
;
248 current
->item
= nextString (current
, ¤t
->u
.stringArgs
.next
);
251 ++current
->u
.argvArgs
.item
;
252 current
->item
= *current
->u
.argvArgs
.item
;
255 if (current
->item
!= NULL
)
256 eFree (current
->item
);
257 current
->item
= nextFileString (current
, current
->u
.fileArgs
.fp
);
260 Assert ("Invalid argument type" == NULL
);
265 extern void argDelete (Arguments
* const current
)
267 Assert (current
!= NULL
);
268 if (current
->type
== ARG_STRING
&& current
->item
!= NULL
)
269 eFree (current
->item
);
270 memset (current
, 0, sizeof (Arguments
));
274 /* vi:set tabstop=4 shiftwidth=4: */