summaryrefslogtreecommitdiffstats
path: root/private/sdktools/masm/asminp.c
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/sdktools/masm/asminp.c
downloadNT4.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/asminp.c')
-rw-r--r--private/sdktools/masm/asminp.c542
1 files changed, 542 insertions, 0 deletions
diff --git a/private/sdktools/masm/asminp.c b/private/sdktools/masm/asminp.c
new file mode 100644
index 000000000..b78670135
--- /dev/null
+++ b/private/sdktools/masm/asminp.c
@@ -0,0 +1,542 @@
+/* asminp.c -- microsoft 80x86 assembler
+**
+** microsoft (r) macro assembler
+** copyright (c) microsoft corp 1986. all rights reserved
+**
+** randy nevin
+**
+** 10/90 - Quick conversion to 32 bit by Jeff Spencer
+*/
+
+#define ASMINP /* prevent external declaration of _asmctype_ */
+
+#include <stdio.h>
+#include <io.h>
+#include <dos.h>
+#include <share.h>
+#include <memory.h>
+#include "asm86.h"
+#include "asmfcn.h"
+#include "asmctype.h"
+#include "asmmsg.h"
+#include "asmfcn.h"
+#include <fcntl.h>
+
+#define DEBFLAG F_INP
+
+#if defined CPDOS && !defined OS2_2 && !defined OS2_NT
+unsigned short _far _pascal DosRead( unsigned short, unsigned char far *, unsigned short, unsigned short far *);
+#endif
+
+
+VOID PASCAL getphysline (void);
+SHORT PASCAL CODESIZE readmore (void);
+SHORT PASCAL CODESIZE incomment( char * );
+
+extern UCHAR _asmctype_[];
+extern char _asmcupper_[];
+extern char _asmTokenMap_[];
+
+
+/*** skipblanks - skip blanks
+ *
+ * skipblanks ()
+ *
+ * Returns - the terminating character
+ */
+
+
+#ifndef M8086OPT
+
+UCHAR CODESIZE
+skipblanks ()
+{
+ while (ISBLANK (NEXTC ()))
+ ;
+ return(*--lbufp);
+}
+
+#endif
+
+
+/*** scanatom - extract next atom into name
+ *
+ * hash = scanatom (pos)
+ *
+ * Entry pos = SCEND if position at first character after token
+ * SCSKIP if position before terminator and not set delim
+ * Exit naim.pszName = next token zero terminated
+ * upper case if caseflag = CASEU or CASEX
+ * case read from file if caseflag = CASEL
+ * naim.pszLowerCase = name in case read from file
+ * naim.usHash = hash value of token in naim.pszName
+ * naim.ucCount = length of string
+ * begatom = pointer to first character of token
+ * endatom = pointer to character after end of token
+ * Returns void
+ * Calls skipblanks
+ */
+
+#ifndef M8086OPT
+
+#define rNEXTC() (*rlbp++)
+#define rPEEKC() (*rlbp)
+#define rBACKC() (rlbp--)
+#define rSKIPC() (rlbp++)
+
+
+SHORT PASCAL CODESIZE
+scanatom (
+ char pos
+){
+ register char *ptr = naim.pszName;
+ register char *lptr = naim.pszLowerCase;
+ register char *rlbp = lbufp;
+ register char cc;
+ register char *n;
+ register SHORT h;
+ long tokLen;
+
+ while (ISBLANK (rNEXTC ()))
+ ;
+ rBACKC ();
+ h = 0;
+ /* Start of atom */
+ begatom = rlbp;
+ if (LEGAL1ST (rPEEKC ())) {
+ n = lptr + SYMMAX;
+ cc = rNEXTC ();
+ if( cc == '.' ){ /* Special case token starting with dot */
+ h = *ptr++ = *lptr++ = cc;
+ cc = rNEXTC ();
+ }
+ if (caseflag == CASEL)
+
+ do {
+ h += MAP(*ptr++ = *lptr++ = cc);
+ } while (TOKLEGAL( cc = rNEXTC() ) && lptr < n);
+ else
+ do {
+ h += (*ptr++ = MAP( *lptr++ = cc ));
+ } while (TOKLEGAL( cc = rNEXTC() ) && lptr < n);
+
+ if (TOKLEGAL (cc))
+ /* Atom longer than table entry, discard remaining chars */
+ while (TOKLEGAL (cc = rNEXTC ()))
+ ;
+ rBACKC ();
+ endatom = rlbp;
+ if (ISBLANK (cc) && pos != SCEND) { /* skipblanks() */
+ while (ISBLANK (rNEXTC ()))
+ ;
+ rBACKC ();
+ }
+ }
+ *ptr = *lptr = '\0';
+ naim.ucCount = lptr - naim.pszLowerCase;
+ naim.usHash = h;
+ lbufp = rlbp;
+ tokLen = lptr - naim.pszLowerCase; /* Using tokLen gets around a C386 6.00.60 bug */
+ return( (SHORT) tokLen ); /* Return length of token */
+}
+
+#endif /* M8086OPT */
+
+
+
+
+/*** readfile - read from input or include file
+ *
+ * ptr = readfile ();
+ *
+ * Entry none
+ * Exit lbuf = next input line
+ * lbufp = start of lbuf
+ * line counter for file incremented
+ * linessrc incremented
+ * Returns pointer to end of line
+ * Calls error
+ */
+
+
+VOID PASCAL CODESIZE
+readfile ()
+{
+ register FCB * pFCBT;
+
+ getline();
+
+ pFCBCur->line++;
+
+ if (srceof) {
+
+ if (!pFCBCur->pFCBParent) {
+ errorc (E_EOF);
+ fprintf (ERRFILE,__NMSG_TEXT(ER_EO2));
+
+ if (fSimpleSeg && pcsegment)
+ endCurSeg();
+
+ longjmp(forceContext, 1);
+
+ } else {
+
+ popcontext = TRUE;
+
+ closefile();
+
+ if (crefing && pass2)
+ fprintf( crf.fil, "\8%s", pFCBCur->fname );
+ }
+ srceof = 0;
+ }
+ else
+ linessrc++;
+}
+
+
+
+
+/*** getline - read from input or include file
+ *
+ * getline()
+ *
+ * Returns in lbuf the next complete logical line. A logical line
+ * may consist of one or more lines connected via the \ continuation
+ * character. This is done as follows. Data is copied from
+ * pFCBCur->tmpbuf. If necessary more data is copied into the
+ * buffer via readmore(). After an entire physical line is read
+ * it is tested as to whether the line is continued on the next
+ * physical line. If not the line is returned in lbuf. Otherwise
+ * the physical line is copied to linebuffer and a call to listline
+ * is made. At which point another physical line is cancatenated
+ * to the line or lines already in lbuf.
+ *
+ * Entry pFCBCur = File currently reading from.
+ * pFCBCur->ctmpbuf = Number of bytes available in buffer
+ * 0 = necessary to read data from disk.
+ * pFCBCur->ptmpbuf = Next position in buffer to copy from.
+ * pFCBCur->line = Number of physical line in file
+ *
+ * Exit - lbuf[] holds a complete logical line, with a space appended.
+ * - linebuffer[] holds last physical line.
+ * - lbufp points to the beginning of lbuf.
+ * - linebp points to null terminator at the end
+ * of the logical line in lbuf.
+ * - linelength is number of bytes of last physical line.
+ * - pFCBCur->ctmpbuf & ptmpbuf & line are updated.
+ * - srceof is true if the end of file was encountered, in
+ * which case the physical line is a null string, and
+ * the logical line is a single space character.
+ */
+
+VOID CODESIZE
+getline()
+{
+ char FAR *p;
+ register char *pchTmp;
+ char *pchPhysLine;
+ INT fFoundEOL; /* True, if endof line copied */
+ register INT count;
+ INT fLineContinued;
+ INT fGotSome;
+
+ lbufp = lbuf; /* Init lbufp for other routines */
+ pchPhysLine = lbuf;
+ fGotSome = FALSE; // nothing seen yet
+ errorlineno = pFCBCur->line + 1;
+ pchTmp = lbuf; // Where to copy the line
+
+ //if( pFCBMain->line == 126-1 ){
+ // _asm int 3
+ //}
+
+ do{
+
+ fFoundEOL = FALSE;
+ do{
+
+ /* If the buffer is empty fill it */
+ if( !pFCBCur->ctmpbuf ){
+ if( readmore() ){ // TRUE if at EOF
+ if( !fGotSome ){
+ srceof = TRUE;
+ linebuffer[0] = '\0';
+ linelength = 0;
+ linebp = lbuf;
+ lbuf[0] = '\0';
+ return;
+ }else{
+ pchTmp++; /* Negate pchTmp-- following this loop */
+ break; /* Break fFoundEOL loop */
+ }
+ }
+ }
+ fGotSome = TRUE;
+
+ /* Find next LF in buffer */
+ p = _fmemchr( pFCBCur->ptmpbuf, '\n', pFCBCur->ctmpbuf );
+ if( p ){ /* If LF was found */
+ count = (p - pFCBCur->ptmpbuf) + 1;
+ fFoundEOL = TRUE;
+ }else{
+ count = pFCBCur->ctmpbuf;
+ }
+
+ /* Check if physical or logical line too long */
+ if( (pchTmp - lbuf) + count >= LBUFMAX ||
+ (pchTmp - pchPhysLine) + count >= LINEMAX-4 ){
+
+ /* Update the position in the buffer */
+ pFCBCur->ptmpbuf += count; // Update where copying from
+ pFCBCur->ctmpbuf -= count;
+
+ errorc( E_LNL ); /* Log the error */
+
+ /* Return a null string line */
+ linebuffer[0] = '\0';
+ linelength = 0;
+ linebp = lbuf;
+ lbuf[0] = ' ';
+ lbuf[1] = '\0';
+ return;
+ }else{
+ /* Copy the line, and update pointers */
+ fMemcpy( pchTmp, pFCBCur->ptmpbuf, count );
+ pchTmp += count; // Update where copying to
+ pFCBCur->ctmpbuf -= count; // Update # bytes left in buffer
+ pFCBCur->ptmpbuf += count; // Update where copying from
+ }
+
+ }while( !fFoundEOL );
+
+ pchTmp--; /* Move back to last character (LF) */
+
+
+/* Strip Carriage Returns that precede LFs */
+ if( *(pchTmp-1) == '\r' ){
+ pchTmp--; /* Throw out Carriage return */
+ }
+
+#ifdef MSDOS
+ /* Strip Multiple Control-Zs */
+ while( *(pchTmp - 1) == 0x1A ){ /* Check for ^Z */
+ pchTmp--;
+ }
+#endif
+ if( pchTmp < lbuf ){ /* Remotely possible if Blank line */
+ pchTmp = lbuf;
+ }
+
+ linelength = pchTmp - pchPhysLine;
+ if( !pass2 || listconsole || lsting ){
+ memcpy( linebuffer, pchPhysLine, linelength );
+ }
+ *( linebuffer + linelength ) = '\0'; //Null terminate the physical line
+
+ if( *(pchTmp - 1) == '\\' && !incomment( pchTmp ) ){
+ pchPhysLine = --pchTmp; /* Overwrite the '\' */
+ fCrefline = FALSE;
+ listline();
+ fCrefline = TRUE;
+ pFCBCur->line++; /* Line count it physical line count */
+ fLineContinued = TRUE;
+ }else{
+ fLineContinued = FALSE;
+ }
+ }while( fLineContinued );
+ *pchTmp++ = ' '; /* Replace line feed with space */
+ *pchTmp = '\0'; /* Null terminate line */
+ linebp = pchTmp;
+ if( lbuf[0] == 12 ){ /* Overwrite leading ctrl-L with space */
+ lbuf[0] = ' ';
+ }
+ /* At this point linebp - lbuf == strlen( lbuf ) */
+}
+
+/*** readmore - read from disk into buffer
+ *
+ *
+ *
+ * Entry pFCBCur = File currently reading from.
+ * pFCBCur->cbbuf = Size of buffer to read into.
+ * pFCBCur->buf = Address of buffer to read into.
+ * pFCBCur->fh = File handle to read from.
+ *
+ * Exit return = TRUE: Not at end of file
+ * pFCBCur->ptmpbuf = First byte of buffer.
+ * pFCBCur->ctmpbuf = Number of bytes in buffer.
+ * return = FALSE: At end of file
+ * No other variables changed.
+ */
+
+SHORT PASCAL CODESIZE
+readmore ()
+{
+ SHORT cb;
+ SHORT fEOF = FALSE;
+
+ /* If the file has been temporarily closed reopen it */
+ if( pFCBCur->fh == FH_CLOSED ){
+ if( (pFCBCur->fh = tryOneFile( pFCBCur->fname )) == -1 ){ /* Open the file */
+ TERMINATE1(ER_ULI, EX_UINP, save); /* Report unable to access file */
+ }
+ /* Seek to old position */
+ if( _lseek( pFCBCur->fh, pFCBCur->savefilepos, SEEK_SET ) == -1L ){
+ TERMINATE1(ER_ULI, EX_UINP, save); /* Report unable to access file */
+ }
+ }
+
+#if !defined CPDOS || defined OS2_2 || defined OS2_NT
+ cb = _read( pFCBCur->fh, pFCBCur->buf, pFCBCur->cbbuf );
+#else
+ if( DosRead( pFCBCur->fh, pFCBCur->buf, pFCBCur->cbbuf, &cb ) ){
+ cb = -1;
+ }
+#endif
+ if( cb == 0 ){
+ fEOF = TRUE; /* End of file found */
+ }else if( cb == (SHORT)-1 ){
+ TERMINATE1(ER_ULI, EX_UINP, save); /* Report unable to access file error */
+ }else{
+ /* Setup the buffer pointers */
+ pFCBCur->ptmpbuf = pFCBCur->buf; /* Init ptr to start of buffer */
+ pFCBCur->ctmpbuf = cb;
+ }
+ return( fEOF );
+}
+
+
+
+
+/*** incomment - Checks a line ending in \ to determine if the \ is in a
+ * comment and is therefore not a comment line.
+ *
+ * Entry Assumes lbuf contains partial logical line ending in a \.
+ * pchEnd - points within lbuf to the terminating LF.
+ * Methode Checks that line is not in a COMMENT directive's scope.
+ * Then checks if the line contains a semicolon. If not, \
+ * IS continuation. If a semicolon is found, line must be
+ * scanned carefully to determine if the semicolon is a
+ * comment delimeter or is in a string or is a character
+ * constant If it is not a comment delimeter, \ IS continuation.
+ * Otherwise, \ is part of comment, and is NOT a continuation.
+ * Exit Returns true if the \ is in a comment
+ * Returns false if the \ is not in a comment, and is therefore
+ * a continuation character.
+ *
+ * Calls memchr
+ *
+ * Created: 9/90 - Jeff Spencer, translated from asm code in asmhelp.asm
+ */
+
+SHORT PASCAL CODESIZE
+incomment(
+ char * pchTmp /* Points to terminating LF in lbuf */
+){
+ SHORT fContSearch;
+ unsigned char * pchSearch;
+ unsigned char * pchSemi;
+ unsigned char chClose;
+ static unsigned char szComment[] = "COMMENT";
+
+
+
+ pchTmp--; /* Point to '\' character */
+ if( handler == HCOMMENT ){ /* If within comment directive */
+ return( TRUE );
+ }
+
+ fContSearch = TRUE;
+ pchSearch = lbuf;
+
+ do{
+ if( pchSemi = memchr( pchSearch, ';', pchTmp - pchSearch )){ /* Check for a semicolon */
+ do{
+ chClose = '\0';
+ switch( *pchSearch++ ){
+ case ';':
+ /* Semicolon is not in quotes, return in comment */
+ return( TRUE );
+ case '\"':
+ chClose = '\"';
+ break;
+ case '\'':
+ chClose = '\'';
+ break;
+ case '<':
+ chClose = '>';
+ break;
+ }
+ /* Below the word quote is used to mean the chClose character */
+ if( chClose ){
+ if( !(pchSearch = memchr( pchSearch, chClose, pchTmp - pchSearch ) ) ){
+ fContSearch = FALSE; /* No matching quote, not a comment */
+ }else{
+ if( pchSearch < pchSemi){
+ /* Semicolon is in quotes */
+ pchSearch++; /* Move past quote just found
+ break; // Look for another semicolon */
+ }else{
+ /* Semicolon is past this set of quotes */
+ /* Continue, Scanning */
+ }
+ }
+ }
+ }while( fContSearch && pchSearch < pchTmp );
+ }else{
+ /* No Semicolon in the line, or it's in quotes */
+ fContSearch = FALSE;
+ }
+ }while( fContSearch );
+
+ /* At this point we know that the \ is not in a semicolon **
+ ** delimited comment. However, we still have to make sure **
+ ** that the comment keyword doesn't appear at the begining **
+ ** of the line. */
+
+ /* Skip leading white space */
+ pchSearch = lbuf;
+ while( *pchSearch == ' ' || *pchSearch == '\t' ){
+ pchSearch++;
+ }
+ for( pchTmp = szComment; *pchTmp; ){
+ if( *pchSearch++ != _asmTokenMap_[*pchTmp++] ){
+ return( FALSE ); /* First word isn't "comment" */
+ }
+ }
+ return( TRUE ); /* comment keyword at start of line, return in comment */
+}
+
+/**** closeFile
+ *
+ * closeFile ()
+ *
+ * Entry Assumes valid pFCBCur->fh or FH_CLOSED
+ * Returns
+ * Calls close()
+ * Note Closes current file - i.e. pFCBCur
+ * and marks all fields in pFCBCur appropriately
+ */
+
+closefile()
+{
+ register FCB *pFCBOld;
+
+ #ifdef BCBOPT
+ BCB * pBCBT;
+
+ if ((pBCBT = pFCBCur->pBCBCur) && pBCBT->pbuf)
+ pBCBT->filepos = 0; /* EOF */
+ #endif
+
+ if( pFCBCur->fh != FH_CLOSED ){ /* Check to see if the file is already closed */
+ _close(pFCBCur->fh);
+ }
+ pFCBOld = pFCBCur;
+ pFCBCur = pFCBCur->pFCBParent; /* Remove from bidirectional linked list */
+ pFCBCur->pFCBChild = NULL;
+
+ _ffree( pFCBOld->buf); /* Free FCB buffer */
+ _ffree( (UCHAR *)pFCBOld ); /* Free FCB */
+}