Category : C++ Source Code
Archive   : VCCRT2.ZIP
Filename : STDARGV.C

 
Output of file : STDARGV.C contained in archive : VCCRT2.ZIP
/***
*stdargv.c - Windows standard & wildcard _setargv routine
*
* Copyright (c) 1990-1992, Microsoft Corporation. All rights reserved.
*
*Purpose:
* processes program command line, with or without wildcard expansion
*
*******************************************************************************/
* *** 11/18/90 ***
* This routine has not yet been tested. Additionally, the wild card
* expansion routine hasn't been re-written for WINDOWS.
*******************************************************************************/
*
*Revision History:
* 11-17-90 JCR module created, based on CRT32 version
*
*******************************************************************************/

#include
#include
#include
#include
#include
#include

/* *** THESE SHOULD BE MOVED TO INTERNAL.H *** */

extern char _far *_pgmptr; /* full program path name */
extern int __argc; /* argument count */
extern char **__argv; /* argument vector */


/*** MOVE THIS TO RTERR.H!!! ***/
#define _RT_SPACEARG 8

extern void _near _amsg_exit(void);

extern void _near _cdecl fatal(void);
static void _near _cdecl parse_cmdline(char far *cmdstart, char **argv, char *args,
int *numargs, int *numbytes);


/***
*_setargv, __setargv - set up "argc" and "argv" for C programs
*
*Purpose:
* Parse the program name and arguments and set up the
* argv[] array and argc value.
*
*Entry:
* Program name = retrieved from GETAPPNAME system call
* Args = retrieved from _lpszCmdLine variable
*
*Exit:
* "argv" points to a null-terminated list of pointers to ASCIZ
* strings, each of which is an argument from the command line.
* Space is allocated from the heap.
*
* "argc" is the number of arguments.
*
* _pgmptr points to the program name.
*
*Exceptions:
* Terminates with "out of memory error" heap allocation fails.
*
*******************************************************************************/

#ifdef WILDCARD
void _cdecl __setargv ( void )
#else
void _cdecl _setargv ( void )
#endif

{
int i;
char *p;
char *exepath; /* pointer exe path */
int numargs, numbytes; /* counters */
char exebuf[_MAX_PATH]; /* buffer to hold exe path */

/*
* Get the full path of the program.
*/

#ifdef _WINDLL
if (i = GetModuleFileName (_hModule, (char far *) exebuf, _MAX_PATH))
#else
if (i = GetModuleFileName (_hInstance, (char far *) exebuf, _MAX_PATH))
#endif

{
#ifdef WILDCARD
/*
* Prefix arg with its first char (see parse_cmdline() for info).
*/

if ((exepath = malloc(i+2)) == NULL)
fatal();
*exepath = exebuf[0];
strcpy(exepath+1,exebuf);
#else
if ((exepath = strdup(exebuf)) == NULL)
fatal();
#endif
}

else
{
/* no progam name */
exepath = NULL;
}

/*
* Find out how many arguments there are and how much space is
* needed to store them.
*/

parse_cmdline(_lpszCmdLine, NULL, NULL, &numargs, &numbytes);

/*
* Allocate space for argv[] vector and strings.
* (Add space for the argv[0] pointer in the vector.)
*/

p = malloc( ((numargs+1)*sizeof(char *)) + numbytes);
if (p == (char far *) NULL)
fatal();

/*
* Set _pgmptr, argv, argc, and argv[0]. Then store args and
* argv ptrs in just allocated block.
*/

__argc = numargs - 1; /* number of args */
__argv = (char **)p; /* poiner to argv vector */
__argv[0] = exepath; /* poiner to argv[0] program name */
_pgmptr = (char far *) exepath; /* pointer to full path */

parse_cmdline(_lpszCmdLine, (char **)p,
(p + ((numargs+1) * sizeof(char *))), &numargs, &numbytes);

#ifdef WILDCARD
/*
* call _cwild to expand wildcards in arg vector
*/

if (_cwild())
fatal();
#endif

}


