831 lines
14 KiB
C
831 lines
14 KiB
C
|
/* asmrec.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
|
||
|
*/
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <string.h>
|
||
|
#include "asm86.h"
|
||
|
#include "asmfcn.h"
|
||
|
#include "asmctype.h"
|
||
|
|
||
|
|
||
|
struct recpars {
|
||
|
SYMBOL FARSYM *recptr;
|
||
|
SYMBOL FARSYM *curfld;
|
||
|
OFFSET recval;
|
||
|
};
|
||
|
|
||
|
struct recdef {
|
||
|
USHORT fldcnt;
|
||
|
USHORT reclen;
|
||
|
SYMBOL FARSYM *recptr;
|
||
|
SYMBOL FARSYM *curfld;
|
||
|
short i;
|
||
|
};
|
||
|
|
||
|
VOID PASCAL CODESIZE recordspec PARMS((struct recdef *));
|
||
|
VOID PASCAL CODESIZE recfill PARMS((struct recpars *));
|
||
|
|
||
|
|
||
|
static OFFSET svpc = 0;
|
||
|
static struct duprec FARSYM *pDUPCur;
|
||
|
|
||
|
/*** checkvalue - insure value will fit in field
|
||
|
*
|
||
|
* checkvalue (width, sign, magnitude)
|
||
|
*
|
||
|
* Entry width = width of field
|
||
|
* sign = sign of result
|
||
|
* magnitude= magnitude of result
|
||
|
* Exit none
|
||
|
* Returns adjusted value
|
||
|
* Calls none
|
||
|
*/
|
||
|
|
||
|
|
||
|
OFFSET PASCAL CODESIZE
|
||
|
checkvalue (
|
||
|
register SHORT width,
|
||
|
register char sign,
|
||
|
register OFFSET mag
|
||
|
){
|
||
|
register OFFSET mask;
|
||
|
|
||
|
if (width == sizeof(OFFSET)*8)
|
||
|
mask = OFFSETMAX;
|
||
|
else
|
||
|
mask = (1 << width) - 1;
|
||
|
if (!sign) {
|
||
|
if (width < sizeof(OFFSET)*8)
|
||
|
if (mag > mask) {
|
||
|
errorc (E_VOR);
|
||
|
mag = mask;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
mag = OFFSETMAX - mag;
|
||
|
mag++;
|
||
|
if (width < sizeof(OFFSET)*8)
|
||
|
if ((mag ^ OFFSETMAX) & ~mask) {
|
||
|
errorc (E_VOR);
|
||
|
mag = mask;
|
||
|
}
|
||
|
}
|
||
|
return (mag & mask);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*** recordspec - parse record field specification fld:wid[=val]
|
||
|
*
|
||
|
* recordspec (p);
|
||
|
*
|
||
|
* Entry p = pointer to record definition structure
|
||
|
* Exit
|
||
|
* Returns
|
||
|
* Calls
|
||
|
*/
|
||
|
|
||
|
|
||
|
VOID PASCAL CODESIZE
|
||
|
recordspec (
|
||
|
register struct recdef *p
|
||
|
){
|
||
|
register SYMBOL FARSYM *fldptr;
|
||
|
register USHORT width;
|
||
|
register struct symbrecf FARSYM *s;
|
||
|
char sign;
|
||
|
OFFSET mag;
|
||
|
|
||
|
getatom ();
|
||
|
if (*naim.pszName) {
|
||
|
|
||
|
if (!symFet ())
|
||
|
symcreate (M_DEFINED | M_BACKREF, RECFIELD);
|
||
|
else {
|
||
|
if (symptr->symu.rec.recptr != p->recptr ||
|
||
|
M_BACKREF & symptr->attr)
|
||
|
|
||
|
errorn (E_SMD);
|
||
|
|
||
|
symptr->attr |= M_BACKREF;
|
||
|
}
|
||
|
crefdef ();
|
||
|
s = &(symptr->symu.rec);
|
||
|
if (symptr->symkind != RECFIELD)
|
||
|
/* Not field */
|
||
|
errorn (E_SDK);
|
||
|
else {
|
||
|
/* Ptr to field */
|
||
|
fldptr = symptr;
|
||
|
|
||
|
if (!p->curfld)
|
||
|
p->recptr->symu.rsmsym.rsmtype.rsmrec.reclist = fldptr;
|
||
|
else
|
||
|
p->curfld->symu.rec.recnxt = fldptr;
|
||
|
|
||
|
/* New last field */
|
||
|
p->curfld = fldptr;
|
||
|
s->recptr = p->recptr;
|
||
|
s->recnxt = NULL;
|
||
|
p->fldcnt++;
|
||
|
if (NEXTC () != ':')
|
||
|
error (E_EXP,"colon");
|
||
|
|
||
|
/* Get field width */
|
||
|
width = (USHORT)exprconst ();
|
||
|
|
||
|
if (skipblanks () == '=') {
|
||
|
SKIPC ();
|
||
|
mag = exprsmag (&sign);
|
||
|
}
|
||
|
else {
|
||
|
sign = FALSE;
|
||
|
mag = 0;
|
||
|
}
|
||
|
|
||
|
if (width == 0 ||
|
||
|
p->reclen + width > wordsize*8) {
|
||
|
STRNFCPY (save, p->curfld->nampnt->id);
|
||
|
/*Overflow */
|
||
|
error (E_VOR, save);
|
||
|
width = 0;
|
||
|
}
|
||
|
|
||
|
s->recinit = checkvalue (width, sign, mag);
|
||
|
s->recmsk = (OFFSET)((1L << width) - 1);
|
||
|
s->recwid = (char)width;
|
||
|
p->reclen += width;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*** recorddefine - parse record definition
|
||
|
*
|
||
|
* recorddefine ();
|
||
|
*
|
||
|
* Entry
|
||
|
* Exit
|
||
|
* Returns
|
||
|
* Calls
|
||
|
*/
|
||
|
|
||
|
|
||
|
VOID PASCAL CODESIZE
|
||
|
recorddefine ()
|
||
|
{
|
||
|
struct recdef a;
|
||
|
struct symbrecf FARSYM *s;
|
||
|
register SHORT cbRec;
|
||
|
|
||
|
a.reclen = 0;
|
||
|
a.fldcnt = 0;
|
||
|
checkRes();
|
||
|
if (!symFet ()) {
|
||
|
/* Make record */
|
||
|
symcreate (M_DEFINED | M_BACKREF, REC);
|
||
|
}
|
||
|
else
|
||
|
symptr->attr |= M_BACKREF;
|
||
|
|
||
|
/* This is def */
|
||
|
crefdef ();
|
||
|
if (symptr->symkind != REC)
|
||
|
/* Wasn't record */
|
||
|
errorn (E_SDK);
|
||
|
else {
|
||
|
/* Leftmost bit of record */
|
||
|
a.reclen = 0;
|
||
|
/*No record filed yet */
|
||
|
a.curfld = NULL;
|
||
|
/* In case error */
|
||
|
symptr->symu.rsmsym.rsmtype.rsmrec.reclist = NULL;
|
||
|
/* Pointer to record name */
|
||
|
a.recptr = symptr;
|
||
|
/* Parse record field list */
|
||
|
BACKC ();
|
||
|
do {
|
||
|
SKIPC ();
|
||
|
recordspec (&a);
|
||
|
|
||
|
} while (skipblanks() == ',');
|
||
|
|
||
|
/* Length of record in bits */
|
||
|
cbRec = a.reclen;
|
||
|
|
||
|
a.recptr->length = cbRec;
|
||
|
a.recptr->offset = (OFFSET)((1L << cbRec) - 1);
|
||
|
a.recptr->symtype = (cbRec > 16 )? 4: ((cbRec > 8)? 2: 1);
|
||
|
/* # of fields in record */
|
||
|
a.recptr->symu.rsmsym.rsmtype.rsmrec.recfldnum = (char)a.fldcnt;
|
||
|
/* 1st field */
|
||
|
a.curfld = a.recptr->symu.rsmsym.rsmtype.rsmrec.reclist;
|
||
|
}
|
||
|
|
||
|
/* For all the fields adjust the shift (stored in offset),
|
||
|
* initial value and mask so the last field is right justified */
|
||
|
|
||
|
while (a.curfld) {
|
||
|
|
||
|
s = &(a.curfld->symu.rec);
|
||
|
|
||
|
/* Start of field */
|
||
|
cbRec = (cbRec > s->recwid)? cbRec - s->recwid: 0;
|
||
|
|
||
|
/* Shift count */
|
||
|
a.curfld->offset = cbRec;
|
||
|
s->recinit <<= cbRec;
|
||
|
s->recmsk <<= cbRec;
|
||
|
|
||
|
a.curfld = s->recnxt; /* Next field */
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*** recfill - get initial value for field in list
|
||
|
*
|
||
|
* recfill (p);
|
||
|
*
|
||
|
* Entry
|
||
|
* Exit
|
||
|
* Returns
|
||
|
* Calls
|
||
|
*/
|
||
|
|
||
|
|
||
|
VOID PASCAL CODESIZE
|
||
|
recfill (
|
||
|
register struct recpars *p
|
||
|
){
|
||
|
register char cc;
|
||
|
struct symbrecf FARSYM *s;
|
||
|
char sign;
|
||
|
OFFSET mag, t;
|
||
|
|
||
|
if (!p->curfld) {
|
||
|
/* More fields than exist */
|
||
|
errorc (E_MVD);
|
||
|
}
|
||
|
else {
|
||
|
s = &(p->curfld->symu.rec);
|
||
|
|
||
|
if ((cc = skipblanks ()) == ',' || cc == '>') {
|
||
|
/* Use default value */
|
||
|
t = s->recinit;
|
||
|
}
|
||
|
else {
|
||
|
/* Have an override */
|
||
|
mag = exprsmag (&sign);
|
||
|
t = checkvalue (s->recwid, sign, mag);
|
||
|
/* Scale value */
|
||
|
t <<= p->curfld->offset;
|
||
|
}
|
||
|
/* Add in new field */
|
||
|
|
||
|
if (s->recwid)
|
||
|
p->recval = (p->recval & ~(s->recmsk)) | t;
|
||
|
|
||
|
p->curfld = s->recnxt;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*** recordparse - parse record specification
|
||
|
*
|
||
|
* recordparse ();
|
||
|
*
|
||
|
* Entry
|
||
|
* Exit
|
||
|
* Returns
|
||
|
* Calls
|
||
|
*/
|
||
|
|
||
|
|
||
|
OFFSET PASCAL CODESIZE
|
||
|
recordparse ()
|
||
|
{
|
||
|
struct recpars a;
|
||
|
struct symbrecf FARSYM *s;
|
||
|
|
||
|
|
||
|
a.recptr = symptr; /* Current record */
|
||
|
|
||
|
if (PEEKC () != '<')
|
||
|
error (E_EXP,"<"); /* Must have < */
|
||
|
else
|
||
|
SKIPC ();
|
||
|
|
||
|
/* No value yet */
|
||
|
a.recval = 0;
|
||
|
/* 1st field in record */
|
||
|
a.curfld = a.recptr->symu.rsmsym.rsmtype.rsmrec.reclist;
|
||
|
|
||
|
BACKC ();
|
||
|
do { /* Fill in values */
|
||
|
SKIPC ();
|
||
|
recfill (&a);
|
||
|
|
||
|
} while (skipblanks () == ',');
|
||
|
|
||
|
while (a.curfld) {
|
||
|
/* Fill in remaining defaults */
|
||
|
s = &(a.curfld->symu.rec);
|
||
|
if (s->recwid)
|
||
|
a.recval = (a.recval & ~(s->recmsk)) | s->recinit;
|
||
|
a.curfld = s->recnxt;
|
||
|
}
|
||
|
if (NEXTC () != '>') /* Must have > */
|
||
|
error (E_EXP,">");
|
||
|
|
||
|
return (a.recval); /* Value of record */
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*** recordinit - parse record allocation
|
||
|
*
|
||
|
* recordinit ();
|
||
|
*
|
||
|
* Entry
|
||
|
* Exit
|
||
|
* Returns
|
||
|
* Calls
|
||
|
*/
|
||
|
|
||
|
|
||
|
VOID PASCAL CODESIZE
|
||
|
recordinit ()
|
||
|
{
|
||
|
initflag = TRUE;
|
||
|
strucflag = FALSE; /* This is RECORD init */
|
||
|
recptr = symptr;
|
||
|
|
||
|
optyp = TDB;
|
||
|
|
||
|
if (symptr->symtype == 2)
|
||
|
optyp = TDW;
|
||
|
#ifdef V386
|
||
|
else if (symptr->symtype == 4)
|
||
|
optyp = TDD;
|
||
|
#endif
|
||
|
|
||
|
datadefine ();
|
||
|
initflag = FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*** nodecreate - create one DUP record
|
||
|
*
|
||
|
* nodecreate ();
|
||
|
*
|
||
|
* Entry
|
||
|
* Exit
|
||
|
* Returns
|
||
|
* Calls
|
||
|
*/
|
||
|
|
||
|
|
||
|
struct duprec FARSYM * PASCAL CODESIZE
|
||
|
nodecreate ()
|
||
|
{
|
||
|
register struct duprec FARSYM *node;
|
||
|
|
||
|
node = (struct duprec FARSYM *)falloc (sizeof (*node), "nodecreate");
|
||
|
node->rptcnt = 1;
|
||
|
node->itemcnt = 0;
|
||
|
node->duptype.dupnext.dup = NULL;
|
||
|
node->itemlst = NULL;
|
||
|
node->dupkind = NEST;
|
||
|
return (node);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*** strucdefine - define structure
|
||
|
*
|
||
|
* strucdefine ();
|
||
|
*
|
||
|
* Entry
|
||
|
* Exit
|
||
|
* Returns
|
||
|
* Calls
|
||
|
*/
|
||
|
|
||
|
|
||
|
VOID PASCAL CODESIZE
|
||
|
strucdefine ()
|
||
|
{
|
||
|
checkRes();
|
||
|
if (!symFet()) {
|
||
|
|
||
|
/* Make STRUC */
|
||
|
symcreate (M_DEFINED | M_BACKREF, STRUC);
|
||
|
}
|
||
|
else
|
||
|
symptr->attr |= M_BACKREF;
|
||
|
|
||
|
/* This is definition */
|
||
|
crefdef ();
|
||
|
if (symptr->symkind != STRUC)
|
||
|
errorn (E_SDK);
|
||
|
|
||
|
else {
|
||
|
symptr->attr |= M_BACKREF;
|
||
|
recptr = symptr; /* Pointer to STRUC name */
|
||
|
recptr->symu.rsmsym.rsmtype.rsmstruc.strucfldnum = 0;
|
||
|
|
||
|
if (! pass2) {
|
||
|
recptr->symu.rsmsym.rsmtype.rsmstruc.type = typeIndex;
|
||
|
typeIndex += 3;
|
||
|
|
||
|
if (pStrucCur)
|
||
|
pStrucCur->alpha = recptr;
|
||
|
else
|
||
|
pStrucFirst = recptr;
|
||
|
|
||
|
pStrucCur = recptr;
|
||
|
}
|
||
|
|
||
|
/* No labeled fields yet */
|
||
|
recptr->symu.rsmsym.rsmtype.rsmstruc.struclist = NULL;
|
||
|
|
||
|
/* Delete old STRUC */
|
||
|
scandup (recptr->symu.rsmsym.rsmtype.rsmstruc.strucbody, oblitdup);
|
||
|
recptr->symu.rsmsym.rsmtype.rsmstruc.strucbody = nodecreate ();
|
||
|
|
||
|
struclabel = NULL; /* No named fields */
|
||
|
strucprev = NULL; /* No body yet */
|
||
|
count = 0; /* No fields yet */
|
||
|
strucflag = TRUE; /* We are STRUC not RECORD */
|
||
|
|
||
|
svpc = pcoffset; /* Save normal PC */
|
||
|
pcoffset = 0; /* Relative to STRUC begin */
|
||
|
|
||
|
swaphandler = TRUE; /* Switch to STRUC builder */
|
||
|
handler = HSTRUC;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*** strucbuild - build the struc block
|
||
|
*
|
||
|
* strucbuild ();
|
||
|
*
|
||
|
* Entry
|
||
|
* Exit
|
||
|
* Returns
|
||
|
* Calls
|
||
|
*/
|
||
|
|
||
|
|
||
|
VOID PASCAL CODESIZE
|
||
|
strucbuild ()
|
||
|
{
|
||
|
labelflag = FALSE;
|
||
|
optyp = 0;
|
||
|
getatom ();
|
||
|
|
||
|
#ifndef FEATURE
|
||
|
|
||
|
if (naim.pszName[0] == '%' && naim.pszName[1] == 0) { /* expand all text macros */
|
||
|
*begatom = ' ';
|
||
|
substituteTMs();
|
||
|
getatom();
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
/* First, look for IF, ELSE & ENDIF stuff */
|
||
|
|
||
|
if (fndir () && (opkind & CONDBEG)) {
|
||
|
firstDirect();
|
||
|
}
|
||
|
else if (generate && *naim.pszName) {
|
||
|
|
||
|
/* next, classify the current token, which is either
|
||
|
* and ENDS, data label or data name */
|
||
|
|
||
|
if (optyp == 0 || !fndir2 ()){
|
||
|
|
||
|
/* first token was a label */
|
||
|
|
||
|
switchname ();
|
||
|
getatom ();
|
||
|
optyp = 0;
|
||
|
|
||
|
if (!fndir2 ())
|
||
|
errorc(E_DIS);
|
||
|
|
||
|
labelflag = TRUE; /* Do have label */
|
||
|
switchname ();
|
||
|
}
|
||
|
|
||
|
if (optyp == TENDS) {
|
||
|
|
||
|
if (!symFet () || symptr != recptr)
|
||
|
errorc(E_BNE);
|
||
|
|
||
|
/* Have end of STRUC */
|
||
|
|
||
|
handler = HPARSE;
|
||
|
swaphandler = TRUE;
|
||
|
strucflag = FALSE;
|
||
|
recptr->symu.rsmsym.rsmtype.rsmstruc.strucfldnum =
|
||
|
/* # of fields */
|
||
|
recptr->symu.rsmsym.rsmtype.rsmstruc.strucbody->itemcnt;
|
||
|
|
||
|
if (pcoffset & 0xFFFF0000)
|
||
|
errorc (E_DVZ);
|
||
|
recptr->symtype = (USHORT)pcoffset; /* Size of STRUC */
|
||
|
recptr->length = 1;
|
||
|
|
||
|
pcdisplay ();
|
||
|
/* Restore PC */
|
||
|
pcoffset = svpc;
|
||
|
}
|
||
|
else if (! (optyp >= TDB && optyp <= TDW))
|
||
|
errorc (E_DIS);
|
||
|
|
||
|
else { /* Have another line of body */
|
||
|
|
||
|
if (!strucprev) {
|
||
|
/* Make first node */
|
||
|
strucprev = nodecreate ();
|
||
|
recptr->symu.rsmsym.rsmtype.rsmstruc.strucbody->
|
||
|
duptype.dupnext.dup = strucprev;
|
||
|
}
|
||
|
else {
|
||
|
strucprev->itemlst = nodecreate ();
|
||
|
strucprev = strucprev->itemlst;
|
||
|
}
|
||
|
recptr->symu.rsmsym.rsmtype.rsmstruc.strucbody->itemcnt++;
|
||
|
/* Add new data line to STRUC */
|
||
|
datadefine ();
|
||
|
strucprev->decltype = optyp;
|
||
|
}
|
||
|
}
|
||
|
if (generate) {
|
||
|
if (!ISTERM (skipblanks()))
|
||
|
errorc (E_ECL);
|
||
|
}
|
||
|
listline ();
|
||
|
}
|
||
|
|
||
|
struct srec {
|
||
|
struct duprec FARSYM *curfld;
|
||
|
USHORT curlen;
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*** createduprec - create short data record with null data
|
||
|
*
|
||
|
* createduprec ();
|
||
|
*
|
||
|
* Entry
|
||
|
* Exit
|
||
|
* Returns
|
||
|
* Calls
|
||
|
*/
|
||
|
|
||
|
|
||
|
struct duprec FARSYM * PASCAL CODESIZE
|
||
|
createduprec ()
|
||
|
{
|
||
|
register struct duprec FARSYM *newrec;
|
||
|
|
||
|
newrec = (struct duprec FARSYM *)falloc (sizeof (*newrec), "createduprec");
|
||
|
newrec->rptcnt = 1;
|
||
|
/* Not a DUP */
|
||
|
newrec->itemcnt = 0;
|
||
|
newrec->itemlst = NULL;
|
||
|
newrec->dupkind = ITEM;
|
||
|
/* this also clears ddata and dup in other variants of struc */
|
||
|
newrec->duptype.duplong.ldata = NULL;
|
||
|
newrec->duptype.duplong.llen = 1;
|
||
|
return (newrec);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*** strucerror - generate structure error message
|
||
|
*
|
||
|
* strucerror ();
|
||
|
*
|
||
|
* Entry
|
||
|
* Exit
|
||
|
* Returns
|
||
|
* Calls
|
||
|
*/
|
||
|
|
||
|
|
||
|
struct duprec FARSYM * PASCAL CODESIZE
|
||
|
strucerror (
|
||
|
SHORT code,
|
||
|
struct duprec FARSYM *node
|
||
|
){
|
||
|
errorc (code);
|
||
|
/* Get rid of bad Oitem */
|
||
|
oblitdup (node);
|
||
|
/* Make up a dummy */
|
||
|
return (createduprec ());
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*** strucfill - fill in structure values
|
||
|
*
|
||
|
* strucfill ();
|
||
|
*
|
||
|
* Entry
|
||
|
* Exit
|
||
|
* Returns
|
||
|
* Calls
|
||
|
*/
|
||
|
|
||
|
|
||
|
VOID PASCAL CODESIZE
|
||
|
strucfill ()
|
||
|
{
|
||
|
register struct duprec FARSYM *pOver;
|
||
|
register struct duprec FARSYM *pInit;
|
||
|
register char *cp;
|
||
|
char svop;
|
||
|
short i, cbCur;
|
||
|
struct datarec drT;
|
||
|
|
||
|
|
||
|
if (!pDUPCur) {
|
||
|
errorc (E_MVD);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (skipblanks() == ',' || PEEKC() == '>') {
|
||
|
/* use default values */
|
||
|
pOver = createduprec ();
|
||
|
}
|
||
|
else {
|
||
|
/* Save operation type */
|
||
|
svop = optyp;
|
||
|
/* Original directive type */
|
||
|
optyp = pDUPCur->decltype;
|
||
|
|
||
|
pOver = datascan (&drT); /* Get item */
|
||
|
|
||
|
optyp = svop;
|
||
|
pInit = pDUPCur->duptype.dupnext.dup;
|
||
|
cbCur = pInit->duptype.duplong.llen;
|
||
|
|
||
|
if (pOver->dupkind == NEST)
|
||
|
/* Bad override val */
|
||
|
pOver = strucerror (E_ODI, pOver);
|
||
|
|
||
|
else if (pDUPCur->itemcnt != 1 || pInit->itemcnt)
|
||
|
/* Can't override field */
|
||
|
pOver = strucerror (E_FCO, pOver);
|
||
|
|
||
|
else if (pOver->dupkind != pInit->dupkind) {
|
||
|
|
||
|
if (pInit->dupkind == ITEM)
|
||
|
cbCur = pInit->duptype.dupitem.ddata->dsckind.opnd.dsize;
|
||
|
}
|
||
|
|
||
|
if (pOver->dupkind == LONG) {
|
||
|
/* If too long, truncate */
|
||
|
|
||
|
if ((i = pOver->duptype.duplong.llen) < cbCur) {
|
||
|
|
||
|
/* Space fill short (after reallocating more space) */
|
||
|
|
||
|
if (!(pOver->duptype.duplong.ldata =
|
||
|
realloc (pOver->duptype.duplong.ldata, cbCur)))
|
||
|
memerror("strucfil");
|
||
|
|
||
|
cp = pOver->duptype.duplong.ldata + i;
|
||
|
|
||
|
for (; i < cbCur; i++)
|
||
|
*cp++ = ' ';
|
||
|
}
|
||
|
else if (pOver->duptype.duplong.llen > cbCur)
|
||
|
errorc (E_OWL);
|
||
|
|
||
|
pOver->duptype.duplong.llen = (unsigned char)cbCur;
|
||
|
}
|
||
|
if ((pOver->dupkind == pInit->dupkind) &&
|
||
|
(pOver->dupkind == ITEM) && !errorcode)
|
||
|
|
||
|
pOver->duptype.dupitem.ddata->dsckind.opnd.dsize =
|
||
|
pInit->duptype.dupitem.ddata->dsckind.opnd.dsize;
|
||
|
}
|
||
|
pDUPCur = pDUPCur->itemlst;
|
||
|
|
||
|
if (strucoveride)
|
||
|
strclastover->itemlst = pOver;
|
||
|
else
|
||
|
strucoveride = pOver;
|
||
|
|
||
|
strclastover = pOver;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*** strucparse - parse structure specification
|
||
|
*
|
||
|
* strucparse ();
|
||
|
*
|
||
|
* Entry
|
||
|
* Exit
|
||
|
* Returns
|
||
|
* Calls
|
||
|
*/
|
||
|
|
||
|
|
||
|
struct duprec FARSYM * PASCAL CODESIZE
|
||
|
strucparse ()
|
||
|
{
|
||
|
/* No items yet */
|
||
|
strucoveride = NULL;
|
||
|
recptr = symptr;
|
||
|
|
||
|
if (skipblanks () != '<')
|
||
|
error (E_EXP,"<");
|
||
|
|
||
|
/* 1st default field */
|
||
|
pDUPCur = recptr->symu.rsmsym.rsmtype.rsmstruc.strucbody->duptype.dupnext.dup;
|
||
|
initflag = FALSE;
|
||
|
strucflag = FALSE;
|
||
|
/* Build list of overrides */
|
||
|
do {
|
||
|
SKIPC ();
|
||
|
strucfill ();
|
||
|
|
||
|
} while (skipblanks () == ',');
|
||
|
|
||
|
initflag = TRUE;
|
||
|
strucflag = TRUE;
|
||
|
while (pDUPCur) {/* Fill rest with overrides */
|
||
|
/* Make dummy entry */
|
||
|
strclastover->itemlst = createduprec ();
|
||
|
strclastover = strclastover->itemlst;
|
||
|
/* Advance to next field */
|
||
|
pDUPCur = pDUPCur->itemlst;
|
||
|
}
|
||
|
if (PEEKC () != '>')
|
||
|
error (E_EXP,">");
|
||
|
else
|
||
|
SKIPC ();
|
||
|
return (recptr->symu.rsmsym.rsmtype.rsmstruc.strucbody);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*** strucinit - initialize structure
|
||
|
*
|
||
|
* strucinit ();
|
||
|
*
|
||
|
* Entry
|
||
|
* Exit
|
||
|
* Returns
|
||
|
* Calls
|
||
|
*/
|
||
|
|
||
|
|
||
|
VOID PASCAL CODESIZE
|
||
|
strucinit ()
|
||
|
{
|
||
|
initflag = TRUE;
|
||
|
strucflag = TRUE;
|
||
|
recptr = symptr;
|
||
|
optyp = TMACRO;
|
||
|
datadsize[TMACRO - TDB] = recptr->symtype;
|
||
|
datadefine ();
|
||
|
initflag = FALSE;
|
||
|
strucflag = FALSE;
|
||
|
}
|