~ubuntu-branches/ubuntu/wily/gargoyle-free/wily-proposed

« back to all changes in this revision

Viewing changes to tads/tads2/os0.c

  • Committer: Bazaar Package Importer
  • Author(s): Sylvain Beucler
  • Date: 2009-09-11 20:09:43 UTC
  • Revision ID: james.westby@ubuntu.com-20090911200943-idgzoyupq6650zpn
Tags: upstream-2009-08-25
ImportĀ upstreamĀ versionĀ 2009-08-25

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifdef RCSID
 
2
static char RCSid[] =
 
3
"$Header: d:/cvsroot/tads/TADS2/OS0.C,v 1.2 1999/05/17 02:52:12 MJRoberts Exp $";
 
4
#endif
 
5
 
 
6
/* 
 
7
 *   Copyright (c) 1992, 2002 Michael J. Roberts.  All Rights Reserved.
 
8
 *   
 
9
 *   Please see the accompanying license file, LICENSE.TXT, for information
 
10
 *   on using and copying this software.  
 
11
 */
 
12
/*
 
13
Name
 
14
  os0.c - argument configuration utility
 
15
Function
 
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:
 
23
 
 
24
     before list = "i"
 
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
 
28
                    -o test.gam test.t"
 
29
 
 
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.
 
35
Notes
 
36
  
 
37
Modified
 
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
 
41
*/
 
42
 
 
43
#include <stdlib.h>
 
44
#include <stdio.h>
 
45
#include <string.h>
 
46
#include <ctype.h>
 
47
#include <assert.h>
 
48
#include "os.h"
 
49
#include "appctx.h"
 
50
#include "argize.h"
 
51
 
 
52
 
 
53
static int os0main_internal(int oargc, char **oargv,
 
54
                            int (*mainfn1)(int, char **, char *),
 
55
                            int (*mainfn2)(int, char **, struct appctxdef *,
 
56
                                           char *), 
 
57
                            const char *before, const char *config,
 
58
                            struct appctxdef *appctx)
 
