#define _MAIN_ #ifdef _UNIX_ #define DIV_PATH ':' #else #define DIV_PATH ';' #endif #include #include #include "tok.h" static char **_Argv; //!!! simplest way to make your own variable unsigned char compilerstr[]="SPHINX C-- 0.239"; char *rawfilename; /* file name */ char *rawext; LISTCOM *listcom; EWAR wartype={NULL,NULL},errfile={NULL,NULL}; int numfindpath=0; char *findpath[16]; char modelmem=TINY; char *stubfile=NULL; char *winstub=NULL; FILE *hout=NULL; char *namestartupfile="startup.h--"; char outext[4]="com"; short extflag=TRUE;//расширение можно присвоить //int scrsize; unsigned char gwarning=FALSE; unsigned char sobj=FALSE; unsigned char usestub=TRUE; unsigned char dpmistub=FALSE; short dllflag=FALSE; static int numstr; char meinfo[]= "\nEdition of this version by\n" " Mishel Sheker\n" " Fido 2:5021/3.40\n" " E-Mail sheker@mail.ru\n" " Russia"; time_t systime; struct tm timeptr; char comsymbios=FALSE; char fobj=FALSE; //признак генерации obj unsigned int startptr = 0x100; // start address unsigned char wconsole=FALSE; //признак генерации консольного приложения windows unsigned char optstr=FALSE; //оптимизация строковых констант unsigned char crif=TRUE; //check reply include file unsigned char idasm=FALSE; //ассемблерные инструкции считать идентификаторами unsigned char wbss=2; //пост переменные в отдельную секцию unsigned char use_env=FALSE; //переменная окружения int numrel=0; //число элементов в таблице перемещений unsigned char useordinal=FALSE; unsigned char useDOS4GW=FALSE; unsigned char clearpost=FALSE; unsigned char uselea=TRUE; unsigned char regoverstack=TRUE; unsigned char shortimport=FALSE; unsigned char useinline=2; unsigned char ocoff=FALSE; unsigned char ESPloc=FALSE; int startupfile=-1; int alignproc=8,aligncycle=8; char *usage[]={ "USAGE: C-- [options] [FILE_NAME.INI] [SOURCE_FILE_NAME]", "", " C-- COMPILER OPTIONS", "", " OPTIMIZATION", "/OC optimize for code size /DE enable temporary expansion variable", "/OS optimize for speed /OST enable optimization string", "/ON enable optimization number /AP[=n] align start function", "/UST use startup code for variables /AC[=n] align start cycles", #ifdef OPTVARCONST "/ORV replace variable on constant /OIR skip repeated initializing register", #else " /OIR skip repeated initializing register", #endif "", " CODE GENERATION", "/2 80286 code optimizations /SA=#### start code address", "/3 80386 code optimizations /AL=## set value insert byte", "/4 80486 code optimizations /WFA fast call API functions", "/5 pentium code optimizations /IV initial all variables", "/A enable address alignment /SUV=#### start address variables", "/AS[=n] def. alignment in structures /LRS load in registers over stack", "/UL use 'lea' for adding registers /JS join stack calling functions", "/BA byte access to array",// /ASP addressing local variable via ESP", "", " PREPROCESSOR", "/IP= include file path /IA assembly instructions as identifier", "/D= defined identifier /CRI- not check include file on repeated", "/MIF= main input file /IND= import name from dll", "/SF= other startup file", "", " LINKING", "/AT insert ATEXIT support block /NS disable stub", "/ARGC insert parse command line /S=##### set stack size", "/P insert parse command line /WIB=##### set image base address", "/C insert CTRL ignoring code /WFU add Fix Up table, for Windows", "/R insert resize memory block /WMB create Windows mono block", "/ENV insert variable with environ /WS= set name stub file for win32", "/J0 disable initial jump to main() /WBSS set post data in bss section", "/J1 initial jump to main() short /WO call API functions on ordinals", "/J2 initial jump to main() near /CPA clear post area", "/STUB= set name stub file /WSI short import table, for Windows", "/DOS4GW file running with DOS4GW /WAF=#### align Windows file (def 512)", "/STM startup code in main function", "", " OUTPUT FILES", "/TEXE DOS EXE file (model TINY) /D32 EXE file (32bit code for DOS)", "/EXE DOS EXE file (model SMALL) /W32 EXE for Windows32 GUI", "/OBJ OBJ output file /W32C EXE for Windows32 console", "/SOBJ slave OBJ output file /DLL DLL for Windows32", "/COFF OBJ COFF output file /DBG create debug information", "/SYM COM file symbiosis /LST create assembly listing", "/SYS device (SYS) file /B32 32bit binary files", "/MEOS executable file for MeOS /MAP create function map file", "/EXT= set file extension", "", " MISCELLANEOUS", "/HELP /H /? help, this info /WORDS list of C-- reserved words", "/W enable warning /LAI list of assembler instructions", "/WF= direct warnings to a file /ME display my name and my address", "/MER=## set maximum number errors /X disable SPHINX C-- header in output", "/NW=## disable selected warnings /WE=## selected warning will be error", //" /SCD split code and date", NULL}; char *dir[]={ "ME", "WORDS", "SYM", "LAI", "OBJ", "SOBJ", "J0", "J1", "J2", "C", "R", "P", "X", "EXE", "S", "SYS", "ARGC", "TEXE", "ROM", "W32", "D32", "W32C", "AT", "WFA", "SA", "STM", "SUV", "UST", "MIF", "DLL", "DOS4GW","ENV", "CPA", "WBSS", "MEOS", "SF", "B32", "WIB", "DBG", "OS", "OC", "A", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "W", "WF", "DE", "ON", "IP", "STUB", "NS", "AP", "D", "OST", "CRI", "IA", "SCD", "AL", "WFU", "IV", "MER", "WMB", "HELP", "H", "?", "AC", "WS", "IND", "WO", "NW", "LST", "AS", "UL", "LRS", "WSI", "WAF", "OIR", "COFF", "JS", "BA", "ASP", #ifdef OPTVARCONST "ORV", #endif "MAP", "WE", "EXT", NULL}; enum { c_me, c_key, c_sym, c_lasm, c_endinfo=c_lasm, c_obj, c_sobj, c_j0, c_j1, c_j2, c_ctrlc, c_r, c_p, c_x, c_exe, c_s, c_sys, c_arg, c_texe, c_rom, c_w32, c_d32, c_w32c, c_at, c_wfa, c_sa, c_stm, c_suv, c_ust, c_mif, c_dll, c_d4g, c_env, c_cpa, c_wbss, c_meos, c_sf, c_b32, c_wib, c_dbg, c_endstart=c_dbg, c_os, c_oc, c_a, c_0, c_1, c_2, c_3, c_4, c_5, c_6, c_7, c_8, c_9, c_w, c_wf, c_de, c_opnum, c_ip, c_stub, c_ns, c_ap, c_define,c_ost, c_cri, c_ia, c_scd, c_al, c_wfu, c_iv, c_mer, c_wmb, c_help, c_h, c_hh, c_ac, c_ws, c_ind, c_wo, c_nw, c_lst, c_as, c_ul, c_lrs, c_wsi, c_waf, c_oir, c_coff, c_js, c_ba, c_asp, #ifdef OPTVARCONST c_orv, #endif c_map, c_we, c_ext, c_end}; #define NUMEXT 6 //число разрешенных расширений компилируемого файла char extcompile[NUMEXT][4]={"c--","cmm","c","h--","hmm","h"}; #ifdef _KOS_ char __pgmname[256]; char __cmdline[256]; #endif char *bufstr=NULL; //буфер для строк из процедур int sbufstr=SIZEBUF; //начальный размер этого буфера void compile(); void PrintInfo(char **str); void LoadIni(char *name); //void CheckNumStr(); void ListId(int num,unsigned char *list,short *ofs); void printmemsizes(); void print8item(char *str); void doposts(void); void GetMemExeDat(); void AddJmpApi(); void startsymbiosys(char *symfile); int writeoutput(); void BadCommandLine(char *str); void CheckExtenshions(); void ImportName(char *name); void WarnUnusedVar();//предупреждения о неиспользованных процедурах и переменных void MakeExeHeader(EXE_DOS_HEADER *exeheader); void CheckPageCode(unsigned int ofs); int MakePE(); int MakeObj(); void CheckUndefClassProc(); /* void PrintTegList(structteg *tteg) { if(tteg){ PrintTegList(tteg->left); PrintTegList(tteg->right); puts(tteg->name); } } */ //unsigned long maxusedmem=0; void ErrOpenFile(char *str) { printf("Unable to open file %s.\n",str); } int main(int argc,char *argv[]) { int count; unsigned char pari=FALSE; printf("\nSPHINX C-- Compiler Version %d.%d%s %s\r\n",ver1,ver2,betta,__DATE__); // scrsize=24; if(argc>1){ _Argv=argv;// This make portable code bufstr=(char *)MALLOC(SIZEBUF); output=(unsigned char *)MALLOC((size_t)MAXDATA); outputdata=output; postbuf=(postinfo *)MALLOC(MAXPOSTS*sizeof(postinfo)); strcpy((char *)string,argv[0]); rawext=strrchr((char *)string,'\\'); if(rawext!=NULL){ rawext[0]=0; IncludePath((char *)string); } rawfilename=getenv("C--"); if(rawfilename!=NULL)IncludePath(rawfilename); rawfilename=rawext=NULL; LoadIni("c--.ini"); for(count=1;count=0)preerror("?endif expected before end of file"); AddObj(); docalls(); //добавить внешние процедуры addinitvar(); CheckUndefClassProc(); if(undefoffstart!=NULL){ //выдать список неизвестных ссылок UNDEFOFF *curptr=undefoffstart; for(;;){ char holdstr[80]; UNDEFOFF *ocurptr; linenumber=curptr->pos->line; sprintf(holdstr,"\'%s\' offset undefined",curptr->name); currentfileinfo=curptr->pos->file; preerror(holdstr); free(curptr->pos); if(curptr->next==NULL)break; ocurptr=curptr->next; free(curptr); curptr=ocurptr; } free(curptr); } while(liststring!=NULL){ STRING_LIST *ins; ins=(STRING_LIST *)liststring; nextstr=ins->next; free(liststring); liststring=nextstr; } free(bufstr); if(warning==TRUE&&wact[7].usewarn)WarnUnusedVar();//предупреждения о неиспользованных процедурах и переменных if(numstrtbl)CreatStrTabRes(); //завершить создание ресурсов if(fobj==FALSE){ if(comfile==file_w32&&error==0){ AddJmpApi(); //косвенные вызовы API CreatWinStub(); } longhold=outptr; if(comfile==file_rom){ ooutptr=outptr; if(modelmem==SMALL){ *(short *)&output[stackstartaddress]=(short)(((outptrdata+postsize+stacksize)/4+1)*4); *(short *)&output[dataromstart]=(short)(outptr+4); *(short *)&output[dataromsize]=(short)(outptrdata/2); // printf("outptr=%d outptrdate=%d outptrsize=%d\n",outptr,outptrdata,outptrsize); for(unsigned int i=0;i32)i=64; else if(i>16)i=32; else if(i>8)i=16; else if(i>4)i=8; else if(i>2)i=4; romsize=i*1024; output[2]=(unsigned char)(romsize/512); } if(outptr>=romsize)preerror("The size of a code is more than the size of the ROM"); for(;outptr65535L) preerror("Data and stack total exceeds 64k"); } else if(comfile==file_sys){ for(int i=0;iname); *(short *)&output[syscom+i*2]=(unsigned short)itok.number; } free(listcom); } else longhold+=(long)postsize+(long)(stacksize); if(am32==0&&longhold>65535L&&!(modelmem==TINY&&(!resizemem)))preerror("Code, data and stack total exceeds 64k"); if(posts>0)doposts(); //Установить адреса вызовов процедур и переходов if(resizemem&&comfile==file_com){ segments_required=(outptr+postsize+stacksize+15)/16; *(short *)&output[resizesizeaddress]=(short)segments_required; *(short *)&output[stackstartaddress]=(short)(segments_required*16); } } deinitregstat(); #ifdef OPTVARCONST KillMainLVIC(); #endif // puts("List Teg name:"); // PrintTegList(tegtree); printf("COMPILING FINISHED. Errors: %d\n",error); if(error==0){ if(cpu>=1){ char m1[12]; switch(cpu){ case 5: strcpy(m1,"Pentium"); break; case 6: strcpy(m1,"MMX"); break; case 7: strcpy(m1,"Pentium II"); break; case 8: strcpy(m1,"Pentium III"); break; case 9: strcpy(m1,"Pentium IV"); break; default: sprintf(m1,"80%d86",cpu); } printf("CPU required: %s or greater.\n",m1); } runfilesize=outptr-startptr; if(comfile==file_rom)runfilesize=romsize; else if(modelmem==SMALL&&comfile==file_exe){ runfilesize+=outptrdata-startptrdata+0x20; postsize+=postsize%2; stacksize=(stacksize+15)/16*16; } else if((comfile==file_exe||comfile==file_d32)&&modelmem==TINY) runfilesize+=0x20; printmemsizes(); endinptr=outptr; if(writeoutput()==0)printf("Run File Saved (%ld bytes).\n",runfilesize); if(comfile==file_w32&&fobj==FALSE)printf("Created file of a format PE for Windows.\nFor alignment section code, added %u zero bytes.\n",filingzerope); // else if(FILEALIGN&&fobj==FALSE)printf("For alignment file, added %u zero bytes.\n",filingzerope); } if(pdbg)DoTDS(); } void printmemsizes() { long stacklong; unsigned int stackword; unsigned int postword,codeword; postword=postsize; codeword=outptr-startptr; stackword=stacksize; if(comfile==file_com||(comfile==file_exe&&modelmem==TINY)){ if(resizemem==0){ stacklong=0xFFFE - outptr - postsize; stackword=stacklong; } codeword=codeword-datasize-alignersize; } else if(comfile==file_sys)stackword=sysstack; else if(comfile==file_exe||comfile==file_rom)datasize=outptrdata; else if(comfile==file_d32)codeword-=datasize; printf("Code: %u bytes, Data: %u bytes, Post: %u bytes, Stack: %u bytes\n" ,codeword,datasize,postword,stackword); for(int i=0;itype){ case CODE_SIZE: *(short *)&output[(postbuf+i)->loc]+=codeword; break; case CODE_SIZE32: *(long *)&output[(postbuf+i)->loc]+=codeword; break; case DATA_SIZE: *(short *)&output[(postbuf+i)->loc]+=datasize; break; case DATA_SIZE32: *(long *)&output[(postbuf+i)->loc]+=datasize; break; case POST_SIZE: *(short *)&output[(postbuf+i)->loc]+=postword; break; case POST_SIZE32: *(long *)&output[(postbuf+i)->loc]+=postword; break; case STACK_SIZE: *(short *)&output[(postbuf+i)->loc]+=stackword; break; case STACK_SIZE32: *(long *)&output[(postbuf+i)->loc]+=stackword; break; } } } void PrintInfo(char **str) { numstr=1; for(int i=0;str[i]!=NULL;i++){ puts(str[i]); // CheckNumStr(); } } /*void CheckNumStr() { #ifndef _UNIX_ if(((numstr+1)%(scrsize-1))==0&&outfile!=0){ puts("Press any key..."); getch(); } numstr++; #endif } */ void strbtrim(char *st) { int i; char *p,*q; p=q=st; while(isspace(*p))p++; //пока незначащие символы while(*p)*q++=*p++; //переместить строку *q='\0'; for(i=strlen(st)-1;isspace(st[i])&&i>=0;i--); st[i+1]='\0'; } unsigned long getnumber(unsigned char *buf) { int temp2; unsigned long retnum; unsigned char *oinput; unsigned int oinptr,oendinptr; if(!isdigit(buf[0]))return 0; oinptr=inptr; oinput=input; oendinptr=endinptr; input=buf; inptr=0; endinptr=256; retnum=scannumber(&temp2); inptr=oinptr; input=oinput; endinptr=oendinptr; return retnum; } int SelectComand(char *pptr,int *count) { int i; unsigned char neg=FALSE; char *ptr; int len; if((ptr=strchr(pptr,';'))!=NULL)*ptr=0;// ищем комментарий отсекаем все после него if((ptr=strchr(pptr,'='))!=NULL){ // ищем знак равенства *ptr=0; // делим ptr++; strbtrim(ptr); //убрать лишние пробелы } strbtrim(pptr); //убрать лишние пробелы if(*pptr==0)return c_end+1; //пустая строка if((i=strlen(pptr))>1&&pptr[i-1]=='-'){ neg=TRUE; pptr[i-1]=0; } strupr(pptr); for(i=0;dir[i]!=NULL;i++){ if(strcmp(dir[i],pptr)==0){ if((i<=c_endinfo)&&count==0){ char buf[80]; sprintf(buf,"Option '%s' is used only in command line",dir[i]); preerror(buf); return i; } if(i<=c_endstart&¬doneprestuff!=TRUE){ errlate: char buf[80]; sprintf(buf,"Too late used '#pragma option %s'",dir[i]); preerror(buf); return i; } switch(i){ case c_j0: jumptomain=(unsigned char)(neg!=FALSE?CALL_NEAR:CALL_NONE); header=(unsigned char)0^neg; break; case c_j1: jumptomain=(unsigned char)CALL_SHORT; header=(unsigned char)1; break; case c_j2: jumptomain=(unsigned char)(neg==FALSE?CALL_NEAR:CALL_NONE); header=(unsigned char)1^neg; break; case c_ctrlc: killctrlc=(unsigned char)1^neg; break; case c_os: optimizespeed=(unsigned char)1^neg; break; case c_oc: optimizespeed=(unsigned char)0^neg; break; case c_r: resizemem=(unsigned char)1^neg; break; case c_p: parsecommandline=(unsigned char)1^neg; break; case c_a: alignword=(unsigned char)1^neg; break; case c_sym: startptr=0x100; comsymbios=TRUE; *count=*count+1; startsymbiosys(_Argv[*count]); break; case c_0: chip=0; break; case c_1: chip=1; break; case c_2: chip=2; break; case c_3: chip=3; break; case c_4: chip=4; break; case c_5: chip=5; break; case c_6: chip=6; break; //MMX case c_7: chip=7; break; //Pro case c_8: chip=8; break; //PII case c_9: chip=9; break; //PIII case c_x: header=(unsigned char)0^neg; break; case c_exe: comfile=file_exe; modelmem=SMALL; splitdata=TRUE; GetMemExeDat(); if(extflag) strcpy(outext,"exe"); startptr=0; // start address startptrdata=0; // data start address dos1=2; dos2=0; break; case c_sys: comfile=file_sys; if(extflag) strcpy(outext,"sys"); startptr=0; // start address startptrdata=0; // data start address jumptomain=CALL_NONE; header=0; break; case c_sobj: sobj=TRUE; FixUp=TRUE; jumptomain=CALL_NONE; case c_obj: fobj=TRUE; // if(comfile==file_d32)FixUp=TRUE; FastCallApi=FALSE; break; case c_me: puts(meinfo); exit( e_ok ); case c_key: int j,jj; puts("LIST OF RESERVED IDENTIFIERS:"); numstr=1; ListId(53,id,idofs); for(j=0;j4096)alignproc=8; } break; case c_define: addconsttotree(ptr,TRUE); break; case c_ost: optstr=(unsigned char)TRUE^neg; break; case c_cri: crif=(unsigned char)1^neg; break; case c_ia: idasm=(unsigned char)1^neg; break; case c_dbg: dbg&=0xFE; char c; c=(unsigned char)1^neg; dbg|=c; if(!neg)InitDbg(); break; case c_scd: /*-----------------13.08.00 23:01------------------- будет введена после доработки динамических процедур --------------------------------------------------*/ splitdata=(unsigned char)1^neg; if(modelmem==SMALL)splitdata=TRUE; break; case c_al: if(ptr==NULL)return c_end; aligner=(unsigned char)getnumber((unsigned char *)ptr); break; case c_at: atex=(unsigned char)1^neg; break; case c_wfa: FastCallApi=(unsigned char)1^neg; break; case c_wfu: FixUpTable=(unsigned char)1^neg; break; case c_wib: if(ptr==NULL)return c_end; ImageBase=getnumber((unsigned char *)ptr); break; case c_iv: notpost=(unsigned char)1^neg; break; case c_mer: if(ptr==NULL)return c_end; if((maxerrors=getnumber((unsigned char *)ptr))==0)maxerrors=16; break; case c_sa: if(ptr==NULL)return c_end; startptrdata=startptr=getnumber((unsigned char *)ptr); break; case c_stm: startuptomain=(unsigned char)1^neg; break; case c_suv: if(ptr==NULL)return c_end; startStartup=getnumber((unsigned char *)ptr); break; case c_wmb: WinMonoBlock=(unsigned char)1^neg; break; case c_ust: useStartup=(unsigned char)1^neg; break; case c_help: case c_h: case c_hh: PrintInfo(usage); exit(e_ok); case c_mif: if(ptr==NULL)return c_end; if(rawfilename!=NULL){ free(rawfilename); rawfilename=NULL; } if(rawext!=NULL){ free(rawext); rawext=NULL; } char *temp; if((temp=strrchr(ptr,'.'))!=NULL){ *temp++=0; rawext=BackString(temp); CheckExtenshions(); } rawfilename=BackString(ptr); break; case c_ac: AlignCycle=(unsigned char)1^neg; if(ptr!=NULL){ aligncycle=getnumber((unsigned char *)ptr); if(aligncycle<1&&aligncycle>4096)aligncycle=8; } break; case c_ws: //dos-stub for windows programs if(winstub)free(winstub); winstub=BackString(ptr); break; case c_ind: ImportName(ptr); break; case c_wbss: wbss=(unsigned char)1^neg; break; case c_wo: useordinal=(unsigned char)1^neg; break; case c_nw: if(ptr==NULL)return c_end; len=getnumber((unsigned char *)ptr); if(len>0&&len<=WARNCOUNT)wact[len-1].usewarn=(unsigned char)0^neg; break; case c_we: if(ptr==NULL)return c_end; len=getnumber((unsigned char *)ptr); if(len>0&&len<=WARNCOUNT){ if(neg)wact[len-1].fwarn=warningprint; else wact[len-1].fwarn=preerror3; } break; case c_lst: SetLST(neg); break; case c_d4g: useDOS4GW=(unsigned char)1^neg; break; case c_env: use_env=(unsigned char)1^neg; break; case c_cpa: clearpost=(unsigned char)1^neg; break; case c_ul: uselea=(unsigned char)1^neg; break; case c_as: if(ptr){ len=getnumber((unsigned char *)ptr); if(caselong(len)!=NUMNUM)strpackdef=len; } else strpackdef=(neg==FALSE?8:1); strpackcur=strpackdef; break; case c_lrs: regoverstack=(unsigned char)1^neg; break; case c_wsi: shortimport=(unsigned char)1^neg; break; case c_waf: if(ptr!=NULL){ FILEALIGN=Align(getnumber((unsigned char *)ptr),16); } break; case c_sf: if(ptr==NULL)return c_end; namestartupfile=BackString(ptr); break; case c_oir: optinitreg=(unsigned char)1^neg; break; case c_coff: ocoff=(unsigned char)1^neg; break; case c_js: addstack=(unsigned char)1^neg; if(addstack==0)RestoreStack(); break; case c_ba: bytesize=(unsigned char)1^neg; break; case c_asp: if(blockproc)goto errlate; else ESPloc=(unsigned char)1^neg; break; #ifdef OPTVARCONST case c_orv: replasevar=(unsigned char)1^neg; if(replasevar&&listvic)ClearLVIC(); break; case c_map: mapfile=(unsigned char)1^neg; break; #endif case c_ext: //***lev*** strcpy(outext,BackString(ptr)); //***lev*** extflag=FALSE; //чтобы расширение не перезабивалось другими ключами, если они идут позже break; //***lev*** } break; } } return i; } void SetLST(unsigned char neg) { if(((dbg&2)>>1)==neg){ dbg&=0xFD; unsigned char c=(unsigned char)((1^neg)<<1); dbg|=c; if(neg){ if((dbg&0xFE)==0)dbgact=TRUE; AddEndLine(); } else{ InitDbg(); if(notdoneprestuff!=TRUE)dbgact=FALSE; //startup cod } } } void print8item(char *str) { // CheckNumStr(); for(int j=0;j<8;j++)printf(str,j); puts(""); } void _loadIni(FILE *inih) { char m1[256]; for(;;){ if(fgets(m1,255,inih)==NULL)break; if(SelectComand(m1,0)==c_end)BadCommandLine(m1); } fclose(inih); } void LoadIni(char *name) { FILE *inih; char m1[256]; // load name //printf("pth: %s\r\n",name); //if (inih = fopen(name,"rb")) //{_loadIni(inih);return;} //if(strcmp(name,"c--.ini")!=0) // return; //load findpath[0]\c--.ini /*if (findpath[0]!=0) { sprintf(m1,"%s\\%s",findpath[0],name); printf("pth: %s\r\n",m1); if (inih = fopen(m1,"rb")) {_loadIni(inih);return;} } //http://android-films.net/download4/iz_mashiny_mp4_480x320_android-films.net.torrent //load PATH[i=0..end]/c--.ini char* pth = 0;//getenv("PATH"); if (pth != 0) { char* start; int size; start = pth; while(*start) { size = 0; char* endp = strchr(start, DIV_PATH); size = (endp == 0)? strlen(start): endp-start; strncpy(m1, start, size); start += size + 1; if ((m1[size - 1] != '/') && (m1[size - 1] != '\\')) m1[size++] = '/'; strcpy(m1 + size,"c--.ini"); printf("pth: %s\r\n",m1); if (inih = fopen(m1,"rb")) {_loadIni(inih);return;} } } #ifdef _KOS_ //for KolibriOS: load program_dir/c--.ini int p; strcpy(m1,__pgmname); p = strlen(m1); while ((*(m1+p)!='/') && (p != 0)) p--; if (p){ p++; strcpy(m1+p,"c--.ini"); printf("pth: %s\r\n",m1); //if (inih = fopen(m1,"rb")) //{_loadIni(inih);return;} } */ //for KolibriOS: load /rd/0/settings/c--.ini inih = fopen("/rd/1/settings/c--.ini","rb"); //for(;;){ // if(fgets(m1,255,inih)==NULL)break; // if(SelectComand(m1,0)==c_end)BadCommandLine(m1); //} fclose(inih); //return; //#endif //_KOS_ } /***************************************************************************** * .NAME : MALLOC * .TITLE : Выделяет память с обработкой ошибок. *****************************************************************************/ void OutMemory() { preerror("Compiler out of memory"); exit(e_outofmemory); } void * MALLOC (unsigned long size) { void *mem; mem=malloc(size); if(mem==NULL)OutMemory(); // if(((unsigned long)mem+size)>maxusedmem)maxusedmem=(unsigned long)mem+size; return mem; } void *REALLOC(void *block,unsigned long size) { void *mem; mem=realloc(block,size); if(mem==NULL)OutMemory(); // if(((unsigned long)mem+size)>maxusedmem)maxusedmem=(unsigned long)mem+size; return mem; } void IncludePath(char *buf) { if(numfindpathtype){ case POST_VAR: *(short *)&output[(postbuf+i)->loc]+=(short)addvalue; break; case POST_VAR32: *(long *)&output[(postbuf+i)->loc]+=addvalue+addvalbss; numrel++; break; case FIX_VAR32: case FIX_CODE32: *(long *)&output[(postbuf+i)->loc]+=addvalw32; numrel++; break; case FIX_CODE_ADD: if(am32){ *(long *)&output[(postbuf+i)->loc]+=addvalw32+(postbuf+i)->num; (postbuf+i)->type=(unsigned short)FIX_VAR32; } else{ *(short *)&output[(postbuf+i)->loc]+=(short)(addval+(postbuf+i)->num); (postbuf+i)->type=(unsigned short)FIX_VAR; } numrel++; break; case DATABLOCK_VAR: *(short *)&output[(postbuf+i)->loc]+=(short)addval; if(FixUp)(postbuf+i)->type=(unsigned short)FIX_VAR; break; case DATABLOCK_VAR32: *(long *)&output[(postbuf+i)->loc]+=addval+addvalw32; if(FixUp)(postbuf+i)->type=(unsigned short)FIX_VAR32; numrel++; break; } } ooutptr=addvalue; //сохранить начало post для debug; } void GetMemExeDat() { if(outputdata==output&&outputdata!=0)outputdata=(unsigned char *)MALLOC((size_t)MAXDATA); } void ListId(int numfirstchar,unsigned char *list,short *ofs) { char buf[40]; for(int i=0;isign=0x5a4D; // MZ // if(modelmem==TINY&&comfile==file_exe)pointstart=0x100; /* else*/ pointstart=EntryPoint(); count=(unsigned short)(runfilesize%512); i=(unsigned short)(runfilesize/512); exeheader->numlastbyte=count; exeheader->numpage=(unsigned short)(count==0?i:i+1); exeheader->headsize=2; // size of header in paragraphs (2 paragraphs) exeheader->initIP=(unsigned short)pointstart; // IP at entry (0x0000) paragraphsrequired=(outptr+outptrdata+postsize+stacksize+15)/16; if(modelmem==TINY&&comfile==file_exe){ exeheader->initSS=0xFFF0; // displacement of SS exeheader->initSP=0xFFFE; // intial value of SP exeheader->initCS=0xfff0; // displacement of CS (0x0000) if(!resizemem){ exeheader->minmem=0xfff; // min-paragraphs exeheader->maxmem=0xffff; // max-paragraphs } else{ paragraphsrequired-=0x10; exeheader->initSP=(unsigned short)(paragraphsrequired*16); // intial value of SP exeheader->minmem=(unsigned short)paragraphsrequired; // min-paragraphs exeheader->maxmem=(unsigned short)paragraphsrequired; // max-paragraphs } } else if(comfile==file_d32){ exeheader->initSP=(unsigned short)stacksize; // intial value of SP exeheader->initSS=(unsigned short)((outptr+postsize+15)/16); // displacement of SS exeheader->initCS=(unsigned short)((pointstart/65536)*4096); if(resizemem){ exeheader->minmem=(unsigned short)paragraphsrequired; // min-paragraphs exeheader->maxmem=(unsigned short)paragraphsrequired; // max-paragraphs } else exeheader->maxmem=(unsigned short)0xFFFF; // max-paragraphs } else{ exeheader->initSS=(unsigned short)(outptr/16); // displacement of SS exeheader->initSP=(unsigned short)(outptrdata+postsize+stacksize); // intial value of SP exeheader->minmem=(unsigned short)paragraphsrequired; // min-paragraphs exeheader->maxmem=(unsigned short)paragraphsrequired; // max-paragraphs } exeheader->ofsreloc=0x1c; // offset of first relocation item (0x0000) } void startsymbiosys(char *symfile) { unsigned int size; int filehandle; long filesize; outptr=startptr; if((filehandle=open(symfile,O_BINARY|O_RDONLY))==-1){; ErrOpenFile(symfile); exit(e_symbioerror); } if((filesize=getfilelen(filehandle))!=-1L){ if(filesize+outptrcount==0&&startupfile!=ptr->file){ linenumber=ptr->line; currentfileinfo=ptr->file; int i=0; switch(ptr->rectok){ case tk_proc: if(ptr->recsegm!=NOT_DYNAMIC||strcmp(ptr->recid,mesmain)==0)break; i++; case tk_structvar: i++; case tk_charvar: case tk_bytevar: case tk_intvar: case tk_wordvar: case tk_longvar: case tk_dwordvar: case tk_floatvar: case tk_pointer: case tk_qword: case tk_double: if(i<=1&&(ptr->recpost==DYNAMIC_VAR||ptr->recpost==DYNAMIC_POST))break; warningnotused(ptr->recid,i); break; } } warnunused(ptr ->left); warnunused(ptr ->right); } } void WarnUnusedVar()//предупреждения о неиспользованных процедурах и переменных { warnunused(treestart); for(unsigned int i=0;istlist); } void addinitvar() { unsigned int i; if(numfloatconst){ //вставить константы float и привязать их if(alignword||optimizespeed)AlignCD(DS,chip>5?16:4); for(i=0;itype==POST_FLOATNUM){ if(am32)*(unsigned long *)&output[(postbuf+i)->loc]=outptrdata+(postbuf+i)->num; else *(unsigned short *)&output[(postbuf+i)->loc]=(unsigned short)(outptrdata+(postbuf+i)->num); if(FixUp)(postbuf+i)->type=FIX_VAR32; else killpost(i--); } } for(i=0;itype==tk_float)sprintf((char *)string,"const float %f",(floatnum+i)->fnum); else sprintf((char *)string,"const double %f",(floatnum+i)->dnum); AddDataNullLine(4,(char *)string); } outdwordd((floatnum+i)->num[0]); if((floatnum+i)->type!=tk_float){ outdwordd((floatnum+i)->num[1]); datasize+=4; } datasize+=4; } free(floatnum); numfloatconst=0; floatnum=NULL; } for(i=0;i<(unsigned int)numswtable;i++){ //создать и вставить таблицы switch int j; FSWI *swt=swtables+i; if(alignword)AlignCD(DS,swt->type); if(dbg&2)AddDataNullLine((char)swt->type,"switch table address"); if(am32==FALSE){ //вставить в код адрес таблицы *(unsigned short *)&output[swt->ptb]=(unsigned short)outptrdata; } else *(unsigned long *)&output[swt->ptb]=outptrdata; unsigned char oam32=am32; am32=(unsigned char)(swt->type/2-1); unsigned long val=swt->defal; int oline=outptrdata; for(j=0;jsizetab;j++){ //заполнить таблицу значениями по умолчанию // if((swt->info+jj)->type==singlcase) AddReloc(DS); if(am32)outdwordd(val); else outwordd(val); } if(swt->mode==2){ if(dbg&2)AddDataNullLine((char)swt->razr,"switch table value"); if(oam32==FALSE){ //вставить в код адрес таблицы *(unsigned short *)&output[swt->ptv]=(unsigned short)outptrdata; } else *(unsigned long *)&output[swt->ptv]=outptrdata; } int ii=0; //счетчик case for(int jj=0;jjnumcase;jj++){ j=(swt->info+jj)->value; //значение val=(swt->info+jj)->postcase; if((swt->info+jj)->type==singlcase){ if(swt->mode==1){ if(am32==FALSE)*(unsigned short *)&outputdata[oline+j*2]=(unsigned short)val; else *(unsigned long *)&outputdata[oline+j*4]=val; } else{ if(am32==FALSE)*(unsigned short *)&outputdata[oline+ii*2]=(unsigned short)val; else *(unsigned long *)&outputdata[oline+ii*4]=val; switch(swt->razr){ case r8: opd(j); break; case r16: outwordd(j); break; case r32: outdwordd(j); break; } ii++; } } else{ jj++; for(;(unsigned int)j<=(swt->info+jj)->value;j++){ if(swt->mode==1){ if(am32==FALSE)*(unsigned short *)&outputdata[oline+j*2]=(unsigned short)val; else *(unsigned long *)&outputdata[oline+j*4]=val; } else{ if(am32==FALSE)*(unsigned short *)&outputdata[oline+ii*2]=(unsigned short)val; else *(unsigned long *)&outputdata[oline+ii*4]=val; switch(swt->razr){ case r8: opd(j); break; case r16: outwordd(j); break; case r32: outdwordd(j); break; } ii++; } } } } am32=oam32; free(swt->info); } if(numswtable){ free(swtables); numswtable=0; } for(i=0;itype==DIN_VAR||(postbuf+i)->type==DIN_VAR32){ idrec *ptr=(idrec *)(postbuf+i)->num; // printf("post=%u num=%08X %s\n",ptr->recpost,ptr->recnumber,ptr->recid); if(ptr->recpost==USED_DIN_VAR)setdindata(ptr,i); else{ if((postbuf+i)->type==DIN_VAR){ *(unsigned short *)&output[(postbuf+i)->loc]+=(unsigned short)(ptr->recnumber); } else{ // printf("loc=%08X num=%08X\n",*(unsigned long *)&output[(postbuf+i)->loc],ptr->recnumber); *(unsigned long *)&output[(postbuf+i)->loc]+=ptr->recnumber; } } if(FixUp)(postbuf+i)->type=(unsigned short)((postbuf+i)->type==DIN_VAR?FIX_VAR:FIX_VAR32); else killpost(i--); } } dopoststrings(); } void setdindata(idrec *ptr,int i) { unsigned char *oldinput; unsigned int oldinptr,oldendinptr; unsigned char bcha; unsigned int oline,ofile; char *ostartline; if(alignword){ if(ptr->rectok==tk_structvar)alignersize+=AlignCD(DS,2); //выровнять else alignersize+=AlignCD(DS,GetVarSize(ptr->rectok)); } // printf("loc=%08X out=%08X num=%08X\n",*(unsigned long *)&output[(postbuf+i)->loc],outptrdata,ptr->recnumber); if((postbuf+i)->type==DIN_VAR)*(unsigned short *)&output[(postbuf+i)->loc]+=(unsigned short)(outptrdata); else *(unsigned long *)&output[(postbuf+i)->loc]+=outptrdata; ptr->recpost=0; ptr->recnumber+=outptrdata; oline=linenum2; ofile=currentfileinfo; oldinput=input; oldinptr=inptr2; bcha=cha2; oldendinptr=endinptr; input=(unsigned char *)ptr->sbuf; inptr2=1; ostartline=startline; startline=(char*)input; cha2=input[0]; linenum2=ptr->line; currentfileinfo=ptr->file; endinptr=strlen((char *)input); endinput=startline+endinptr; endoffile=0; tok=ptr->rectok; if(tok==tk_structvar)datasize+=initstructvar((structteg *)ptr->newid,ptr->recrm); else{ long type,ssize; unsigned char typev; if(tok>=tk_charvar&&tok<=tk_doublevar){ type=tok-(tk_charvar-tk_char); typev=variable; ssize=typesize(type); } else if(tok==tk_pointer){ typev=pointer; type=itok.type; if(am32==FALSE&&((itok.flag&f_far)==0))ssize=2; else ssize=4; } datasize+=initglobalvar(type,ptr->recsize/ssize,ssize,typev); } free(input); linenum2=oline; currentfileinfo=ofile; input=oldinput; inptr2=oldinptr; cha2=bcha; endinptr=oldendinptr; endoffile=0; startline=ostartline; } FILE *CreateOutPut(char *ext,char *mode) { char buf[256]; FILE *diskout; sprintf(buf,"%s.%s",rawfilename,ext); if((diskout=fopen(buf,mode))==NULL){ ErrOpenFile(buf); exit(e_notcreateoutput); } return diskout; } int numundefclassproc=0; idrec **undefclassproc; void AddUndefClassProc() { if(numundefclassproc==0)undefclassproc=(idrec **)MALLOC(sizeof(idrec **)); else undefclassproc=(idrec **)REALLOC(undefclassproc,sizeof(idrec **)*(numundefclassproc+1)); undefclassproc[numundefclassproc]=itok.rec; numundefclassproc++; } void CheckUndefClassProc() { for(int i=0;irectok==tk_undefproc){ currentfileinfo=ptr->file; linenumber=ptr->line; thisundefined(ptr->recid); } } }