Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
548 serge 1
/****************************************************************************
2
*
3
*                            Open Watcom Project
4
*
5
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
6
*
7
*  ========================================================================
8
*
9
*    This file contains Original Code and/or Modifications of Original
10
*    Code as defined in and that are subject to the Sybase Open Watcom
11
*    Public License version 1.0 (the 'License'). You may not use this file
12
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
13
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
14
*    provided with the Original Code and Modifications, and is also
15
*    available at www.sybase.com/developer/opensource.
16
*
17
*    The Original Code and all software distributed under the License are
18
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
19
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
20
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
21
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
22
*    NON-INFRINGEMENT. Please see the License for the specific language
23
*    governing rights and limitations under the License.
24
*
25
*  ========================================================================
26
*
27
* Description:  Functions to set up argc and argv parameters of main(), etc.
28
*
29
****************************************************************************/
30
#define __NETWARE__
31
 
32
#ifdef __NETWARE__
33
    void __Init_Argv( void ) { }
34
    void __Fini_Argv( void ) { }
35
#else
36
//#include "dll.h"        // needs to be first
37
#include "variety.h"
38
#include "widechar.h"
39
#include 
40
#include 
41
#include 
42
#include 
43
//#include "liballoc.h"
44
#include "initarg.h"
45
 
46
extern  int         __historical_splitparms;
47
extern  void        _Not_Enough_Memory( void );             /* 25-jul-89 */
48
static  unsigned    _SplitParms(int, CHAR_TYPE *, CHAR_TYPE **, CHAR_TYPE ** );
49
_WCRTLINKD static CHAR_TYPE  *__F_NAME(__CmdLine,__wCmdLine);       /* cmdline buffer */
50
 
51
_WCRTLINK void *__F_NAME( _getargv, _wgetargv )(
52
        int historical, CHAR_TYPE *exe, CHAR_TYPE *cmd,
53
        int *pargc, CHAR_TYPE ***pargv );
54
 
55
void __F_NAME(__Init_Argv,__wInit_Argv)( void )
56
{
57
    __F_NAME( __CmdLine, __wCmdLine ) = __F_NAME( _getargv, _wgetargv )(
58
        __historical_splitparms,
59
        __F_NAME( _LpPgmName, _LpwPgmName ), __F_NAME( _LpCmdLine, _LpwCmdLine ),
60
        &__F_NAME( _argc, _wargc ), &__F_NAME( _argv, _wargv ) );
61
 
62
    __F_NAME( __argc, __wargc )   = __F_NAME( _argc, _wargc );
63
    __F_NAME( ___Argc, ___wArgc ) = __F_NAME( _argc, _wargc );
64
    __F_NAME( __argv, __wargv )   = __F_NAME( _argv, _wargv );
65
    __F_NAME( ___Argv, ___wArgv ) = __F_NAME( _argv, _wargv );
66
}
67
 
68
_WCRTLINK void *__F_NAME( _getargv, _wgetargv )(
69
        int historical, CHAR_TYPE *exe, CHAR_TYPE *cmd,
70
        int *pargc, CHAR_TYPE ***pargv )
71
{
72
    unsigned    argc;           /* argument count */
73
    CHAR_TYPE   **argv;         /* Actual arguments */
74
    CHAR_TYPE   *endptr;        /* ptr to end of command line */
75
    unsigned    len;            /* length of command line */
76
    CHAR_TYPE   *cmdline;       /* copy of command line */
77
    unsigned    size;           /* amount to allocate */
78
    unsigned    argv_offset;    /* offset of argv in storage */
79
 
80
    argc = _SplitParms( historical, cmd, NULL, &endptr ) + 1;
81
    len = (unsigned) ( endptr - cmd ) + 1;
82
    argv_offset = __ALIGN_SIZE(len * sizeof(CHAR_TYPE));
83
    size = argv_offset + (argc+1) * sizeof(CHAR_TYPE *);
84
    // round up size for alignment of argv pointer
85
    size = __ALIGN_SIZE( size );
86
 
87
    #if defined(__REAL_MODE__) && defined(__BIG_DATA__)
88
        #if defined(__OS2_286__)
89
            if( _osmode == DOS_MODE ) {
90
                cmdline = lib_nmalloc( size );
91
                if( (void _WCI86NEAR *) cmdline == NULL ) {
92
                    cmdline = lib_malloc( size );
93
                }
94
            } else {
95
                cmdline = lib_malloc( size );
96
            }
97
        #else
98
            cmdline = lib_nmalloc( size );
99
            if( (void _WCI86NEAR *) cmdline == NULL ) {
100
                cmdline = lib_malloc( size );
101
            }
102
        #endif
103
    #else
104
        cmdline = lib_malloc( size );
105
    #endif
106
    argv = NULL;
107
    argc = 0;
108
    if( cmdline ) {
109
        memcpy( cmdline, cmd, len * sizeof(CHAR_TYPE) );
110
        argv = (void *) ( ( ( char*) cmdline ) + argv_offset );
111
        argv[0] = exe;
112
        argc = _SplitParms( historical, cmdline, argv + 1, &endptr ) + 1;
113
        argv[argc] = NULL;
114
    }
115
    *pargc = argc;
116
    *pargv = argv;
117
    return( cmdline );
118
}
119
 