59
{
 
60
    int       argc = 0;
 
61
    int       fargc = 0;
 
62
    char    **argv;
 
63
    char     *configbuf = 0;
 
64
    int       i;
 
65
    osfildef *fp;
 
66
    long      fsiz;
 
67
    char      buf[256];
 
68
    char     *save_ext = 0;
 
69
    int       ret;
 
70
 
 
71
    /*
 
72
     *   Check for an embedded SAVX resource, which specifies the default
 
73
     *   saved game file suffix. 
 
74
     */
 
75
    if (oargv != 0 && oargv[0] != 0
 
76
        && (fp = os_exeseek(oargv[0], "SAVX")) != 0)
 
77
    {
 
78
        unsigned short len;
 
79
        
 
80
        /* read the length and then read the name */
 
81
        if (!osfrb(fp, &len, sizeof(len))
 
82
            && len < sizeof(buf)
 
83
            && !osfrb(fp, buf, len))
 
84
        {
 
85
            /* null-terminate the value */
 
86
            buf[len] = '\0';
 
87
 
 
88
            /* tell the OS layer about it */
 
89
            os_set_save_ext(buf);
 
90
 
 
91
            /* save a copy of the extension */
 
92
            save_ext = (char *)osmalloc(len + 1);
 
93
            strcpy(save_ext, buf);
 
94
        }
 
95
 
 
96
        /* done with it */
 
97
        osfcls(fp);
 
98
        fp = 0;
 
99
    }
 
100
 
 
101
    /*
 
102
     *   Try for an embedded configuration file.  If we don't find one,
 
103
     *   try locating an external configuration file. 
 
104
     */
 
105
    if (oargv != 0 && oargv[0] != 0
 
106
        && (fp = os_exeseek(oargv[0], "RCFG")) != 0)
 
107
    {
 
108
        osfrb(fp, &fsiz, sizeof(fsiz));
 
109
    }
 
110
    else if (config != 0
 
111
             && os_locate(config, (int)strlen(config), oargv[0], buf,
 
112
                       (size_t)sizeof(buf))
 
113
             && (fp = osfoprb(buf, OSFTTEXT)) != 0)
 
114
    {
 
115
        osfseek(fp, 0L, OSFSK_END);
 
116
        fsiz = osfpos(fp);
 
117
        osfseek(fp, 0L, OSFSK_SET);
 
118
    }
 
119
    else
 
120
    {
 
121
        fsiz = 0;
 
122
        fp = 0;
 
123
    }
 
124
 
 
125
    /* read the file if we found anything */
 
126
    if (fsiz != 0)
 
127
    {
 
128
        configbuf = (char *)osmalloc((size_t)(fsiz + 1));
 
129
        if (configbuf != 0)
 
130
        {
 
131
            /* read the configuration file into the buffer */
 
132
            osfrb(fp, configbuf, (size_t)fsiz);
 
133
 
 
134
            /* null-terminate it */
 
135
            configbuf[fsiz] = '\0';
 
136
 
 
137
            /* count arguments */
 
138
            fargc = countargs(configbuf);
 
139
        }
 
140
    }
 
141
 
 
142
    /* close the file if we opened one */
 
143
    if (fp != 0)
 
144
        osfcls(fp);
 
145
 
 
146
    /* allocate space for the argument vector */
 
147
    argv = (char **)osmalloc((size_t)((oargc + fargc + 1) * sizeof(*argv)));
 
148
 
 
149
    /* first argument is always original argv[0] */
 
150
    argv[argc++] = oargv[0];
 
151
 
 
152
    /* put all user -i flags next */
 
153
    for (i = 0 ; i < oargc ; ++i)
 
154
    {
 
155
        if (oargv[i][0] == '-' && strchr(before, oargv[i][1]))
 
156
        {
 
157
            argv[argc++] = oargv[i];
 
158
            if (oargv[i][2] == '\0' && i+1 < oargc) argv[argc++] = oargv[++i];
 
159
        }
 
160
    }
 
161
 
 
162
    /* put all config file flags next */
 
163
    if (configbuf != 0)
 
164
    {
 
165
        int ret, foundargc;
 
166
 
 
167
        /* parse the arguments */
 
168
        ret = argize(configbuf, &foundargc, &argv[argc], fargc);
 
169
 
 
170
        /* add them into our arguments */
 
171
        argc += foundargc;
 
172
 
 
173
        /* make sure we scanned the same number of args we anticipated */
 
174
        assert(ret == 0);
 
175
        assert(foundargc == fargc);
 
176
    }
 
177
 
 
178
    /* put all user parameters other than -i flags last */
 
179
    for (i = 1 ; i < oargc ; ++i)
 
180
    {
 
181
        if (oargv[i][0] == '-' && strchr(before, oargv[i][1]))
 
182
        {
 
183
            if (oargv[i][2] == '\0' && i+1 < oargc) ++i;
 
184
        }
 
185
        else
 
186
        {
 
187
            argv[argc++] = oargv[i];
 
188
        }
 
189
    }
 
190
 
 
191
    /* call appropriate real main with the modified argument list */
 
192
    if (mainfn1)
 
193
        ret = (*mainfn1)(argc, argv, save_ext);
 
194
    else
 
195
        ret = (*mainfn2)(argc, argv, appctx, save_ext);
 
196
 
 
197
    /* forget our saved extension */
 
198
    if (save_ext != 0)
 
199
        osfree(save_ext);
 
200
 
 
201
    /* return the result */
 
202
    return ret;
 
203
}
 
204
 
 
205
 
 
206
/*
 
207
 *   Old-style os0main: call with main function that doesn't take a host
 
208
 *   container application context 
 
209
 */
 
210
int os0main(int oargc, char **oargv,
 
211
            int (*mainfn)(int, char **, char *),
 
212
            const char *before, const char *config)
 
213
{
 
214
    return os0main_internal(oargc, oargv, mainfn, 0, before, config, 0);
 
215
}
 
216
 
 
217
/*
 
218
 *   New-style os0main: call with main function that takes a host
 
219
 *   container application context 
 
220
 */
 
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)
 
225
{
 
226
    return os0main_internal(oargc, oargv, 0, mainfn, before, config, appctx);
 
227
}
 
228