#include #include #include #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

. * @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 ) 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 ). * * 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 */ 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

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

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

. * * @comm This function used by 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

. * * @parm PSTR | szPath | Path string. * * @rdesc Returns pointer to head of file extension within

, * 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; }