283 lines
6.9 KiB
C
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;
|
||
|
}
|