3
"$Header: d:/cvsroot/tads/TADS2/OS0.C,v 1.2 1999/05/17 02:52:12 MJRoberts Exp $";
7
* Copyright (c) 1992, 2002 Michael J. Roberts. All Rights Reserved.
9
* Please see the accompanying license file, LICENSE.TXT, for information
10
* on using and copying this software.
14
os0.c - argument configuration utility
16
This module allows a "main" routine to get additional arguments
17
from a configuration file. We look for the given configuration
18
file in the current directory, and if not found, in the executable's
19
directory. The arguments it contains are added before the command
20
line arguments, except that any argument flags (along with an extra
21
argument string, if any) listed in the "before" list are moved to
22
the beginning of the argument list. For example:
25
config file contains "-m 128000 -1+ -tf- -i /tads/include"
26
command line contains "-1- -i ../include -o test.gam test.t"
27
translation: "-i ../include -m 128000 -1+ -f- -i /tads/include
30
This allows arguments to be sorted according to precedence so that
31
an argument in the command line overrides an argument in the config
32
file. The "before" list contains options that need to come first
33
to override subsequent instances of the same option; other options
34
override by coming later in the string.
38
04/04/99 CNebel - Use new argize function; fix Metrowerks errors.
39
04/24/93 JEras - use new os_locate() to find config file
40
04/22/92 MJRoberts - creation
53
static int os0main_internal(int oargc, char **oargv,
54
int (*mainfn1)(int, char **, char *),
55
int (*mainfn2)(int, char **, struct appctxdef *,
57
const char *before, const char *config,
58
struct appctxdef *appctx)
72
* Check for an embedded SAVX resource, which specifies the default
73
* saved game file suffix.
75
if (oargv != 0 && oargv[0] != 0
76
&& (fp = os_exeseek(oargv[0], "SAVX")) != 0)
80
/* read the length and then read the name */
81
if (!osfrb(fp, &len, sizeof(len))
83
&& !osfrb(fp, buf, len))
85
/* null-terminate the value */
88
/* tell the OS layer about it */
91
/* save a copy of the extension */
92
save_ext = (char *)osmalloc(len + 1);
93
strcpy(save_ext, buf);
102
* Try for an embedded configuration file. If we don't find one,
103
* try locating an external configuration file.
105
if (oargv != 0 && oargv[0] != 0
106
&& (fp = os_exeseek(oargv[0], "RCFG")) != 0)
108
osfrb(fp, &fsiz, sizeof(fsiz));
111
&& os_locate(config, (int)strlen(config), oargv[0], buf,
113
&& (fp = osfoprb(buf, OSFTTEXT)) != 0)
115
osfseek(fp, 0L, OSFSK_END);
117
osfseek(fp, 0L, OSFSK_SET);
125
/* read the file if we found anything */
128
configbuf = (char *)osmalloc((size_t)(fsiz + 1));
131
/* read the configuration file into the buffer */
132
osfrb(fp, configbuf, (size_t)fsiz);
134
/* null-terminate it */
135
configbuf[fsiz] = '\0';
137
/* count arguments */
138
fargc = countargs(configbuf);
142
/* close the file if we opened one */
146
/* allocate space for the argument vector */
147
argv = (char **)osmalloc((size_t)((oargc + fargc + 1) * sizeof(*argv)));
149
/* first argument is always original argv[0] */
150
argv[argc++] = oargv[0];
152
/* put all user -i flags next */
153
for (i = 0 ; i < oargc ; ++i)
155
if (oargv[i][0] == '-' && strchr(before, oargv[i][1]))
157
argv[argc++] = oargv[i];
158
if (oargv[i][2] == '\0' && i+1 < oargc) argv[argc++] = oargv[++i];
162
/* put all config file flags next */
167
/* parse the arguments */
168
ret = argize(configbuf, &foundargc, &argv[argc], fargc);
170
/* add them into our arguments */
173
/* make sure we scanned the same number of args we anticipated */
175
assert(foundargc == fargc);
178
/* put all user parameters other than -i flags last */
179
for (i = 1 ; i < oargc ; ++i)
181
if (oargv[i][0] == '-' && strchr(before, oargv[i][1]))
183
if (oargv[i][2] == '\0' && i+1 < oargc) ++i;
187
argv[argc++] = oargv[i];
191
/* call appropriate real main with the modified argument list */
193
ret = (*mainfn1)(argc, argv, save_ext);
195
ret = (*mainfn2)(argc, argv, appctx, save_ext);
197
/* forget our saved extension */
201
/* return the result */
207
* Old-style os0main: call with main function that doesn't take a host
208
* container application context
210
int os0main(int oargc, char **oargv,
211
int (*mainfn)(int, char **, char *),
212
const char *before, const char *config)
214
return os0main_internal(oargc, oargv, mainfn, 0, before, config, 0);
218
* New-style os0main: call with main function that takes a host
219
* container application context
221
int os0main2(int oargc, char **oargv,
222
int (*mainfn)(int, char **, struct appctxdef *, char *),
223
const char *before, const char *config,
224
struct appctxdef *appctx)
226
return os0main_internal(oargc, oargv, 0, mainfn, before, config, appctx);