/***
*static void parse_cmdline(cmdstart, argv, args, numargs, numbytes)
*
*Purpose:
* Parses the command line and sets up the argv[] array.
* On entry, cmdstart should point to the command line,
* argv should point to memory for the argv array, args
* points to memory to place the text of the arguments.
* If these are NULL, then no storing (only counting)
* is done. On exit, *numargs has the number of
* arguments (plus one for a final NULL argument),
* and *numbytes has the number of bytes used in the buffer
* pointed to by args.
*
* Notes:
*
* (1) Input command line is expected to be in the following
* format:
*
*
* (2) The input string is NOT expected to contain the program
* pathname (e.g., argv[0] string).
*
#ifdef WILDCARD
* (3) To handle later wild card expansion, we prefix each entry by
* it's first character before quote handling. This is done
* so _cwild() knows whether to expand an entry or not.
#endif
*
*Entry:
* char far *cmdstart - Ptr to arg portion of command
* char **argv - where to build argv array; NULL means don't build
* char *args - where to place argument text; NULL don't store text
* int *numargs - where to return argument count
* int *numbytes - where to return byte count
*
*Exit:
* no return value
* int *numargs - returns number of argv entries created
* int *numbytes - number of bytes used in args buffer
*
*Exceptions:
*
*******************************************************************************/

static void _near _cdecl parse_cmdline (
char far *cmdstart,
char **argv,
char *args,
int *numargs,
int *numbytes
)
{
char far *p;
int inquote=0; /* 1 = inside quotes */
unsigned numslash; /* num of backslashes seen */

*numbytes = 0;
*numargs = 0;

/*
* Initialization
*/

p = cmdstart;

if (argv)
*argv++; /* step over argv[0] entry */

/*
* Loop once for each argument
*/

for(;;) {

/* skip blanks */

while (*p == ' ' || *p == '\t')
++p;

if (*p == '\0')
break; /* end of args */

/* scan an argument */
if (argv)
*argv++ = args; /* store ptr to arg */
++*numargs;

#ifdef WILDCARD
/*
* Prefix each entry by it's first character before quote handling.
*/

if (args)
*args++ = *p;
++*numbytes;
#endif

/*
* loop through scanning one argument
*
* Rules: 2N backslashes + " ==> N backslashes and begin/end quote
* 2N+1 backslashes + " ==> N backslashes + literal "
* N backslashes ==> N backslashes
*/

for (;;) {

numslash = 0;
while (*p == '\\') {
/* count number of backslashes for use below */
++p;
++numslash;
}

if (*p == '\"') {
/* if 2N backslashes before, start/end quote, otherwise
copy literally */
if (numslash % 2 == 0) {
inquote = !inquote;
++p; /* don't copy quote */
}
numslash /= 2; /* divide numslash by two */
}

/* copy slashes */
while (numslash--) {
if (args)
*args++ = '\\';
++*numbytes;
}

/* if at end of arg, break loop */
if (*p == '\0' || (!inquote && (*p == ' ' || *p == '\t')))
break;

/* copy character into argument */
if (args)
*args++ = *p;
++*numbytes;
++p;

}

/*
* null-terminate the argument
*/

if (args)
*args++ = '\0'; /* terminate string */
++*numbytes;
}

/*
* Put a NULL pointer at the end of the argv[] array.
*/

if (argv)
*argv++ = NULL;
++*numargs;

}


#ifdef WILDCARD
/***
*_find(pattern) - find matching filename
*
*Purpose:
* if argument is non-null, do a DOSFINDFIRST on that pattern
* otherwise do a DOSFINDNEXT call. Return matching filename
* or NULL if no more matches.
*
*Entry:
* pattern = pointer to pattern or NULL
* (NULL means find next matching filename)
*
*Exit:
* returns pointer to matching file name
* or NULL if no more matches.
*
*Exceptions:
*
*******************************************************************************/

#ifdef _WINDOWS
#error *** ROUTINE NOT PORTED TO WINDOWS!!! ***
#endif

char * _cdecl _find (
char *pattern
)
{
FILEFINDBUF findbuf;
HDIR findhandle = HDIR_SYSTEM;
ULONG findcount = 1;
int rc;

if (pattern)
rc = DOSFINDFIRST(pattern, &findhandle, FILE_NORMAL | FILE_DIRECTORY,
&findbuf, sizeof(findbuf), &findcount, 1L, 0L);
else
rc = DOSFINDNEXT(findhandle, &findbuf, sizeof(findbuf), &findcount);

return(rc ? NULL : findbuf.achName);
}

#endif /* WILDCARD */


/***
*fatal() - Fatal error due to out of heap space
*
*Purpose:
* Terminate program with "not enough space for arguments"
*
*Entry:
* void
*Exit:
* void
*
*Exceptions:
*
*******************************************************************************/

static void _near _cdecl fatal(void)
{

_asm {
mov ax,_RT_SPACEARG
jmp _amsg_exit;
}
}


  3 Responses to “Category : C++ Source Code
Archive   : VCCRT2.ZIP
Filename : STDARGV.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/