Files
Leency 7984195956 upload fixed verion by paulcodeman
git-svn-id: svn://kolibrios.org@7700 a494cfbc-eb01-0410-851d-a64ba20cac60
2019-11-14 18:45:31 +00:00

6449 lines
162 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#define _TOKA_
#include "tok.h"
#pragma option -w-pin
#ifdef _WIN32_
#include <windows.h>
#endif
#include <unistd.h>
#include <sys/stat.h>
#include "dirlist.h"
#include "id.h"
#include "resname.h"
struct idrec *treestart=NULL;
struct idrec *definestart=NULL;
UNDEFOFF *undefoffstart=NULL;
DLLLIST *listdll=NULL;
struct structteg *tegtree=NULL; //глобальный срисок тегов
struct structteg *ltegtree=NULL; //локальный срисок тегов
//struct idrec *lstructlist=NULL; //список локальных структур
SINFO strinf={NULL};
static int notdef=TRUE;
static char precha;
int scanalltoks=TRUE;
static volatile idrec **DynamicList=NULL;
static int sizeDL; //размер списка
static volatile int countDP; //число динамических процедур в списке
static int findofset=FALSE;
#define STEPDL 128; //шаг увеличения размера списка
ITOK structadr;
char id2[ID2S][9]={
"ESCHAR","ESBYTE","ESINT","ESWORD","ESLONG","ESDWORD","ESFLOAT","ESQWORD","ESDOUBLE",
"CSCHAR","CSBYTE","CSINT","CSWORD","CSLONG","CSDWORD","CSFLOAT","CSQWORD","CSDOUBLE",
"SSCHAR","SSBYTE","SSINT","SSWORD","SSLONG","SSDWORD","SSFLOAT","SSQWORD","SSDOUBLE",
"DSCHAR","DSBYTE","DSINT","DSWORD","DSLONG","DSDWORD","DSFLOAT","DSQWORD","DSDOUBLE",
"FSCHAR","FSBYTE","FSINT","FSWORD","FSLONG","FSDWORD","FSFLOAT","FSQWORD","FSDOUBLE",
"GSCHAR","GSBYTE","GSINT","GSWORD","GSLONG","GSDWORD","GSFLOAT","GSQWORD","GSDOUBLE",};
char regs[2][8][4]={"AX","CX","DX","BX","SP","BP","SI","DI",
"EAX","ECX","EDX","EBX","ESP","EBP","ESI","EDI"};
char begs[8][3]={"AL","CL","DL","BL","AH","CH","DH","BH"};
char segs[6][3]={"ES","CS","SS","DS","FS","GS"};
char mon[12][4]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug",
"Sep","Oct","Nov","Dec"};
unsigned char cha2;
char skipfind=FALSE; /* пропуск поиска в глобальном дереве и среди
локальных переменных */
static unsigned char savestring3=FALSE; //разрешить запись в буфер string3
static int posstr3; //указатель позиции в string3
unsigned int inptr2;
unsigned int linenum2=0; //если не нуль, то идет обраьотка
char displaytokerrors; /* flag to display errors, 0 for tok2 scan */
char *bufrm=NULL;
char *startline=NULL;
char *endinput=NULL;
unsigned char skiplocals=FALSE;
int scanlexmode=STDLEX;
unsigned char bytesize=TRUE;
COM_MOD *cur_mod=NULL;
void docals(struct idrec *ptr);
void dostructvar2(int *tok4,ITOK *itok4,struct structteg *tteg,unsigned char *string4); //разбор структур на переменные и структуры
void dosizeof(ITOK *itok4); //опр значение sizeof
void ofsstr(int *tok4,ITOK *itok4);
int searchlocals(ITOK *itok4,int *tok4,unsigned char *string4);
unsigned char convert_char();
void tokscan (int *tok4,ITOK *itok4,unsigned char *string4);
int calcnum(int *ctok,ITOK *cstok,char *cstring,long *retval);
int GetDirective(char *str);
int CheckAsmName(char *name);
void tag_massiv(int *tok4,ITOK *itok4,unsigned char *string4);
int CheckResName(char *name);
void GetTypeVar(int *tok4);
int RegToRM(int number,int tok4);
elementteg *FindClassEl(structteg *searcht,unsigned char *string4,int *addofs,
structteg *subteg);
int AskUseDestr(structteg *searcht);
int SaveStruct(int size,idrec *newrec);
int CheckDefPar(char *name);
int searchtree2(idrec *fptr,ITOK *itok4,int *tok4,unsigned char *string4);
extern void blockerror();
extern void block16_32error();
extern void notstructname();
extern void badtoken();
extern void opb(unsigned long num,unsigned int ofs,unsigned int size);
extern void CorrectOfsBit(int bitofs);
extern int skipstring(int pos,unsigned char term);
extern int skipcomment(int pos);
void retoldscanmode(int mode)
{
if(mode==STDLEX&&cha2==13&&tok!=tk_endline){
cha2=cha;
}
scanlexmode=mode;
}
void CheckConvertString(char *string4)
{
if(cha=='o'){
OemToChar(string4,string4);
nextchar();
}
else if(cha=='w'){
CharToOem(string4,string4);
nextchar();
}
}
void DateToStr(char *buf)
{
// GetDateFormat(LOCALE_SYSTEM_DEFAULT,DATE_SHORTDATE|LOCALE_NOUSEROVERRIDE,NULL,NULL,buf,80);
sprintf(buf,"%2d %s %d",timeptr.tm_mday,mon[timeptr.tm_mon],timeptr.tm_year+1900);
}
void compressoffset(ITOK *thetok)
{
if(thetok->sib==CODE16){
if(thetok->rm!=rm_d16){
thetok->rm&=7;
if(thetok->number==0){
if(thetok->rm==rm_BP)thetok->rm|=rm_mod01;
}
else if((int)thetok->number<128&&(int)thetok->number>=-128)thetok->rm|=rm_mod01;
else thetok->rm|=rm_mod10;
}
}
else{
if(thetok->rm!=rm_d32&&thetok->rm!=rm_sib){
thetok->rm&=7;
if(thetok->number==0){
if(thetok->rm==5)thetok->rm|=rm_mod01;
if(thetok->rm==4&&(thetok->sib&7)==5)thetok->rm|=rm_mod01;
}
else if(thetok->number<128&&thetok->number>=-128)thetok->rm|=rm_mod01;
else thetok->rm|=rm_mod10;
}
}
}
int CalcRm16(int base,int idx)
{
int rm;
rm=0;
switch(base+idx){
case 2: rm++;
case 4: rm++;
case 6: rm++;
case 5: rm++;
case 12: rm++;
case 11: rm++;
case 10: rm++;
}
return rm;
}
void SRBackBuf(int mode) //save/restore BackTextBlock
{
static int size=0;
static char *buf;
if(mode==0){
if(SizeBackBuf){
size=SizeBackBuf;
SizeBackBuf=0;
buf=BackTextBlock;
}
}
else{
SizeBackBuf=size;
size=0;
BackTextBlock=buf;
}
}
void ExpandRm(int rm,int sib,int *zoom,int *base,int *idx)
{
int rm0;
int reg1=-1,reg2=-1;
int z=0;
rm0=rm&0x7;
if(sib==CODE16||sib==(CODE16+1)){
switch(rm0){
case 0:
reg1=BX;
reg2=SI;
break;
case 1:
reg1=BX;
reg2=DI;
break;
case 2:
reg1=BP;
reg2=SI;
break;
case 3:
reg1=BP;
reg2=DI;
break;
case 4:
reg2=SI;
break;
case 5:
reg2=DI;
break;
case 6:
if((rm&0xC0)!=0)reg1=BP;
break;
case 7:
reg1=BX;
break;
}
}
else{
if(rm0==4){
reg1=sib&7;
reg2=(sib>>3)&7;
if(reg1==5&&(rm&0xc0)==0)reg1=-1;
if(reg2==4)reg2=-1;
else z=sib>>6;
}
else{
reg1=rm0;
if(reg1==5&&(rm&0xc0)==0)reg1=-1;
}
}
*base=reg1;
*idx=reg2;
*zoom=z;
}
int CheckZoom(int size)
{
int zoom=0;
switch(size){
case 8: zoom++;
case 4: zoom++;
case 2: zoom++;
}
return zoom;
}
void calcrm(ITOK *itok4,int ttok)//обработка выражения в []
{
int idx,base,razr=0,zoom,rm=0;
long numrm=0,cnum,ocnum;
int nextscan;
ITOK cstok,dstok;
int ctok,sopenb;
unsigned char *pstring;
unsigned int flag;
unsigned int sizevar=1;
unsigned int prevtok=tk_number,operand=tk_plus;
int dsword,dsword2;
nextchar();
whitespace();//пропуск незначащих символов
if(!displaytokerrors){
for(int i=1;i!=0;){
FastTok(0,&ctok,&cstok);
switch(ctok){
case tk_closeblock: i--; break;
case tk_openblock: i++; break;
case tk_eof: i=0; break;
}
}
return;
}
dsword2=dsword=itok4->post&POINTER;
itok4->post&=NOTPOINTER;
memcpy(&dstok,itok4,sizeof(ITOK));
ExpandRm(dstok.rm,dstok.sib,&zoom,&base,&idx);
if((dstok.sib==CODE16||dstok.sib==(CODE16+1))&&dstok.rm!=rm_d16)razr=r16;
if(am32&&dstok.rm!=rm_d32){
rm=dstok.rm&0xC0;
razr=r32;
}
// printf("in idx=%d base=%d zoom=%d\n",idx,base,zoom);
pstring=(unsigned char *)MALLOC(STRLEN);
sopenb=inptr;
char bcha=cha;
SRBackBuf(0);
flag=f_useidx;//0;//cstok.flag;
if(bytesize==FALSE){
sizevar=GetVarSize(ttok);
if(dsword)sizevar=1;
if(am32)zoom=CheckZoom(sizevar);
}
if(cha=='&'){
nextchar();
whitespace();//пропуск незначащих символов
sizevar=1;
zoom=0;
}
for(;;){
nextscan=TRUE;
if(cha=='#'&&dsword)dsword=1;
tokscan(&ctok,&cstok,pstring);
whitespace();//пропуск незначащих символов
if(dsword==1)strcpy(dstok.name,cstok.name);
// printf("tok=%d num=%d %s\n",ctok,cstok.number,cstok.name);
loopsw:
switch(ctok){
case tk_reg:
if(razr==0)razr=r16;
else if(razr==r32||sizevar!=1||operand!=tk_plus)goto runblock; //16.12.04 22:39
if(cstok.number==BP||cstok.number==BX){
if(base==-1)base=cstok.number;
else goto runblock;
}
else if(cstok.number==SI||cstok.number==DI){
if(idx==-1)idx=cstok.number;
else goto runblock;
}
else goto runblock;
prevtok=tk_reg;
break;
case tk_minus:
if(calcnum(&ctok,&cstok,(char *)pstring,&cnum)==0)goto runblock;
prevtok=tk_number;
ocnum=cstok.number;
goto enumb;
case tk_number:
if(operand==tk_mult&&prevtok==tk_reg32){
if(zoom==0){
prevtok=tk_number;
if(razr==0)razr=r32;
else if(razr==r16)goto runblock;
zoom=CheckZoom(cstok.number);
if(zoom)break;
}
else goto runblock;
}
prevtok=tk_number;
ocnum=cstok.number;
if(zoom==0&&razr!=r16&&(idx==-1||base==-1)){
if((zoom=CheckZoom(cstok.number))!=0){
if(cha=='*'){
nextchar();
tokscan(&ctok,&cstok,pstring);
if(ctok==tk_reg32){
if(idx!=-1)base=idx;
idx=cstok.number;
prevtok=tk_reg32;
if(razr==0)razr=r32;
break;
}
if(ctok==tk_number){
calclongnumber(&ocnum,cstok.number,tk_mult);
numrm+=ocnum;
zoom=0;
break;
}
goto runblock;
}
zoom=0;
}
}
if(calcnum(&ctok,&cstok,(char *)pstring,&cnum)==0)goto runblock;
enumb:
flag^=cstok.flag;
whitespace();//пропуск незначащих символов
ocnum=cnum;
numrm+=cnum;
if(cstok.type==tp_opperand||cstok.type==tp_stopper)nextscan=FALSE;
else{
operand=tk_plus;
goto loopsw;
}
break;
case tk_reg32:
// printf("prevtok=%d operand=%d ocnum=%d idx=%d base=%d zoom=%d\n",prevtok,operand,ocnum,idx,base,zoom);
if(razr==0)razr=r32;
if(razr==r16||(operand!=tk_plus&&operand!=tk_mult)||(idx!=-1&&base!=-1))goto runblock;
if(sizevar!=1){
if(idx!=-1)goto runblock;
idx=cstok.number;
}
else if(operand==tk_mult){
if(prevtok!=tk_number)goto runblock;
zoom=CheckZoom(ocnum);
numrm-=ocnum;
if(idx!=-1)base=idx;
idx=cstok.number;
}
else if(cha=='*'){
if(idx!=-1)base=idx;
idx=cstok.number;
}
else if(base==-1)base=cstok.number;
else if(idx==-1)idx=cstok.number;
// else goto runblock;
prevtok=tk_reg32;
break;
case tk_postnumber:
if(dsword==0||sizevar!=1)goto runblock;
if((cstok.post&USED_DIN_VAR)==USED_DIN_VAR){ //динамическая переменная
if(dstok.rec!=NULL)goto runblock;
dstok.rec=cstok.rec;
}
if(operand==tk_minus)numrm-=cstok.number;
else numrm+=cstok.number;
dstok.post|=cstok.post;
prevtok=tk_number;
break;
case tk_undefofs:
if(dsword==0||sizevar!=1)goto runblock;
if(operand==tk_minus)numrm-=cstok.number;
else numrm+=cstok.number;
dstok.post|=UNDEF_OFSET;
strcpy(dstok.name,cstok.name);
flag^=cstok.flag;
prevtok=tk_number;
break;
case tk_rmnumber:
/* if(strinf.bufstr!=NULL){
free(strinf.bufstr);
strinf.bufstr=NULL;
goto runblock;
}*/
if(dsword==0||sizevar!=1)goto runblock;
if(operand==tk_minus)numrm-=cstok.number;
else numrm+=cstok.number;
dstok.post|=cstok.post;
if(dstok.sib==CODE16){
if(cstok.rm!=rm_d16){
switch(cstok.rm&7){
case 0:
if(base!=-1||idx!=-1)goto runblock;
base=BX; idx=SI; break;
case 1:
if(base!=-1||idx!=-1)goto runblock;
base=BX; idx=DI; break;
case 2:
if(base!=-1||idx!=-1)goto runblock;
base=BP; idx=SI; break;
case 3:
if(base!=-1||idx!=-1)goto runblock;
base=BP; idx=DI; break;
case 4:
if(idx!=-1)goto runblock;
idx=SI; break;
case 5:
if(idx!=-1)goto runblock;
idx=DI; break;
case 6:
if(idx!=-1)goto runblock;
base=BP; break;
case 7:
if(idx!=-1)goto runblock;
base=BX; break;
}
}
razr=r16;
}
else{
if(cstok.rm!=rm_d32){
rm=cstok.rm&0xC0;
cstok.rm&=7;
if(base==-1)base=cstok.rm;
else if(idx==-1){
idx=base;
base=cstok.rm;
}
else goto runblock;
if(base==4){
base=cstok.sib&7;
idx=(cstok.sib>>3)&7;
if(base==5&&rm==0)base=-1;
if(idx==4)idx=-1;
}
}
else dstok.flag|=cstok.flag&f_reloc;
razr=r32;
}
break;
//-----------------28.07.98 13:59-------------------
// var[i]
//--------------------------------------------------
default:
runblock:
if(dsword2){
CharToBackBuf('&');
if(strinf.bufstr){
free(strinf.bufstr);
strinf.bufstr=NULL;
}
}
AddBackBuf(sopenb,bcha);
if(bufrm){
if(strcmp(bufrm,"&this;")==0){
free(bufrm);
CharToBackBuf(0);
sprintf((char *)string3,"&%s*%d+this;",BackTextBlock,GetVarSize(ttok));
bufrm=BackString((char *)string3);
// puts((char *)string3);
goto con1;
}
else free(bufrm);
}
CharToBackBuf(';');
CharToBackBuf(0);
bufrm=(char *)REALLOC(BackTextBlock,SizeBackBuf+1);
con1:
if(cha!=']')blockerror();
tokscan(&ctok,&cstok,pstring);
if(itok4->sib>=CODE16)itok4->sib++;
SRBackBuf(1);
// if(itok4->post&POINTER)itok4->post=0;//&=NOTPOINTER;
free(pstring);
itok4->flag|=flag;
return;
//-----------------28.07.98 13:59-------------------
// end
//--------------------------------------------------
}
if(dsword==1)dsword=0;
if(nextscan){
tokscan(&ctok,&cstok,pstring);
whitespace();//пропуск незначащих символов
}
while(ctok==tk_minus){
if(calcnum(&ctok,&cstok,(char *)pstring,&cnum)==0)goto runblock;
whitespace();//пропуск незначащих символов
numrm+=cnum;
flag^=cstok.flag;
if(cstok.type!=tp_opperand&&cstok.type!=tp_stopper){
operand=tk_plus;
goto loopsw;
}
}
operand=ctok;
// printf("operand tok=%d flag=%08X %s\n",ctok,cstok.flag,cstok.name);
if(ctok==tk_closeblock||ctok==tokens||ctok==tk_eof)break;
if(ctok!=tk_plus&&ctok!=tk_mult)goto runblock;
// flag|=cstok.flag;
}
// printf("out idx=%d base=%d zoom=%d\n",idx,base,zoom);
SRBackBuf(1);
if(ctok!=tk_closeblock)expected(']');
numrm*=sizevar;
dstok.number+=numrm;
if(razr==r16){
if(idx==-1&&base==-1)cstok.rm=6;
else{
cstok.rm=CalcRm16(base,idx)|rm_mod10;
dstok.sib=CODE16;
}
}
else if(razr==0){
if(dstok.number<65536&&dstok.number>-65535)cstok.rm=6;
else{
cstok.rm=5;
dstok.sib=0;
}
if(am32)cstok.rm=5;
}
else{
// printf("razr=%d sib=%08X %s\n",razr,dstok.sib,dstok.name);
if(dstok.sib>CODE32)dstok.sib-=CODE32;
else dstok.sib=0;
if(idx!=-1){
cstok.rm=4;
if(idx==4)preerror("ESP cannot be the index register");
if(base!=-1)dstok.sib=(zoom<<6)+(idx<<3)+base;
else{
dstok.sib=(zoom<<6)+(idx<<3)+5;
rm=(base==5?rm_mod10:0);
}
}
else{
if(base==4){
dstok.sib=(4<<3)+4;
cstok.rm=4;
}
else if(base==-1){
cstok.rm=rm_d32;
}
else cstok.rm=base;
}
if(base!=-1||rm!=0)cstok.rm|=rm_mod10; //корекция MOD будет позднее, а сейчас максимум
}
dstok.rm=cstok.rm;
dstok.flag|=flag;
memcpy(itok4,&dstok,sizeof(ITOK));
free(pstring);
}
int calcnum(int *ctok,ITOK *cstok,char *cstring,long *retval)
{
long value;
unsigned int flag;
if(*ctok==tk_minus){
tokscan(ctok,cstok,(unsigned char *)cstring);
if(*ctok!=tk_number)return(0);
cstok->number=-cstok->number;
}
else if(*ctok!=tk_number)return(0);
value=cstok->number;
flag=cstok->flag;
for(;;){
int otok;
tokscan(ctok,cstok,(unsigned char *)cstring);
otok=*ctok;
if(otok==tk_closeblock)break;
tokscan(ctok,cstok,(unsigned char *)cstring);
if(*ctok!=tk_number){
if(*ctok==tk_reg32&&(otok==tk_mult||otok==tk_minus)){
*ctok=(unsigned int)cstok->number;
*retval=value;
cstok->flag=flag;
return 0;
}
break;
}
if(calclongnumber(&value,cstok->number,otok)==FALSE){
if(displaytokerrors)blockerror();
break;
}
/* switch(otok){
case tk_minus: value-=cstok->number; break;
case tk_plus: value+=cstok->number; break;
case tk_xor: value^=cstok->number; break;
case tk_and: value&=cstok->number; break;
case tk_or: value|=cstok->number; break;
case tk_mod: value%=cstok->number; break;
case tk_div: value/=cstok->number; break;
case tk_mult: value*=cstok->number; break;
case tk_rr: value>>=cstok->number; break;
case tk_ll: value<<=cstok->number; break;
case tk_xorminus: value^=-cstok->number; break;
case tk_andminus: value&=-cstok->number; break;
case tk_orminus: value|=-cstok->number; break;
case tk_modminus: value%=-cstok->number; break;
case tk_divminus: value/=-cstok->number; break;
case tk_multminus: value*=-cstok->number; break;
case tk_rrminus: value>>=-cstok->number; break;
case tk_llminus: value<<=-cstok->number; break;
default: if(displaytokerrors)blockerror(); goto end;
}*/
flag^=cstok->flag;
}
//end:
cstok->flag=flag;
*retval=value;
return -1;
}
void CheckReg(int idx,int base,int *reg1,int *reg2,int razr)
{
if(razr==r32){
unsigned char lreg[16];
int i;
for(i=0;i<8;i++){
if(i==ESP||i==EBP)lreg[i]=1;
else{
if((idx!=-1&&idx==i)||(base!=-1&&base==i))lreg[i]=1;
else lreg[i]=0;
}
// printf("%c",lreg[i]+'0');
}
if(lreg[*reg1]==0)lreg[*reg1]=1;
else{
for(i=8;i!=0;i--){
if(lreg[i]==0){
lreg[i]=1;
*reg1=i;
break;
}
}
}
// printf("\nreg1=%d",*reg1);
if(lreg[*reg2]!=0){
for(i=8;i!=0;i--){
if(lreg[i]==0){
*reg2=i;
break;
}
}
}
// printf(" reg2=%d\n",*reg2);
}
else{
if(base!=-1){
if(base==*reg1)*reg1=SI;
else if(base==*reg2)*reg2=DI;
if(*reg1==*reg2){
if(*reg1==SI)*reg2=DI;
else *reg2=SI;
}
}
if(idx!=-1){
if(idx==SI)*reg1=DI;
else *reg1=SI;
*reg2=CX;
}
}
}
void CheckAllMassiv(char *&buf,int sizeel,SINFO *strc,ITOK *ctok,int reg1,int reg2)
{
int zoom0,idx0,base0,newreg;
int zoom1=0,zoom2=0;
char pv=FALSE;
int razr=r32;
//printf("sib=%X\n",ctok->sib);
switch(ctok->sib){
case CODE16+2:
case CODE32+2: ctok->sib--;
case CODE16+1:
case CODE32+1: ctok->sib--;
}
if(ctok->sib==CODE16){
razr=r16;
if(am32)block16_32error();
}
if(buf==NULL&&strc->bufstr==NULL)return;
ExpandRm(ctok->rm,ctok->sib,&zoom0,&base0,&idx0);
if(base0==-1&&idx0!=-1&&zoom0==0){
base0=idx0;
idx0=-1;
}
CheckReg(idx0,base0,&reg1,&reg2,razr);
// printf("reg1=%d reg2=%d idx0=%d base0=%d zoom0=%d\n",reg1,reg2,idx0,base0,zoom0);
if(buf!=NULL){
if(*buf=='&'){
sizeel=1;
pv=TRUE;
ctok->flag&=~f_reloc;
}
if((newreg=CheckIDXReg(buf,sizeel,reg1))!=NOINREG){
if(newreg!=SKIPREG){
if(razr==r16){
if(newreg!=BX&&newreg!=DI&&newreg!=SI&&newreg!=BP)goto noopt;
if(base0!=-1&&(newreg==BX||newreg==BP))goto noopt;
if(idx0!=-1&&(newreg==DI||newreg==SI))goto noopt;
}
waralreadinitreg(regs[am32][reg1],regs[am32][newreg]);
reg1=newreg;
}
free(buf);
buf=NULL;
}
else{
if(razr==r32){
if((zoom1=CheckZoom(sizeel))){
sizeel=1;
if((newreg=CheckIDXReg(buf,sizeel,reg1))!=NOINREG){
if(newreg!=SKIPREG){
waralreadinitreg(regs[1][reg1],regs[1][newreg]);
reg2=reg1;
reg1=newreg;
}
free(buf);
buf=NULL;
goto cont1;
}
}
}
noopt:
if(razr==r32&&idx0==-1&&base0==-1&&zoom1==0){
ITOK wtok;
wtok=*ctok;
newreg=CheckMassiv(buf,sizeel,reg1,&idx0,&base0,&wtok.number);
*ctok=wtok;
// newreg=CheckMassiv(buf,sizeel,reg1);
}
else newreg=CheckMassiv(buf,sizeel,reg1);
if(newreg!=-1){
reg2=reg1;
reg1=newreg;
}
}
}
else{
reg2=reg1;
reg1=-1;
}
cont1:
// printf("reg1=%d reg2=%d idx0=%d base0=%d zoom0=%d\n",reg1,reg2,idx0,base0,zoom0);
if(strc->bufstr!=NULL){
sizeel=strc->size;
if((newreg=CheckIDXReg(strc->bufstr,sizeel,reg2))!=NOINREG){
if(newreg!=SKIPREG){
if(razr==r16){
if(newreg!=BX&&newreg!=DI&&newreg!=SI&&newreg!=BP)goto noopt2;
if(base0!=-1&&(newreg==BX||newreg==BP))goto noopt2;
if(idx0!=-1&&(newreg==DI||newreg==SI))goto noopt2;
}
waralreadinitreg(regs[am32][reg2],regs[am32][newreg]);
reg2=newreg;
}
free(strc->bufstr);
strc->bufstr=NULL;
}
else{
if(razr==r32&&zoom1==0){
if((zoom2=CheckZoom(sizeel))){
sizeel=1;
if((newreg=CheckIDXReg(strc->bufstr,sizeel,reg2))!=NOINREG){
if(newreg!=SKIPREG){
waralreadinitreg(regs[2][reg1],regs[2][newreg]);
reg2=newreg;
}
free(strc->bufstr);
strc->bufstr=NULL;
goto cont2;
}
}
}
noopt2:
if((newreg=CheckMassiv(strc->bufstr,sizeel,reg2))!=-1)reg2=newreg;
}
cont2:
if(reg1==-1){
reg1=reg2;
zoom1=zoom2;
reg2=-1;
zoom2=0;
}
}
else reg2=-1;
// printf("reg1=%d reg2=%d idx0=%d base0=%d zoom0=%d\n",reg1,reg2,idx0,base0,zoom0);
if(base0==-1){
if(reg1!=-1&&zoom1==0){
base0=reg1;
reg1=reg2;
zoom1=zoom2;
reg2=-1;
zoom2=0;
}
else if(reg2!=-1&&zoom2==0){
base0=reg2;
reg2=-1;
}
}
if(idx0==-1){
if(zoom1){
zoom0=zoom1;
zoom1=0;//zoom2;
idx0=reg1;
reg1=reg2;
reg2=-1;
}
else{
if(reg1!=-1){
idx0=reg1;
reg1=reg2;
zoom1=zoom2;
reg2=-1;
zoom2=0;
}
}
}
// printf("reg1=%d reg2=%d idx0=%d base0=%d zoom0=%d\n",reg1,reg2,idx0,base0,zoom0);
if(reg2!=-1){
if(zoom1==0&&zoom2==0){
op(3);
op(0xC0+reg1*8+reg2); //add reg1,reg2
}
else{
if(zoom1==0){
op(0x8d); //lea reg1,[reg1+reg2*zoom2]
op(reg1*8+4);
op((zoom2<<6)+(reg2<<3)+reg1);
}
else{
op(0x8d); //lea reg1,[reg2+reg1*zoom1]
op(reg1*8+4);
op((zoom1<<6)+(reg1<<3)+reg2);
zoom1=0;
}
}
ClearReg(reg1);
}
if(reg1!=-1){
if(base0!=-1){
if(zoom1==0){
op(3);
op(0xC0+reg1*8+base0); //add reg1,base0
}
else{
op(0x8d); //lea reg1,[base0+reg1*zoom1]
op(reg1*8+4);
op((zoom1<<6)+(reg1<<3)+base0);
}
}
else if(zoom1){
op(0xC1);
op(0xE0+reg1); //shl reg2,zoom2
op(zoom1);
}
base0=reg1;
}
if(razr==r32){
ctok->sib=CODE32;
if(idx0!=-1){
ctok->rm=4;
if(base0!=-1){
ctok->sib=(zoom0<<6)+(idx0<<3)+base0;
ctok->rm|=rm_mod10;
}
else ctok->sib=(zoom0<<6)+(idx0<<3)+5;
}
else{
ctok->rm=base0;
if(pv==FALSE)ctok->rm|=rm_mod10;
}
}
else{
if(base0==SI||base0==DI){
if(idx0==BX||idx0==BP||idx0==-1){
newreg=idx0;
idx0=base0;
base0=newreg;
}
else{
op(3);
op(0xC0+base0*8+idx0); //add base0,idx0
idx0=base0;
base0=-1;
}
}
if(idx0==BX||idx0==BP){
if(base0==-1){
newreg=idx0;
idx0=base0;
base0=newreg;
}
else{
op(3);
op(0xC0+base0*8+idx0); //add base0,idx0
idx0=base0;
base0=-1;
}
}
ctok->rm=CalcRm16(base0,idx0)|rm_mod10;
}
if(ctok->post==0&&(ctok->flag&f_reloc)==0)compressoffset(ctok);
}
int CheckMassiv(char *&buf,int sizeel,int treg,int *idx,int *base,long *num)
{
ITOK oitok;
SINFO ostr;
unsigned char *oldinput;
unsigned int oldinptr,oldendinptr;
unsigned char bcha;
int otok;
char *ostring;
char *ofsst;
int retcode=-1;
//07.09.04 22:45
COM_MOD *ocurmod=cur_mod;
cur_mod=NULL;
/////////////////
ostring=BackString((char *)string);
ofsst=BackString(buf);
free(buf);
buf=NULL;
oldinput=input; //сохр некотор переменые
oldinptr=inptr2;
bcha=cha2;
oldendinptr=endinptr;
otok=tok;
oitok=itok;
ostr=strinf;
strinf.bufstr=NULL;
if(idx&&*idx==-1&&*base==-1){
char *tbuf;
int i;
int idx0,base0;
long numr;
int operand;
int startptr,skipvar;
int firsttok;
i=0;
idx0=base0=-1;
numr=0;
if(*ofsst=='&')i++;
tbuf=BackString(ofsst+i);
// puts(tbuf);
input=(unsigned char *)tbuf;
inptr2=1;
cha2=input[0];
endinptr=strlen((char *)input);
operand=tk_plus;
startptr=0;
firsttok=tk_eof;
do{
skipvar=FALSE;
getoperand();
if(operand==tk_plus){
if(tok==tk_reg32){
if(itok.number!=treg){
skipvar=TRUE;
if(idx0==-1)idx0=itok.number;
else if(base0==-1)base0=itok.number;
else skipvar=FALSE;
}
else if(firsttok==tk_eof)firsttok=tk_reg32;
}
else if(tok==tk_number){
numr+=itok.number;
skipvar=TRUE;
}
else if(firsttok==tk_eof)firsttok=tok;
}
if(operand==tk_minus&&tok==tk_number){
numr-=itok.number;
skipvar=TRUE;
}
if(skipvar){
for(;startptr<inptr2-1;startptr++)input[startptr]=' ';
}
startptr=inptr2-1;
nexttok();
if(tok==tk_plus||tok==tk_minus){
if(firsttok==tk_eof){
if(tok==tk_minus)break;
for(;startptr<inptr2-1;startptr++)input[startptr]=' ';
startptr=inptr2-1;
firsttok=tok;
}
operand=tok;
}
else break;
}while(1);
// printf("%s (%u) >%s\n",(startfileinfo+currentfileinfo)->filename,linenumber,tbuf);
if(tok==tk_semicolon/*&&(idx0!=-1||base0!=-1)*/){
*idx=idx0;
*base=base0;
*num+=numr;
free(ofsst);
ofsst=tbuf;
// printf("idx0=%d base0=%d num=%d\n",idx0,base0,numr);
}
else free(tbuf);
}
input=(unsigned char *)ofsst;
inptr2=1;
cha2=input[0];
if(cha2=='&'){
inptr2=2;
cha2=input[1];
}
endinptr=strlen((char *)input);
getoperand();
if(am32&&sizeel==1&&tok==tk_reg32&&itok2.type==tp_stopper)retcode=itok.number;
else{
warningreg(regs[am32][treg]);
if((chip==7||chip==8)&&am32==FALSE&&((sizeel>1&&sizeel<6)||sizeel==8||sizeel==9)){
//избежать обращение к частному регистру
op(0x31);
op(0xC0+treg*9);
}
ofsst=NULL;
if(treg==AX)do_e_axmath(0,(am32+1)*2,&ofsst);
else getintoreg(treg,(am32+1)*2,0,&ofsst);
IDXToReg((char *)input,sizeel,treg);
}
strinf=ostr;
tok=otok;
itok=oitok;
endoffile=0;
free(input);
input=oldinput;
inptr2=oldinptr;
cur_mod=ocurmod; //07.09.04 22:45
cha2=bcha;
endinptr=oldendinptr;
otok=0;
strcpy((char *)string,ostring);
free(ostring);
if(sizeel>1)RegMulNum(treg,sizeel,(am32+1)*2,0,&otok,0);
return retcode;
}
void nextchar()
{
if(inptr<endinptr){
cha=input[inptr];
endoffile=0;
if(savestring3)string3[posstr3++]=cha;
inptr++;
precha=0;
if(inptr==endinptr&&cur_mod&&displaytokerrors){
precha=cur_mod->input[cur_mod->inptr];
// printf("cha=%02X\n",cha);
}
}
else{
if(cur_mod){
if(displaytokerrors){
inptr=cur_mod->inptr;
input=cur_mod->input;
// printf("last cha=%02X\n",input[inptr]);
if(cur_mod->numparamdef)clearregstat();
endinptr=cur_mod->endinptr;
linenumber=cur_mod->linenumber;
currentfileinfo=cur_mod->currentfileinfo;
COM_MOD *temp=cur_mod;
cur_mod=cur_mod->next;
if(temp->freze==FALSE){
if(temp->paramdef)free(temp->paramdef);
// if(debug)printf("Free curmod %08X new cur_mod %08X\n",temp,cur_mod);
free(temp);
}
// else if(debug)printf("Freze curmod %08X\n",temp);
nextchar();
// printf("%c\n",cha);
if(!cur_mod)notdef=TRUE;
}
else{
cha=cur_mod->input[cur_mod->inptr2];
cur_mod->inptr2++;
}
}
else{
cha=26;
endoffile++;
if(endoffile>2)unexpectedeof();
}
}
}
void ScanTok2()
{
inptr2=inptr;
linenum2=linenumber;
cha2=cha;
displaytokerrors=0;
tokscan(&tok2,&itok2,string2);
}
unsigned int ScanTok3()
{
unsigned int oinptr,oline,otok,rtok;
unsigned char ocha;
ITOK oitok;
ocha=cha;
oinptr=inptr;
oline=linenumber;
otok=tok;
oitok=itok;
do{
FastTok(1);
if(tok==tk_id||tok==tk_ID){
char disp=displaytokerrors;
displaytokerrors=0;
strcpy((char *)string3,itok.name);
searchtree(&itok,&tok,string3); //NEW 09.06.06 20:29
// searchtree2(definestart,&itok,&tok,string3);
displaytokerrors=disp;
}
}while(tok==tk_endline);
rtok=tok;
tok=otok;
cha=ocha;
itok=oitok;
inptr=oinptr;
linenumber=oline;
return rtok;
}
//extern idrec *crec;
void nexttok()
{
#ifdef DEBUGMODE
if(debug)puts("start nexttok");
#endif
inptr=inptr2;
linenumber=linenum2;
cha=cha2;
displaytokerrors=1;
tokscan(&tok,&itok,string); //разбор команды
// printf("input=%08X inptr=%08X tok=%d %s\n",input,inptr,tok,itok.name);
if(tok==tk_dblcolon&&numblocks){
skiplocals=TRUE;
tokscan(&tok,&itok,string); //разбор команды
}
ScanTok2();
if(tok2==tk_dblcolon&&numblocks){
skiplocals=TRUE;
tokscan(&tok2,&itok2,string2);
}
if(tok2==tk_tilda){
if(ScanTok3()==tk_number){
tok2=tk_number;
// puts("tok2=tk_tilda tok3=tk_number");
}
}
linenumber=linenum2;
// new !!! 02.04.02 20:22
if(tok==tk_int&&idasm==TRUE&&tok2==tk_number){
tok=tk_idasm;
itok.rm=a_int;
}
// new !!! 02.04.02 20:22
#ifdef DEBUGMODE
if(debug)printdebuginfo();
#endif
if(tok2==tk_number){
if(tok==tk_not){
nexttok();
if(itok.rm!=tk_float&&itok.rm!=tk_double){
if(scanlexmode==RESLEX){
if(itok.number)itok.number=0;
else itok.number=1;
}
else itok.lnumber^=-1;
}
else illegalfloat();
return;
}
if(tok==tk_tilda){
// puts("tok=tk_tilda tok2=tk_number");
nexttok();
if(itok.rm!=tk_float&&itok.rm!=tk_double)itok.lnumber=~itok.lnumber;
else illegalfloat();
return;
}
}
if(idasm==TRUE&&tok==tk_loop&&tok2!=tk_openbracket){
tok=tk_idasm;
itok.rm=a_loop;
return;
}
if(tok==tk_dollar){
if(itok2.type==tp_opperand||itok2.type==tp_stopper||tok2==tk_dollar){
tok=tk_number;
itok.number=outptr;
if(FixUp)itok.flag|=f_reloc; //new!!!
return;
}
int qq; //09.07.08 13:27 new
if((qq=CheckAsmName(itok2.name))!=-1){
tok=tk_idasm;
itok.rm=qq;
strcpy(itok.name,itok2.name);
ScanTok2();
}
}
if(tok>=tk_charvar&&tok<=tk_doublevar){
localrec *ptr;
ptr=itok.locrec;
switch(itok.type){
case tp_paramvar:
// case tp_ppointer:
// case tp_pfpointer:
if(ptr->fuse==NOTINITVAR&&tok2==tk_assign&&(!asmparam))warningnotused(itok.name,4);
goto llq;
case tp_localvar:
// case tp_lpointer:
// case tp_lfpointer:
if(ptr->fuse==NOTINITVAR&&tok2!=tk_assign){
if(asmparam)ptr->fuse|=INITVAR;
else warningusenotintvar(itok.name);
}
llq:
ptr->fuse|=(unsigned char)(tok2==tk_assign?INITVAR:USEDVAR);
break;
}
#ifdef OPTVARCONST
if(calcnumber&&CheckConstVar(&itok))tok=tk_number;
#endif
}
#ifdef OPTVARCONST
if(tok2>=tk_charvar&&tok2<=tk_doublevar){
if(calcnumber&&CheckConstVar(&itok2))tok2=tk_number;
}
#endif
if(usedirectiv==FALSE&&calcnumber==FALSE)while(tok==tk_question)directive();
//16.08.04 00:23
if(tok==tk_at&&tok2==tk_macro){
nexttok();
}
#ifdef OPTVARCONST
displaytokerrors=1;
#endif
// if(crec)printf("num=%08X\n",crec->recnumber);
}
void whitespace() //пропуск нзначащих символов
{
while(isspace(cha)||cha==255||cha==0){
if(cha==13){
linenumber++;
if((dbg&2)&&displaytokerrors&&notdef)startline=(char*)(input+inptr+1);
if(scanlexmode==RESLEX||scanlexmode==DEFLEX||scanlexmode==ASMLEX)break;
}
nextchar();
}
}
unsigned char convert_char()
//Returns the value of the current character. Parses \n and \x00 etc.
//cha equals the last character used.
{
int hold=0;
int i;
unsigned char c;
if(cha!='\\'){
if(cha==13){
linenumber++;
if((dbg&2)&&displaytokerrors&&notdef)startline=(char*)(input+inptr+1);
}
return(cha);
}
nextchar(); // move past '\\'
switch(cha){
case 'a': return('\a'); // what is \a anyway?
case 'b': return('\b');
case 'f': return('\f');
case 'l': return(10);
case 'n': return(13);
// case 'p': return('Ь');
case 'r': return(13);
case 't': return('\t');
case 'v': return('\v');
case 'x':
for(i=0;i<2;i++){
c=cha;
nextchar();
hold*=16;
if(isdigit(cha))hold+=cha-'0';
else if(isxdigit(cha))hold+=(cha&0x5f)-'7';
else{
// expectederror("hexadecimal digit");
if(savestring3)posstr3--;
inptr--;
cha=c;
break;
}
}
return (unsigned char)hold;
default:
if(isdigit(cha)){
hold=cha-'0';
for(i=0;i<2;i++){
c=cha;
nextchar();
if(isdigit(cha))hold=hold*10+(cha-'0');
else{
// expectederror("decimal digit");
if(savestring3)posstr3--;
inptr--;
cha=c;
break;
}
}
return (unsigned char)hold;
}
return cha;
}
}
void convert_string(unsigned char *str)
{
int k,j,i;
unsigned char c;
unsigned char hold;
for(k=0,j=0;;k++,j++){
c=str[k];
if(c=='\\'){
c=str[++k];
switch(c){
case 'a': hold='\a'; break; // what is \a anyway?
case 'b': hold='\b'; break;
case 'f': hold='\f'; break;
case 'l': hold=10; break;
case 'n': str[j++]=13; hold=10; break;
case 'r': hold=13; break;
case 't': hold='\t'; break;
case 'v': hold='\v'; break;
case 'x':
hold=0;
for(i=0;i<2;i++){
c=str[++k];
hold*=(unsigned char)16;
if(isdigit(c))hold+=(unsigned char)(c-'0');
else if(isxdigit(c))hold+=(unsigned char)((c&0x5f)-'7');
else{
k--;
break;
}
}
break;
default:
hold=c;
if(isdigit(c)){
hold-='0';
for(i=0;i<2;i++){
c=str[++k];
if(isdigit(c))hold=(unsigned char)(hold*10+(c-'0'));
else{
k--;
break;
}
}
}
}
str[j]=hold;
}
else str[j]=c;
if(c==0)break;
}
}
int CheckChar2()
{
if(isalnum(cha)||cha=='_'||cha>=0x80)return TRUE;
return FALSE;
}
void GetTokString(int *tok4,ITOK *itok4,unsigned char *string4,int useunicode)
{
int strptr=0;
if(displaytokerrors){
savestring3=TRUE;
posstr3=0;
}
nextstr:
nextchar(); //строковая константа
while(cha!='\"'&&!endoffile&&strptr<STRLEN-1){
string4[strptr++]=convert_char();
if((char)cha=='n'&&string4[strptr-1]==13){//have to add char 10 for \n value
string4[strptr++]=10;
}
nextchar();
}
if(displaytokerrors){
savestring3=FALSE;
string3[posstr3-1]=0;
}
if(strptr>=(STRLEN-1)&&displaytokerrors)preerror("Maximum String Length Exceeded");
string4[strptr]=0;
*tok4=tk_string;
// itok4->number=strptr;
itok4->rm=1; //есть оригинал строки
if(cha!='\"')expected('\"');
while(cha!='\"'&&!endoffile)nextchar(); //scan until closing '\"'
nextchar();
if(dosstring)itok4->flag=dos_term;
CheckConvertString((char *)string4);
switch(cha){
case 'z':
itok4->flag=zero_term;
nextchar();
break;
case 'n':
itok4->flag=no_term;
nextchar();
break;
case '$':
itok4->flag=dos_term;
nextchar();
break;
}
CheckConvertString((char *)string4);
// 10.08.04 22:20
whitespace(); //пропуск незначащих символов
if(cha=='\"'){
if(displaytokerrors)savestring3=TRUE;
goto nextstr;
}
if(useunicode&&displaytokerrors){
char *bak;
bak=BackString((char *)string4);
strptr=MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,bak,-1,(wchar_t *)string4,STRLEN)-1;
// printf("size string=%d\n",strptr);
// if(itok4->flag==no_term)strptr--;
strptr*=2;
// string4[strptr-2]=string4[strptr-1]=0;
itok4->flag|=s_unicod;
free(bak);
}
itok4->number=strptr;
}
void tokscan(int *tok4,ITOK *itok4,unsigned char *string4)
// поиск идентификаторов, директив ...
{
int useme;
unsigned int strptr=0;
char uppercase=1,next=1;
//установки по умолчанию
#ifdef DEBUGMODE
if(debug)printf("start tokscan input=%08X inptr=%08X %c%s\n",input,inptr,cha,input+inptr);
#endif
if(am32==FALSE){
itok4->rm=rm_d16;
itok4->sib=CODE16;
}
else{
itok4->rm=rm_d32;
itok4->sib=CODE32;
}
itok4->segm=DS;
itok4->lnumber=0;
itok4->post=0;
itok4->flag=0;
itok4->size=0;
itok4->rec=NULL;
itok4->type=tp_ucnovn;
itok4->npointr=0;
itok4->name[0]=0;
whitespace(); //пропуск незначащих символов
// if(displaytokerrors)printf("%c ",cha);
if(isalpha(cha)||(cha=='_')||(cha>=0x80)){ //идентификатор
do{
string4[strptr++]=cha;
if(islower(cha))uppercase=0;
nextchar();
}while((strptr<IDLENGTH)&&(CheckChar2()==TRUE));
if(strptr>=IDLENGTH){ //длина больше 32
if(displaytokerrors)preerror("Maximum length for an identifier exceeded");
while(CheckChar2()==TRUE)nextchar(); //дочитать слово
strptr=IDLENGTH-1; //обрезать до 32
}
if(cha=='~'&&strptr<IDLENGTH-1){
string4[strptr++]=cha;
nextchar();
if(cha!='('){
inptr--;
strptr--;
cha='~';
}
}
string4[strptr]=0;
strcpy(itok4->name,(char *)string4);
// if(displaytokerrors)printf("%s (%u) >%s\n",(startfileinfo+currentfileinfo)->filename,linenumber,itok4->name);
#ifdef DEBUGMODE
if (debug)printf("ID: '%s' cur_mod=%08X prev cur_mod=%08X\n",itok4->name,cur_mod,cur_mod==NULL?0:cur_mod->next);
#endif
if(scanlexmode==RESLEX){
if(stricmp((char *)string4,"not")==0)*tok4=tk_not;
else if(stricmp((char *)string4,"or")==0)*tok4=tk_or;
else if(stricmp((char *)string4,"xor")==0)*tok4=tk_xor;
else if(stricmp((char *)string4,"and")==0)*tok4=tk_and;
else{
if(uppercase)*tok4=tk_ID;
else *tok4=tk_id;
searchtree(itok4,tok4,string4);
if(*tok4==tk_id||*tok4==tk_ID){
if((useme=CheckResName(itok4->name))!=-1){
*tok4=tk_rescommand;
itok4->number=useme;
}
}
}
return;
}
if(uppercase){ //верхний регистр
if(strptr==1&&string4[0]=='L'&&cha=='"'){
itok4->name[0]=0;
GetTokString(tok4,itok4,string4,TRUE);
return;
}
*tok4=tk_ID;
if(string4[1]=='S'&&strptr>=5&&strptr<=8){
for(useme=0;useme<ID2S;useme++){ //проверка на ESBYTE ...
if(strcmp((char *)string4,id2[useme])==0){
*tok4=tk_charvar+useme%DATATYPES;
itok4->segm=useme/DATATYPES;
itok4->number=0;
itok4->post=POINTER;
goto yesid;
}
}
}
}
else *tok4=tk_id;
if(strptr==2){ //длина 2 символа check for AX, CX, DX, ...
if((string4[0]&0x5f)=='S'&&(string4[1]&0x5f)=='T'){
if(cha=='('){
nextchar();
if(cha>='0'&&cha<='7'){
itok4->number=cha-'0';
nextchar();
if(cha!=')')expected(')');
nextchar();
*tok4=tk_fpust;
}
}
else{
itok4->number=0;
*tok4=tk_fpust;
}
return;
}
if(asmparam||*tok4==tk_ID){
for(useme=0;useme<8;useme++){
int i;
if(asmparam)i=stricmp((char *)string4,regs[0][useme]);
else i=strcmp((char *)string4,regs[0][useme]);
if(i==0){
*tok4=tk_reg;
itok4->number=useme;
extreg:
if(cha=='.'){
tag_massiv(tok4,itok4,string4);
goto yesid;
}
return;
}
if(asmparam)i=stricmp((char *)string4,begs[useme]);
else i=strcmp((char *)string4,begs[useme]);
if(i==0){
*tok4=tk_beg;
itok4->number=useme;
return;
}
}
if(string4[1]=='S'||(asmparam&&string4[1]=='s')){
for(useme=0;useme<6;useme++){ // check for CS, SS, ...
if(string4[0]==segs[useme][0]||(asmparam&&(string4[0]&0x5F)==segs[useme][0])){
if(cha==':'){
int oinptr=inptr;
unsigned char ocha=cha;
int oline=linenumber;
nextchar();
/* switch(cha&(asmparam==FALSE?0xFF:0x5F)){
case 'E':
case 'B':
case 'S':
case 'D':*/
tokscan(tok4,itok4,string4);
if(*tok4>=tk_bits&&*tok4<=tk_doublevar){
itok4->segm=useme;
goto yesid;
}
// }
inptr=oinptr;
cha=ocha;
linenumber=oline;
}
*tok4=tk_seg;
itok4->number=useme;
return;
}
}
}
}
}
if(strptr==3&&(string4[0]=='E'||(asmparam&&string4[0]=='e'))){// check for EAX, ECX, EDX, ...
for(useme=0;useme<8;useme++){
int i;
if(asmparam)i=stricmp((char *)&string4[1],regs[0][useme]);
else i=strcmp((char *)&string4[1],regs[0][useme]);
if(i==0){
*tok4=tk_reg32;
itok4->number=useme;
extreg32:
if(cha=='.'){
tag_massiv(tok4,itok4,string4);
goto yesid;
}
if(cha==':'){
int oinptr=inptr;
unsigned char ocha=cha;
int oline=linenumber;
nextchar();
tokscan(tok4,itok4,string4);
if(*tok4==tk_reg32||*tok4==tk_reg){
itok4->number|=useme*256;
*tok4=tk_reg64;
goto yesid;
}
inptr=oinptr;
cha=ocha;
linenumber=oline;
}
return;
}
}
}
if(asmparam){
if((string4[1]&0x5f)=='R'){
if(string4[2]>='0'&&string4[2]<='7'){
itok4->number=string4[2]-'0';
switch((string4[0]&0x5f)){
case 'C': *tok4=tk_controlreg; return;// check for CR0, CR1, ...
case 'D': *tok4=tk_debugreg; return;//check for DR0, DR1, ...
case 'T': *tok4=tk_testreg; return;//check for TR0, TR1, ...
default: itok4->number=0; break;
}
}
}
else if((*(short *)&string[0]&0x5f5f)==0x4d4d){
if(string4[2]>='0'&&string4[2]<='7'){
itok4->number=string4[2]-'0';
*tok4=tk_mmxreg;
return;
}
}
else if((*(short *)&string[1]&0x5f5f)==0x4d4d&&(string4[0]&0x5f)=='X'){
if(string4[3]>='0'&&string4[3]<='7'){
itok4->number=string4[3]-'0';
*tok4=tk_xmmreg;
return;
}
}
}
if(useasm==FALSE){
if((useme=FastSearch(id,idofs,2,(char *)string4))!=-1)*tok4=useme;
else if(idasm==TRUE&&(useme=CheckAsmName((char *)string4))!=-1){
*tok4=tk_idasm;
itok4->rm=useme;
return;
}
}
if(*tok4==tk_id||*tok4==tk_ID){
if(cur_mod&&cur_mod->numparamdef&&(displaytokerrors||scanalltoks)){//18.03.05 15:12
/* if(debug&&cur_mod){
printf("Find %s in %d entries curmod=%08X\n",itok4->name,cur_mod->numparamdef,cur_mod);
COM_MOD *nmod;
nmod=cur_mod;
while(nmod){
printf("\tinput=%08X inptr=%08X\n",nmod->input,nmod->inptr);
nmod=nmod->next;
}
}*/
if(CheckDefPar(itok4->name)){
tokscan(tok4,itok4,string4);
if(displaytokerrors==0){
inptr=cur_mod->inptr;
input=cur_mod->input;
endinptr=cur_mod->endinptr;
linenumber=cur_mod->linenumber;
currentfileinfo=cur_mod->currentfileinfo;
COM_MOD *temp=cur_mod;
cur_mod=cur_mod->next;
free(temp);
nextchar();
}
#ifdef DEBUGMODE
if(debug)printf("1601 tok=%d input=%08X inptr=%08X disp=%d %s %c%40s\n\t%s\n",*tok4,input,inptr,displaytokerrors,itok4->name,cha,input+inptr,""/*input*/);
#endif
return;
}
}
if(searchlocals(itok4,tok4,string4)==FALSE){//поиск среди локальных меток
//если ничего не найдено поиск в дереве переменых
searchtree(itok4,tok4,string4);
if(*tok4==tk_endline){
if(scanlexmode!=DEFLEX){
tokscan(tok4,itok4,string4);
#ifdef DEBUGMODE
if(debug)printf("1610 tok=%d input=%08X inptr=%08X disp=%d %s %c%40s\n\t%s\n",*tok4,input,inptr,displaytokerrors,itok4->name,cha,input+inptr,""/*input*/);
#endif
return;
}
*tok4=tk_macro;
}
if(*tok4==tk_number||*tok4==tk_idasm)return;
if((*tok4>=tk_bits&&*tok4<=tk_doublevar)||*tok4==tk_pointer){
if(itok4->rm==rm_d16||itok4->rm==rm_d32){
if(am32==FALSE){
itok4->rm=rm_d16;
itok4->sib=CODE16;
}
else{
itok4->rm=rm_d32;
itok4->sib=CODE32;
}
}
if(itok4->post==DYNAMIC_POST){ //преобразовать динамическую локальную в локальную
if(alignword&&*tok4!=tk_charvar&&*tok4!=tk_bytevar){ //выровнять на четный адрес
switch(*tok4){
case tk_intvar:
case tk_wordvar:
if(postsize%2==1)postsize++;
break;
default:
if(postsize%4!=0)postsize+=4-(postsize%4);
break;
}
}
idrec *ptr=itok4->rec;
itok4->post=ptr->recpost=1;
itok4->number=ptr->recnumber=postsize;
if(am32==FALSE&&(postsize+itok4->size)>0xFFFFL)tobigpost();
postsize+=itok4->size;
}
else if(itok4->post==DYNAMIC_VAR){
idrec *ptr=itok4->rec;
itok4->post=ptr->recpost=USED_DIN_VAR;
}
}
}
if(tok==tk_reg)goto extreg;
if(tok==tk_reg32)goto extreg32;
}
switch(*tok4){
int len;
case tk_dataptr: *tok4=tk_number; itok4->number=outptrdata;
if(FixUp)itok.flag|=f_reloc; //new!!!
break;
case tk_codeptr: *tok4=tk_number; itok4->number=outptr;
if(FixUp)itok.flag|=f_reloc; //new!!!
break;
case tk_postptr: *tok4=tk_number; itok4->number=postsize; break;
case tk_line: *tok4=tk_number; itok4->number=linenumber; break;
case tk_file:
*tok4=tk_string;
strcpy((char *)string4,(startfileinfo+currentfileinfo)->filename);
itok4->number=strlen((char *)string4);
break;
case tk_structvar:
struct idrec *ptrs;
ptrs=itok4->rec;
// puts(itok4->name);
dostructvar2(tok4,itok4,(structteg *)ptrs->newid,string4);
break;
case tk_sizeof:
dosizeof(itok4);
if(itok4->post)*tok4=tk_postnumber;
else *tok4=tk_number;
break;
case tk_signed:
case tk_unsigned:
case tk_int:
case tk_long:
case tk_short:
if(itok4->type!=tp_modif){
GetTypeVar(tok4);
itok4->type=tp_modif;
}
break;
case tk_ID:
// printf("%s %s %d %c\n",itok.name,string4,strptr,cha);
if(strlen(itok4->name)==1&&itok4->name[0]=='L'&&cha=='"'){
itok4->name[0]=0;
GetTokString(tok4,itok4,string4,TRUE);
return;
}
case tk_id:
if(findofset==FALSE){
struct structteg *tteg;
// if(displaytokerrors)printf("find teg %s cha=%02X\n",itok4->name,cha);
if(((tteg=FindTeg(FALSE,itok4->name))!=NULL||
(tteg=FindTeg(TRUE,itok4->name))!=NULL)&&(cha=='.'||precha=='.')){
// if(displaytokerrors)puts("finding");
dostructvar2(tok4,itok4,tteg,string4);
// printf("tok=%d\n",*tok4);
if(displaytokerrors&&(*tok4==tk_proc||*tok4==tk_declare||
*tok4==tk_undefproc)&&(itok4->flag&f_static)==0)unknownobj(itok4->name);
}
}
break;
}
if(*tok4==tk_string&&displaytokerrors){
strcpy((char *)string3,(char *)string4);
if(itok4->rm==2){
convert_string(string4);
itok4->rm--;
}
if(dosstring)itok.flag=dos_term;
}
yesid:
if((*tok4>=tk_bits&&*tok4<=tk_doublevar)||*tok4==tk_pointer){
whitespace();//пропуск незначащих символов
if(cha=='[')calcrm(itok4,*tok4);//обработка выражения в []
}
if(itok4->rm!=rm_d16&&*tok4!=tk_proc&&*tok4!=tk_undefproc&&
*tok4!=tk_apiproc&&*tok4!=tk_declare&&(!(*tok4==tk_pointer&&itok4->type==tk_proc)))
if(itok4->post==0&&(itok4->flag&f_reloc)==0){ // cannot compress if POST var
compressoffset(itok4);
}
next=0;
}
else if(isdigit(cha)){//числа
inptr--;
itok4->lnumber=scannumber(&itok4->rm);
*tok4=tk_number;
next=0;
}
else switch(cha){
case '\"':
GetTokString(tok4,itok4,string4,FALSE);
next=0;
break;
case '\'': //символьная константа может иметь более 1 символа
nextchar();
next=0;
if(scanlexmode==RESLEX){
*tok4=tk_singlquote;
break;
}
*tok4=tk_number;
itok4->number=0;
while(cha!='\''&&!endoffile){ // special character
itok4->lnumber=itok4->lnumber*256+convert_char();
nextchar();
}
if(cha!='\''){
if(displaytokerrors)expected('\'');
}
else nextchar();
next=0;
break;
case '-':
nextchar();
switch(cha){
case '=': *tok4=tk_minusequals; break; //минус равно
case '-': *tok4=tk_minusminus; break; //минус-минус
default: *tok4=tk_minus; next = 0; itok4->type=tp_opperand; break;//минус
}
break;
case '+':
nextchar();
switch(cha){
case '=': *tok4=tk_plusequals; break; //плюс равно
case '+': *tok4=tk_plusplus; break; //плюс-плюс
default: whitespace(); // spaces allowed between
if(cha=='-')*tok4=tk_minus; // optimization of + -
else{
*tok4=tk_plus; //плюс
next=0;
}
itok4->type=tp_opperand;
break;
}
break;
case '*':
nextchar();
switch(cha){
case '=': *tok4=tk_multequals; break;
case '-': *tok4=tk_multminus; break; //умножить минус
default:
*tok4=tk_mult; //умножить
next=0;
}
itok4->type=tp_opperand;
break;
case '/': nextchar();
switch(cha){
case '*': nextchar(); //соментарий
useme=1;
while(!endoffile&&useme>0){
whitespace();
if(cha=='*'){
nextchar();
if(cha=='/'){
nextchar();
if(cha=='/')nextchar();
else useme--;
}
continue;
}
else if(cha=='/'){
nextchar();
if(cha=='*')useme++;
else if(cha=='/'){
nextchar();
continue;
}
else continue;
}
nextchar();
}
if(endoffile){
*tok4=tk_eof;
if(useme>0&&displaytokerrors)unexpectedeof();
}
else tokscan(tok4,itok4,string4);
break;
case '/':
do{
nextchar();
}while(!endoffile&&cha!=13); //строка коментария
if(endoffile)*tok4=tk_eof;
else{
if(scanlexmode==DEFLEX)*tok4=tk_endline;
else{
whitespace();
if(cha==13)nextchar();
tokscan(tok4,itok4,string4);
}
}
break;
case '=': *tok4=tk_divequals; nextchar(); return;
default:
whitespace();
if(cha=='-'){
*tok4=tk_divminus; //деление
nextchar();
}
else *tok4=tk_div;
itok4->type=tp_opperand;
break;
}
next=0;
break;
case '%':
nextchar();
whitespace();
if(cha=='-')*tok4=tk_modminus; //остаток от деления
else{
*tok4=tk_mod;
next=0;
}
itok4->type=tp_opperand;
break;
case '|':
nextchar();
switch(cha){
case '=': *tok4=tk_orequals; break; //OR=
case '|': *tok4=tk_oror; break; //OR-OR
default:
whitespace();
if(cha=='-')*tok4=tk_orminus; //OR-
else{
*tok4=tk_or;
if(cha==13)nextchar(); //OR
next=0;
}
itok4->type=tp_opperand;
break;
}
break;
case '&':
nextchar();
switch(cha){
case '=': *tok4=tk_andequals; break; //AND=
case '&': *tok4=tk_andand; break;
default:
whitespace();
if(cha=='-')*tok4=tk_andminus;
else{
*tok4=tk_and;
next=0;
}
itok4->type=tp_opperand;
break;
}
break;
case '!':
nextchar();
if(cha=='='){
*tok4=tk_notequal; //!=
itok4->type=tp_compare;
}
else{
*tok4=tk_not;
next=0;
}
break;
case '^':
nextchar();
if(cha=='=')*tok4=tk_xorequals; //XOR=
else{
whitespace();
if(cha=='-')*tok4=tk_xorminus;
else{
*tok4=tk_xor;
next=0;
}
itok4->type=tp_opperand;
}
break;
case '=':
nextchar();
if(cha=='='){
*tok4=tk_equalto; //==
itok4->type=tp_compare;
}
else{
*tok4=tk_assign; //присвоить
next=0;
}
break;
case '>':
nextchar();
switch(cha){
case '>':
nextchar();
if(cha=='=')*tok4=tk_rrequals; //сдвиг вправо с присвоением
else{
whitespace();
if(cha=='-')*tok4 = tk_rrminus;
else{
*tok4=tk_rr; //сдвиг вправо
next=0;
}
itok4->type=tp_opperand;
}
break;
case '<': *tok4=tk_swap; break; //обмен
case '=': *tok4=tk_greaterequal; itok4->type=tp_compare; break; //больше или равно
default: *tok4=tk_greater; next=0; itok4->type=tp_compare; break; //больше
}
break;
case '<':
nextchar();
switch(cha){
case '<':
nextchar();
if(cha=='=')*tok4=tk_llequals; //сдвиг влево с присвоением
else{
whitespace();
if(cha=='-')*tok4=tk_llminus;
else{
*tok4=tk_ll; //сдвиг влево
next=0;
}
itok4->type=tp_opperand;
}
break;
case '>': *tok4=tk_notequal; itok4->type=tp_compare; break; //!=
case '=': *tok4=tk_lessequal; itok4->type=tp_compare; break; //меньше или равно
default: *tok4=tk_less; next=0; itok4->type=tp_compare; break;//меньше
}
break;
case '#':
next=0;
nextchar();
findofset=TRUE;
tokscan(tok4,itok4,string4);
findofset=FALSE;
if((useme=GetDirective((char *)string4))!=-1){
itok4->number=useme;
*tok4=tk_question;
break;
}
if(*tok4==tk_dblcolon){
skiplocals=TRUE;
tokscan(tok4,itok4,string4);
}
/* char buf[16];
strncpy(buf,(char *)(input+inptr),15);
buf[15]=0;*/
// printf("sib=%08X tok=%d rm=%d post=%d number=%d size=%d segm=%d flag=%08X %s\n",itok4->sib,*tok4,itok4->rm,itok4->post,itok4->number,itok4->size,itok4->segm,itok4->flag,itok4->name/*,buf*/);
// printf("skiplocals=%d skipfind=%d searchteg=%08X\n",skiplocals,skipfind,searchteg);
switch(*tok4){
case tk_structvar:
// printf("%08X %s\n",itok4->sib,itok4->name);
if((itok4->sib&1)==0){
ofsstr(tok4,itok4);
// if(displaytokerrors)printf("sib=%08X tok=%d rm=%d post=%d number=%d size=%d segm=%d flag=%08X %s\n",itok4->sib,*tok4,itok4->rm,itok4->post,itok4->number,itok4->size,itok4->segm,itok4->flag,itok4->name/*,buf*/);
break;
}
itok4->rm=(am32==0?rm_d16:rm_d32);
case tk_struct:
*tok4=tk_number;
if(bufrm){
*tok4=tk_rmnumber;
if(itok4->type==tp_classvar)itok4->flag|=f_useidx;
}
break;
case tk_apiproc: //!!!16.12.06 23:06
itok4->rm=tk_undefofs;
*tok4=tk_apioffset;
if(FixUp)itok4->flag|=f_reloc; //new!!! 27.06.05 22:25
strcpy((char *)string4,itok4->name);
// printf("sib=%08X tok=%d rm=%d post=%d number=%d size=%d segm=%d %s\n",itok4->sib,*tok4,itok4->rm,itok4->post,itok4->number,itok4->size,itok4->segm,itok4->name/*,buf*/);
break;
case tk_proc:
case tk_interruptproc:
if(cha=='.')goto structofs;
procofs:
if(itok4->segm!=NOT_DYNAMIC){
if(displaytokerrors){
idrec *ptr=itok4->rec;
itok4->segm=ptr->recsegm=DYNAMIC_USED;
}
itok4->rm=*tok4=tk_undefofs; //смещение еще не известной метки
itok4->number=0;
// if(FixUp)itok4->flag|=f_reloc; //new!!! 27.06.05 22:25
}
else{
*tok4=tk_number;
itok4->segm=CS;//(splitdata==FALSE)?DS:CS;
// if(FixUp)itok4->flag|=f_reloc;
}
if(FixUp)itok4->flag|=f_reloc; //new!!! 27.06.05 22:25
strcpy((char *)string4,itok4->name);
// printf("sib=%08X tok=%d rm=%d post=%d number=%d size=%d segm=%d %s\n",itok4->sib,*tok4,itok4->rm,itok4->post,itok4->number,itok4->size,itok4->segm,itok4->name/*,buf*/);
break;
case tk_id:
case tk_ID:
structofs:
struct structteg *tteg;
if(((tteg=FindTeg(FALSE,itok4->name))!=NULL||
(tteg=FindTeg(TRUE,itok4->name))!=NULL)/*&&cha=='.'*/){
dostructvar2(tok4,itok4,tteg,string4);
// printf("sib=%08X tok=%d rm=%d post=%d number=%d size=%d %s\n",itok4->sib,*tok4,itok4->rm,itok4->post,itok4->number,itok4->size,itok4->name/*,buf*/);
if(*tok4==tk_proc)goto procofs;//04.10.04 14:25
if(*tok4==tk_declare)goto undefofs; //24.09.04 00:33
// printf("tok=%d segm=%d %s\n",*tok4,itok4->segm,itok4->name);
if(strinf.bufstr){
*tok4=tk_rmnumber;
if(itok4->type==tp_classvar)itok4->flag|=f_useidx;
}
else{
if(FixUp&&*tok4==tk_proc)itok4->flag|=f_reloc; //new!!!
else itok4->flag&=~f_reloc;
// else itok4->flag&=!f_reloc; 16.08.04 18:51
//30.09.04 20:22
if(itok4->post){
*tok4=tk_postnumber;
itok4->rm=tk_undefofs;
}
else
/////
*tok4=tk_number;
}
}
else{
undefofs:
itok4->rm=*tok4=tk_undefofs; //смещение еще не известной метки
itok4->number=0;
if(FixUp)itok4->flag|=f_reloc; //new!!!
}
case tk_number:
case tk_rmnumber:
break;
case tk_reg:
case tk_reg32:
itok4->rm=RegToRM(itok4->number,*tok4)/*|rm_mod10*/;
*tok4=(am32==0?tk_wordvar:tk_dwordvar);//tk_rmnumber;
itok4->number=0;
break;
default:
if(cha=='.')goto structofs;
if((*tok4>=tk_bits&&*tok4<=tk_doublevar)||tok==tk_pointer){
#ifdef OPTVARCONST
if(displaytokerrors)ClearVarByNum(itok4);
#endif
switch(itok4->type){
case tp_localvar:
case tp_paramvar:
localrec *ptr;
ptr=itok4->locrec;
ptr->fuse|=(unsigned char)(INITVAR|USEDVAR);
break;
case tk_proc:
itok4->rm=itok4->sib;
itok4->sib=am32==0?CODE16:CODE32;
break;
}
itok4->size=GetVarSize(*tok4);
if((itok4->sib==CODE16&&itok4->rm==rm_d16)||
(itok4->sib==CODE32&&itok4->rm==rm_d32)){
if(itok4->post==0){
*tok4=tk_number;
itok4->segm=DS;
if(FixUp)itok4->flag|=f_reloc;
itok4->rm=am32==FALSE?tk_word:tk_dword;
}
else{
*tok4=tk_postnumber;
itok4->rm=tk_undefofs;
}
}
else{
*tok4=tk_rmnumber;
if(itok4->type==tp_classvar)itok4->flag|=f_useidx;
}
}
else{
itok4->rm=*tok4=tk_undefofs; //смещение еще не известной метки
itok4->number=0;
strcpy((char *)string4,itok4->name);
}
break;
}
itok4->type=tp_ofs;
// if(displaytokerrors)printf("name=%s tok=%d post=%d flag=%08X rm=%d\n",itok4->name,*tok4,itok4->post,itok4->flag,itok4->rm);
break;
case '(':
if(*(unsigned short *)&(input[inptr])==
#ifdef _WC_
')E'
#else
'E)'
#endif
||
(*(unsigned short *)&(input[inptr])==
#ifdef _WC_
')e'
#else
'e)'
#endif
)){
for(useme=0;useme<8;useme++){
int i;
if(asmparam)i=strnicmp((char *)input+inptr+2,regs[0][useme],2);
else i=strncmp((char *)input+inptr+2,regs[0][useme],2);
if(i==0){
inptr+=4;
nextchar();
itok4->number=useme;
if(am32){
*tok4=tk_reg32;
goto extreg32;
}
*tok4=tk_reg;
goto extreg;
}
}
}
*tok4=tk_openbracket;
break;
case ':':
nextchar();
if(cha!=':'){
next=0;
*tok4=tk_colon;
}
else *tok4=tk_dblcolon;
break;
case ';': itok4->type=tp_stopper; *tok4=tk_semicolon; break;
case ')': itok4->type=tp_stopper; *tok4=tk_closebracket; break;
case '{': *tok4=tk_openbrace; break;
case '}': itok4->type=tp_stopper; *tok4=tk_closebrace; break;
case '[': *tok4=tk_openblock; break;
case ']': itok4->type=tp_stopper; *tok4=tk_closeblock; break;
case ',': itok4->type=tp_stopper; *tok4=tk_camma; break;
case '.':
next=0;
nextchar();
if(cha!='.'){
*tok4=tk_period;
break;
}
nextchar();
if(cha!='.'){
badtoken();
nextchar();
tokscan(tok4,itok4,string4);
break;
}
nextchar();
*tok4=tk_multipoint;
break;
case '@': *tok4=tk_at; break;
case '$': *tok4=tk_dollar; break;
case '?':
nextchar();
tokscan(tok4,itok4,string4);
*tok4=tk_question;
itok4->number=GetDirective((char *)string4);
return;
case '~': *tok4=tk_tilda; break;
case 26: *tok4=tk_eof; return;
case 13: *tok4=tk_endline; break;
case '\\':
nextchar();
if(cha==13){
tokscan(tok4,itok4,string4);
if(*tok4==tk_endline)tokscan(tok4,itok4,string4);
return;
}
default:
badtoken();
nextchar();
tokscan(tok4,itok4,string4);
return;
}
if(next)nextchar();
#ifdef DEBUGMODE
if(debug)printf("2172 tok=%d input=%08X inptr=%08X disp=%d %s %X %s\n",*tok4,input,inptr,displaytokerrors,itok4->name,cha,input+inptr);
#endif
}
void NewMod(int numipar)
{
COM_MOD *newm;
int oline;
int numpar=0,ns,i,size,nsize;
char *buf=NULL;
newm=(COM_MOD *)MALLOC(sizeof(COM_MOD));
newm->numparamdef=numipar;
newm->freze=FALSE;
size=0;
whitespace();
if(cha=='('){
nextchar();
whitespace();
if(cha!=')'){
inptr--;
oline=linenumber;
for(i=inptr,ns=1;ns>0;i++){ //поиск параметров
switch(input[i]){
case '(': ns++; break;
case ')': ns--; break;
case ',':
if(ns==1){
numpar++;
nsize=i-inptr;
if(!buf)buf=(char *)MALLOC(nsize+1);
else buf=(char *)REALLOC(buf,size+nsize+1);
strncpy(buf+size,(char *)(input+inptr),nsize);
buf[size+nsize]=0;
strbtrim(buf+size);
// puts(buf+size);
size+=strlen(buf+size)+1;
inptr+=nsize+1;
}
break;
case '/':
i=skipcomment(i);
break;
case '"':
case 0x27:
i=skipstring(i,input[i]);
break;
}
if((unsigned int)i>=endinptr){
unexpectedeof();
break;
}
}
linenumber=oline;
numpar++;
nsize=i-inptr;
if(!buf)buf=(char *)MALLOC(nsize);
else buf=(char *)REALLOC(buf,size+nsize);
strncpy(buf+size,(char *)(input+inptr),nsize-1);
buf[size+nsize-1]=0;
strbtrim(buf+size);
// puts(buf+size);
inptr=i;
}
if(numipar>numpar)missingpar(itok.name);
else if(numipar<numpar)extraparam(itok.name);
newm->numparamdef=numpar;
}
else inptr--;
newm->input=input;
newm->inptr2=newm->inptr=inptr;
newm->endinptr=endinptr;
newm->linenumber=linenumber;
newm->currentfileinfo=currentfileinfo;
newm->paramdef=buf;
newm->next=cur_mod;
cur_mod=newm;
// if(debug)printf("New curmod %08X numpar=%d input=%08X prev curmod=%08X\n",cur_mod,numipar,input,cur_mod->next);
nextchar();
/* char *temp=buf;
for(i=0;i<numpar;i++){
nsize=strlen(temp)+1;
puts(temp);
temp+=nsize;
}*/
}
void BackMod()
{
if(cur_mod){
inptr=cur_mod->inptr;
inptr2=cur_mod->inptr2;
input=cur_mod->input;
endinptr=cur_mod->endinptr;
linenumber=cur_mod->linenumber;
currentfileinfo=cur_mod->currentfileinfo;
cur_mod=cur_mod->next;
cha2=input[inptr2];
}
}
char *FindDefPar(char *name,COM_MOD *cmod)
{
char *temp;
int i,numpar,nsize=0;
numpar=cmod->numparamdef;
temp=cmod->declareparamdef;
// if(debug)printf("check for %s\n",name);
for(i=0;i<numpar;i++){
nsize=strlen(temp)+1;
// if(debug)printf("\t%s\n",temp);
if(strcmp(name,temp)==0){
temp=cmod->paramdef;
for(;i>0;i--){
temp+=strlen(temp)+1;
}
return temp;
}
temp+=nsize;
}
return NULL;
}
int CheckDefPar(char *name)
{
char *temp,*nname;
COM_MOD *fmod;
fmod=cur_mod;
nname=name;
while((temp=FindDefPar(nname,fmod))!=NULL){
nname=temp;
if(fmod->next==NULL)break;
fmod=fmod->next;
}
if(fmod==cur_mod&&temp==NULL)return FALSE;
SetNewStr(nname);
return TRUE;
}
void SetNewStr(char *name)
{
COM_MOD *fmod;
fmod=(COM_MOD *)MALLOC(sizeof(COM_MOD));
fmod->next=cur_mod;
fmod->numparamdef=0;
fmod->paramdef=NULL;
fmod->freze=FALSE;
fmod->input=input;
fmod->inptr2=fmod->inptr=inptr-1;
fmod->endinptr=endinptr;
fmod->linenumber=linenumber;
fmod->currentfileinfo=currentfileinfo;
cur_mod=fmod;
// if(debug)printf("new curmod %08X prev cur_mod=%08X old input %08X %s\n",cur_mod,cur_mod->next,input,name);
input=(unsigned char*)(name);
inptr=1;
cha=input[0];
endinptr=strlen(name)+1;
}
int searchtree2(idrec *fptr,ITOK *itok4,int *tok4,unsigned char *string4)
//поиск в дереве переменых
{
struct idrec *ptr;
int cmpresult;
for(ptr=fptr;ptr!=NULL;){
if((cmpresult=strcmp(ptr->recid,(char *)string4))==0){
if(scanlexmode==RESLEX&&ptr->rectok!=tk_number&&ptr->rectok!=tk_string)break;
itok4->lnumber=ptr->reclnumber;
itok4->rm=ptr->recrm;
*tok4=ptr->rectok;
itok4->post=ptr->recpost;
itok4->segm=ptr->recsegm;
itok4->flag|=ptr->flag;
itok4->size=ptr->recsize;
itok4->sib=ptr->recsib;
itok4->rec=ptr;
itok4->type=ptr->type;
itok4->npointr=ptr->npointr;
// if(debug)printf("Find: tok=%d\n",*tok4);
if(displaytokerrors){
ptr->count++;
// printf("%s notdoneprestuff=%d tok=%d segm=%d\n",itok4->name,notdoneprestuff,*tok4,itok4->segm);
if(notdoneprestuff==2&&*tok4==tk_proc&&itok4->segm==DYNAMIC)AddDynamicList(ptr);
}
if(*tok4==tk_macro){
// printf("tok=%d %s %s\n",*tok4,itok4->name,input);
if(dirmode==dm_if)return TRUE;
if(scanlexmode==DEFLEX||scanlexmode==DEFLEX2)*tok4=tk_id;
else if(displaytokerrors){
NewMod(itok4->size);
notdef=FALSE;
cur_mod->declareparamdef=ptr->newid;
input=(unsigned char*)(ptr->sbuf);
inptr=1;
cha=input[0];
endinptr=strlen((char *)input);
// if(debug)printf("New cur_mod tok=%d numpar=%d %s %s\n",*tok4,cur_mod->numparamdef,itok4->name,input);
// debug=TRUE;
clearregstat();
*tok4=tk_endline;
return TRUE;
}
}
else if(ptr->newid){
switch(*tok4){
case tk_string:
memcpy((char *)string4,ptr->newid,itok4->number);
if(displaytokerrors&&itok4->rm==1&&ptr->sbuf)strcpy((char *)string3,ptr->sbuf);
break;
case tk_structvar:
itok4->segm=0;
if(ptr->recpost==DYNAMIC_POST){
ptr->recpost=itok4->post=1;
if(alignword){ //выровнять на четный адрес
if(postsize%2==1)postsize++;
}
itok4->number=ptr->recnumber=postsize;
if(am32==FALSE&&(ptr->recsize+postsize)>0xFFFFL)tobigpost();
postsize+=ptr->recsize;
}
else if(ptr->recpost==DYNAMIC_VAR)itok4->post=ptr->recpost=USED_DIN_VAR;
return TRUE;
case tk_proc:
case tk_apiproc:
case tk_declare:
case tk_undefproc:
strcpy((char *)string4,ptr->newid);
break;
default:
if(scanlexmode==DEFLEX2){
*tok4=tk_id;
return TRUE;
}
strcpy((char *)string4,ptr->newid);
if(strcmp((char *)string4,ptr->recid)!=0){ // see if ID has changed
// searchtree2(fptr,itok4,tok4,string4); // search again
searchtree(itok4,tok4,string4); // search again
switch(*tok4){
case tk_proc:
case tk_apiproc:
case tk_declare:
case tk_undefproc:
strcpy(itok4->name,ptr->recid); //имя нужно для undefine
break;
default:
strncpy(itok4->name,(char *)string4,IDLENGTH-1); //имя нужно для undefine
break;
}
return TRUE;
}
break;
}
}
else string4[0]=0;
strcpy(itok4->name,ptr->recid); //имя нужно для undefine
if(displaytokerrors)ptr->count++;
break;
}
else if(cmpresult<0)ptr=ptr->left;
else ptr=ptr->right;
}
if(ptr==NULL)return FALSE;
else return TRUE;
}
int searchtree(ITOK *itok4,int *tok4,unsigned char *string4)
{
int retval=FALSE;
if(skipfind==FALSE){
if(staticlist)retval=searchtree2(staticlist,itok4,tok4,string4);
if(!retval)retval=searchtree2(treestart,itok4,tok4,string4);
if(!retval){
if((retval=searchtree2(definestart,itok4,tok4,string4))==TRUE){
if(scanlexmode==DEFLEX2)*tok4=tk_id;
}
}
}
return retval;
}
void AddDynamicList(idrec *ptr)
{
// printf("Add dinamic list %s %08X seg=%d tok=%d\n",ptr->recid,ptr,ptr->recsegm,ptr->rectok);
if(DynamicList==NULL){
sizeDL=STEPDL;
DynamicList=(volatile idrec **)MALLOC(sizeof(idrec **)*sizeDL);
countDP=0;
}
else if(sizeDL==(countDP+1)){
sizeDL+=STEPDL;
DynamicList=(volatile idrec **)REALLOC(DynamicList,sizeof(idrec **)*sizeDL);
}
for(int i=0;i<countDP;i++)if(ptr==DynamicList[i])return;
DynamicList[countDP]=ptr;
countDP++;
}
void docals(struct idrec *ptr)
/* extract any procedures required from interal library and insert any
dynamic procedures that have been called.*/
{
if(ptr!=NULL){
// printf("%s\n",ptr->recid);
tok=ptr->rectok;
if(sdp_mode==FALSE&&(ptr->flag&f_export)!=0&&tok==tk_proc){
if(lexport==NULL){
lexport=(struct listexport *)MALLOC(sizeof(struct listexport));
lexport->address=ptr->recnumber;
strcpy(lexport->name,ptr->recid);
numexport=1;
}
else{
int cmpname,i;
for(i=0;i<numexport;i++){
if((cmpname=strcmp(ptr->recid,(lexport+i)->name))<=0)break;
}
if(cmpname!=0){
lexport=(struct listexport *)REALLOC(lexport,sizeof(struct listexport)*(numexport+1));
if(cmpname<0){
for(int j=numexport;j>i;j--){
memcpy(&(lexport+j)->address,&(lexport+j-1)->address,sizeof(struct listexport));
}
}
numexport++;
(lexport+i)->address=ptr->recnumber;
strcpy((lexport+i)->name,ptr->recid);
}
}
}
if(!(ptr->flag&f_extern)){
if(tok==tk_undefproc){
strcpy(itok.name,ptr->recid);
if(sdp_mode){
int boutptr=outptr;
int i;
if((ptr->flag&f_typeproc)==tp_fastcall){
if((i=includeit(1))!=-1){
if(updatecall((unsigned int)ptr->recnumber,boutptr,0)>0){
ptr->rectok=tk_proc;
ptr->recnumber=boutptr; // record location placed
ptr->recrm=i;
ptr->count++;
}
}
}
else{
if((i=includeproc())!=-1){
if(updatecall((unsigned int)ptr->recnumber,boutptr,0)>0){
ptr->rectok=tk_proc;
ptr->recnumber=boutptr; // record location placed
ptr->recrm=i;
ptr->count++;
}
}
}
}
else{
if(updatecall((unsigned int)ptr->recnumber,outptr,0)>0){
ptr->recnumber=outptr; // record location placed
linenumber=ptr->line;
currentfileinfo=ptr->file;
if((ptr->flag&f_typeproc)==tp_fastcall){
if(includeit(1)==-1)thisundefined(itok.name);
}
else{
if(includeproc()==-1)thisundefined(itok.name);
}
ptr->rectok=tk_proc;
ptr->count++;
}
}
}
else if(tok==tk_proc){
// printf("%08X %s\n",ptr->recpost,ptr->recid);
itok.segm=ptr->recsegm;
if(itok.segm==DYNAMIC_USED){
// printf("%08X %s\n",ptr->recpost,ptr->recid);
// if(updatecall((unsigned int)ptr->recnumber,outptr,0)>0){
itok.number=ptr->recnumber;
itok.flag=ptr->flag;
itok.post=ptr->recpost;
strcpy(itok.name,ptr->recid);
if(ptr->newid==NULL)string[0]=0;
else strcpy((char *)string,(char *)ptr->newid);
itok.rm=ptr->recrm;
itok.size=ptr->recsize;
itok.rec=ptr;
insert_dynamic();
// }
}
}
// else printf("tok=%d %s\n",tok,ptr->recid);
}
docals(ptr ->left);
docals(ptr ->right);
}
}
void docalls2()
{
// puts("start docalls2");
docals(treestart);
for(unsigned int i=0;i<totalmodule;i++)docals((startfileinfo+i)->stlist);
// puts("end docalls2");
}
void docalls() /* attempt to declare undefs from library and dynamic proc's */
{
int numdinproc;
// puts("start docalls");
notdoneprestuff=2;
docalls2();
while(DynamicList!=NULL){
idrec *ptr;
numdinproc=0;
// printf("%d dinamic proc\n",countDP);
for(int i=0;i<countDP;i++){
ptr=(idrec *)DynamicList[i];
tok=ptr->rectok;
itok.segm=ptr->recsegm;
// printf("%d %08X seg=%d tok=%d %s\n",i+1,ptr,itok.segm,ptr->rectok,ptr->recid);
if(itok.segm==DYNAMIC_USED){
itok.number=ptr->recnumber;
itok.flag=ptr->flag;
strcpy(itok.name,ptr->recid);
if(ptr->newid==NULL)string[0]=0;
else strcpy((char *)string,(char *)ptr->newid);
itok.rm=ptr->recrm;
itok.size=ptr->recsize;
itok.rec=ptr;
insert_dynamic();
numdinproc++;
}
}
docalls2();
if(numdinproc==0)break;
}
free(DynamicList);
DynamicList=NULL;
countDP=0;
// puts("end docalls");
}
void CreatParamDestr(idrec *ptrs)
{
if(am32==FALSE){
structadr.rm=rm_d16;
structadr.sib=CODE16;
}
else{
structadr.rm=rm_d32;
structadr.sib=CODE32;
}
structadr.segm=DS;
structadr.number=ptrs->recnumber;
structadr.flag=0;
structadr.size=0; //addofs
structadr.rec=NULL;
structadr.type=tp_ucnovn;
structadr.npointr=0;
structadr.post=ptrs->recpost;
if(ptrs->recsegm==USEDSTR)structadr.sib++;
if(structadr.post==LOCAL){
if(ESPloc&&am32){
structadr.rm=rm_mod10|rm_sib;
structadr.sib=0x24;
structadr.number+=addESP;
}
else{
structadr.rm=rm_mod10|(am32==FALSE?rm_BP:rm_EBP);
}
structadr.segm=SS;
compressoffset(&structadr);
}
}
void CallDestr(idrec *ptr)
{
int oinptr2;
char ocha2;
int oldendinptr=endinptr;
unsigned char odbg;
int otok,otok2;
unsigned char *oinput;
ITOK oitok; //18.08.04 19:07
oinptr2=inptr2;
ocha2=cha2;
odbg=dbg;
dbg=0;
otok=tok;
otok2=tok2;
oitok=itok; //18.08.04 19:07
oinput=input;
string[0]=0;
if(ptr->newid)strcpy((char *)string,ptr->newid);
itok.type=ptr->type;
itok.npointr=ptr->npointr;
itok.rm=ptr->recrm;
itok.flag=ptr->flag;
itok.rec=ptr;
strcpy(itok.name,ptr->recid);
itok.number=ptr->recnumber;
tok=ptr->rectok;
itok.post=ptr->recpost;
itok.segm=ptr->recsegm;
itok.sib=ptr->recsib;
ptr->count++;
if(itok.segm==DYNAMIC)AddDynamicList(ptr);
tok2=tk_openbracket;
input=(unsigned char*)"();";
inptr2=1;
cha2='(';
endinptr=3;
docommand();
tok=otok;
input=oinput;
inptr2=oinptr2;
cha2=ocha2;
tok2=otok2;
endinptr=oldendinptr;
dbg=odbg;
itok=oitok;//18.08.04 19:07
}
elementteg *FindOneDestr(structteg *searcht)
{
elementteg *bazael=searcht->baza,*retrez=NULL;
idrec *ptrs;
int i;
/// new!
for(i=0;i<searcht->numoper;i++){
ptrs=(bazael+i)->rec;
if((bazael+i)->tok==tk_proc&&(ptrs->flag&fs_destructor)!=0)return(bazael+i);
}
for(i=0;i<searcht->numoper;i++){
ptrs=(bazael+i)->rec;
if((bazael+i)->tok==tk_baseclass
||(bazael+i)->tok==tk_struct //new 20.06.05 21:32
){
if((retrez=FindOneDestr((structteg *)ptrs))!=NULL)break;
}
}
return retrez;
}
void Destructor(idrec *ptrs)
{
char name[IDLENGTH];
struct elementteg *bazael;
int addofs;
structteg *tteg;
tteg=(structteg *)ptrs->newid;
sprintf(name,"%s~",tteg->name);
if((bazael=FindClassEl(tteg,(unsigned char *)name,&addofs,NULL))==NULL){
if((bazael=FindOneDestr(tteg))==NULL)preerror("destructor not defined");
}
if(ptrs->recsize)CreatParamDestr(ptrs);
else structadr.sib=THIS_ZEROSIZE;
CallDestr(bazael->rec);
}
void RunNew(int size)
{
char buf[128];
int oinptr2;
char ocha2;
int oldendinptr=endinptr;
unsigned char odbg;
int otok,otok2;
unsigned char *oinput;
oinptr2=inptr2;
ocha2=cha2;
odbg=dbg;
sprintf(buf,"__new(%u);}",size);
dbg=0;
otok=tok;
otok2=tok2;
oinput=input;
input=(unsigned char*)buf;
inptr2=1;
cha2='_';
tok=tk_openbrace;
endinptr=strlen(buf);
doblock();
tok=otok;
tok2=otok2;
input=oinput;
inptr2=oinptr2;
cha2=ocha2;
endinptr=oldendinptr;
dbg=odbg;
}
void donew()
{
structteg *tteg;
elementteg *bazael;
int addofs=0;
struct idrec *ptr;
nexttok();
if((tteg=FindTeg(FALSE))==NULL&&(tteg=FindTeg(TRUE))==NULL){
tegnotfound();
er:
while(tok2!=tk_semicolon&&tok!=tk_eof)nexttok();
return;
}
// printf("flag=%08X\n",tteg->flag);
if((tteg->flag&fs_constructor)==0){
RunNew(tteg->size);
goto er;
}
bazael=FindClassEl(tteg,(unsigned char *)tteg->name,&addofs,NULL);
structadr.sib=THIS_NEW;
structadr.number=tteg->size;
ptr=bazael->rec;
string[0]=0;
if(ptr->newid!=NULL)strcpy((char *)string,ptr->newid);
itok.type=ptr->type;
itok.npointr=ptr->npointr;
itok.rm=ptr->recrm;
itok.flag=ptr->flag;
itok.rec=ptr;
strcpy(itok.name,ptr->recid);
itok.number=ptr->recnumber;
tok=ptr->rectok;
itok.post=ptr->recpost;
itok.segm=ptr->recsegm;
itok.sib=ptr->recsib;
ptr->count++;
if(itok.segm==DYNAMIC)AddDynamicList(ptr);
// docommand();
if(dbg)AddLine();
int oflag=current_proc_type;
current_proc_type&=~f_static;
if(tok==tk_proc)doanyproc();
else doanyundefproc();
current_proc_type=oflag;
}
void dodelete()
{
int addofs=0;
int oinptr,oinptr2;
char ocha2;
int oldendinptr=endinptr;
unsigned char odbg;
unsigned char *oinput;
structteg *tteg=NULL;
elementteg *bazael;
char buf[128];
getoperand();
if(tok==tk_structvar){
oinptr=tok2;
// if((itok.flag&fs_useconstr)!=0){
if((itok.flag&fs_destructor)!=0){
Destructor(itok.rec);
}
else if(itok.rec->newid&&AskUseDestr((structteg *)itok.rec->newid))Destructor(itok.rec);
// }
if(oinptr!=tk_semicolon)nexttok();
}
else{
ITOK wtok;
char *wbuf;
wbuf=bufrm;
bufrm=NULL;
wtok=itok;
SINFO wstr;
wstr=strinf;
strinf.bufstr=NULL;
getinto_e_ax(0,tok,&wtok,wbuf,&wstr,(am32+1)*2);
bufrm=NULL;
strinf.bufstr=NULL;
if(tok2!=tk_semicolon){
nexttok();
if((tteg=FindTeg(FALSE))==NULL&&(tteg=FindTeg(TRUE))==NULL){
tegnotfound();
while(tok!=tk_semicolon&&tok!=tk_eof)nexttok();
return;
}
}
oinptr2=inptr2;
ocha2=cha2;
odbg=dbg;
dbg=0;
oinput=input;
int oflag=current_proc_type;
current_proc_type&=~f_static;
if(tteg){
structadr.number=0;
if((tteg->flag&fs_destructor)!=0){
op(0x50);
addESP+=am32==FALSE?2:4;
sprintf(buf,"%s~",tteg->name);
bazael=FindClassEl(tteg,(unsigned char *)buf,&addofs,NULL);
structadr.sib=THIS_REG;
structadr.rm=AX;
structadr.size=addofs; // ???? 19.08.04 12:54 нигде не используется
CallDestr(bazael->rec);
addESP-=am32==FALSE?2:4;
op(0x58);
}
else if(AskUseDestr(tteg)){
bazael=FindOneDestr(tteg);
op(0x50);
addESP+=am32==FALSE?2:4;
structadr.sib=THIS_REG;
structadr.rm=AX;
structadr.size=0;//addofs;
CallDestr(bazael->rec);
addESP-=am32==FALSE?2:4;
op(0x58);
}
}
input=(unsigned char*)"__delete((E)AX);}";
inptr2=1;
cha2='_';
endinptr=strlen((char *)input);
tok=tk_openbrace;
doblock();
input=oinput;
inptr2=oinptr2;
cha2=ocha2;
endinptr=oldendinptr;
dbg=odbg;
current_proc_type=oflag;
}
nextseminext();
}
int AskUseDestr(structteg *searcht)
{
elementteg *bazael=searcht->baza;
if((searcht->flag&fs_destructor)!=0)return TRUE;
for(int i=0;i<searcht->numoper;i++){
// printf("tok=%d\n",(bazael+i)->tok);
if((bazael+i)->tok==tk_baseclass
||(bazael+i)->tok==tk_struct //new 20.06.05 21:33
){
if(AskUseDestr((structteg *)(bazael+i)->rec))return TRUE;
}
}
return FALSE;
}
void AutoDestructor()
{
struct localrec *ptrs;
int calldestruct=FALSE;
int zerosize=FALSE;
treelocalrec *ftlr;
for(ftlr=tlr;ftlr!=NULL;ftlr=ftlr->next){
for(ptrs=ftlr->lrec;ptrs!=NULL;ptrs=ptrs->rec.next){
if(ptrs->rec.rectok==tk_structvar){
if((ptrs->rec.flag&fs_destructor)!=0||AskUseDestr((structteg *)ptrs->rec.newid)){
if(!calldestruct){
calldestruct=TRUE;
if(ptrs->rec.recsize==0||returntype==tk_void)zerosize=TRUE;
else{
op66(r32);
op(0x50);
addESP+=4;
}
}
Destructor(&ptrs->rec);
}
}
}
}
if(calldestruct&&zerosize==FALSE){
op66(r32);
op(0x58);
addESP-=4;
}
}
elementteg *FindClassEl(structteg *searcht,unsigned char *string4,int *addofs,
structteg *subteg)
{
struct elementteg *bazael=searcht->baza;
int numclass=0;
void **listclass;
//11.08.04 22:54
char name[IDLENGTH];
strcpy(name,searcht->name);
for(unsigned int i=0;i<searcht->numoper;i++){
if((bazael+i)->tok==tk_baseclass){
if(!numclass)listclass=(void **)MALLOC(sizeof(void **));
else listclass=(void **)REALLOC(listclass,sizeof(void **)*(numclass+1));
listclass[numclass]=(void *)(bazael+i)->nteg;
numclass++;
continue;
}
if(strcmp((bazael+i)->name,(char *)string4)==0){
if(subteg&&subteg!=searcht)continue;
if(numclass)free(listclass);
//11.08.04 22:54
strcpy((char *)string4,name);
return (bazael+i);
}
}
if(numclass){
structteg *ssubteg=subteg;
for(int i=numclass-1;i>=0;i--){
structteg *s=(structteg *)listclass[i];
if(subteg==searcht)ssubteg=s;
if((bazael=FindClassEl(s,string4,addofs,ssubteg))!=NULL){
i--;
while(i>=0){
s=(structteg *)listclass[i];
*addofs+=s->size;
i--;
}
free(listclass);
return bazael;
}
}
free(listclass);
}
return NULL;
}
int CallDestructor(structteg *searcht)
{
elementteg *bazael=searcht->baza;
idrec *ptrs;
for(int i=0;i<searcht->numoper;i++){
ptrs=(bazael+i)->rec;
if((searcht->flag&fs_destructor)==0){
if((bazael+i)->tok==tk_baseclass){
if(CallDestructor((structteg *)ptrs))return TRUE;
}
}
else if((bazael+i)->tok==tk_proc&&(ptrs->flag&fs_destructor)!=0){
structadr.sib=THIS_PARAM;
structadr.number=0;//addofs;
CallDestr(ptrs);
return TRUE;
}
}
return FALSE;
}
void CopyTok(int *tok4,ITOK *itok4,idrec *ptr)
{
itok4->number=ptr->recnumber;
itok4->rm=ptr->recrm;
*tok4=ptr->rectok;
itok4->post=ptr->recpost;
itok4->segm=ptr->recsegm;
itok4->flag=ptr->flag;
itok4->size=ptr->recsize;
itok4->sib=ptr->recsib;
itok4->rec=ptr;
itok4->type=ptr->type;
itok4->npointr=ptr->npointr;
}
int searchlocals(ITOK *itok4,int *tok4,unsigned char *string4)
//поиск локальных переменых связаного списка
{
if(skiplocals){
skiplocals=FALSE;
return FALSE;
}
if(skipfind==LOCAL)return FALSE;
treelocalrec *ftlr;
struct localrec *ptr;
for(ftlr=tlr;ftlr!=NULL;ftlr=ftlr->next){
for(ptr=ftlr->lrec;ptr!=NULL;ptr=ptr->rec.next){
// puts(ptr->rec.recid);
if(strcmp(ptr->rec.recid,(char *)string4)==0){
itok4->number=ptr->rec.recnumber;
*tok4=ptr->rec.rectok;
itok4->locrec=ptr;
if(displaytokerrors){
if(mapfile){
if(ptr->li.count==0)ptr->li.usedfirst=linenumber;
else ptr->li.usedlast=linenumber;
ptr->li.count++;
}
if(*tok4==tk_structvar)ptr->rec.count++;
}
// printf("type=%d num=%08X %s\n",ptr->rec.type,ptr->rec.recnumber,ptr->rec.recid);
if(ptr->rec.type==tp_postvar){
itok4->segm=DS;
itok4->flag=ptr->rec.flag;
itok4->size=ptr->rec.recsize;
itok4->rm=(am32==FALSE?rm_d16:rm_d32);
itok4->npointr=ptr->rec.npointr;
itok4->type=tp_localvar;
itok4->post=1;
if(*tok4==tk_structvar){
itok4->rec=&ptr->rec;
itok4->post=ptr->rec.recpost;
// itok4->segm=0;
}
return TRUE;
}
if(ptr->rec.type==tp_gvar){
itok4->number=0;
itok4->rm=(am32==FALSE?rm_d16:rm_d32);
itok4->segm=DS;
itok4->size=ptr->rec.recsize;
itok4->npointr=ptr->rec.npointr;
itok4->type=ptr->rec.recsib; //????01.09.05 15:58
itok4->post=USED_DIN_VAR;
if(ptr->rec.recpost==DYNAMIC_VAR)ptr->rec.recpost=USED_DIN_VAR;
itok4->rec=&ptr->rec;
ptr->fuse=USEDVAR;
if(*tok4==tk_structvar){
itok4->number=ptr->rec.recnumber;
itok4->flag|=ptr->rec.flag;
}
return TRUE;
}
itok4->type=ptr->rec.type;
if(ptr->rec.type==tp_paramvar||ptr->rec.type==tp_localvar){
if(ESPloc&&am32){
itok4->rm=rm_mod10|rm_sib;
itok4->sib=0x24;
if(ptr->rec.type==tp_paramvar)itok4->number+=localsize+addESP;
else itok4->number+=-4+addESP;
}
else itok4->rm=rm_mod10|(am32==FALSE?rm_BP:rm_EBP);
itok4->segm=SS;
itok4->npointr=ptr->rec.npointr;
if(ptr->rec.npointr){
itok4->type=(unsigned short)*tok4-tk_charvar+tk_char;
*tok4=tk_pointer;
}
if(*tok4==tk_structvar){
itok4->rec=&ptr->rec;
itok4->post=ptr->rec.recpost;
itok4->segm=0;
}
}
else if(!(ptr->rec.rectok==tk_locallabel||ptr->rec.rectok==tk_number)){
internalerror("Bad *tok4 value in searchlocals");
}
itok4->size=ptr->rec.recsize;
itok4->flag=ptr->rec.flag;
return TRUE;
}
}
}
if(searchteg){
struct elementteg *bazael;
int addofs=0;
structteg *subteg=NULL;
if(cha==':'&&cha2==':'){
nextchar();
nextchar();
if((subteg=FindTeg(TRUE,itok4->name))==NULL&&displaytokerrors)undefclass(itok4->name);
tokscan(tok4,itok4,string4);
whitespace();
}
if(destructor){
destructor=FALSE;
strcat((char *)string4,"~");
}
if((bazael=FindClassEl(searchteg,string4,&addofs,subteg))!=NULL){
*tok4=bazael->tok;
itok4->type=tp_classvar;
// printf("tok=%d bazael->rec=%08X %s\n",*tok4,bazael->rec,itok4->name);
if(*tok4==tk_proc||*tok4==tk_pointer){
idrec *ptr=bazael->rec;
if(strchr(itok4->name,'@')==NULL){
strcat(itok4->name,"@");
strcat(itok4->name,(char *)string4);
}
// }
// printf("tok=%d %s %s\n",*tok4,ptr->recid,ptr->newid);
if(*tok4==tk_proc&&ptr->newid!=NULL)strcpy((char *)string4,ptr->newid);
CopyTok(tok4,itok4,bazael->rec);
structadr.sib=THIS_PARAM;
structadr.number=0;//addofs;
if(displaytokerrors){
ptr->count++;
if(*tok4==tk_proc){
if(itok4->segm==DYNAMIC)AddDynamicList(ptr);
}
}
if(*tok4==tk_pointer)goto locvar;
}
else if(*tok4==tk_struct){
*tok4=tk_structvar;
// printf("teg=%08X\n",bazael->nteg);
dostructvar2(tok4,itok4,(structteg *)bazael->nteg,string4);
if(*tok4==tk_structvar){
itok4->rec=(idrec *)bazael->nteg;
itok4->number+=(itok4->post==0?0:itok4->rm*((structteg *)bazael->nteg)->size);
itok4->size=(itok4->post==0?bazael->numel:1)*((structteg *)bazael->nteg)->size;
itok4->number+=bazael->ofs+addofs;
if(displaytokerrors){
if(strinf.bufstr!=NULL)free(strinf.bufstr);
strinf.bufstr=(char *)MALLOC(7);
strcpy(strinf.bufstr,"&this;");
strinf.size=1;
}
// itok4->flag|=f_useidx;
// if(itok4->sib>=CODE16)itok4->sib++;
return TRUE;
}
else if(*tok4==tk_proc){
structadr.sib=THIS_PARAM;
structadr.number+=bazael->ofs+addofs;
if(itok4->sib>=CODE16)itok4->sib++;
return TRUE;
}
goto locvar;;
}
else{
if(bazael->rec){ //static var
CopyTok(tok4,itok4,bazael->rec);
return TRUE;
}
locvar:
itok4->number+=bazael->ofs+addofs;
if(displaytokerrors){
if(bufrm!=NULL)free(bufrm);
bufrm=(char *)MALLOC(7);
strcpy(bufrm,"&this;");
}
// itok4->flag|=f_useidx;
if(itok4->sib>=CODE16)itok4->sib++;
// printf("sib=%08X tok=%d rm=%d post=%d number=%d size=%d %s\n",itok4->sib,*tok4,itok4->rm,itok4->post,itok4->number,itok4->size,string4);
}
return TRUE;
}
}
return FALSE;
}
void dostructvar2(int *tok4,ITOK *itok4,struct structteg *tteg,unsigned char *string4) //разбор структур на переменные и структуры
{
struct elementteg *bazael;
int numel=0;
int usenumstruct=FALSE;
int sopenb;
long cnum;
ITOK cstok;
char *cstring;
char c=0;
int i;
structteg *subteg=NULL;
structadr=*itok4;
// bazael=tteg->baza;
whitespace();//пропуск незначащих символов
cstring=(char *)MALLOC(STRLEN);
if(cha=='['){ //[ номер структуры
usenumstruct=TRUE;
nextchar();
sopenb=inptr;
unsigned char bcha=cha;
tokscan(&i,&cstok,(unsigned char *)cstring);
if(bufrm){
free(bufrm);
bufrm=NULL;
}
if(i==tk_number){ //числовой
ITOK dstok;
memcpy(&dstok,itok4,sizeof(ITOK));
calcnum(&i,&cstok,cstring,&cnum);
memcpy(itok4,&dstok,sizeof(ITOK));
if(i!=tk_closeblock)goto notnum;
numel=cnum;
}
else{
notnum:
//new!!!
if(displaytokerrors){
if(itok4->segm==USEDSTR)preerror("only once possible use variable an index structure");
// if(itok4->segm==USEDSTR&&displaytokerrors)preerror("only once possible use variable an index structure");
itok4->segm=USEDSTR;
SRBackBuf(0);
AddBackBuf(sopenb,bcha);
CharToBackBuf(';');
CharToBackBuf(0);
if(cha!=']')blockerror();
if(strinf.bufstr!=NULL)free(strinf.bufstr);//internalerror("Previous block was not used");
strinf.bufstr=(char *)REALLOC(BackTextBlock,SizeBackBuf+1);
SRBackBuf(1);
nextchar();
//new!!!
}
else{
do{
tokscan(&i,&cstok,(unsigned char *)cstring);
if(i==tk_eof)break;
}while(i!=tk_closeblock);
}
c=1;
strinf.size=tteg->size;
}
itok4->flag|=f_useidx;
whitespace();//пропуск незначащих символов
}
if(cha=='.'){
int fdestr=FALSE;
nextchar();
if(cha=='~'){
nextchar();
fdestr=TRUE;
}
skipfind=LOCAL;
do{
tokscan(&i,&cstok,(unsigned char *)cstring);
// puts(cstok.name);
if(cha=='.')searchtree2(definestart,&cstok,&i,(unsigned char *)cstring);
}while(i==tk_endline);
whitespace();
if(cha==':'){
nextchar();
if(cha!=':')expectederror("::");
nextchar();
if((subteg=FindTeg(TRUE,cstok.name))==NULL&&displaytokerrors)undefclass(cstok.name);
tokscan(&i,&cstok,(unsigned char *)cstring);
whitespace();
}
skipfind=FALSE;
int addofs=0;
if(fdestr)strcat(cstok.name,"~");
if((bazael=FindClassEl(tteg,(unsigned char *)cstok.name,&addofs,subteg))==NULL){
if(displaytokerrors)unknownstruct(cstok.name,tteg->name);
*tok4=tk_number;
free(cstring);
return;
}
free(cstring);
*tok4=bazael->tok;
itok4->size=bazael->numel*GetVarSize(*tok4);
cnum=(c==0?tteg->size*numel:0);
if((itok4->flag&f_extern)!=0)itok4->number+=((bazael->ofs+cnum)<<16);
else itok4->number+=bazael->ofs+cnum;
if(*tok4==tk_struct){
*tok4=tk_structvar;
itok4->size=bazael->numel*((structteg *)bazael->nteg)->size;
dostructvar2(tok4,itok4,(structteg *)bazael->nteg,string4);
return;
}
if((itok4->flag&f_extern)!=0)itok4->number+=addofs<<16;
else itok4->number+=addofs;
// printf("tok=%d %s\n",*tok4,bufrm);
if(*tok4==tk_proc||*tok4==tk_pointer){
idrec *ptr;//=NULL;
if(*tok4==tk_proc){
if(am32==FALSE){
structadr.rm=rm_d16;
structadr.sib=CODE16;
}
else{
structadr.rm=rm_d32;
structadr.sib=CODE32;
}
structadr.segm=DS;
structadr.number=itok4->number;
// structadr.number=0;
structadr.flag=0;
structadr.size=addofs;
structadr.type=tp_ucnovn;
structadr.npointr=0;
structadr.post=itok4->post;
structadr.rec=(structadr.post==USED_DIN_VAR?itok4->rec:NULL);
if(itok4->segm==USEDSTR)structadr.sib++;
if(structadr.post==LOCAL){
if(ESPloc&&am32){
structadr.rm=rm_mod10|rm_sib;
structadr.sib=0x24; //???
structadr.number+=addESP;
}
else{
structadr.rm=rm_mod10|(am32==FALSE?rm_BP:rm_EBP);
}
structadr.segm=SS;
compressoffset(&structadr);
if(tteg->size==0)structadr.sib=THIS_ZEROSIZE; //14.11.05 13:51
}
/* if(strcmp(bazael->name,tteg->name)==0&&itok4->rec){ //вызов конструктора
ptr=itok4->rec;
// printf("constructor %08X\n",ptr);
}*/
}
// if(ptr)printf("new address constructor %08X\n",bazael->rec);
ptr=bazael->rec;
itok4->type=ptr->type;
itok4->npointr=ptr->npointr;
itok4->rm=ptr->recrm;
itok4->flag=ptr->flag;
itok4->rec=ptr;
strcpy(itok4->name,ptr->recid);
if(*tok4==tk_pointer){
// puts("Check this code");
string4[0]=0;
if(ptr->newid!=NULL)strcpy((char *)string4,ptr->newid);
*tok4=ptr->rectok;
//!!!
if(itok4->type==tk_proc&&cha!='('){
itok4->type=(am32==FALSE?tk_wordvar:tk_dwordvar);
goto notbit;
}
if(itok4->type!=tk_proc)goto notbit;
// printf("post=%08X %s\n",itok4->post,itok4->name);
if(itok4->post==LOCAL){
if(ESPloc&&am32){
itok4->rm=rm_mod10|rm_sib;
itok4->sib=0x24;
itok4->number+=addESP;
}
else{
itok4->sib=rm_mod10|(am32==FALSE?rm_BP:rm_EBP); //???rm
}
itok4->segm=SS;
itok4->post=FALSE;
}
else{
itok4->sib=(am32==FALSE?rm_d16:rm_d32); //установки по умолчанию
itok4->segm=DS;
}
// itok4->post=0;
itok4->flag|=f_useidx;
return;
}
itok4->number=ptr->recnumber;
*tok4=ptr->rectok;
itok4->post=ptr->recpost;
itok4->segm=ptr->recsegm;
itok4->sib=ptr->recsib;
itok4->size=ptr->recsize; //11.08.04 00:24
//11.09.04 00:28
if(strchr(itok4->name,'@')==NULL){
strcat(itok4->name,"@");
strcat(itok4->name,(char *)string4);
}
string4[0]=0;
if(ptr->newid!=NULL)strcpy((char *)string4,ptr->newid);
////////////////////
// printf("tok=%d num=%d %s\n",*tok4,itok4->number,itok4->name);
if(displaytokerrors){
ptr->count++;
if(*tok4==tk_proc&&itok4->segm==DYNAMIC)AddDynamicList(ptr);
if(*tok4!=tk_proc&&*tok4!=tk_undefproc&&*tok4!=tk_declare)thisundefined(ptr->recid,FALSE);
}
return;
}
// if((itok4->flag&f_extern)!=0)itok4->number+=addofs;
// else itok4->number+=addofs;
if(*tok4==tk_bits){
itok4->flag|=f_useidx;
itok4->number+=bazael->bit.ofs/8;
if((bazael->bit.ofs%8)==0){
switch(bazael->bit.siz){
case 8:
*tok4=tk_bytevar;
goto notbit;
case 16:
*tok4=tk_wordvar;
goto notbit;
case 32:
*tok4=tk_dwordvar;
goto notbit;
}
}
itok4->bit.siz=bazael->bit.siz;
itok4->bit.ofs=bazael->bit.ofs%8;
}
else if(bazael->rec){ //static var
CopyTok(tok4,itok4,bazael->rec);
return;
}
notbit:
itok4->sib=cstok.sib;
if(itok4->post==LOCAL){
if(ESPloc&&am32){
itok4->rm=rm_mod10|rm_sib;
// printf("sib=%x tok=%d name=%s\n",itok4->sib,*tok4,itok4->name);
itok4->sib=0x24;
itok4->number+=addESP;
}
else{
itok4->rm=rm_mod10|(am32==FALSE?rm_BP:rm_EBP);
if(itok4->segm==USEDSTR&&itok4->sib>=CODE16)itok4->sib++;
}
itok4->segm=SS;
itok4->post=FALSE;
itok4->flag=f_useidx;
}
else{
itok4->rm=(am32==FALSE?rm_d16:rm_d32); //установки по умолчанию
if(itok4->segm==USEDSTR&&itok4->sib>=CODE16)itok4->sib++;
itok4->segm=DS;
itok4->flag=FixUp|f_useidx;
}
return;
}
// itok4->size=(numel==0?bazael->numel:1)*((structteg *)bazael->nteg)->size;
// itok4->rec=(idrec *)tteg;
itok4->rm=numel;
itok4->post=usenumstruct;
free(cstring);
}
void dosizeof(ITOK *itok4) //опр значение sizeof
{
struct structteg *tteg;
int i,brase=FALSE;
ITOK cstok;
whitespace();//пропуск незначащих символов
itok4->number=0;
if(cha=='('){
nextchar();
brase=TRUE;
}
// if((cha!='(')&&(displaytokerrors))expected('(');
// nextchar();
cstok.name[0]=0;
// if(displaytokerrors)puts("start sizeof");
tokscan(&i,&cstok,string2);
// if(displaytokerrors)printf("tok=%d findoffset=%d %s\n",i,findofset,cstok.name);
if(i==tk_dblcolon&&numblocks){
skiplocals=TRUE;
tokscan(&i,&cstok,string2);
}
if(strcmp(cstok.name,"__CODESIZE")==0){
itok4->post=CODE_SIZE+am32;
}
else if(strcmp(cstok.name,"__DATASIZE")==0){
itok4->post=DATA_SIZE+am32;
}
else if(strcmp(cstok.name,"__POSTSIZE")==0){
itok4->post=POST_SIZE+am32;
}
else if(strcmp(cstok.name,"__STACKSIZE")==0){
itok4->post=STACK_SIZE+am32;
}
else{
switch(i){
case tk_char:
case tk_byte:
case tk_beg:
itok4->number=1;
break;
case tk_int:
case tk_word:
case tk_reg:
case tk_seg:
itok4->number=2;
break;
case tk_float:
case tk_reg32:
case tk_long:
case tk_dword:
itok4->number=4;
break;
case tk_double:
case tk_qword:
itok4->number=8;
break;
case tk_string:
itok4->number=cstok.number;
if(/*itok4->*/cstok.flag!=no_term)itok4->number++;
break;
case tk_bits:
itok4->number=cstok.bit.siz;
break;
case tk_proc:
case tk_charvar:
case tk_bytevar:
case tk_intvar:
case tk_wordvar:
case tk_longvar:
case tk_dwordvar:
case tk_floatvar:
case tk_structvar:
case tk_qwordvar:
case tk_doublevar:
case tk_interruptproc:
if(cstok.size==0)if(displaytokerrors)preerror("unknown size");
itok4->number=cstok.size;
break;
default:
if((tteg=FindTeg(FALSE,cstok.name))!=NULL||(tteg=FindTeg(TRUE,cstok.name))!=NULL){
if(cha=='.'){
dostructvar2(&i,itok4,tteg,string2);
itok4->number=itok4->size;
if(bufrm){
free(bufrm);
bufrm=NULL;
}
}
else itok4->number=tteg->size;
itok4->flag=0;
break;
}
if(strcmp("file",(char *)string2)==0){
displaytokerrors=1;
tokscan(&i,&cstok,string2);
if(i==tk_string){
struct stat statbuf;
if(stat((char *)string3,&statbuf)!=0)unableopenfile((char *)string3);
else itok4->number=statbuf.st_size;
}
else stringexpected();
}
else if(displaytokerrors)preerror("illegal use of sizeof");
break;
}
}
whitespace();//пропуск незначащих символов
if(brase){
if(cha!=')'&&displaytokerrors)expected(')');
nextchar();
}
}
void ofsstr(int *tok4,ITOK *itok4)
{
struct structteg *tteg;
int newreg=(idxregs[4]==255?idxregs[0]:idxregs[4]); //14.06.06 20:06
int poststr;
int flagstr;
if(itok4->type==tp_classvar){
tteg=(structteg *)itok4->rec;
poststr=0;
flagstr=f_useidx;
}
else{
struct idrec *ptrs;
ptrs=itok4->rec;
tteg=(structteg *)ptrs->newid;
poststr=ptrs->recpost;
flagstr=ptrs->flag;
}
if(tteg==NULL){
if(displaytokerrors){
unknowntagstruct(itok4->name);
}
return;
}
if(strinf.bufstr==NULL&&itok4->post==TRUE)itok4->number+=(tteg->size*(itok4->rm));
itok4->size=tteg->size;
itok4->sib=(am32==FALSE?CODE16:CODE32);
char ocha=cha;
int binptr=inptr;
if(poststr==LOCAL){
itok4->rm=rm_mod10;
if(strinf.bufstr==NULL){
if(ESPloc&&am32){
itok4->rm|=rm_sib;
itok4->sib=0x24;
}
else{
itok4->rm|=(am32==FALSE?rm_BP:rm_EBP);
}
}
else{
if(displaytokerrors){
if((newreg=CheckIDXReg(strinf.bufstr,strinf.size,idxregs[0]))!=NOINREG){
if(newreg==SKIPREG){
newreg=idxregs[0];
}
else{
if(am32==FALSE&&newreg!=DI)goto noopt1;
waralreadinitreg(regs[am32][idxregs[0]],regs[am32][newreg]);
}
free(strinf.bufstr);
strinf.bufstr=NULL;
goto cont1;
}
newreg=idxregs[0];
noopt1:
CheckMassiv(strinf.bufstr,strinf.size,idxregs[0]);
cont1: ;
}
if(am32==FALSE)itok4->rm|=CalcRm16(BP,newreg);
else{
itok4->sib=(newreg<<3)+(ESPloc?ESP:EBP);
itok4->rm=4|rm_mod10;
}
}
itok4->segm=SS;
if(ESPloc&&am32)itok4->number+=addESP;
// else itok4->number-=localsize;
*tok4=tk_rmnumber;
if(itok4->type==tp_classvar)itok4->flag|=f_useidx;
itok4->post=FALSE;
compressoffset(itok4);
}
else{
itok4->post=poststr;
if(strinf.bufstr==NULL){
itok4->rm=(am32==FALSE?rm_d16:rm_d32); //установки по умолчанию
if(itok4->post!=0)*tok4=tk_postnumber;
else *tok4=tk_number;
}
else{
if(displaytokerrors){
if((newreg=CheckIDXReg(strinf.bufstr,strinf.size,idxregs[0]))!=NOINREG){
if(newreg==SKIPREG){
newreg=idxregs[0];
}
else{
if(am32==FALSE&&newreg!=DI&&newreg!=BX)goto noopt2;
waralreadinitreg(regs[am32][idxregs[0]],regs[am32][newreg]);
}
free(strinf.bufstr);
strinf.bufstr=NULL;
goto cont2;
}
newreg=(idxregs[4]==255?idxregs[0]:idxregs[4]); //14.06.06 20:06
noopt2:
CheckMassiv(strinf.bufstr,strinf.size,(idxregs[4]==255?idxregs[0]:idxregs[4]));
cont2: ;
}
itok4->rm=RegToRM(newreg,(am32==FALSE?tk_reg:tk_reg32))|rm_mod10;
*tok4=tk_rmnumber;
}
itok4->segm=DS;
}
if(itok4->post==0&&(itok4->flag&f_reloc)==0){ // cannot compress if POST var
compressoffset(itok4);
}
// compressoffset(itok4);
itok4->flag|=flagstr;
inptr=binptr;
cha=ocha;
}
void AddUndefOff(int segm,char *ostring) //зафиксировать обращение к еще не объявленым именам
/*segm - сегмент откуда идет обращение
0 - сегмент кода
1 - сегмент данных
2 - сегмент кода, но без занесения в таблицу перемещений
3 - сегмент данных, но без занесения в таблицу перемещений
*/
{
UNDEFOFF *curptr;
if(undefoffstart==NULL){ //если еще не было неизв меток
undefoffstart=(UNDEFOFF *)MALLOC(sizeof(UNDEFOFF));
memset(undefoffstart,0,sizeof(UNDEFOFF));
strcpy(undefoffstart->name,ostring);
}
for(curptr=undefoffstart;;curptr=curptr->next){
if(strcmp(curptr->name,ostring)==0){ //ранее уже обращались к ней
//таблица обращений к undef
if(curptr->pos==NULL)curptr->pos=(IOFS *)MALLOC(sizeof(IOFS)*(curptr->num+1));
else curptr->pos=(IOFS *)REALLOC(curptr->pos,sizeof(IOFS)*(curptr->num+1));
(curptr->pos+curptr->num)->ofs=segm==0?outptr:outptrdata;
(curptr->pos+curptr->num)->dataseg=(unsigned char)segm;
(curptr->pos+curptr->num)->line=linenumber;
(curptr->pos+curptr->num)->file=currentfileinfo;
curptr->num++;
return;
}
if(curptr->next==NULL)break; //конец списка
}
curptr=curptr->next=(UNDEFOFF *)MALLOC(sizeof(UNDEFOFF)); //новая undef
memset(curptr,0,sizeof(UNDEFOFF));
strcpy(curptr->name,ostring);
curptr->num=1;
curptr->pos=(IOFS *)MALLOC(sizeof(IOFS));
curptr->pos->ofs=segm==0?outptr:outptrdata;
curptr->pos->dataseg=(unsigned char)segm;
curptr->pos->line=linenumber;
curptr->pos->file=currentfileinfo;
}
int CheckUseAsUndef(unsigned char *name)
{
UNDEFOFF *curptr;
int count=0;
if(undefoffstart==NULL)return 0; //не было обращений к undef
for(curptr=undefoffstart;;curptr=curptr->next){
if(strcmp(curptr->name,(char *)name)==0){ //нашли
count=curptr->num;
break;
}
if(curptr->next==NULL)break;
}
return count;
}
int FindOff(unsigned char *name,int base) //поиск ссылок на текущее имя
{
/*-----------------13.08.00 23:48-------------------
просмотреть процедуру при вводе разделения данных и кода
--------------------------------------------------*/
UNDEFOFF *curptr,*prev;
unsigned char segm;
unsigned int ofs,valofs;
int count=0;
if(undefoffstart==NULL)return 0; //не было обращений к undef
for(curptr=undefoffstart;;curptr=curptr->next){
if(strcmp(curptr->name,(char *)name)==0){ //нашли
for(int i=0;i<curptr->num;i++){
ofs=(curptr->pos+i)->ofs;
segm=(curptr->pos+i)->dataseg;
if(base==DS&&dynamic_flag){ //было обращение к динамическим иниц. переменным
CheckPosts();
(postbuf+posts)->type=(unsigned short)(am32==0?DIN_VAR:DIN_VAR32);
(postbuf+posts)->num=(int)itok.rec;
(postbuf+posts)->loc=ofs;
}
else{
if((segm&1)==0||modelmem==TINY){ //в сегменте кода
if(base!=VARPOST){
// if(am32==FALSE)valofs=*(unsigned short *)&output[ofs];
// else valofs=*(unsigned long *)&output[ofs];
// valofs+=(base==CS?outptr:outptrdata);
valofs=(base==CS?outptr:outptrdata);
}
else valofs=postsize;
if(am32==FALSE)*(unsigned short *)&output[ofs]+=(unsigned short)valofs;
else *(unsigned long *)&output[ofs]+=valofs;
}
else{
if(am32==FALSE)*(unsigned short *)&outputdata[ofs]+=(unsigned short)(base==CS?outptr:outptrdata);
else *(unsigned long *)&outputdata[ofs]+=(unsigned long)(base==CS?outptr:outptrdata);
}
if((FixUp!=FALSE&&(segm&2)==0)/*||base==VARPOST*/){
CheckPosts();
(postbuf+posts)->type=(unsigned char)
// (base==VARPOST?(am32==FALSE?POST_VAR:POST_VAR32):
((segm&1)==0?(am32==FALSE?FIX_VAR:FIX_VAR32):
(am32==FALSE?FIX_CODE:FIX_CODE32)
// )
);
(postbuf+posts)->loc=ofs;
posts++;
}
if(base==VARPOST){
unsigned int i;
for(i=0;i<posts;i++){
if(ofs==(postbuf+i)->loc)break;
}
if(i==posts){
CheckPosts();
posts++;
(postbuf+i)->loc=ofs;
}
(postbuf+i)->type=(unsigned char)(am32==FALSE?POST_VAR:POST_VAR32);
}
}
}
free(curptr->pos);
if(undefoffstart->next==NULL)undefoffstart=NULL;
else if(undefoffstart==curptr)undefoffstart=curptr->next;
else{
for(prev=undefoffstart;prev->next!=curptr;prev=prev->next);
prev->next=curptr->next;
}
count=curptr->num;
free(curptr);
break;
}
if(curptr->next==NULL)break;
}
return count;
}
int FindUseName(char *name) //поиск ссылок на текущее имя
{
UNDEFOFF *curptr;
if(undefoffstart){
for(curptr=undefoffstart;;curptr=curptr->next){
if(strcmp(curptr->name,(char *)name)==0){ //нашли
return curptr->num;
}
if(curptr->next==NULL)break;
}
}
return 0;
}
int GetDirective(char *str)
{
int i;
i=FastSearch(dirlist,ofsdir,1,str);
// printf("i=%d %s\n",i,str);
if(i!=-1&&i<d_end1&&notdoneprestuff!=TRUE&&displaytokerrors!=0){
char buf[80];
sprintf(buf,"Too late to change %s",str);
preerror(buf);
}
return i;
}
int FastSearch(unsigned char *list,short unsigned *ofs,int type,char *str)
{
if((strlen(str)-1)>0){
short offs=-1;
unsigned char c;
c=str[0];
switch(type){
case 0:
if(c>='A'&&c<='Z')offs=ofs[c-'A'];
break;
case 1:
if(c=='D')offs=ofs[0];
else if(c>='a'&&c<='z')offs=ofs[c-0x60];
break;
case 2:
if(c=='_')offs=ofs[26];
else if(c>='a'&&c<='z')offs=ofs[c-'a'+27];
else offs=ofs[c-'A'];
break;
case 3:
if(c>='a'&&c<='z')offs=ofs[c-0x61];
break;
}
// if(type==0)printf("%s\n",str);
if(offs!=-1){
for(unsigned char *ii=(unsigned char *)(list+offs);;ii++){
short types;
if((types=*(short *)&*ii)==-1)break;
ii+=2;
unsigned char c=*ii;
int i;
i=1;
while(c==str[i]){
if(c==0)return types;
ii++;
i++;
c=*ii;
}
if(c>str[i])break;
while(*ii!=0)ii++;
}
}
}
return -1;
}
/*-----------------05.01.00 22:56-------------------
Работа со структурами
--------------------------------------------------*/
int GetVarSize(int var)
{
switch(var){
case tk_reg:
case tk_intvar:
case tk_seg:
case tk_wordvar: return 2;
case tk_bits:
case tk_charvar:
case tk_beg:
case tk_bytevar: return 1;
case tk_pointer:
if(am32==0)return 2;
case tk_longvar:
case tk_dwordvar:
case tk_reg32:
case tk_floatvar: return 4;
case tk_doublevar:
case tk_qwordvar: return 8;
default:
if(am32)return 4;
}
return 2;
}
unsigned long getsizebit(int size)
{
unsigned long num;
nexttok();
if(tok!=tk_number)numexpected();
num=doconstdwordmath();
if(num>(unsigned int)(size*8))preerror("Bit field to large");
return num;
}
int GetFirstDestr(structteg *searcht)
{
elementteg *bazael=searcht->baza;
idrec *ptrs;
if((searcht->flag&fs_destructor)!=0)return TRUE;
for(int i=0;i<searcht->numoper;i++){
ptrs=(bazael+i)->rec;
if((bazael+i)->tok==tk_baseclass){
if(GetFirstDestr((structteg *)ptrs))return TRUE;
}
}
return FALSE;
}
void AddTegToTree(structteg *newteg,int Global)
{
struct structteg *tteg;
int i;
tteg=(Global==TRUE?tegtree:ltegtree);
if(tteg==NULL)(Global==TRUE?tegtree:ltegtree)=newteg;
else{
while(((i=strcmp(tteg->name,newteg->name))<0&&tteg->left!=NULL)||(i>0&&tteg->right!=NULL))
tteg=(i<0?tteg->left:tteg->right);
(i<0?tteg->left:tteg->right)=newteg;
}
}
int IsClass(structteg *searcht)
{
elementteg *bazael=searcht->baza;
if((searcht->flag&fs_destructor)!=0)return TRUE;
for(int i=0;i<searcht->numoper;i++){
if((bazael+i)->tok==tk_baseclass)return TRUE;
// if(IsClass((structteg *)(bazael+i)->rec))return TRUE;
else if((bazael+i)->tok==tk_proc){
if((bazael+i)->rec&&((bazael+i)->rec->flag&f_classproc))return TRUE;
}
}
return FALSE;
}
struct structteg *CreatTeg(int Global,int useunion,int noname) //создать новый тег
{
struct structteg *newteg,*tteg;
struct elementteg *bazael;
int ssize=0,numel=0,localtok,size,numt,nameid=FALSE,tsize;
int bitofs=0,bitsize=0,i,type;
int isdestr=FALSE,isbase=0;
int unionsize=0;
newteg=(struct structteg *)MALLOC(sizeof(struct structteg));
newteg->left=newteg->right=NULL;
newteg->baza=NULL;
newteg->flag=useunion;
newteg->name[0]=0;
if(tok==tk_ID||tok==tk_id){
strcpy(newteg->name,itok.name);
AddTegToTree(newteg,Global);
nexttok();
nameid=TRUE;
}
if(tok==tk_colon){
nexttok();
do{
if((tteg=FindTeg(TRUE))==NULL)undefclass(itok.name);
else{
size=tteg->size;
if(numel==0)bazael=(struct elementteg *)MALLOC(sizeof(struct elementteg));
else bazael=(struct elementteg *)REALLOC(bazael,sizeof(struct elementteg)*(numel+1));
for(i=0;i<numel;i++){
if(strcmp((bazael+i)->name,itok.name)==0){
sprintf((char *)string,"Dublicate base class '%s'",itok.name);
preerror((char *)string);
}
}
strcpy((bazael+numel)->name,itok.name);
(bazael+numel)->tok=tk_baseclass;
(bazael+numel)->ofs=ssize;
(bazael+numel)->numel=1;
ssize+=size;
(bazael+numel)->nteg=tteg;
numel++;
isbase++;
}
nexttok();
if(tok==tk_openbrace)break;
expecting(tk_camma);
}while(tok!=tk_eof);
if(useunion)preerror("union cannot have a base type");
}
expecting(tk_openbrace);
while(tok!=tk_closebrace&&tok!=tk_eof){
int oflag,orm,npointr;
int utestInitVar=FALSE;
orm=tokens;
npointr=oflag=0;
type=variable;
if(tok==tk_tilda){
newteg->flag|=fs_destructor;
oflag|=fs_destructor;
// oflag=newteg->flag;
nexttok();
isdestr=TRUE;
}
//13.09.04 00:08
if(tok==tk_static){
oflag|=f_static;
nexttok();
}
/////////////
switch(tok){
case tk_int: orm=tok; localtok=tk_intvar; size=2; break;
case tk_word: orm=tok; localtok=tk_wordvar; size=2; break;
case tk_char: orm=tok; localtok=tk_charvar; size=1; break;
case tk_byte: orm=tok; localtok=tk_bytevar; size=1; break;
case tk_long: orm=tok; localtok=tk_longvar; size=4; break;
case tk_dword: orm=tok; localtok=tk_dwordvar; size=4; break;
case tk_float: orm=tok; localtok=tk_floatvar; size=4; break;
case tk_qword: orm=tok; localtok=tk_qwordvar; size=8; break;
case tk_double: orm=tok; localtok=tk_doublevar; size=8; break;
case tk_union:
nexttok();
i=FALSE;
if(bitofs&&(!useunion)){
ssize+=(bitofs+7)/8;
bitofs=0;
}
if(tok==tk_openbrace)i=TRUE;
if((tteg=CreatTeg(Global,TRUE,i))!=NULL){
if(tok==tk_semicolon){
if(numel==0)bazael=(struct elementteg *)MALLOC(sizeof(struct elementteg)*tteg->numoper);
else bazael=(struct elementteg *)REALLOC(bazael,sizeof(struct elementteg)*(numel+tteg->numoper));
for(i=0;i<tteg->numoper;i++)(tteg->baza+i)->ofs+=ssize;
memcpy((elementteg *)(bazael+numel),tteg->baza,sizeof(struct elementteg)*tteg->numoper);
tsize=tteg->size;
if(useunion==FALSE)ssize+=tsize;
else if(unionsize<(unsigned int)(tsize))unionsize=tsize;
numel+=tteg->numoper;
free(tteg->baza);
free(tteg);
size=0;
nexttok();
break;
}
else{
tsize=size=tteg->size;
localtok=tk_struct;
goto dproc2;
}
}
else declareunion();
break;
case tk_struct:
nexttok();
case tk_id:
case tk_ID:
if(bitofs&&(!useunion)){
ssize+=(bitofs+7)/8;
bitofs=0;
}
i=0;
if(tok==tk_openbrace||tok2==tk_openbrace){
if(tok==tk_openbrace)i=TRUE;
if((tteg=CreatTeg(Global,FALSE,i))!=NULL){
if(tok!=tk_semicolon){
tsize=size=tteg->size;
localtok=tk_struct;
// printf("tok=%d %s\n",tok,itok.name);
goto dproc2;
}
else{
if(numel==0)bazael=(struct elementteg *)MALLOC(sizeof(struct elementteg)*tteg->numoper);
else bazael=(struct elementteg *)REALLOC(bazael,sizeof(struct elementteg)*(numel+tteg->numoper));
for(i=0;i<tteg->numoper;i++)(tteg->baza+i)->ofs+=ssize;
memcpy((elementteg *)(bazael+numel),tteg->baza,sizeof(struct elementteg)*tteg->numoper);
tsize=tteg->size;
if(useunion==FALSE)ssize+=tsize;
else if(unionsize<(unsigned int)(tsize))unionsize=tsize;
numel+=tteg->numoper;
free(tteg->baza);
free(tteg);
size=0;
nexttok();
break;
}
}
datatype_expected();
}
if(strcmp(itok.name,newteg->name)==0&&tok2==tk_openbracket){
if(oflag==0){
newteg->flag|=fs_constructor;
oflag|=fs_constructor;
orm=am32==FALSE?tk_word:tk_dword;
}
else if(oflag==fs_destructor){
strcat(itok.name,"~");
orm=tk_void;
}
goto dproc2;
}
if((tteg=FindTeg(FALSE))!=NULL||(tteg=FindTeg(TRUE))!=NULL){
if(tok2==tk_mult){
while(tok2==tk_mult)nexttok();
if(am32){
localtok=tk_dwordvar;
size=4;
orm=tk_dword;
}
else{
localtok=tk_wordvar;
size=2;
orm=tk_word;
}
warpointerstruct();
}
else{
size=tteg->size;
localtok=tk_struct;
}
goto locvar;
// break;
}
default:
skipfind=LOCAL; //запретить поиск в глобальном и локальном списке
utestInitVar=TRUE;
if((i=testInitVar())==FALSE||i==2){ //определение процедуры пока не обрабатываем
skipfind=FALSE; //разрешить поиск
FindEndLex();
datatype_expected();
nexttok();
size=0;
break;
}
oflag|=itok.flag;
npointr=itok.npointr;
if(itok.npointr)itok.rm=(am32==TRUE?tk_dword:tk_word);
orm=itok.rm;
if(tok2==tk_openbracket&&strcmp(itok.name,newteg->name)==0){
newteg->flag|=fs_constructor;
oflag|=fs_constructor;
if(orm==tokens)orm=am32==FALSE?tk_word:tk_dword;
}
/* if(tok==tk_openbracket){
if(itok.npointr)orm=am32==FALSE?tk_word:tk_dword;
npointr=0;
nexttok();
while(tok==tk_mult){ //указатель на процедуру
npointr++;
nexttok();
}
type=pointer;
}*/
goto dproc2;
}
if(size!=0){
locvar:
do{
tsize=size;
skipfind=LOCAL; //запретить поиск в глобальном и локальном списке
nexttok();
if(tok==tk_colon){
numt=getsizebit(size);
if(numt==0)numt=size*8-bitofs%(size*8); //(am32==0?16:32)-bitofs%(am32==0?16:32);
bitofs+=numt;
continue;
}
dproc2:
if(numel==0)bazael=(struct elementteg *)MALLOC(sizeof(struct elementteg));
else bazael=(struct elementteg *)REALLOC(bazael,sizeof(struct elementteg)*(numel+1));
if(tok!=tk_ID&&tok!=tk_id){
utestInitVar=TRUE;
if(testInitVar()==FALSE){ //определение процедуры пока не обрабатываем
idalreadydefined();
}
else{
oflag|=itok.flag;
npointr=itok.npointr;
if(itok.npointr)itok.rm=(am32==TRUE?tk_dword:tk_word);
if(itok.rm!=tokens)orm=itok.rm;
if(tok==tk_openbracket){
if(itok.npointr)orm=am32==FALSE?tk_word:tk_dword;
npointr=0;
nexttok();
while(tok==tk_mult){ //указатель на процедуру
npointr++;
nexttok();
}
type=pointer;
}
for(i=0;i<numel;i++){
if(strcmp((bazael+i)->name,itok.name)==0)idalreadydefined();
}
strcpy((bazael+numel)->name,itok.name);
if(tok2==tk_openbracket&&strcmp(itok.name,newteg->name)==0){
newteg->flag|=fs_constructor;
oflag|=fs_constructor;
if(orm==tokens)orm=am32==FALSE?tk_word:tk_dword;
}
nexttok();
if(tok==tk_openbracket||type==pointer)goto dproc;
if(npointr){
idrec *nrec;
nrec=(bazael+numel)->rec=(idrec *)MALLOC(sizeof(idrec));
strcpy(nrec->recid,(bazael+numel)->name);//скопир название
nrec->newid=NULL;
nrec->npointr=(unsigned short)npointr;
nrec->flag=oflag;
nrec->line=linenumber;
nrec->file=currentfileinfo;
nrec->rectok=(bazael+numel)->tok=tk_pointer;
nrec->type=(unsigned short)orm;
tsize=2;
if(am32||(oflag&f_far))tsize=4;
goto endelteg;
}
else unuseableinput();
}
}
else{
for(i=0;i<numel;i++){
if(strcmp((bazael+i)->name,itok.name)==0){
idalreadydefined();
FindEndLex();
break;
}
}
strcpy((bazael+numel)->name,itok.name/*(char *)string*/);
if(tok2==tk_openbracket&&utestInitVar==FALSE){
if(tok==tk_id)oflag|=(comfile==file_w32?tp_stdcall:tp_pascal); //тип проц по умолчанию
else oflag=tp_fastcall;
}
// printf("tok=%d %s\n",tok,itok.name);
nexttok();
if(tok==tk_colon){
numt=getsizebit(size);
if(numt==0)preerror("Bit fields must contain at least one bit");
(bazael+numel)->ofs=ssize;
(bazael+numel)->tok=tk_bits;
(bazael+numel)->bit.siz=numt;
(bazael+numel)->bit.ofs=bitofs;
if(useunion==FALSE)bitofs+=numt;
else if(numt>bitsize)bitsize=numt;
// printf("n=%d size=%d %s\n",numel,numt,(bazael+numel)->name);
}
else if(tok==tk_openbracket){
dproc:
idrec *nrec;
param[0]=0;
if(type==pointer)expecting(tk_closebracket);
else{
if(npointr){
orm=am32==FALSE?tk_word:tk_dword;
npointr=0;
}
}
skipfind=FALSE; //разрешить поиск
expecting(tk_openbracket);
if((oflag&f_typeproc)==tp_fastcall)declareparamreg();
else declareparamstack();
skipfind=LOCAL;
nrec=(bazael+numel)->rec=(idrec *)MALLOC(sizeof(idrec));
strcpy(nrec->recid,(bazael+numel)->name);//скопир название
nrec->newid=NULL;
// printf("name=%s param=%s\n",nrec->recid,param);
if(param[0]!=0)nrec->newid=BackString((char *)param);
if(orm==tokens)orm=am32==FALSE?tk_word:tk_dword;//tk_void;
nrec->npointr=(unsigned short)npointr;
nrec->recrm=orm;
nrec->flag=oflag;
nrec->line=linenumber;
nrec->file=currentfileinfo;
nrec->count=0;
nrec->recpost=0;//itok.post;
nrec->recsize=0;//itok.size;
nrec->recsib=(am32==TRUE?CODE32:CODE16);//itok.sib;
nrec->sbuf=NULL;
if(npointr){
nrec->rectok=(bazael+numel)->tok=tk_pointer;
nrec->type=tk_proc;
nrec->recsib=am32==FALSE?rm_d16:rm_d32;
tsize=2;
if(am32||(oflag&f_far))tsize=4;
if(bitofs&&(!useunion)){
ssize+=(bitofs+7)/8;
bitofs=0;
}
tsize=Align(tsize,strpackcur); //new 16.03.05 14:21
nrec->recnumber=(bazael+numel)->ofs=ssize;
if(useunion==FALSE)ssize+=tsize;
else if(unionsize<(unsigned int)(tsize))unionsize=tsize;
}
else{
(bazael+numel)->tok=tk_proc;
nrec->rectok=tk_declare;
nrec->type=tp_ucnovn;
nrec->recsegm=NOT_DYNAMIC;
(bazael+numel)->ofs=0;
nrec->recnumber=secondcallnum++;
nrec->flag|=f_classproc;
}
(bazael+numel)->numel=1;
nexttok();
if(tok==tk_openbracket)IsUses(nrec);
// printf("name=%s post=%08X\n",nrec->recid,nrec->recpost);
}
else{
(bazael+numel)->rec=NULL;
(bazael+numel)->tok=localtok;
endelteg:
if(bitofs&&(!useunion)){
ssize+=(bitofs+7)/8;
bitofs=0;
}
(bazael+numel)->ofs=ssize;
numt=1;
if(tok==tk_openblock){//[
skipfind=FALSE;
nexttok();
numt=doconstlongmath();
expecting(tk_closeblock);
skipfind=LOCAL;
}
(bazael+numel)->numel=numt;
// printf("%d: unionsize=%d elemsize=%d\n",numel,unionsize,tsize*numt);
if((oflag&f_static)){
idrec *nrec;
nrec=(bazael+numel)->rec=(idrec *)MALLOC(sizeof(idrec));
strcpy(nrec->recid,(bazael+numel)->name);//скопир название
nrec->line=linenumber;
nrec->file=currentfileinfo;
nrec->count=0;
nrec->sbuf=NULL;
nrec->recsize=tsize*numt;
nrec->recsegm=DS;
if(localtok==tk_struct){
nrec->recsib=0;
nrec->newid=(char *)tteg;
(bazael+numel)->tok=nrec->rectok=tk_structvar;
nrec->flag=/*flag|*/tteg->flag;
if(FixUp)nrec->flag|=f_reloc;
nrec->recrm=numt;
}
else{
nrec->newid=NULL;
nrec->npointr=(unsigned short)npointr;
nrec->recrm=(am32==FALSE?rm_d16:rm_d32);
if(FixUp)oflag|=f_reloc;
nrec->flag=oflag;
nrec->recsib=(am32==TRUE?CODE32:CODE16);//itok.sib;
nrec->rectok=localtok;
nrec->type=tp_ucnovn;
}
if(tok==tk_assign){
skipfind=FALSE; //разрешить поиск
nrec->recpost=0;
if(localtok==tk_struct){
if(alignword)alignersize+=AlignCD(DS,2); //выровнять
nrec->recnumber=outptrdata; //адрес начала структуры
i=initstructvar(tteg,numt);
if(numt==0){
numt=i/tteg->size;
if((i%tteg->size)!=0){
numt++;
i=tteg->size-(i%tteg->size);
for(;i!=0;i--)opd(0);
i=numt*tteg->size;
}
nrec->recrm=numel;
nrec->recsize=i;
}
datasize+=i;
}
else{
if(alignword)alignersize+=AlignCD(DS,tsize);
nrec->recnumber=outptrdata;
initglobalvar(orm,numt,tsize,variable);
datasize+=tsize*numt;
}
}
else{
nrec->recpost=1;
if(localtok==tk_struct){
if(numt==0){
ZeroMassiv();
break;
}
}
if(alignword){ //выровнять на четный адрес
if(postsize%2==1)postsize++;
if(tsize==4&&postsize%4!=0)postsize+=2;
}
nrec->recnumber=postsize;
AddPostData(numt*tteg->size);
}
}
else{
tsize=Align(tsize*numt,strpackcur); //new 16.03.05 14:21
if(useunion==FALSE)ssize+=tsize;
else if(unionsize<(unsigned int)tsize)unionsize=tsize;
if(localtok==tk_struct)(bazael+numel)->nteg=tteg;
}
}
if(useunion)bitofs=0;
numel++;
}
newteg->size=ssize+unionsize;
}while(tok==tk_camma);
skipfind=FALSE; //разрешить поиск
seminext();
}
};//while(tok!=tk_closebrace&&tok!=tk_eof);
if(bitofs&&useunion==FALSE)ssize+=(bitofs+7)/8;
else if(bitsize&&((unsigned int)((bitsize+7)/8)>unionsize))unionsize=(bitsize+7)/8;
// printf("bitofs=%d size=%d\n",bitofs,ssize);
if(isdestr==FALSE&&isbase>1){
char *buf=(char *)MALLOC(16);
strcpy(buf,"(){");
int j;
for(i=0,j=0;i<isbase;i++){
if(GetFirstDestr((structteg *)(bazael+i)->nteg))j++;
}
if(j>1){
strcat(buf,"};");
int oflag,oinptr2;
char ocha2;
int oldendinptr=endinptr;
char *oinput;
idrec *nrec;
oinptr2=inptr2;
ocha2=cha2;
oinput=(char*)input;
string[0]=0;
newteg->flag|=fs_destructor;
strcpy(itok.name,newteg->name);
if(CidOrID()==tk_ID)oflag=tp_fastcall;
else oflag=(comfile==file_w32?tp_stdcall:tp_pascal);
bazael=(struct elementteg *)REALLOC(bazael,sizeof(struct elementteg)*(numel+1));
strcpy((bazael+numel)->name,itok.name);
strcat((bazael+numel)->name,"~");
itok.rec=nrec=(bazael+numel)->rec=(idrec *)MALLOC(sizeof(idrec));
strcpy(nrec->recid,itok.name);//скопир название
nrec->newid=NULL;
itok.npointr=nrec->npointr=0;
itok.rm=nrec->recrm=tk_void;
itok.flag=nrec->flag=fs_destructor|oflag|f_classproc;
nrec->line=linenumber;
nrec->file=currentfileinfo;
nrec->count=0;
itok.post=nrec->recpost=0;
itok.size=nrec->recsize=0;
itok.sib=nrec->recsib=(am32==TRUE?CODE32:CODE16);
nrec->sbuf=NULL;
(bazael+numel)->tok=tk_proc;
tok=nrec->rectok=tk_declare;
itok.type=nrec->type=tp_ucnovn;
itok.segm=nrec->recsegm=NOT_DYNAMIC;
(bazael+numel)->ofs=0;
itok.number=nrec->recnumber=secondcallnum++;
(bazael+numel)->numel=1;
numel++;
input=(unsigned char*)buf;
inptr2=1;
cha2='(';
endinptr=strlen(buf);
searchteg=newteg;
dynamic_proc();
searchteg=NULL;
input=(unsigned char*)oinput;
inptr2=oinptr2;
cha2=ocha2;
endinptr=oldendinptr;
}
free(buf);
}
newteg->size=ssize+unionsize;
newteg->numoper=numel;
newteg->baza=bazael;
nexttok();
if(noname==FALSE&&nameid==FALSE){
if(tok==tk_ID||tok==tk_id){
strcpy(newteg->name,itok.name);
AddTegToTree(newteg,Global);
}
else{
notstructname();
if(newteg->baza)free(newteg->baza);
free(newteg);
newteg=NULL;
}
}
return newteg;
}
struct structteg * FindTeg(int Global,char *name) //найти тег
{
struct structteg *tteg;
int i;
char *tn;
if((tn=strchr(name,'@'))!=NULL)*tn=0;
tteg=(Global==TRUE?tegtree:ltegtree);
while(tteg&&(i=strcmp(tteg->name,name))!=0)tteg=(i<0?tteg->left:tteg->right);
return tteg;
}
unsigned int SaveVal(unsigned long long val,int type)
{
unsigned int loop=0;
switch(type){
case tk_bytevar:
case tk_charvar:
opd(val);
break;
case tk_wordvar:
case tk_intvar:
outwordd(val);
loop++;
break;
case tk_dwordvar:
case tk_longvar:
case tk_floatvar:
outdwordd(val);
loop+=3;
break;
case tk_qwordvar:
case tk_doublevar:
outqwordd(val);
loop+=7;
break;
case tk_pointer:
if(am32){
outdwordd(val);
loop+=3;
}
else{
outwordd(val);
loop++;
}
break;
case tk_proc:
loop--;
break;
default: internalerror("Bad type variable");
}
return loop;
}
void FillTeg(unsigned long long val,unsigned int numel,struct structteg *tteg)
/*-----------------03.10.99 00:20-------------------
заполнить структуру одинаковыми величинами
--------------------------------------------------*/
{
struct elementteg *elem=tteg->baza;
int bitofs=0;
unsigned int startstruct;
if(dbg&2)AddDataLine(1/*,variable*/);
for(unsigned int j=0;j<numel;j++){
startstruct=outptrdata;
for(unsigned int c=0;c<tteg->numoper;c++){
if((elem+c)->ofs)outptrdata=startstruct+(elem+c)->ofs;
if(splitdata==FALSE)outptr=outptrdata;
int type=(elem+c)->tok;
if(type==tk_bits){
opb(val,(elem+c)->bit.ofs,(elem+c)->bit.siz);
bitofs=(elem+c)->bit.ofs+(elem+c)->bit.siz;
}
else{
if(bitofs){
CorrectOfsBit(bitofs);
bitofs=0;
}
for(unsigned int i=0;i<(elem+c)->numel;i++){
if(type==tk_struct||type==tk_baseclass){
FillTeg(val,(elem+c)->numel,(struct structteg *)(elem+c)->nteg);
break;
}
SaveVal(val,type);
}
}
}
}
if(bitofs)CorrectOfsBit(bitofs);
}
unsigned int Fill2Teg(unsigned int numel,struct structteg *tteg)
/*-----------------03.10.99 00:20-------------------
заполнить структуру величинами
--------------------------------------------------*/
{
unsigned long long hold;
struct elementteg *elem=tteg->baza;
unsigned int tnumel=0; //номер елемента одного типа
unsigned int ttype=0; //номер элемента структуры
unsigned int nums=0; //номер копии структуры
unsigned int loop=0; //заполненый размер
int type=tokens;
int bitofs=0;
unsigned int startstruct=outptrdata;
scanalltoks=FALSE;
for(;;){
hold=0;
if(tnumel==(elem+ttype)->numel||type==tk_bits){
tnumel=0;
ttype++;
if(ttype==tteg->numoper){
ttype=0;
nums++;
startstruct=outptrdata;
if(nums==numel){
scanalltoks=TRUE;
return loop;
}
}
loop=(elem+ttype)->ofs;
outptrdata=startstruct+loop;
if(splitdata==FALSE)outptr=outptrdata;
loop+=tteg->size*nums;
}
tnumel++;
type=(elem+ttype)->tok;
// puts((elem+ttype)->name);
if(type==tk_struct||type==tk_baseclass){
tnumel=(elem+ttype)->numel;
loop+=Fill2Teg((elem+ttype)->numel,(struct structteg *)(elem+ttype)->nteg);
if(tok==tk_closebrace)break;
continue;
}
if(type==tk_proc)continue;
if((elem+ttype)->rec&&((elem+ttype)->rec->flag&f_static))continue;
if(dbg&2)AddDataLine((char)GetVarSize(type)/*,variable*/);
loopsw:
int htok=tok;
// printf("tok=%d\n",tok);
switch(tok){
case tk_camma:
hold=0;
goto strl3;
case tk_postnumber:
(itok.flag&f_extern)==0?setwordpost(&itok):setwordext(&itok.number);
itok.flag=0;
// goto strl1;
case tk_undefofs:
// AddUndefOff(1,itok.name);
//strl1:
tok=tk_number;
if(htok==tk_undefofs)AddUndefOff(3,itok.name);
hold+=doconstdwordmath();
if(tok==tk_plus&&tok2==tk_postnumber&&htok!=tk_undefofs){
nexttok();
goto loopsw;
}
goto strl2;
case tk_minus:
case tk_number:
if(type==tk_bytevar||type==tk_wordvar||type==tk_dwordvar||type==tk_bits||type==tk_pointer){
hold=doconstdwordmath();
}
else if(type==tk_charvar||type==tk_intvar||type==tk_longvar){
hold=doconstlongmath();
}
else if(type==tk_floatvar)hold=doconstfloatmath();
else if(type==tk_doublevar)hold=doconstdoublemath();
else if(type==tk_qwordvar)hold=doconstqwordmath();
// printf("tok=%d num=%08X\n",tok,hold);
strl2:
if((postnumflag&f_reloc)!=0)AddReloc();
strl3:
if(type==tk_bits){
opb(hold,(elem+ttype)->bit.ofs,(elem+ttype)->bit.siz);
bitofs=(elem+ttype)->bit.ofs+(elem+ttype)->bit.siz;
}
else{
if(bitofs){
CorrectOfsBit(bitofs);
loop+=(bitofs+7)/8;
bitofs=0;
}
loop+=SaveVal(hold,type);
}
break;
case tk_string:
if(type==tk_bytevar||type==tk_charvar){
unsigned int i;
if((unsigned int)itok.number<(elem+ttype)->numel)i=itok.number;
else i=(elem+ttype)->numel;
tnumel=0;
for(;tnumel<i;tnumel++){
opd(string[tnumel]);
}
if(tnumel<(elem+ttype)->numel){
switch(itok.flag&3){
case zero_term:
if(itok.flag&s_unicod)opd(0);
opd(0);
tnumel++;
break;
case dos_term:
if(itok.flag&s_unicod)opd(0);
opd('$');
tnumel++;
break;
}
while(tnumel<(elem+ttype)->numel){
opd(aligner);
tnumel++;
}
}
loop+=tnumel-1;
nexttok();
break;
}
if(am32==FALSE){
outwordd(addpoststring());
if(type==tk_longvar||type==tk_dwordvar){
loop+=2;
outword(0);
}
loop++;
}
else{
if(type==tk_intvar||type==tk_wordvar)dwordvalexpected();
outdwordd(addpoststring());
loop+=3;
}
nexttok();
break;
default:
numexpected();
nexttok();
break;
}
loop++;
if(tok==tk_closebrace)break;
// printf("tok=%d\n",tok);
expecting(tk_camma);
}
scanalltoks=TRUE;
if(bitofs){
CorrectOfsBit(bitofs);
loop+=(bitofs+7)/8;
}
return loop;
}
unsigned int initstructvar(structteg *tteg,int numel)
{
unsigned int loop=0;
nexttok();
switch(tok){ //заполнить величинами
case tk_minus:
case tk_number:
if(numel==0)ZeroMassiv();
FillTeg(doconstqwordmath(),numel,tteg);
loop=numel*tteg->size;
break;
case tk_from: //считать файл с данными
nexttok();
loop=dofrom();
for(;loop<tteg->size*numel;loop++)opd(aligner);
nexttok();
break;
case tk_extract: //считать фрагмент файла с данными
nexttok();
loop=doextract();
for(;loop<tteg->size*numel;loop++)opd(aligner);
break;
case tk_openbrace: //массив данных
nexttok();
loop=Fill2Teg(numel,tteg);
for(;loop<tteg->size*numel;loop++)opd(aligner);
if(tok!=tk_closebrace){
preerror("extra parameter at initialization of structure");
while(tok!=tk_closebrace&&tok!=tk_eof)nexttok();
}
nexttok();
break;
default:
// printf("tok=%d\n",tok);
numexpected(); nexttok(); break;
}
return loop;
}
void InitStruct2(unsigned int flag,structteg *tteg) //инициализировать глобальную структуру
{
struct idrec *newrec=NULL,*ptr;
int numel,count;
char done=0,dynamic;
unsigned int loop;
while(tok!=tk_eof&&done==0){
loop=0;
// printf("3 tok=%d %s\n",tok,itok.name);
switch(tok){
case tk_id:
case tk_ID: //инициализировать структуру
//выделить память под новую структ
newrec=(struct idrec *)MALLOC(sizeof(struct idrec));
// if(strcmp(itok.name,"ccchrg")==0)printf("rec=%08X teg=%08X size=%X %s\n",newrec,tteg,sizeof(idrec),itok.name);
ptr=((flag&f_static)==0?treestart:staticlist); //начало дерева
if(ptr==NULL)((flag&f_static)==0?treestart:staticlist)=newrec;//начало дерева
else{ //поиск строки в дереве
while(((numel=strcmp(ptr->recid,itok.name))<0&&ptr->left!=NULL)||(numel>0&&ptr->right!=NULL)){
ptr=(numel<0?ptr->left:ptr->right);
}
(numel<0?ptr->left:ptr->right)=newrec; //строка меньше
}
newrec->recsib=0;
strcpy(newrec->recid,itok.name);//скопир название
newrec->newid=(char *)tteg;
newrec->left=NULL;
newrec->right=NULL;
newrec->rectok=tk_structvar;
newrec->flag=flag|tteg->flag;
newrec->line=linenumber;
newrec->file=currentfileinfo;
newrec->type=tp_gvar;
if(FixUp)newrec->flag|=f_reloc;
numel=1;
nexttok();
if(tok==tk_openblock){//[
nexttok();
if(tok!=tk_closeblock)numel=doconstlongmath(); //число элементов
else numel=0;
expecting(tk_closeblock);//]
}
newrec->recrm=numel;
newrec->recsize=numel*tteg->size;
dynamic=FALSE;
if(tok==tk_assign||notpost==TRUE){//=
if(useStartup==TRUE&&tok!=tk_assign&&numel!=0){
if(SaveStruct(numel*tteg->size,newrec)==TRUE)break;
}
if(alignword&&(!dynamic_flag))alignersize+=AlignCD(DS,2); //выровнять
// NotPostUnion();
itok.rec=newrec;
if((count=FindOff((unsigned char *)newrec->recid,DS))==0){
if(dynamic_flag)dynamic=DYNAMIC_VAR;
}
else if(dynamic_flag)dynamic=USED_DIN_VAR;
newrec->recnumber=(dynamic==0?outptrdata:0); //адрес начала структуры
newrec->recpost=dynamic;
if(notpost==TRUE&&tok!=tk_assign){
if(numel==0)ZeroMassiv();
for(;loop<tteg->size*numel;loop++)opd(aligner);
datasize+=loop;
break;
}
if(dynamic)newrec->sbuf=dynamic_var();
else{
loop=initstructvar(tteg,numel);
if(numel==0){
numel=loop/tteg->size;
if((loop%tteg->size)!=0){
numel++;
int i=tteg->size-(loop%tteg->size);
for(;i!=0;i--)opd(0);
loop=numel*tteg->size;
}
newrec->recrm=numel;
newrec->recsize=loop;
}
datasize+=loop;
}
}
else{
if(numel==0){
ZeroMassiv();
break;
}
if(CheckUseAsUndef((unsigned char *)newrec->recid)==0&&dynamic_flag)dynamic=TRUE;
switch(tok){ //неинициализированные
default: expected(';');
case tk_semicolon: done=1;// ;
case tk_camma: //, post global type
// long longpostsize;
if(useStartup==TRUE){
if(SaveStruct(numel*tteg->size,newrec)==TRUE){
nexttok();
break;
}
}
newrec->recpost=dynamic+1;
loop=numel*tteg->size;
if((flag&f_extern)==0&&dynamic==0){
if(alignword){ //выровнять на четный адрес
if(postsize%2==1)postsize++;
}
newrec->recnumber=postsize;
}
else newrec->recnumber=externnum++;
count=FindOff((unsigned char *)newrec->recid,VARPOST);
if((flag&f_extern)==0&&dynamic==0)
/*-----------------10.09.02 23:21-------------------
этот вызов должен быть после FindOff
--------------------------------------------------*/
AddPostData(loop);
nexttok();
break;
}
}
newrec->count=count;
break;
case tk_proc:
case tk_qwordvar:
case tk_doublevar:
case tk_floatvar:
case tk_dwordvar:
case tk_longvar:
case tk_charvar:
case tk_intvar:
case tk_bytevar:
case tk_wordvar: idalreadydefined(); nexttok(); break;
default:
if(newrec)expected(';');
else errstruct();
FindStopTok();
case tk_semicolon: done=1;
case tk_camma: nexttok(); break;
}
}
dopoststrings();
}
void InitStruct() //инициализировать глобальную структуру
{
struct structteg *tteg;
unsigned int flag;
//if(debug)puts("start init struct");
flag=itok.flag;
if(fstatic){
flag|=f_static;
fstatic=FALSE;
}
if(tok==tk_struct)nexttok();
else if(tok2!=tk_id&&tok2!=tk_ID){
if(tok2==tk_dblcolon){
itok.flag=f_classproc;
itok.rm=am32==FALSE?tk_word:tk_dword;//tk_void;
itok.npointr=0;
doclassproc(0/*comfile==file_w32?tk_stdcall:tk_pascal 18.10.05 10:52*/);
return;
}
notstructname();
}
tteg=FindTeg(TRUE);
if(tteg==NULL){
if(tok==tk_openbrace||tok2==tk_openbrace||tok==tk_colon||tok2==tk_colon)
tteg=CreatTeg(TRUE); //найти или создать тег
else{
while(tok!=tk_semicolon&&tok!=tk_eof)nexttok();
tegnotfound();
return;
}
}
else{
if(tok2==tk_openbrace)idalreadydefined();
nexttok();
}
InitStruct2(flag,tteg);
}
unsigned long LocalStruct2(int flag,int *localline,int binptr,char bcha,structteg *tteg) //инициализировать локальную структуру
{
int numel,first=FALSE;
struct localrec *newrec;
unsigned long size=0;
skipfind=TRUE; //запретить искать в глобальном дереве
do{
if(first!=FALSE){
binptr=inptr2;
bcha=cha2;
nexttok();
}
first=TRUE;
if(tok!=tk_ID&&tok!=tk_id)idalreadydefined();
else{ //инициализировать структуру
numel=1;
newrec=addlocalvar((char *)string,tk_structvar,localsize);
newrec->rec.newid=(char *)tteg;
newrec->rec.flag=tteg->flag;
newrec->rec.type=tp_localvar;
nexttok();
if(tok==tk_openblock){//[
skipfind=FALSE;
nexttok();
numel=doconstlongmath(); //число элементов
skipfind=TRUE;
expecting(tk_closeblock);//]
}
newrec->rec.recrm=numel;
size=numel*tteg->size;
newrec->rec.recsize=size;
if(flag&f_static){
// if(bcha==0)not_union_static();
if(tok==tk_assign){
// newrec->rec.rectok=tk_structvar;
newrec->rec.recnumber=0;
newrec->rec.recpost=DYNAMIC_VAR;
// newrec->rec.recsize=tteg->size;
// newrec->rec.recrm=numel;
newrec->rec.line=linenumber;
newrec->rec.file=currentfileinfo;
newrec->rec.npointr=0;
newrec->rec.sbuf=dynamic_var();
newrec->rec.recsib=newrec->rec.type=tp_gvar;
}
else{
newrec->rec.recpost=TRUE;
if(alignword){ //выровнять на четный адрес
if(postsize%2==1)postsize++;
}
newrec->rec.recnumber=postsize;
AddPostData(size);
}
size=0;
}
else{
size=Align(size,(am32==FALSE?2:4));
newrec->rec.recpost=LOCAL;
newrec->rec.recnumber=-localsize-size;
// localsize+=size;
if(tok==tk_assign){
if(*localline==0)*localline=linenumber;
AddBackBuf(binptr,bcha);
}
}
}
localsize+=size;
}while(tok==tk_camma);
skipfind=FALSE; //запретить искать в глобальном дереве
// localsize+=size;
itok.name[0]=0;
seminext();
return size;
}
unsigned long LocalStruct(int flag,int *localline) //инициализировать локальную структуру
{
struct structteg *tteg;
int binptr;
char bcha;
structteg *osearchteg;
osearchteg=searchteg;
searchteg=NULL;
skipfind=TRUE; //запретить искать в глобальном дереве
if(tok==tk_struct)nexttok();
binptr=inptr2;
bcha=cha2;
if((tteg=FindTeg(FALSE))==NULL&&(tteg=FindTeg(TRUE))==NULL){
skipfind=FALSE;
if(tok==tk_openbrace||tok2==tk_openbrace){
tteg=CreatTeg(FALSE); //найти или создать тег
}
else{
while(tok!=tk_semicolon&&tok!=tk_eof)nexttok();
tegnotfound();
searchteg=osearchteg;
return 0;
}
}
else{
searchteg=osearchteg;
if(tok2==tk_openbrace){
idalreadydefined();
SkipBlock2();
return 0;
}
nexttok();
if(tok!=tk_id&&tok!=tk_ID){
notstructname();
FindStopTok();
return 0;
}
}
searchteg=osearchteg;
return LocalStruct2(flag,localline,binptr,bcha,tteg);
}
void dostruct()
{
struct structteg *tteg;
int numel;
int usenumstr;
SINFO rstr;
char *ofsst=NULL;
int oneloop=FALSE;
unsigned long hnum;
unsigned int num,sized=0,sign=FALSE;
unsigned long adr;
int localstr=FALSE;
int poststr;
int flagstr;
struct idrec *ptrs;
if(tok2==tk_assign){
switch(ScanTok3()){
case tk_proc:
case tk_apiproc:
case tk_undefproc:
case tk_declare:
ptrs=itok.rec;
if(ptrs->recpost==LOCAL){
if(ESPloc&&am32){
itok.rm=rm_mod10|rm_sib;
itok.sib=0x24;
itok.number+=addESP;
}
else{
itok.rm=rm_mod10|(am32==FALSE?rm_BP:rm_EBP);
}
itok.segm=SS;
itok.post=0;
compressoffset(&itok);
}
else{
itok.segm=DS;
itok.rm=(am32==FALSE?rm_d16:rm_d32); //установки по умолчанию
itok.post=ptrs->recpost;
}
itok.sib=(am32==FALSE?CODE16:CODE32);
itok.flag=ptrs->flag;
switch(itok.size){
case 1:
tok=tk_bytevar;
dobytevar(0);
break;
case 2:
case 3:
tok=tk_wordvar;
do_d_wordvar(0,r16);
break;
case 4:
case 5:
case 6:
case 7:
tok=tk_dwordvar;
do_d_wordvar(0,r32);
break;
default:
tok=tk_qwordvar;
doqwordvar();
break;
}
return;
}
}
adr=itok.number;
numel=itok.rm; //число структур
usenumstr=itok.post; //было указание номера структуры
if(itok.type==tp_classvar){
tteg=(structteg *)itok.rec;
poststr=0;
flagstr=f_useidx;
}
else{
ptrs=itok.rec;
tteg=(structteg *)ptrs->newid;
if(ptrs->recpost==LOCAL)localstr=TRUE;
poststr=ptrs->recpost;
flagstr=ptrs->flag;
}
rstr=strinf;
strinf.bufstr=NULL;
num=itok.size;
// if(bufrm)printf("num=%d %s\n",adr,bufrm);
nexttok();
if(tok==tk_assign){
getoperand();
int starts=0; //смещение заполнения в структуре
if(tok==tk_int||tok==tk_word){
sized=2;
getoperand();
}
else if(tok==tk_long||tok==tk_dword){
sized=4;
getoperand();
}
else if(tok==tk_char||tok==tk_byte){
sized=1;
getoperand();
}
switch(tok){
case tk_charvar:
case tk_bytevar:
case tk_intvar:
case tk_wordvar:
case tk_longvar:
case tk_dwordvar:
int razr,retreg;
ITOK wtok;
char *wbuf;
wbuf=bufrm;
bufrm=NULL;
wtok=itok;
SINFO wstr;
wstr=strinf;
strinf.bufstr=NULL;
if((retreg=CheckIDZReg(itok.name,AX,razr=GetVarSize(tok)))!=NOINREG){
GenRegToReg(AX,retreg,razr);
IDZToReg(itok.name,AX,razr);
if(bufrm){
free(bufrm);
bufrm=NULL;
}
if(strinf.bufstr){
free(strinf.bufstr);
strinf.bufstr=NULL;
}
if(sized){
switch(razr){
case r8: tok=tk_beg; break;
case r16: tok=tk_reg; break;
case r32: tok=tk_reg32; break;
}
itok.number=0;
goto convr;
}
break;
}
IDZToReg(itok.name,AX,razr);
if(sized==0){
switch(tok){
case tk_charvar:
case tk_bytevar:
getintoal(tok,&wtok,wbuf,&wstr);
sized=1;
break;
case tk_intvar:
sign=TRUE;
case tk_wordvar:
getinto_e_ax(sign,tok,&wtok,wbuf,&wstr,r16);
sized=2;
break;
case tk_longvar:
sign=TRUE;
case tk_dwordvar:
getinto_e_ax(sign,tok,&wtok,wbuf,&wstr,r32);
sized=4;
break;
}
}
else{
convr:
switch(sized){
case 1:
getintoal(tok,&wtok,wbuf,&wstr);
break;
case 2:
getinto_e_ax(0,tok,&wtok,wbuf,&wstr,r16);
break;
case 4:
getinto_e_ax(0,tok,&wtok,wbuf,&wstr,r32);
break;
}
}
if(usenumstr!=FALSE){
// num/=ptrs->recrm; //указан номер структуры - значит не все
num=tteg->size;
if(strinf.bufstr==NULL)starts=num*numel;
}
num/=sized;
goto fillstr;
case tk_minus:
nexttok();
if(tok!=tk_number){
errstruct();
break;
}
itok.number=-itok.number;
case tk_number:
if(sized==0){
sized=4;
if(itok.number<65536)sized=2;
if(itok.number<256)sized=1;
}
if(usenumstr!=FALSE){
// num/=ptrs->recrm; //указан номер структуры - значит не все
num=tteg->size;
if(strinf.bufstr==NULL)starts=num*numel;
}
if(strinf.bufstr==NULL){
if(optimizespeed==TRUE){
if(sized==1&&(num%2)==0){
sized=2;
itok.number=(itok.number&255)|((itok.number<<8)&0xFF00);
}
if(chip>2&&sized==2&&(num%4)==0){
sized=4;
itok.number=(itok.number&0xFFFF)|(itok.number<<16);
}
}
else{
if(am32==FALSE){
if(sized==1&&((num<7&&(num%2)==0)||(itok.number==0&&num==8))){
sized=2;
itok.number=(itok.number&255)|((itok.number<<8)&0xFF00);
}
}
else if(chip>2&&sized!=4&&(num%4)==0&&itok.number==0)sized=4;
}
}
num/=sized;
if(num==1){
oneloop++;
hnum=itok.number;
}
else if(num==2&&sized==2&&chip>2){
oneloop++;
hnum=(itok.number&0xFFFF)|(itok.number<<16);
sized=4;
num=1;
}
else if(num==4&&sized==1&&chip>2){
oneloop++;
itok.number&=255;
hnum=itok.number|(itok.number<<8)|(itok.number<<16)|(itok.number<<24);
sized=4;
num=1;
}
else{
if(sized==1){
if(itok.number==0)outword(0x00B0);
else{
op(0xB0);
op(itok.number);
}
ConstToReg(itok.number,AX,r8);
}
else MovRegNum(sized,0,itok.number,EAX);
}
fillstr:
// itok.number=ptrs->recnumber;
itok.number=adr;
if(rstr.bufstr==NULL)itok.number+=starts;
itok.sib=(am32==FALSE?CODE16:CODE32);
if(localstr){
if(comfile!=file_w32&&oneloop==FALSE){
pushss();
popes();
}
if(ESPloc&&am32){
itok.rm=rm_mod10|rm_sib;
itok.sib=0x24;
itok.number+=addESP;
}
else{
itok.rm=rm_mod10|(am32==FALSE?rm_BP:rm_EBP);
}
itok.segm=SS;
tok=tk_rmnumber;
itok.post=0;
itok.size=tteg->size;
compressoffset(&itok);
if(rstr.bufstr!=NULL)CheckAllMassiv(bufrm,2,&rstr,&itok,EDI,EDX);
}
else{
if(comfile!=file_w32&&oneloop==FALSE){
pushds();
popes();
}
itok.post=poststr;
itok.segm=DS;
itok.rm=(am32==FALSE?rm_d16:rm_d32); //установки по умолчанию
itok.rec=NULL;//ptrs;
if(rstr.bufstr==NULL){
if(itok.post!=0)tok=tk_postnumber;
else tok=tk_number;
}
else{
// printf("bufrm=%s rstr=%s\n",bufrm,rstr.bufstr);
CheckAllMassiv(bufrm,2,&rstr,&itok,EDI,EDX);
// puts("end rm");
tok=tk_rmnumber;
itok.size=tteg->size; // ???? trap
}
}
itok.flag=flagstr;
if(oneloop){
switch(sized){
case 1:
outseg(&itok,2);
op(0xC6);
op(itok.rm);
outaddress(&itok);
op(hnum);
break;
case 2:
case 4:
op66(sized);
if(hnum==0){
outseg(&itok,2);
op(0x83);
op(itok.rm+0x20);
outaddress(&itok);
op(0);
break;
}
if((sized==4&&hnum==0xFFFFFFFF)||(sized==2&&hnum==0xFFFF)){
outseg(&itok,2);
op(0x83);
op(itok.rm+0x8);
outaddress(&itok);
op(0xFF);
break;
}
if(optimizespeed==0&&sized==4&&short_ok(hnum,TRUE)){
op(0x6A);
op(hnum); //push short number
op66(sized);
outseg(&itok,2);
op(0x8f);
op(itok.rm);
outaddress(&itok);
break;
}
outseg(&itok,2);
op(0xC7); //mov word[],number
op(itok.rm);
outaddress(&itok);
if(sized==2)outword(hnum);
else outdword(hnum);
break;
}
}
else{
warningreg(regs[am32][DI]);
getintoreg_32(DI,(am32+1)*2,0,&ofsst);
if(num<=2||(num<=4&&(!optimizespeed))){
for(unsigned int i=0;i<num;i++){
if(sized==1)stosb();
else if(sized==2)stosw();
else stosd();
}
}
else{
MovRegNum((am32+1)*2,0,num,ECX);
warningreg(regs[am32][CX]);
ConstToReg(0,ECX,(am32+1)*2);
op(0xF3); // REPZ
if(sized==1)stosb();
else if(sized==2)stosw();
else stosd();
}
}
nexttok();
break;
case tk_structvar:
struct structteg *tteg2;
int numel2;
int usenumstr2;
unsigned int num2;
int localstr2;
int poststr2;
int flagstr2;
// adr=itok.number;
localstr2=FALSE;
numel2=itok.rm; //число структур
usenumstr2=itok.post; //было указание номера структуры
if(itok.type==tp_classvar){
tteg2=(structteg *)itok.rec;
poststr2=0;
flagstr2=f_useidx;
}
else{
struct idrec *ptrs;
ptrs=itok.rec;
tteg2=(structteg *)ptrs->newid;
if(ptrs->recpost==LOCAL)localstr2=TRUE;
poststr2=ptrs->recpost;
flagstr2=ptrs->flag;
}
num2=itok.size;
// ptrs2=itok.rec;
// tteg2=(structteg *)ptrs2->newid;
// numel2=itok.rm; //число структур
// num2=tteg2->size;
if(usenumstr2!=FALSE){
num2=tteg->size;
if(strinf.bufstr==NULL)starts=num2*numel2;
}
// if(itok.post==FALSE)num2*=ptrs2->recrm; //не указан номер структуры - значит все
// else if(strinf.bufstr==NULL)starts=num2*numel2;
if(strinf.bufstr==NULL)itok.number+=starts;
itok.sib=(am32==FALSE?CODE16:CODE32);
if(localstr2){
itok.rm=rm_mod10;
if(strinf.bufstr==NULL){
if(ESPloc&&am32){
itok.rm|=rm_sib;
itok.sib=0x24;
}
else{
itok.rm|=(am32==FALSE?rm_BP:rm_EBP);
}
}
else{
CheckAllMassiv(bufrm,2,&strinf);
if(am32==FALSE)itok.rm|=rm_BPSI;
else{
itok.sib=(ESPloc?0x34:0x35);
itok.rm=4|rm_mod10;
}
}
itok.segm=SS;
if(ESPloc&&am32)itok.number+=addESP;
// else itok.number-=localsize;
tok=tk_rmnumber;
itok.size=tteg2->size;
itok.post=0;
compressoffset(&itok);
}
else{
itok.post=poststr2;
itok.rm=(am32==FALSE?rm_d16:rm_d32); //22.11.04 09:22//установки по умолчанию
if(strinf.bufstr==NULL){
if(itok.post==TRUE)tok=tk_postnumber;
else tok=tk_number;
}
else{
CheckAllMassiv(bufrm,2,&strinf);
itok.rm=rm_mod10|(am32==FALSE?rm_SI:6);
tok=tk_rmnumber;
itok.size=tteg2->size;
}
itok.segm=DS;
}
///!new
itok.flag=flagstr2;
warningreg(regs[am32][SI]);
///!new
// printf("tok=%d rm=%08X %s",tok,itok.rm,itok.name);
getintoreg_32(SI,(am32+1)*2,0,&ofsst);
ClearReg(SI);
num=tteg->size;
starts=0;
if(usenumstr==FALSE)num*=tteg->size; //ptrs->recrm; //не указан номер структуры - значит все
else if(rstr.bufstr==NULL)starts=num*numel;
itok.number=adr;//ptrs->recnumber;
if(rstr.bufstr==NULL)itok.number+=starts;
itok.sib=(am32==FALSE?CODE16:CODE32);
if(localstr){
// if(ptrs->recpost==LOCAL){
if(ESPloc&&am32){
itok.rm=rm_mod10|rm_sib;
itok.sib=0x24;
itok.number+=addESP;
}
else{
itok.rm=rm_mod10|(am32==FALSE?rm_BP:rm_EBP);
}
itok.segm=SS;
tok=tk_rmnumber;
itok.size=tteg->size;
itok.post=0;
compressoffset(&itok);
if(rstr.bufstr!=NULL)CheckAllMassiv(bufrm,2,&rstr,&itok,EDI,EDX);
}
else{
itok.post=poststr;//ptrs->recpost;
itok.segm=DS;
itok.rm=(am32==FALSE?rm_d16:rm_d32); //установки по умолчанию
if(rstr.bufstr==NULL){
if(itok.post==TRUE)tok=tk_postnumber;
else tok=tk_number;
}
else{
CheckAllMassiv(bufrm,2,&rstr,&itok,EDI,EDX);
tok=tk_rmnumber;
itok.size=tteg->size;
}
}
///!new
itok.flag=flagstr;//ptrs->flag;
warningreg(regs[am32][DI]);
if(num2>num)warnsize();
ClearReg(DI);
///!new
usenumstr2=DS;
if(poststr2==LOCAL)usenumstr2=SS;
getintoreg_32(DI,(am32+1)*2,0,&ofsst);
num=num2;
sized=1;
if(optimizespeed){
if((num%2)==0)sized=2;
if(chip>2&&(num%4)==0)sized=4;
}
else{
if(am32==FALSE){
if((num%2)==0)sized=2;
}
else{
if(chip>2&&(num%4)==0)sized=4;
}
}
num/=sized;
///!new
if(num<=2||(num<=4&&(!optimizespeed&&usenumstr2!=SS))){
for(unsigned int i=0;i<num;i++){
if(usenumstr2==SS)op(0x36);
if(sized==1)movsb();
else if(sized==2)movsw();
else movsd();
}
}
else{
///!new
MovRegNum((am32+1)*2,0,num,ECX);
warningreg(regs[am32][CX]);
ConstToReg(0,ECX,(am32+1)*2);
if(comfile!=file_w32){
if(poststr)pushss();
// if(ptrs->recpost==LOCAL)pushss();
else pushds();
popes();
}
op(0xF3); // REPZ
if(usenumstr2==SS)op(0x36);
if(sized==1)movsb();
else if(sized==2)movsw();
else movsd();
}
break;
default: errstruct();
}
}
else{
nexttok();
errstruct();
}
if(ofsst)free(ofsst);
}
int SaveStruct(int size,idrec *newrec)
{
int i=0;
if((startStartup+size)<endStartup){
if(alignword){ //выровнять на четный адрес
if(startStartup%2==1)i=1;
}
if((startStartup+size+i)<=endStartup){
startStartup+=i;
newrec->recnumber=startStartup; //адрес начала структуры
newrec->recpost=FALSE;
startStartup+=size;
return TRUE;
}
}
return FALSE;
}
int CheckAsmName(char *name)
{
char buf[IDLENGTH];
strcpy(buf,name);
strupr(buf);
return FastSearch((unsigned char *)asmMnem,ofsmnem,0,buf);
}
void FastTok(int mode,int *tok4,ITOK *itok4)
{
int useme;
int next=1;
*tok4=tokens;
itok4->type=tp_ucnovn;
whitespace(); //пропуск незначащих символов
if(isalpha(cha)||(cha=='_')||cha>=0x80){ //идентификатор
if(mode==1){
int i=0;
do{
itok4->name[i++]=cha;
nextchar();
}while(CheckChar2()==TRUE&&i<IDLENGTH);
if(i==IDLENGTH)i--;
itok4->name[i]=0;
}
while(CheckChar2()==TRUE)nextchar(); //дочитать слово
*tok4=tk_id;
return;
}
if(isdigit(cha)){//числа
if(mode==1){
inptr--;
itok4->lnumber=scannumber(&itok4->rm);
}
else{
do{
nextchar();
}while(isdigit(cha));
}
*tok4=tk_number;
return;
}
else switch(cha){
case '\"':
nextchar(); //строковая константа
while(cha!='\"'&&!endoffile){
convert_char();
nextchar();
}
*tok4=tk_string;
break;
case '\'': //символьная константа может иметь более 1 символа
nextchar();
while(cha!='\''&&!endoffile){ // special character
convert_char();
nextchar();
}
break;
case '/': nextchar();
switch(cha){
case '*': nextchar(); //соментарий
useme=1;
if(mode==2)itok4->number=inptr-2;
while(!endoffile&&useme>0){
whitespace();
if(cha=='*'){
nextchar();
if(cha=='/')useme--;
else continue;
}
else if(cha=='/'){
nextchar();
if(cha=='*')useme++;
else continue;
}
nextchar();
}
if(mode==2)*tok4=tk_comment2;
else FastTok(mode,tok4,itok4);
if(endoffile)*tok4=tk_eof;
return;
case '/':
if(mode==2)itok4->number=inptr-2;
do{
nextchar();
}while(!endoffile&&cha!=13); //строка коментария
if(endoffile)*tok4=tk_eof;
if(mode==2)*tok4=tk_comment1;
else FastTok(mode,tok4,itok4);
return;
}
break;
case '#':
case '?':
nextchar();
// tokscan(&tok,&itok,string);
FastTok(1,tok4,itok4);
// if((itok.number=GetDirective((char *)string))!=-1){
if(*tok4==tk_id&&(itok4->number=GetDirective(itok4->name))!=-1){
*tok4=tk_question;
}
return;
case ';': *tok4=tk_semicolon; break;
case '[': *tok4=tk_openblock; break;
case ']': *tok4=tk_closeblock; break;
case '(': *tok4=tk_openbracket; break;
case ')': *tok4=tk_closebracket; break;
case '{': *tok4=tk_openbrace; break;
case '}': *tok4=tk_closebrace; break;
case ',': *tok4=tk_camma; break;
case ':': *tok4=tk_colon; break;
case 26: *tok4=tk_eof; return;
case 13: *tok4=tk_endline; break;
case '\\':
nextchar();
if(cha==13){
FastTok(mode,tok4,itok4);
if(tok==tk_endline)FastTok(mode,tok4,itok4);
return;
}
break;
case '!':
nextchar();
if(cha=='='){
*tok4=tk_notequal; //!=
itok4->type=tp_compare;
}
else{
*tok4=tk_not;
next=0;
}
break;
case '=':
nextchar();
if(cha=='='){
*tok4=tk_equalto; //==
itok4->type=tp_compare;
}
else{
*tok4=tk_assign; //присвоить
next=0;
}
break;
case '>':
nextchar();
switch(cha){
case '>':
nextchar();
if(cha=='=')*tok4=tk_rrequals; //сдвиг вправо с присвоением
else{
*tok4=tk_rr; //сдвиг вправо
next=0;
itok4->type=tp_opperand;
}
break;
case '<': *tok4=tk_swap; break; //обмен
case '=': *tok4=tk_greaterequal; itok4->type=tp_compare; break; //больше или равно
default: *tok4=tk_greater; next=0; itok4->type=tp_compare; break; //больше
}
break;
case '<':
nextchar();
switch(cha){
case '<':
nextchar();
if(cha=='=')*tok4=tk_llequals; //сдвиг влево с присвоением
else{
*tok4=tk_ll; //сдвиг влево
next=0;
itok4->type=tp_opperand;
}
break;
case '>': *tok4=tk_notequal; itok4->type=tp_compare; break; //!=
case '=': *tok4=tk_lessequal; itok4->type=tp_compare; break; //меньше или равно
default: *tok4=tk_less; next=0; itok4->type=tp_compare; break;//меньше
}
break;
}
if(next)nextchar();
}
void FindDirectiv()
//ускоренный поиск директивы
{
inptr=inptr2;
cha=cha2;
linenumber=linenum2;
do{
FastTok(0);
}while(tok!=tk_question&&tok!=tk_eof);
inptr2=inptr;
cha2=cha;
linenum2=linenumber;
}
unsigned long long scannumber(int *rm)
{
int useme=0,binnum=0;
unsigned char c;
unsigned long long number=0;
*rm=tokens;
for(int i=inptr;;i++){
c=input[i];
unsigned char cc=c&(unsigned char)0x5f;
if(cc>='A'&&cc<='F'){
if(cc=='B'&&binnum==1)binnum++;
else binnum=3;
useme=3;
}
else if(c<'0'||c>'9'){
if(useme==0&&c=='.'&&input[i+1]!='.'){ //float
binnum=3;
useme++;
*rm=tk_double;
*(double *)&number=atof((char *)&input[inptr]);
// printf("float=%f %08X\n",*(float *)&number,*(long *)&number);
inptr=i+1;
do{
nextchar();
}while(isdigit(cha));
if((cha&0x5f)!='E')break;
nextchar();
if(isdigit(cha)||cha=='-'){
do{
nextchar();
}while(isdigit(cha));
}
break;
}
else if(cc=='H'){ //hex
useme=2;
binnum=3;
break;
}
break;
}
else if(c<'2'&&(binnum==0||binnum==2))binnum++;
}
if(binnum==2)goto cbinnum;
if(useme!=1){
nextchar();
if(useme==2)goto hexnum;
if(cha=='0'){
nextchar();
switch(cha&0x5f){
case 'X': // hexadecimal number
nextchar();
hexnum:
while(isxdigit(cha)){
number*=16;
if(isdigit(cha))number+=cha-'0';
else number+=(cha&0x5f)-'7';
nextchar();
}
if(useme==2)nextchar();
useme++;
break;
case 'B': // binary number
cbinnum:
nextchar();
while(cha=='0'||cha=='1'){
number=number*2+(cha-'0');
nextchar();
}
if(binnum==2)nextchar();
else useme++;
break;
case 'O': // octal number
nextchar();
while(cha>='0'&&cha<='7'){
number=number*8+(cha-'0');
nextchar();
}
useme++;
break;
}
}
if(useme==0||useme==3){ // decimal number
while(isdigit(cha)){
number=number*10+(cha-'0');
nextchar();
}
}
}
c=(unsigned char)(cha&0x5F);
if(c=='I'){
if(input[inptr]=='6'&&input[inptr+1]=='4'){
inptr+=2;
nextchar();
*rm=tk_qword;
}
}
else if(c=='L'||c=='U'||c=='F'||c=='Q'){
if(c=='L')*rm=tk_dword;
if(c=='F'){
*rm=tk_float;
*(float *)&number=*(double *)&number;
}
if(c=='Q')*rm=tk_qword;
nextchar();
c=(unsigned char)(cha&0x5F);
if(c=='L'||c=='U'){
if(c=='L')*rm=tk_dword;
nextchar();
}
}
if(*rm==tokens){
if(number<256)*rm=tk_byte;
else if(number<65536)*rm=tk_word;
else if(number<0x100000000LL)*rm=tk_dword;
else *rm=tk_qword;
}
return number;
}
void tag_massiv(int *tok4,ITOK *itok4,unsigned char *string4)
{
struct structteg *tteg;
int number,tok,rm;
tok=*tok4;
number=itok4->number;
nextchar();
//14.09.04 18:52
do{
FastTok(1,tok4,itok4);
strcpy((char *)string4,itok4->name);
searchtree2(definestart,itok4,tok4,string4);
}while(*tok4==tk_endline);
///////////////////
// printf("tok=%d %s\n",*tok4,itok4->name);
char *tn;
if((tn=strchr(itok4->name,'@'))!=NULL)*tn=0;
if((tteg=FindTeg(FALSE,itok4->name))!=NULL||(tteg=FindTeg(TRUE,itok4->name))!=NULL){
// printf("tok=%d %s\n",*tok4,itok4->name);
itok4->number=0;
dostructvar2(tok4,itok4,tteg,string4);
rm=RegToRM(number,tok);
// printf("tok=%d rm=%d %s\n",*tok4,itok4->rm,itok4->name);
if(*tok4==tk_pointer&&itok4->type==tk_proc){
itok4->sib=rm|rm_mod10;
itok4->flag&=~f_reloc;
}
else if(*tok4!=tk_proc&&*tok4!=tk_declare/*&&(itok4->flag&f_static)==0 эффект добавления регристра*/){
itok4->rm=rm_mod10|rm;
itok4->flag&=~f_reloc;
}
if(*tok4==tk_proc||*tok4==tk_declare||*tok4==tk_undefproc){
structadr.sib=THIS_REG;
structadr.rm=number;
}
else if(*tok4==tk_id||*tok4==tk_ID||*tok4==tk_structvar){
*tok4=tk_rmnumber;
itok4->segm=(splitdata==FALSE)?DS:CS;
itok4->post=0;
}
if(bufrm&&strcmp(bufrm,"&this;")==0){
free(bufrm);
bufrm=NULL;
}
// printf("tok=%d rm=%d post=%d %s\n",*tok4,itok4->rm,itok4->post,itok4->name);
// if(strinf.bufstr)puts(strinf.bufstr);
}
else if(displaytokerrors){
unknowntagstruct(itok4->name);
*tok4=tk_number;
}
}
int RegToRM(int number,int tok4)
{
int rm;
if(displaytokerrors){
if(am32==FALSE&&tok4==tk_reg32)regBXDISIBPexpected();
else if(am32&&tok4==tk_reg)reg32expected();
}
if(am32==FALSE){
switch(number){
case BX:
rm=rm_BX;
break;
case DI:
rm=rm_DI;
break;
case SI:
rm=rm_SI;
break;
case BP:
rm=rm_BP;
break;
default:
if(displaytokerrors)regBXDISIBPexpected();
break;
}
}
else rm=number;
return rm;
}
int CheckResName(char *name)
{
char buf[IDLENGTH];
strcpy(buf,name);
strlwr(buf);
return FastSearch((unsigned char *)resMnem,ofsres,3,buf);
}
int GetTokVar2()
{
ITOK cstok;
int i;
unsigned char ocha=cha;
unsigned int oinptr=inptr;
int oline=linenumber;
char odisplay=displaytokerrors;
displaytokerrors=0;
tokscan(&i,&cstok,string2);
displaytokerrors=odisplay;
switch(i){
case tk_number:
cha=ocha;
inptr=oinptr;
linenumber=oline;
case tk_int:
case tk_char:
case tk_long:
case tk_short:
case tk_byte:
case tk_word:
case tk_dword:
case tk_signed:
case tk_unsigned:
return i;
}
cha=ocha;
inptr=oinptr;
linenumber=oline;
return 0;
}
void GetTypeVar(int *tok4)
{
static int use=0;
int i;
if(use)return;
use=1;
i=GetTokVar2();
if(*tok4==tk_signed){
if(i==tk_char||i==tk_int||i==tk_long){
*tok4=i;
i=GetTokVar2();
if(*tok4==tk_long){
if(i==tk_long)*tok4=tk_qword;
else if(i!=tk_int&&i!=0&&displaytokerrors)unknowntype();
}
if(*tok4==tk_int&&am32)*tok4=tk_long;
}
else if(i==tk_short){
i=GetTokVar2();
*tok4=tk_int;
if(i!=0&&i!=tk_int&&displaytokerrors)unknowntype();
}
else if(i==0)*tok4=(am32==0?tk_int:tk_long);
else if(displaytokerrors)unknowntype();
}
else if(*tok4==tk_unsigned){
switch(i){
case tk_char:
*tok4=tk_byte;
break;
case tk_int:
*tok4=(am32==0?tk_word:tk_dword);
break;
case tk_long:
*tok4=tk_dword;
i=GetTokVar2();
if(i==tk_long)*tok4=tk_qword;
else if(i!=tk_int&&i!=0&&displaytokerrors)unknowntype();
break;
case tk_short:
*tok4=tk_word;
i=GetTokVar2();
if(i!=0&&i!=tk_int&&displaytokerrors)unknowntype();
break;
case 0:
*tok4=(am32==0?tk_word:tk_dword);
break;
default:
if(displaytokerrors)unknowntype();
}
}
else if(i==tk_int&&(*tok4==tk_long||*tok4==tk_short))*tok4=i;
else if(*tok4==tk_short)*tok4=tk_int;
else if(*tok4==tk_int&&(!(idasm==TRUE&&i==tk_number))&&am32)*tok4=tk_long;
else if(i==tk_long&& *tok4==tk_long)*tok4=tk_qword;
use=0;
}
int CheckDef()
{
int otok;
if(skipfind!=LOCAL)return FALSE;
switch(tok2){
case tk_semicolon:
case tk_assign:
case tk_openblock:
case tk_openbracket:
case tk_camma:
case tk_openbrace:
return FALSE;
}
otok=tok;
searchtree2(definestart,&itok,&tok,string);
if(tok==otok)return FALSE;
return TRUE;
}
/* end of TOKA.C */