120
 
121
static unsigned _SplitParms( int historical, CHAR_TYPE *p, CHAR_TYPE **argv, CHAR_TYPE **endptr )
122
{
123
    register unsigned argc;
124
    register CHAR_TYPE *start;
125
    register CHAR_TYPE *new;
126
    enum QUOTE_STATE {
127
        QUOTE_NONE,             /* no " active in current parm */
128
        QUOTE_DELIMITER,        /* " was first char and must be last */
129
        QUOTE_STARTED   /* " was seen, look for a match */
130
    };
131
    register enum QUOTE_STATE state;
132
 
133
    argc = 0;
134
    for(;;) {
135
        while( *p == ' ' || *p == '\t' ) {
136
            ++p; /* skip over blanks or tabs */
137
        }
138
        if( *p == '\0' ) break;
139
        /* we are at the start of a parm */
140
        state = QUOTE_NONE;
141
        if( *p == '\"' ) {
142
            p++;
143
            state = QUOTE_DELIMITER;
144
        }
145
        new = start = p;
146
        for(;;) {
147
            if( *p == '\"' ) {
148
                if( !historical ) {
149
                    p++;
150
                    if( state == QUOTE_NONE ) {
151
                        state = QUOTE_STARTED;
152
                    } else {
153
                        state = QUOTE_NONE;
154
                    }
155
                    continue;
156
                } else {
157
                    if( state == QUOTE_DELIMITER ) {
158
                        break;
159
                    }
160
                }
161
            }
162
            if( *p == ' ' || *p == '\t' ) {
163
                if( state == QUOTE_NONE ) {
164
                    break;
165
                }
166
            }
167
            if( *p == '\0' ) break;
168
            if( *p == '\\' ) {
169
                if( !historical ) {
170
                    if( p[1] == '\"' ) {
171
                        ++p;
172
                        if( p[-2] == '\\' ) {
173
                            continue;
174
                        }
175
                    }
176
                } else {
177
                    if( p[1] == '\"' || p[1] == '\\' && state == QUOTE_DELIMITER ) {
178
                        ++p;
179
                    }
180
                }
181
            }
182
            if( argv ) {
183
                *(new++) = *p;
184
            }
185
            ++p;
186
        }
187
        if( argv ) {
188
            argv[ argc ] = start;
189
            ++argc;
190
 
191
            /*
192
              The *new = '\0' is req'd in case there was a \" to "
193
              translation. It must be after the *p check against
194
              '\0' because new and p could point to the same char
195
              in which case the scan would be terminated too soon.
196
            */
197
 
198
            if( *p == '\0' ) {
199
                *new = '\0';
200
                break;
201
            }
202
            *new = '\0';
203
            ++p;
204
        } else {
205
            ++argc;
206
            if( *p == '\0' ) {
207
                break;
208
            }
209
            ++p;
210
        }
211
    }
212
    *endptr = p;
213
    return( argc );
214
}
215
 
216
void __F_NAME(__Fini_Argv,__wFini_Argv)( void )
217
{
218
    if( __F_NAME(__CmdLine,__wCmdLine) != NULL ) {
219
        lib_free( __F_NAME(__CmdLine,__wCmdLine) );
220
    }
221
}
222
#endif