223 lines
7.4 KiB
C
223 lines
7.4 KiB
C
|
/****************************************************************************
|
||
|
*
|
||
|
* Open Watcom Project
|
||
|
*
|
||
|
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
|
||
|
*
|
||
|
* ========================================================================
|
||
|
*
|
||
|
* This file contains Original Code and/or Modifications of Original
|
||
|
* Code as defined in and that are subject to the Sybase Open Watcom
|
||
|
* Public License version 1.0 (the 'License'). You may not use this file
|
||
|
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
|
||
|
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
|
||
|
* provided with the Original Code and Modifications, and is also
|
||
|
* available at www.sybase.com/developer/opensource.
|
||
|
*
|
||
|
* The Original Code and all software distributed under the License are
|
||
|
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||
|
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
|
||
|
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
|
||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
|
||
|
* NON-INFRINGEMENT. Please see the License for the specific language
|
||
|
* governing rights and limitations under the License.
|
||
|
*
|
||
|
* ========================================================================
|
||
|
*
|
||
|
* Description: Functions to set up argc and argv parameters of main(), etc.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
#define __NETWARE__
|
||
|
|
||
|
#ifdef __NETWARE__
|
||
|
void __Init_Argv( void ) { }
|
||
|
void __Fini_Argv( void ) { }
|
||
|
#else
|
||
|
//#include "dll.h" // needs to be first
|
||
|
#include "variety.h"
|
||
|
#include "widechar.h"
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include <io.h>
|
||
|
//#include "liballoc.h"
|
||
|
#include "initarg.h"
|
||
|
|
||
|
extern int __historical_splitparms;
|
||
|
extern void _Not_Enough_Memory( void ); /* 25-jul-89 */
|
||
|
static unsigned _SplitParms(int, CHAR_TYPE *, CHAR_TYPE **, CHAR_TYPE ** );
|
||
|
_WCRTLINKD static CHAR_TYPE *__F_NAME(__CmdLine,__wCmdLine); /* cmdline buffer */
|
||
|
|
||
|
_WCRTLINK void *__F_NAME( _getargv, _wgetargv )(
|
||
|
int historical, CHAR_TYPE *exe, CHAR_TYPE *cmd,
|
||
|
int *pargc, CHAR_TYPE ***pargv );
|
||
|
|
||
|
void __F_NAME(__Init_Argv,__wInit_Argv)( void )
|
||
|
{
|
||
|
__F_NAME( __CmdLine, __wCmdLine ) = __F_NAME( _getargv, _wgetargv )(
|
||
|
__historical_splitparms,
|
||
|
__F_NAME( _LpPgmName, _LpwPgmName ), __F_NAME( _LpCmdLine, _LpwCmdLine ),
|
||
|
&__F_NAME( _argc, _wargc ), &__F_NAME( _argv, _wargv ) );
|
||
|
|
||
|
__F_NAME( __argc, __wargc ) = __F_NAME( _argc, _wargc );
|
||
|
__F_NAME( ___Argc, ___wArgc ) = __F_NAME( _argc, _wargc );
|
||
|
__F_NAME( __argv, __wargv ) = __F_NAME( _argv, _wargv );
|
||
|
__F_NAME( ___Argv, ___wArgv ) = __F_NAME( _argv, _wargv );
|
||
|
}
|
||
|
|
||
|
_WCRTLINK void *__F_NAME( _getargv, _wgetargv )(
|
||
|
int historical, CHAR_TYPE *exe, CHAR_TYPE *cmd,
|
||
|
int *pargc, CHAR_TYPE ***pargv )
|
||
|
{
|
||
|
unsigned argc; /* argument count */
|
||
|
CHAR_TYPE **argv; /* Actual arguments */
|
||
|
CHAR_TYPE *endptr; /* ptr to end of command line */
|
||
|
unsigned len; /* length of command line */
|
||
|
CHAR_TYPE *cmdline; /* copy of command line */
|
||
|
unsigned size; /* amount to allocate */
|
||
|
unsigned argv_offset; /* offset of argv in storage */
|
||
|
|
||
|
argc = _SplitParms( historical, cmd, NULL, &endptr ) + 1;
|
||
|
len = (unsigned) ( endptr - cmd ) + 1;
|
||
|
argv_offset = __ALIGN_SIZE(len * sizeof(CHAR_TYPE));
|
||
|
size = argv_offset + (argc+1) * sizeof(CHAR_TYPE *);
|
||
|
// round up size for alignment of argv pointer
|
||
|
size = __ALIGN_SIZE( size );
|
||
|
|
||
|
#if defined(__REAL_MODE__) && defined(__BIG_DATA__)
|
||
|
#if defined(__OS2_286__)
|
||
|
if( _osmode == DOS_MODE ) {
|
||
|
cmdline = lib_nmalloc( size );
|
||
|
if( (void _WCI86NEAR *) cmdline == NULL ) {
|
||
|
cmdline = lib_malloc( size );
|
||
|
}
|
||
|
} else {
|
||
|
cmdline = lib_malloc( size );
|
||
|
}
|
||
|
#else
|
||
|
cmdline = lib_nmalloc( size );
|
||
|
if( (void _WCI86NEAR *) cmdline == NULL ) {
|
||
|
cmdline = lib_malloc( size );
|
||
|
}
|
||
|
#endif
|
||
|
#else
|
||
|
cmdline = lib_malloc( size );
|
||
|
#endif
|
||
|
argv = NULL;
|
||
|
argc = 0;
|
||
|
if( cmdline ) {
|
||
|
memcpy( cmdline, cmd, len * sizeof(CHAR_TYPE) );
|
||
|
argv = (void *) ( ( ( char*) cmdline ) + argv_offset );
|
||
|
argv[0] = exe;
|
||
|
argc = _SplitParms( historical, cmdline, argv + 1, &endptr ) + 1;
|
||
|
argv[argc] = NULL;
|
||
|
}
|
||
|
*pargc = argc;
|
||
|
*pargv = argv;
|
||
|
return( cmdline );
|
||
|
}
|
||
|
|
||
|
|
||
|
static unsigned _SplitParms( int historical, CHAR_TYPE *p, CHAR_TYPE **argv, CHAR_TYPE **endptr )
|
||
|
{
|
||
|
register unsigned argc;
|
||
|
register CHAR_TYPE *start;
|
||
|
register CHAR_TYPE *new;
|
||
|
enum QUOTE_STATE {
|
||
|
QUOTE_NONE, /* no " active in current parm */
|
||
|
QUOTE_DELIMITER, /* " was first char and must be last */
|
||
|
QUOTE_STARTED /* " was seen, look for a match */
|
||
|
};
|
||
|
register enum QUOTE_STATE state;
|
||
|
|
||
|
argc = 0;
|
||
|
for(;;) {
|
||
|
while( *p == ' ' || *p == '\t' ) {
|
||
|
++p; /* skip over blanks or tabs */
|
||
|
}
|
||
|
if( *p == '\0' ) break;
|
||
|
/* we are at the start of a parm */
|
||
|
state = QUOTE_NONE;
|
||
|
if( *p == '\"' ) {
|
||
|
p++;
|
||
|
state = QUOTE_DELIMITER;
|
||
|
}
|
||
|
new = start = p;
|
||
|
for(;;) {
|
||
|
if( *p == '\"' ) {
|
||
|
if( !historical ) {
|
||
|
p++;
|
||
|
if( state == QUOTE_NONE ) {
|
||
|
state = QUOTE_STARTED;
|
||
|
} else {
|
||
|
state = QUOTE_NONE;
|
||
|
}
|
||
|
continue;
|
||
|
} else {
|
||
|
if( state == QUOTE_DELIMITER ) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if( *p == ' ' || *p == '\t' ) {
|
||
|
if( state == QUOTE_NONE ) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if( *p == '\0' ) break;
|
||
|
if( *p == '\\' ) {
|
||
|
if( !historical ) {
|
||
|
if( p[1] == '\"' ) {
|
||
|
++p;
|
||
|
if( p[-2] == '\\' ) {
|
||
|
continue;
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
if( p[1] == '\"' || p[1] == '\\' && state == QUOTE_DELIMITER ) {
|
||
|
++p;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if( argv ) {
|
||
|
*(new++) = *p;
|
||
|
}
|
||
|
++p;
|
||
|
}
|
||
|
if( argv ) {
|
||
|
argv[ argc ] = start;
|
||
|
++argc;
|
||
|
|
||
|
/*
|
||
|
The *new = '\0' is req'd in case there was a \" to "
|
||
|
translation. It must be after the *p check against
|
||
|
'\0' because new and p could point to the same char
|
||
|
in which case the scan would be terminated too soon.
|
||
|
*/
|
||
|
|
||
|
if( *p == '\0' ) {
|
||
|
*new = '\0';
|
||
|
break;
|
||
|
}
|
||
|
*new = '\0';
|
||
|
++p;
|
||
|
} else {
|
||
|
++argc;
|
||
|
if( *p == '\0' ) {
|
||
|
break;
|
||
|
}
|
||
|
++p;
|
||
|
}
|
||
|
}
|
||
|
*endptr = p;
|
||
|
return( argc );
|
||
|
}
|
||
|
|
||
|
void __F_NAME(__Fini_Argv,__wFini_Argv)( void )
|
||
|
{
|
||
|
if( __F_NAME(__CmdLine,__wCmdLine) != NULL ) {
|
||
|
lib_free( __F_NAME(__CmdLine,__wCmdLine) );
|
||
|
}
|
||
|
}
|
||
|
#endif
|