diff options
author | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
---|---|---|
committer | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
commit | e611b132f9b8abe35b362e5870b74bce94a1e58e (patch) | |
tree | a5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/sdktools/masm/ui.c | |
download | NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2 NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip |
Diffstat (limited to 'private/sdktools/masm/ui.c')
-rw-r--r-- | private/sdktools/masm/ui.c | 924 |
1 files changed, 924 insertions, 0 deletions
diff --git a/private/sdktools/masm/ui.c b/private/sdktools/masm/ui.c new file mode 100644 index 000000000..2fe116eb2 --- /dev/null +++ b/private/sdktools/masm/ui.c @@ -0,0 +1,924 @@ +/* dos prompting-style user interface +** +** currently supports interfaces for: +** masm, cref +** +** written by: +** randy nevin, microsoft, 5/15/85 +** +** 10/90 - Quick conversion to 32 bit by Jeff Spencer +** +** (c)copyright microsoft corp 1985 +*/ + +#include <stdio.h> +#include <ctype.h> +#include <string.h> + +#if defined OS2_2 || defined OS2_NT /* OS2 2.0 or NT? */ +/* Use common MSDOS code also */ +# define MSDOS +# define FLATMODEL +# define FAR +# define PASCAL +#else +# define FAR far +# define PASCAL pascal +#endif + +#ifdef MSDOS +# include <dos.h> +#endif + +#ifdef MASM +# include "asmmsg.h" +#else +# include "crefmsg.h" +#endif + +#define GLOBAL /* C functions and external vars global by default */ +#define LOCAL static +#define EXTERNAL extern + +#define MASTER 0 /* file name must be present, and is inherited */ +#define INHERIT 1 /* if no file name, inherit from Master */ +#define NUL 2 /* file name is NUL.ext if not given */ +#define NULL 0 + +#define SLASHORDASH 0 +#define SLASHONLY 1 +#define DASHONLY 2 + +#define TOLOWER(c) (c | 0x20) /* works only for alpha inputs */ + +#ifdef MSDOS +# define SEPARATOR '\\' +# define ALTSEPARATOR '/' +# if !defined CPDOS && !defined OS2_2 && !defined OS2_NT +# define ARGMAX 128 /* maximum length of all arguments */ +# else +# define ARGMAX 512 /* maximum length of all arguments */ +# endif + LOCAL char Nul[] = "NUL"; + extern char *getenv(); +# ifdef MASM + LOCAL unsigned char switchar = SLASHORDASH; + EXTERNAL errorcode; +# else + LOCAL unsigned char switchar = SLASHONLY; +# endif +# define ERRFILE stdout +#else +# define SEPARATOR '/' +# define ARGMAX 5120 /* maximum length of all arguments */ + LOCAL char Nul[] = "nul"; + LOCAL unsigned char switchar = DASHONLY; +# define ERRFILE stderr +#endif + +#if defined MSDOS && !defined FLATMODEL + extern char near * pascal __NMSG_TEXT(); + extern char FAR * pascal __FMSG_TEXT(); +#endif +#if defined MSDOS && defined FLATMODEL + /* For FLATMODEL map message functions to the replacements */ + #define __NMSG_TEXT NMsgText + #define __FMSG_TEXT FMsgText + extern char * NMsgText(); + extern char * FMsgText(); +#endif + +#ifdef MASM +# define FILES 4 /* number to prompt for */ +# define EX_HEAP 8 /* exit code if heap fails */ +#define EX_DSYM 10 /* error defining symbol from command line */ +#define PX87 1 + +#define CVLINE 1 +#define CVSYMBOLS 2 + +#define TERMINATE(message, exitCode)\ + terminate((exitCode << 12) | message) + +#define TERMINATE1(message, exitCode, a1)\ + terminate((exitCode << 12) | message, a1) + +# ifdef MSDOS + LOCAL char *Prompt[FILES] = { + "Source filename [", + "Object filename [", + "Source listing [", + "Cross-reference [" + }; +# endif + + LOCAL char *Ext[FILES] = { /* default extensions */ +# ifdef MSDOS + ".ASM", + ".OBJ", + ".LST", + ".CRF" +# else + ".asm", + ".obj", + ".lst", + ".crf" +# endif + }; + + LOCAL unsigned char Default[FILES] = { /* default root file name */ + MASTER, + INHERIT, + NUL, + NUL + }; +#endif + +#ifdef CREF +# define FILES 2 /* number to prompt for */ +# define EX_HEAP 1 /* exit code if heap fails */ + +# ifdef MSDOS + LOCAL char *Prompt[FILES] = { + "Cross-reference [", + "Listing [" + }; +# endif + + LOCAL char *Ext[FILES] = { /* default extensions */ +# ifdef MSDOS + ".CRF", + ".REF" +# else + ".crf", + ".ref" +# endif + }; + + LOCAL unsigned char Default[FILES] = { /* default root file name */ + MASTER, + INHERIT + }; +#endif + +GLOBAL char *file[FILES]; /* results show up here; caller knows how many */ + +LOCAL char *Buffer; +LOCAL char *Master = NULL; +LOCAL unsigned char Nfile = 0; /* file[Nfile] is the next one to set */ +LOCAL unsigned char FirstLine = 1; /* defaults are different for first line */ + +extern unsigned short warnlevel; /* warning level */ +extern unsigned short codeview; /* codeview obj level */ +extern char loption; /* listing options */ +extern char crefopt; /* cross reference options */ + +#ifdef MSDOS +# if defined OS2_2 || defined OS2_NT + /* OS2 2.0 command line variables will go here */ +# else +# if defined CPDOS + /* OS2 1.X variables */ + EXTERNAL unsigned _aenvseg; + EXTERNAL unsigned _acmdln; +# else + /* DOS variables */ + EXTERNAL unsigned _psp; /* segment addr of program segment prefix */ +# endif +# endif +#endif + +#ifdef MASM + LOCAL unsigned char lflag = 0; + LOCAL unsigned char cflag = 0; + EXTERNAL char terse; + EXTERNAL unsigned short errornum; + EXTERNAL char lbuf[256 + 512 + 1]; + void PASCAL error_line (struct _iobuf *, unsigned char *, short); +#else + char lbuf[512]; +#endif + +#ifndef MSDOS + EXTERNAL char *gets(); +#endif + +EXTERNAL char *malloc(); +EXTERNAL char *strcat(), *strcpy(), *_strdup(), *strchr(), *strrchr(); + +LOCAL int DoArgs(); /* defined below */ +LOCAL int DoName(); /* defined below */ +LOCAL int DoNull(); /* defined below */ +LOCAL char *DoSwitch(); /* defined below */ +LOCAL HeapError(); /* defined below */ + +#ifdef MSDOS + LOCAL DoPrompt(); /* defined below */ + LOCAL TryAgain(); /* defined below */ +#endif + + + +GLOBAL void +UserInterface ( + /* get file names & switches from args and subsequent prompts */ + int argc, + char **argv, + char *banner +){ + register char *p; + register unsigned length; +#if defined MSDOS && !defined OS2_2 && !defined OS2_NT + char FAR *q; +#else + unsigned count; +#endif + + Buffer = lbuf; + +#ifdef MASM +# ifdef MSDOS + if ((p = getenv("MASM"))) { /* do initialization vars first */ + strcpy( Buffer, p ); /* fetch them into the buffer */ + DoArgs(); /* process them */ + } +# endif +#endif + + p = Buffer; + +#if defined MSDOS && !defined OS2_2 && !defined OS2_NT +#if defined CPDOS + /* this is how we get the command line if we're on CPDOS */ + + FP_SEG( q ) = _aenvseg; + FP_OFF( q ) = _acmdln; + + while(*q++) ; /* skip argv[0] */ + + while (isspace( *q )) /* skip blanks between argv[0] and argv[1] */ + q++; + + length = sizeof(lbuf) - 1; + while (length-- && (*p++ = *q++)) /* copy command line arguments */ + ; +# else + /* this is how we get the command line if we're on MSDOS */ + FP_SEG( q ) = _psp; + FP_OFF( q ) = 0x80; + length = *q++ & 0xFF; + + while (length--) + *p++ = *q++; + + *p = '\0'; +# endif +#else + /* this is how we get the command line if we're on XENIX or OS2 2.0 */ + argv++; + count = ARGMAX - 1; + + while (--argc) { /* concatenate args */ + if ((length = strlen( *argv )) > count) /* don't overflow */ + length = count; + + strncpy( p, *argv++, length ); + p += length; + + if ((count -= length) && *argv) { /* separator */ + *p++ = ' '; + count--; + } + } + +# if !defined OS2_2 && !defined OS2_NT + *p++ = ';'; +# endif + *p = '\0'; +#endif + +#ifdef CREF + printf( "%s", banner ); +#endif + + DoArgs(); + +#ifdef MASM + if (!terse) + printf( "%s", banner ); +#endif + +#ifdef MSDOS + FirstLine = 0; + + while (Nfile < FILES) + DoPrompt(); +#endif + + if (Master && Master != Nul) + free( Master ); + } + + +LOCAL int +DoArgs () + /* process concatenated args looking for file names and switches */ + { + register char *p; + register char *q; + char *filename = NULL; + + for (p = Buffer; *p; p++) +#ifdef MSDOS + if (*p == '/' + && (switchar == SLASHONLY || switchar == SLASHORDASH) + || *p == '-' + && (switchar == DASHONLY || switchar == SLASHORDASH)) +#else + if (*p == '-') +#endif + { /* application dependent switch */ +#ifdef MSDOS + if (switchar == SLASHORDASH) + switchar = *p == '/' ? SLASHONLY : DASHONLY; +#endif + p = DoSwitch( p ); + } + else if (*p == ';') { /* use defaults for everything else */ + if (DoName( filename )) { /* possibly NULL */ +#ifdef MSDOS + TryAgain(); + return( 1 ); +#else +# ifdef MASM + printf( __NMSG_TEXT(ER_EXS) ); +# else + printf( __NMSG_TEXT(ER_EXC) ); +# endif + exit( 1 ); +#endif + } + + FirstLine = 0; /* ...and away we go! */ + + while (Nfile < FILES) + if (DoNull()) { +#ifdef MSDOS + TryAgain(); + return( 1 ); +#else +# ifdef MASM + printf( __NMSG_TEXT(ER_EXS) ); +# else + printf( __NMSG_TEXT(ER_EXC) ); +# endif + exit( 1 ); +#endif + } + + return( 0 ); + } + else if (*p == ',') { /* file name separator */ + if (DoName( filename )) { /* possibly NULL */ +#ifdef MSDOS + TryAgain(); + return( 1 ); +#else +# ifdef MASM + printf( __NMSG_TEXT(ER_EXS) ); +# else + printf( __NMSG_TEXT(ER_EXC) ); +# endif + exit( 1 ); +#endif + } + + filename = NULL; + } + else if (!isspace( *p )) { /* gather filename */ + q = p + 1; + + while (*q && *q != ';' && *q != ',' && !isspace( *q )) { +#ifdef MSDOS + if (*q == '/') + if (switchar == SLASHONLY) + break; + else if (switchar == SLASHORDASH) { + switchar = SLASHONLY; + break; + } +#endif + q++; + } + + if (filename) { /* already have one */ + if (DoName( filename )) { +#ifdef MSDOS + TryAgain(); + return( 1 ); +#else +# ifdef MASM + printf( __NMSG_TEXT(ER_EXS) ); +# else + printf( __NMSG_TEXT(ER_EXC) ); +# endif + exit( 1 ); +#endif + } + } + + if (!(filename = malloc( q - p + 1 ))) + HeapError(); + else { /* remember file name */ + strncpy( filename, p, q - p ); + filename[q - p] = '\0'; + } + + p = q - 1; /* go to end of file name */ + } + + if (filename && DoName( filename )) { +#ifdef MSDOS + TryAgain(); + return( 1 ); +#else +# ifdef MASM + printf( __NMSG_TEXT(ER_EXS) ); +# else + printf( __NMSG_TEXT(ER_EXC) ); +# endif + exit( 1 ); +#endif + } + + return( 0 ); + } + + +LOCAL int +DoName ( filename ) + /* enter filename as next file name, if appropriate (possibly NULL) */ + char *filename; + { + register char *p; + register char *q; + int cb; + + if (Nfile >= FILES) { /* too many file names */ + if (filename) { + fprintf(ERRFILE,__NMSG_TEXT(ER_EXT) ); + free( filename ); + } + + return( 0 ); + } + + if (!filename) /* try (MASTER)/INHERIT/NUL */ + return( DoNull() ); + + if (p = strrchr( filename, SEPARATOR )) + p++; +#ifdef MSDOS + else if ((p = strrchr( filename, ':' )) && /* look for drive specifier */ + p[1] != NULL ) + + p++; +#endif + else + p = filename; + +#ifdef MSDOS + if (q = strrchr( p, ALTSEPARATOR )) + p = q + 1; +#endif + + /* p points to first char of filename past last '\' or ':', if any */ + + if (!*p) /* last char of filename is '\' or ':'; assume directory */ + switch (Default[Nfile]) { + case MASTER: +#ifdef MSDOS + fprintf(ERRFILE,__NMSG_TEXT(ER_INV) ); +#endif + free( filename ); + return( 1 ); + break; + default: + /* case NUL: */ +#ifdef MSDOS + if (!FirstLine) { + if (!(p = malloc( strlen( filename ) + + strlen( Nul ) + + strlen( Ext[Nfile] ) + 1 ))) + HeapError(); + + strcat( strcat( strcpy( p, filename ), Nul ), Ext[Nfile] ); + break; + } + /* else just treat as inherited from Master */ +#endif + case INHERIT: + if (!Master) + Master = Nul; + + if (!(p = malloc( strlen( filename ) + + strlen( Master ) + + strlen( Ext[Nfile] ) + 1 ))) + HeapError(); + + strcat( strcat( strcpy( p, filename ), Master ), Ext[Nfile] ); + break; + } + else { /* some sort of file name is present */ + if (Default[Nfile] == MASTER) /* save Master file name */ + if (q = strchr( p, '.' )) { + if (!(Master = malloc( q - p + 1 ))) + HeapError(); + + strncpy( Master, p, q - p ); + Master[q - p] = '\0'; + } + else if (!(Master = _strdup( p ))) + HeapError(); + + if (strchr( p, '.' )) { /* extension present */ + if (!(p = _strdup( filename ))) + HeapError(); + } + else { /* supply default extension */ + cb = 0; + + if (p[1] == ':' && p[2] == NULL) + cb = strlen(Master); + + if (!(p = malloc( strlen( filename ) + + strlen( Ext[Nfile] ) + 1 + cb ) )) + HeapError(); + + strcat(strcat(strcpy( p, + filename ), + (cb)? Master: ""), + Ext[Nfile] ); + } + } + + file[Nfile++] = p; + free( filename ); + return( 0 ); + } + + +LOCAL int +DoNull () + /* select the default name (depends on if FirstLine or not) */ + { + char *p; + + switch (Default[Nfile]) { + case MASTER: +#ifdef MSDOS + fprintf(ERRFILE,__NMSG_TEXT(ER_INV) ); +#endif + return( 1 ); + break; + default: + /* case NUL: */ + if (!FirstLine +#ifdef MASM + && !(lflag && Nfile == 2) + && !(cflag && Nfile == 3) +#endif + ) { + if (!(p = malloc( strlen( Nul ) + 1 + + strlen( Ext[Nfile] ) ))) + HeapError(); + + strcat( strcpy( p, Nul ), Ext[Nfile] ); + break; + } + /* else just treat as inherited from Master */ + case INHERIT: + if (!Master) + Master = Nul; + + if (!(p = malloc( strlen( Master ) + 1 + + strlen( Ext[Nfile] ) ))) + HeapError(); + + strcat( strcpy( p, Master ), Ext[Nfile] ); + break; + } + + file[Nfile++] = p; + return( 0 ); + } + + +#ifdef MASM +# define FALSE 0 +# define TRUE 1 + +#ifdef MSDOS +# define DEF_OBJBUFSIZ 8 +#endif + +# define CASEU 0 +# define CASEL 1 +# define CASEX 2 + +# define INCLUDEMAX 10 +# define EX_ARGE 1 + +# ifdef MSDOS + EXTERNAL unsigned short obufsiz; +# endif + + EXTERNAL char segalpha; + EXTERNAL char debug; + EXTERNAL char fltemulate; + EXTERNAL char X87type; + EXTERNAL char inclcnt; + EXTERNAL char *inclpath[]; + EXTERNAL char caseflag; + EXTERNAL char dumpsymbols; + EXTERNAL char verbose; + EXTERNAL char origcond; + EXTERNAL char listconsole; + EXTERNAL char checkpure; + +int PASCAL definesym(); + + /* process masm switches */ + +LOCAL char * DoSwitch ( p ) +register char *p; +{ + char *q; + char *r; + char c; + int i; + + switch (TOLOWER(*++p)) { + case 'a': + segalpha = TRUE; + break; +# ifdef MSDOS + case 'b': + for(p++; isdigit(p[1]); p++); + + break; +# endif + case 'c': + cflag = TRUE; + if (isalpha (p[1])) { + if (TOLOWER(*++p) == 's') + crefopt++; + else { + TERMINATE1(ER_UNS, EX_ARGE, *p ); + return; + } + } + break; + + case 'd': + if (!*++p || isspace( *p ) || *p == ',' || *p == ';') { + debug = TRUE; + p--; + } + else { + for (q = p + 1; *q && !isspace( *q ) + && *q != '=' && *q != ',' + && *q != ';'; q++) + ; + + if (*q == '=') { + q++; + while (*q && !isspace( *q ) + && *q != ',' && *q != ';') + q++; + } + + c = *q; + *q = '\0'; + definesym( p ); + + if (errorcode){ + error_line (ERRFILE, "command line", 0); + + if (errornum) + exit (EX_DSYM); + } + *q = c; + p = q - 1; + } + + break; + + case 'e': + fltemulate = TRUE; + X87type = PX87; + break; + case 'h': +#ifdef FLATMODEL + printf("%s\n", __FMSG_TEXT(ER_HDUSE)); +#else + printf("%Fs\n", __FMSG_TEXT(ER_HDUSE)); +#endif + for (i = ER_H01; i <= ER_H18; i++) +#ifdef FLATMODEL + printf( "\n/%s", __FMSG_TEXT(i)); +#else + printf( "\n/%Fs", __FMSG_TEXT(i)); +#endif + + exit( 0 ); /* let him start again */ + break; + case 'i': + for (q = ++p; *q && + !isspace( *q ) && *q != ',' && *q != ';' && + *q != (switchar == DASHONLY? '-': '/'); q++) + ; + + if (q == p) + TERMINATE(ER_PAT, EX_ARGE ); + + if (inclcnt < INCLUDEMAX - 1) { + if (!(r = malloc( q - p + 1 ))) + HeapError(); + + strncpy( r, p, q - p ); + r[q - p] = '\0'; + inclpath[inclcnt++] = r; + } + + p = q - 1; + break; + case 'l': + lflag = TRUE; + if (isalpha (p[1])) { + if (TOLOWER(*++p) == 'a') + loption++; + else { + TERMINATE1(ER_UNS, EX_ARGE, *p ); + return; + } + } + break; + case 'm': + switch (TOLOWER(*++p)) { + case 'l': + caseflag = CASEL; + break; + case 'u': + caseflag = CASEU; + break; + case 'x': + caseflag = CASEX; + break; + default: + TERMINATE1(ER_UNC, EX_ARGE, *p ); + return; + } + + break; + case 'n': + dumpsymbols = FALSE; + break; + case 'p': + checkpure = TRUE; + break; + case 'r': /* old switch ignored */ + break; + case 's': + segalpha = FALSE; + break; + case 't': + terse = TRUE; + verbose = FALSE; + break; + case 'v': + verbose = TRUE; + terse = FALSE; + break; + + case 'w': + if (! isdigit(p[1]) || + (warnlevel = atoi(&p[1])) > 2){ + + TERMINATE(ER_WAN, EX_ARGE ); + return; + } + + for(p++; isdigit(p[1]); p++); + break; + + case 'x': + origcond = TRUE; + break; + case 'z': /* Zd or Zi apply to codeview */ + + if (TOLOWER(p[1]) == 'd'){ + codeview = CVLINE; + p++; + break; + } + else if (TOLOWER(p[1]) == 'i'){ + codeview = CVSYMBOLS; + p++; + break; + } + + /* else its just a Z */ + + listconsole = TRUE; + break; + default: + TERMINATE1(ER_UNS, EX_ARGE, *p ); + return; + } + + return( p ); + } +#endif + +#ifdef CREF + LOCAL char * + DoSwitch ( /* p */ ) + /* process cref switches (presently, none) */ + /* char *p; */ + { + fprintf( stderr, "cref has no switches\n" ); + exit( 1 ); + } +#endif + + +#ifdef MSDOS +LOCAL +DoPrompt () + /* prompt user for a file name (any number of optional switches) */ + { + unsigned char oldNfile; + + fprintf(stderr, Prompt[Nfile] ); + + switch (Default[Nfile]) { + case MASTER: + break; + case INHERIT: + fprintf(stderr, Master ); + break; + default: + /* case NUL: */ + fprintf(stderr, Nul ); + break; + } + + fprintf(stderr, "%s]: ", Ext[Nfile] ); + + if (!gets( Buffer )) { + fprintf(ERRFILE,__NMSG_TEXT(ER_SIN) ); + +# ifdef MASM + exit( EX_ARGE ); +# else + exit( 1 ); +# endif + } + + oldNfile = Nfile; + + if (!DoArgs() && oldNfile == Nfile && DoNull()) + TryAgain(); + } +#endif + + +LOCAL +HeapError () + /* malloc() has failed; exit program */ + { +#ifdef CREF + + fprintf(ERRFILE,__NMSG_TEXT(ER_HEP)); + exit(EX_HEAP); +#else + TERMINATE(ER_HEP, EX_HEAP); +#endif + } + + +#ifdef MSDOS +LOCAL +TryAgain () + /* user caused fatal error; start reprompting from beginning */ + { + if (Master && Master != Nul) { + free( Master ); + Master = NULL; + } + + while (Nfile) + free( file[--Nfile] ); + } +#endif |