NT4/private/windows/media/tools/extract/parsearg.c
2020-09-30 17:12:29 +02:00

283 lines
6.9 KiB
C

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "extract.h"
/*
* Global file list holder
*/
FileEntry *FilesToProcess = NULL;
/*
* File local procedures
*/
void AddFileToProcess(PSTR pch, int type);
FileEntry *AllocNewFile(FileEntry **start_file);
PSTR FindExt(PSTR szPath);
char errMissingFile[] = "Error: No file specified for '-%c' option.\n";
char errIllegalOption[] = "Error: Illegal option flag '-%c'\n";
/*
* @doc EXTRACT
* @api void | ParseArgs | Parse the command line arguments and build
* the linked list of files to process.
*
* @parm int | argc | Number of elements of array <p argv>.
* @parm char ** | argv | Array of strings each giving one word of the
* command line arguments.
*
* @comm Processes the command line, and builds a linked list of
* FileEntry structures specifying the source files to process. This
* list is headed by the global variable FilesToProcess. If no source files
* were specified on the command line, FilesToProcess will be NULL.
*
* Each element of FilesToProcess will contain the name of the source
* file to be processed (buffer allocated using <f StringAlloc>) and the
* source file as can be determined from the file extension or the
* current file type as specified using command line options. This type
* is set into the FileEntry structure for the file.
*
* The global variables fNoOutput and szOutputFile will be set according
* to the output options specified. If no output is desired, fNoOutput
* will be true. If stdout is to be used for output, szOutputFile will
* be NULL. If a file is to be used for output, szOutputFile will
* contain a string filename (allocated using <f StringAlloc>).
*
* Illegal options will cause the parameter usage display to be printed
* and the program exited.
*
*/
void ParseArgs(argc,argv)
int argc;
char **argv;
{
int i,j;
FileEntry *cur_file;
PSTR sz;
/* The file type for this set of files. Defaults to SRC_UNKNOWN */
int wCurFileType = SRC_UNKNOWN;
int wType;
cur_file=NULL;
i = 1;
while( i < argc ) {
/* Decide what to do with this command line argument
*/
switch (*argv[i]) {
/*
* It is a flag
*/
#ifdef MSDOS
case '/' :
#endif
case '-' :
++argv[i];
switch( *argv[i] ) {
/* Setup the no output switch, only check syntax */
case 'n':
case 'N':
fNoOutput = True;
break;
/* Output file option */
case 'o':
case 'O':
++argv[i];
if(*argv[i]==':')
++argv[i];
if(strlen(argv[i])==0) /* we have /l<space><file> */
i++;
if (*argv[i])
szOutputFile = StringAlloc(argv[i]);
else {
fprintf(stderr, errMissingFile, 'o');
Usage(argv[0]);
}
break;
/* Treat following files a MASM source code */
case 'A':
case 'a':
wCurFileType = SRC_MASM;
break;
/* Treat following files as C source code */
case 'c':
case 'C':
wCurFileType = SRC_C;
/* Treat following files as unknown source code */
case 'd':
case 'D':
wCurFileType = SRC_UNKNOWN;
break;
default:
fprintf(stderr, errIllegalOption, *argv[i]);
/* FALL THROUGH */
case '?':
case 'H':
case 'h':
Usage(argv[0]);
exit(1);
} /* switch for case of '-' or '/' */
break;
/*
* This isn't a flag, see type of filename
*/
default:
/* let's look to see what kind of file it is */
wType = wCurFileType;
sz = FindExt(argv[i]);
if (sz) { // has an extension, figure it out
if (!strcmpi(sz, "C"))
wType = SRC_C;
else if (!strcmpi(sz, "ASM"))
wType = SRC_MASM;
}
/* Add this file as chosen file type */
AddFileToProcess(argv[i], wType);
break;
} /* switch */
i++;
} /*while */
}
/*
* @doc EXTRACT
*
* @func void | Usage | Prints usage information to 'stderr'.
*/
void Usage(PSTR progName)
{
fprintf(stderr, "usage: %s [-o outputFile] [-n] [files]\n\n", progName);
fprintf(stderr, "[-a] \t\t\tMASM source file.\n");
fprintf(stderr, "[-n] \t\t\tNo output, error check only.\n");
fprintf(stderr, "[-o outputFile] \tPlaces output in file outputFile,\n");
fprintf(stderr, "\t\t\tOr uses standard output if not specified.\n");
fprintf(stderr, "[files] \t\tList of files to be processed.");
fprintf(stderr, "If none specified,\n\t\t\tuses standard input.\n");
fprintf(stderr, "\nexample: %s file.c >file.doc\n", progName);
}
/*
* @doc EXTRACT
* @api void | AddFileToProcess | Adds filename <p pch> to the list of
* files to be processed.
*
* @parm PSTR | pch | Identifies the filename to be processed.
*
* @parm int | type | Source code type of file.
*
* @comm Adds <p pch> to the linked list of files to be processed that
* is pointed to by global FilesToProcess. This function is used by the
* argument processing module, and should not be called by other
* sections of the program.
*
*/
void AddFileToProcess(PSTR pch, int type)
{
FileEntry *cur_file;
#ifdef FILEDEBUG
dprintf("Adding input file to list: %s", pch);
dprintf(" Type: ");
switch (type) {
case SRC_C:
dprintf("C");
break;
case SRC_MASM:
dprintf("MASM");
break;
case SRC_UNKNOWN:
default:
dprintf("UNKNOWN");
break;
}
dprintf("\n");
#endif
cur_file = AllocNewFile(&FilesToProcess);
cur_file->filename = StringAlloc(pch);
cur_file->type = type;
}
/*
* @doc EXTRACT
* @api FileEntry * | AllocNewFile | Allocates a new file entry
* structure, and appends this structure a the linked list of filenames
* to process.
*
* @parm FileEntry ** | start_file | The address of the pointer to the
* head of the linked list. If NULL, this pointer will be set to the
* newly allocated FileEntry structure.
*
* @rdesc Returns a pointer to the newly allocated FileEntry structure.
* This structure will have been placed into the linked list pointed to
* by <p *start_file>.
*
* @comm This function used by <f ParseArgs> and should not be called
* by other portions of the program.
*
*/
FileEntry *AllocNewFile(FileEntry **start_file)
{
FileEntry * cur_file;
FileEntry * tmp_file;
cur_file=(FileEntry *) NearMalloc(sizeof(FileEntry), True);
if(!*start_file) {
*start_file=cur_file;
}
else {
tmp_file = *start_file;
while(tmp_file->next)
tmp_file = tmp_file->next;
tmp_file->next = cur_file;
}
return(cur_file);
}
/*
* @doc EXTRACT
* @api PSTR | FileExt | Returns a pointer to the head of the file
* extension of pathname <p szPath>.
*
* @parm PSTR | szPath | Path string.
*
* @rdesc Returns pointer to head of file extension within <p szPath>,
* or NULL if no extension exists on szPath.
*
*/
#define SLASH(c) ((c) == '\\' || (c) == '/')
PSTR FindExt(PSTR szPath)
{
PSTR sz;
for (sz=szPath; *sz && *sz!=' '; sz++)
;
for (; sz>=szPath && !SLASH(*sz) && *sz!='.'; sz--)
;
return *sz=='.' ? ++sz : NULL;
}