Subversion Repositories Kolibri OS

Rev

Rev 9352 | Rev 9358 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
6446 GerdtR 1
#define _MAIN_
2
 
3
#ifdef _UNIX_
6447 GerdtR 4
#define DIV_PATH ':'			//делитель путей в переменной окружения PATH
5
#define DIV_FOLD '/'			//этим символом разделяются папки в пути к файлу
6
#endif
7
 
8
#ifdef _WIN32_
6446 GerdtR 9
#define DIV_PATH ';'
6447 GerdtR 10
#define DIV_FOLD '\\'
6446 GerdtR 11
#endif
12
 
6447 GerdtR 13
#ifdef _KOS_
14
#define DIV_PATH ';'
15
#define DIV_FOLD '/'
16
#endif
17
 
6446 GerdtR 18
#include 
6618 siemargl 19
#include 
20
#include 
6446 GerdtR 21
#include 
22
#include "tok.h"
23
 
24
static char **_Argv; //!!! simplest way to make your own variable
25
 
26
unsigned char compilerstr[]="SPHINX C-- 0.239";
27
char *rawfilename;					/* file name */
28
char *rawext;
29
LISTCOM *listcom;
30
EWAR wartype={NULL,NULL},errfile={NULL,NULL};
31
int numfindpath=0;
32
char *findpath[16];
33
char modelmem=TINY;
34
char *stubfile=NULL;
35
char *winstub=NULL;
36
FILE *hout=NULL;
7700 leency 37
const char *namestartupfile="startup.h--";
6446 GerdtR 38
 
7700 leency 39
char outext[4]="kex";
6446 GerdtR 40
short extflag=TRUE;//расширение можно присвоить
41
//int scrsize;
42
unsigned char gwarning=FALSE;
43
unsigned char sobj=FALSE;
44
unsigned char usestub=TRUE;
45
unsigned char dpmistub=FALSE;
46
short dllflag=FALSE;
47
static int numstr;
48
 
49
char meinfo[]=
50
	"\nEdition of this version by\n"
51
	"    Mishel Sheker\n"
52
	"    Fido 2:5021/3.40\n"
53
	"    E-Mail sheker@mail.ru\n"
54
	"    Russia";
55
 
56
time_t systime;
57
struct tm timeptr;
58
char comsymbios=FALSE;
59
char fobj=FALSE;	//признак генерации obj
60
unsigned int	startptr = 0x100; 			// start address
61
unsigned char wconsole=FALSE;	//признак генерации консольного приложения windows
62
unsigned char optstr=FALSE;	//оптимизация строковых констант
63
unsigned char crif=TRUE;	//check reply include file
64
unsigned char idasm=FALSE;	//ассемблерные инструкции считать идентификаторами
65
unsigned char wbss=2;	//пост переменные в отдельную секцию
66
unsigned char use_env=FALSE;	//переменная окружения
67
int numrel=0;	//число элементов в таблице перемещений
68
unsigned char useordinal=FALSE;
69
unsigned char useDOS4GW=FALSE;
70
unsigned char clearpost=FALSE;
71
unsigned char uselea=TRUE;
72
unsigned char regoverstack=TRUE;
73
unsigned char shortimport=FALSE;
74
unsigned char useinline=2;
75
unsigned char ocoff=FALSE;
76
unsigned char ESPloc=FALSE;
77
 
78
int startupfile=-1;
79
int alignproc=8,aligncycle=8;
80
 
7700 leency 81
const char *usage[]={
6446 GerdtR 82
"USAGE: C-- [options] [FILE_NAME.INI] [SOURCE_FILE_NAME]",
83
"",
84
"                       C-- COMPILER OPTIONS",
85
"",
86
"                           OPTIMIZATION",
7700 leency 87
"-OC  optimize for code size           -DE  enable temporary expansion variable",
88
"-OS  optimize for speed               -OST enable optimization string",
89
"-ON  enable optimization number       -AP[=n] align start function",
90
"-UST use startup code for variables   -AC[=n] align start cycles",
6446 GerdtR 91
#ifdef OPTVARCONST
7700 leency 92
"-ORV replace variable on constant     -OIR skip repeated initializing register",
6446 GerdtR 93
#else
7700 leency 94
"                                      -OIR skip repeated initializing register",
6446 GerdtR 95
#endif
96
"",
97
"                          CODE GENERATION",
7700 leency 98
"-2   80286 code optimizations         -SA=#### start code address",
99
"-3   80386 code optimizations         -AL=## set value insert byte",
100
"-4   80486 code optimizations         -WFA fast call API functions",
101
"-5   pentium code optimizations       -IV  initial all variables",
102
"-A   enable address alignment         -SUV=#### start address variables",
103
"-AS[=n] def. alignment in structures  -LRS load in registers over stack",
104
"-UL  use 'lea' for adding registers   -JS  join stack calling functions",
105
"-BA  byte access to array",//             -ASP addressing local variable via ESP",
6446 GerdtR 106
"",
107
"                           PREPROCESSOR",
7700 leency 108
"-IP=  include file path         -IA   assembly instructions as identifier",
109
"-D= defined identifier        -CRI- not check include file on repeated",
110
"-MIF= main input file           -IND= import name from dll",
111
"-SF=  other startup file",
6446 GerdtR 112
"",
113
"                              LINKING",
7700 leency 114
"-AT    insert ATEXIT support block    -NS    disable stub",
115
"-ARGC  insert parse command line      -S=#####  set stack size",
116
"-P     insert parse command line      -WIB=##### set image base address",
117
"-C     insert CTRL ignoring code   -WFU   add Fix Up table, for Windows",
118
"-R     insert resize memory block     -WMB   create Windows mono block",
119
"-ENV   insert variable with environ   -WS= set name stub file for win32",
120
"-J0    disable initial jump to main() -WBSS  set post data in bss section",
121
"-J1    initial jump to main() short   -WO    call API functions on ordinals",
122
"-J2    initial jump to main() near    -CPA   clear post area",
123
"-STUB=  set name stub file      -WSI   short import table, for Windows",
124
"-DOS4GW file running with DOS4GW      -WAF=#### align Windows file (def 512)",
125
"-STM   startup code in main function",
6446 GerdtR 126
"",
127
"                           OUTPUT FILES",
7700 leency 128
"-TEXE DOS EXE file (model TINY)       -D32  EXE file (32bit code for DOS)",
129
"-EXE  DOS EXE file (model SMALL)      -W32  EXE for Windows32 GUI",
130
"-OBJ  OBJ output file                 -W32C EXE for Windows32 console",
131
"-SOBJ slave OBJ output file           -DLL  DLL for Windows32",
132
"-COFF OBJ COFF output file            -DBG  create debug information",
133
"-SYM  COM file symbiosis              -LST  create assembly listing",
134
"-SYS  device (SYS) file               -B32  32bit binary files",
135
"-MEOS executable file for MeOS        -MAP  create function map file",
136
"-EXT=  set file extension",
6446 GerdtR 137
"",
138
"                           MISCELLANEOUS",
7700 leency 139
"-HELP -H -? help, this info           -WORDS list of C-- reserved words",
140
"-W         enable warning             -LAI   list of assembler instructions",
141
"-WF= direct warnings to a file  -ME    display my name and my address",
142
"-MER=##    set maximum number errors  -X     disable SPHINX C-- header in output",
143
"-NW=##     disable selected warnings  -WE=## selected warning will be error",
144
//" -SCD        split code and date",
6446 GerdtR 145
NULL};
146
 
7700 leency 147
const char *dir[]={
6446 GerdtR 148
	"ME",    "WORDS",   "SYM",   "LAI",
149
 
150
	"OBJ",   "SOBJ",    "J0",		 "J1",     "J2",    "C",     "R",
151
	"P",     "X",       "EXE",   "S",      "SYS",   "ARGC",  "TEXE",
152
	"ROM",   "W32",     "D32",   "W32C",   "AT",    "WFA",   "SA",
153
	"STM",   "SUV",     "UST",   "MIF",    "DLL", 	"DOS4GW","ENV",
154
	"CPA",   "WBSS",    "MEOS",  "SF",     "B32",   "WIB",   "DBG",
155
 
156
	"OS",    "OC",      "A",     "0",      "1",     "2",     "3",
157
	"4",     "5",       "6",     "7",      "8",     "9",     "W",
158
	"WF",    "DE",
159
	"ON",    "IP",      "STUB",  "NS",     "AP",    "D",     "OST",
160
	"CRI",   "IA",      "SCD",   "AL",     "WFU",   "IV",
161
	"MER",   "WMB",     "HELP",  "H",      "?",     "AC",    "WS",
162
	"IND",   "WO",      "NW",    "LST",    "AS",    "UL",    "LRS",
163
	"WSI",   "WAF",     "OIR",   "COFF",   "JS",    "BA",    "ASP",
164
#ifdef OPTVARCONST
165
	"ORV",
166
#endif
167
   "MAP",  "WE",   "EXT",   NULL};
168
 
169
enum {
170
	c_me,    c_key,     c_sym,   c_lasm,   c_endinfo=c_lasm,
171
 
172
	c_obj,   c_sobj,    c_j0,    c_j1,     c_j2,    c_ctrlc, c_r,
173
	c_p,     c_x,		    c_exe,   c_s,      c_sys,   c_arg,   c_texe,
174
	c_rom,   c_w32,     c_d32,   c_w32c,   c_at,    c_wfa,   c_sa,
175
	c_stm,   c_suv,     c_ust,   c_mif,    c_dll,   c_d4g,   c_env,
176
	c_cpa,   c_wbss,    c_meos,  c_sf,     c_b32,   c_wib,   c_dbg,
177
	c_endstart=c_dbg,
178
 
179
	c_os,    c_oc,      c_a,     c_0,      c_1,     c_2,     c_3,
180
	c_4,     c_5,       c_6,     c_7,      c_8,     c_9,     c_w,
181
	c_wf,    c_de,
182
	c_opnum, c_ip,      c_stub,  c_ns,     c_ap,    c_define,c_ost,
183
	c_cri,   c_ia,      c_scd,   c_al,     c_wfu,   c_iv,
184
	c_mer,   c_wmb,     c_help,  c_h,      c_hh,    c_ac,    c_ws,
185
	c_ind,   c_wo,      c_nw,    c_lst,    c_as,    c_ul,    c_lrs,
186
	c_wsi,   c_waf,     c_oir,   c_coff,   c_js,    c_ba,    c_asp,
187
#ifdef OPTVARCONST
188
	c_orv,
189
#endif
190
	c_map,   c_we,      c_ext,   c_end};
191
 
192
#define NUMEXT 6	//число разрешенных расширений компилируемого файла
193
char extcompile[NUMEXT][4]={"c--","cmm","c","h--","hmm","h"};
194
 
195
#ifdef _KOS_
196
char __pgmname[256];
197
char __cmdline[256];
198
#endif
199
 
200
char *bufstr=NULL;	//буфер для строк из процедур
201
int sbufstr=SIZEBUF;	//начальный размер этого буфера
202
 
203
void compile();
204
void PrintInfo(char **str);
205
void LoadIni(char *name);
206
//void CheckNumStr();
7700 leency 207
void ListId(int num,unsigned char *list,unsigned short *ofs);
6446 GerdtR 208
void printmemsizes();
209
void print8item(char *str);
210
void doposts(void);
211
void GetMemExeDat();
212
void AddJmpApi();
213
void startsymbiosys(char *symfile);
214
int writeoutput();
215
void BadCommandLine(char *str);
216
void  CheckExtenshions();
217
void ImportName(char *name);
218
void WarnUnusedVar();//предупреждения о неиспользованных процедурах и переменных
219
void MakeExeHeader(EXE_DOS_HEADER *exeheader);
220
void CheckPageCode(unsigned int ofs);
221
int MakePE();
222
int MakeObj();
223
void CheckUndefClassProc();
7543 leency 224
 
9355 turbocat 225
#ifdef _KOS_
226
extern "C"{
227
    void con_set_title(char* title);
228
}
229
#endif
7700 leency 230
 
231
void ListId(int numfirstchar,unsigned char *list,unsigned short *ofs)
232
{
233
char buf[40];
234
	for(int i=0;i
235
		if((short)ofs[i]!=-1){
236
			if(i<26)buf[0]=(char)('A'+i);
237
			else if(i==26)buf[0]='_';
238
			else buf[0]=(char)(i-27+'a');
239
			unsigned char *ii=(unsigned char *)(list+ofs[i]);
240
			while(*(short *)&*ii!=-1){
241
				ii+=2;
242
				strcpy(buf+1,(char *)ii);
243
				ii+=strlen((char *)ii)+1;
244
				puts(buf);
245
//				CheckNumStr();
246
			}
247
		}
248
	}
249
}
250
 
6446 GerdtR 251
/*
252
void PrintTegList(structteg *tteg)
253
{
254
	if(tteg){
255
		PrintTegList(tteg->left);
256
		PrintTegList(tteg->right);
257
		puts(tteg->name);
258
	}
259
} */
260
 
261
//unsigned long maxusedmem=0;
262
 
263
void ErrOpenFile(char *str)
264
{
265
	printf("Unable to open file %s.\n",str);
266
}
267
 
268
int main(int argc,char *argv[])
269
{
270
int count;
271
unsigned char pari=FALSE;
6447 GerdtR 272
	char *buffer;
6446 GerdtR 273
 
274
	printf("\nSPHINX C-- Compiler   Version %d.%d%s   %s\r\n",ver1,ver2,betta,__DATE__);
9355 turbocat 275
#ifdef _KOS_
276
	con_set_title((char*)compilerstr);
277
#endif
6446 GerdtR 278
//	scrsize=24;
279
	if(argc>1){
280
		_Argv=argv;// This make portable code
281
		bufstr=(char *)MALLOC(SIZEBUF);
282
		output=(unsigned char *)MALLOC((size_t)MAXDATA);
283
		outputdata=output;
284
		postbuf=(postinfo *)MALLOC(MAXPOSTS*sizeof(postinfo));
285
		strcpy((char *)string,argv[0]);
6447 GerdtR 286
		rawext=strrchr((char *)string,DIV_FOLD);
6446 GerdtR 287
 
288
		if(rawext!=NULL){
289
			rawext[0]=0;
290
			IncludePath((char *)string);
291
		}
292
		rawfilename=getenv("C--");
293
		if(rawfilename!=NULL)IncludePath(rawfilename);
294
 
295
		rawfilename=rawext=NULL;
7700 leency 296
		LoadIni((char *)"c--.ini");
6446 GerdtR 297
 
298
		for(count=1;count
6447 GerdtR 299
			//if(argv[count][0]=='/'||argv[count][0]=='-'){
300
			if(argv[count][0]=='-'){
6446 GerdtR 301
				if(SelectComand(argv[count]+1,&count)==c_end) BadCommandLine(argv[count]);
302
			}
303
			else{
304
				if(pari==FALSE){
305
					rawfilename=argv[count];
306
					pari=TRUE;
307
					if((rawext=strrchr(rawfilename,'.'))!=NULL){
308
						if(stricmp(rawext,".ini")==0){	//указан ini файл
309
							rawfilename=NULL;
310
							rawext=NULL;
6447 GerdtR 311
							LoadIni(argv[count]);
6446 GerdtR 312
							if(rawfilename==NULL)pari=FALSE;
313
						}
314
						else{
315
							*rawext++=0;
316
							CheckExtenshions();
317
						}
318
					}
319
				}
320
			}
321
		}
322
	}
323
	if(rawfilename==NULL){
7700 leency 324
		PrintInfo((char **)usage);
6446 GerdtR 325
		exit( e_noinputspecified );
326
	}
327
	time(&systime); //текущее время
328
	memcpy(&timeptr,localtime(&systime),sizeof(tm));
329
	InitDefineConst();
330
	compile();
331
	if(error==0)exit(e_ok);
332
	exit(e_someerrors);
333
	return 0;
334
}
335
 
336
void CheckExtenshions()
337
{
338
int i;
339
	for(i=0;i
340
		if(stricmp(rawext,extcompile[i])==0)break;
341
	}
342
	if(i==NUMEXT){
343
	 	printf("Bad input file extension '%s'.",rawext);
344
	  exit(e_badinputfilename);
345
	}
346
}
347
 
348
void compile()
349
{
350
long segments_required;
351
union{
352
	long longhold;
353
	void *nextstr;
354
};
355
//создать имя файла с предупреждениями и если он есть удалить
356
	errfile.name=(char *)MALLOC(strlen(rawfilename)+5);
357
	sprintf(errfile.name,"%s.err",rawfilename);
358
	if(stat(errfile.name,(struct stat *)string2)==0)remove(errfile.name);
359
//если есть имя файла для предупреждений проверить его существование и удалить.
360
	if(wartype.name!=NULL){
361
		if(stat(wartype.name,(struct stat *)string2)==0)remove(wartype.name);
362
	}
363
	puts("Compiling Commenced . . .");
364
	if(rawext!=NULL)sprintf((char *)string,"%s.%s",rawfilename,rawext);
365
	else{
366
		for(unsigned int i=0;i
367
			sprintf((char *)string,"%s.%s",rawfilename,extcompile[i]);
368
			if(stat((char *)string,(struct stat *)string2)==0)break;
369
		}
370
	}
371
	linenumber=0;
372
	initregstat();
373
#ifdef OPTVARCONST
374
	CreateMainLVIC();
375
#endif
376
#ifdef __NEWLEX__
377
	inittokn();
378
#endif
379
	compilefile((char *)string,2); //собственно разборка и компиляция
380
	puts("Link . . .");
381
	if(comfile==file_w32&&wbss==2){
382
		wbss=FALSE;
383
		if(wconsole==FALSE)wbss=TRUE;
384
	}
385
	if(notdoneprestuff==TRUE)doprestuff();	//startup code
386
	if(endifcount>=0)preerror("?endif expected before end of file");
387
	AddObj();
388
	docalls();	//добавить внешние процедуры
389
	addinitvar();
390
	CheckUndefClassProc();
391
	if(undefoffstart!=NULL){	//выдать список неизвестных ссылок
392
		UNDEFOFF *curptr=undefoffstart;
393
		for(;;){
394
			char holdstr[80];
395
			UNDEFOFF *ocurptr;
396
			linenumber=curptr->pos->line;
397
			sprintf(holdstr,"\'%s\' offset undefined",curptr->name);
398
			currentfileinfo=curptr->pos->file;
399
			preerror(holdstr);
400
			free(curptr->pos);
401
			if(curptr->next==NULL)break;
402
			ocurptr=curptr->next;
403
			free(curptr);
404
			curptr=ocurptr;
405
		}
406
		free(curptr);
407
	}
408
	while(liststring!=NULL){
409
		STRING_LIST *ins;
410
		ins=(STRING_LIST *)liststring;
411
		nextstr=ins->next;
412
		free(liststring);
413
		liststring=nextstr;
414
	}
415
	free(bufstr);
416
	if(warning==TRUE&&wact[7].usewarn)WarnUnusedVar();//предупреждения о неиспользованных процедурах и переменных
417
	if(numstrtbl)CreatStrTabRes();	//завершить создание ресурсов
418
	if(fobj==FALSE){
419
		if(comfile==file_w32&&error==0){
420
			AddJmpApi();	//косвенные вызовы API
421
			CreatWinStub();
422
		}
423
		longhold=outptr;
424
		if(comfile==file_rom){
425
			ooutptr=outptr;
426
			if(modelmem==SMALL){
427
				*(short *)&output[stackstartaddress]=(short)(((outptrdata+postsize+stacksize)/4+1)*4);
428
				*(short *)&output[dataromstart]=(short)(outptr+4);
429
				*(short *)&output[dataromsize]=(short)(outptrdata/2);
430
//				printf("outptr=%d outptrdate=%d outptrsize=%d\n",outptr,outptrdata,outptrsize);
431
				for(unsigned int i=0;i
432
			}
433
			if(romsize==0){
434
				unsigned int i=outptr/1024;
435
				if((outptr%1024)!=0)i++;
436
				if(i>32)i=64;
437
				else if(i>16)i=32;
438
				else if(i>8)i=16;
439
				else if(i>4)i=8;
440
				else if(i>2)i=4;
441
		 		romsize=i*1024;
442
				output[2]=(unsigned char)(romsize/512);
443
			}
444
			if(outptr>=romsize)preerror("The size of a code is more than the size of the ROM");
445
			for(;outptr
446
			unsigned char summa=0;
447
			for(unsigned int i=0;i
448
			output[romsize-1]-=summa;
449
			outptr=ooutptr;
450
		}
451
		else if(modelmem==SMALL&&comfile==file_exe){ // if an EXE file
452
			longhold+=AlignCD(CS,16);
453
//			if((outptr%16)!=0)outptr+=16-outptr%16;// paragraph align the end of the code seg
454
			if(((long)outptrdata+(long)postsize+(long)stacksize)>65535L)
455
					preerror("Data and stack total exceeds 64k");
456
		}
457
		else if(comfile==file_sys){
458
			for(int i=0;i
459
				searchvar((listcom+i)->name);
460
				*(short *)&output[syscom+i*2]=(unsigned short)itok.number;
461
			}
462
			free(listcom);
463
		}
464
		else longhold+=(long)postsize+(long)(stacksize);
465
		if(am32==0&&longhold>65535L&&!(modelmem==TINY&&(!resizemem)))preerror("Code, data and stack total exceeds 64k");
466
		if(posts>0)doposts();  //Установить адреса вызовов процедур и переходов
467
		if(resizemem&&comfile==file_com){
468
			segments_required=(outptr+postsize+stacksize+15)/16;
469
			*(short *)&output[resizesizeaddress]=(short)segments_required;
470
			*(short *)&output[stackstartaddress]=(short)(segments_required*16);
471
		}
472
	}
473
	deinitregstat();
474
#ifdef OPTVARCONST
475
	KillMainLVIC();
476
#endif
477
//	puts("List Teg name:");
478
//	PrintTegList(tegtree);
479
	printf("COMPILING FINISHED.  Errors: %d\n",error);
480
	if(error==0){
481
		if(cpu>=1){
482
			char m1[12];
483
			switch(cpu){
484
				case 5:
485
					strcpy(m1,"Pentium");
486
					break;
487
				case 6:
488
					strcpy(m1,"MMX");
489
					break;
490
				case 7:
491
					strcpy(m1,"Pentium II");
492
					break;
493
				case 8:
494
					strcpy(m1,"Pentium III");
495
					break;
496
				case 9:
497
					strcpy(m1,"Pentium IV");
498
					break;
499
				default: sprintf(m1,"80%d86",cpu);
500
			}
501
			printf("CPU required: %s or greater.\n",m1);
502
		}
503
		runfilesize=outptr-startptr;
504
		if(comfile==file_rom)runfilesize=romsize;
505
		else if(modelmem==SMALL&&comfile==file_exe){
506
			runfilesize+=outptrdata-startptrdata+0x20;
507
			postsize+=postsize%2;
508
			stacksize=(stacksize+15)/16*16;
509
		}
510
		else if((comfile==file_exe||comfile==file_d32)&&modelmem==TINY)
511
				runfilesize+=0x20;
512
		printmemsizes();
513
		endinptr=outptr;
514
		if(writeoutput()==0)printf("Run File Saved (%ld bytes).\n",runfilesize);
515
		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);
516
//		else if(FILEALIGN&&fobj==FALSE)printf("For alignment file, added %u zero bytes.\n",filingzerope);
517
	}
518
		if(pdbg)DoTDS();
519
}
520
 
521
void printmemsizes()
522
{
523
long stacklong;
524
unsigned int stackword;
525
unsigned int postword,codeword;
526
	postword=postsize;
527
	codeword=outptr-startptr;
528
	stackword=stacksize;
529
	if(comfile==file_com||(comfile==file_exe&&modelmem==TINY)){
530
		if(resizemem==0){
531
			stacklong=0xFFFE - outptr - postsize;
532
			stackword=stacklong;
533
		}
534
		codeword=codeword-datasize-alignersize;
535
	}
536
	else if(comfile==file_sys)stackword=sysstack;
537
	else if(comfile==file_exe||comfile==file_rom)datasize=outptrdata;
538
	else if(comfile==file_d32)codeword-=datasize;
539
	printf("Code: %u bytes, Data: %u bytes, Post: %u bytes, Stack: %u bytes\n"
540
			,codeword,datasize,postword,stackword);
541
	for(int i=0;i
542
		switch((postbuf+i)->type){
543
			case CODE_SIZE:
544
				*(short *)&output[(postbuf+i)->loc]+=codeword;
545
				break;
546
			case CODE_SIZE32:
547
				*(long *)&output[(postbuf+i)->loc]+=codeword;
548
				break;
549
			case DATA_SIZE:
550
				*(short *)&output[(postbuf+i)->loc]+=datasize;
551
				break;
552
			case DATA_SIZE32:
553
				*(long *)&output[(postbuf+i)->loc]+=datasize;
554
				break;
555
			case POST_SIZE:
556
				*(short *)&output[(postbuf+i)->loc]+=postword;
557
				break;
558
			case POST_SIZE32:
559
				*(long *)&output[(postbuf+i)->loc]+=postword;
560
				break;
561
			case STACK_SIZE:
562
				*(short *)&output[(postbuf+i)->loc]+=stackword;
563
				break;
564
			case STACK_SIZE32:
565
				*(long *)&output[(postbuf+i)->loc]+=stackword;
566
				break;
567
		}
568
	}
569
}
570
 
571
void PrintInfo(char **str)
572
{
573
	numstr=1;
574
	for(int i=0;str[i]!=NULL;i++){
575
		puts(str[i]);
576
//		CheckNumStr();
577
	}
578
}
579
 
580
/*void CheckNumStr()
581
{
582
#ifndef _UNIX_
583
	if(((numstr+1)%(scrsize-1))==0&&outfile!=0){
584
		puts("Press any key...");
585
		getch();
586
	}
587
	numstr++;
588
#endif
589
} */
590
 
591
void strbtrim(char *st)
592
{
593
int i;
594
char *p,*q;
595
	p=q=st;
596
	while(isspace(*p))p++;	//пока незначащие символы
597
	while(*p)*q++=*p++;     //переместить строку
598
	*q='\0';
599
	for(i=strlen(st)-1;isspace(st[i])&&i>=0;i--);
600
	st[i+1]='\0';
601
}
602
 
603
unsigned long getnumber(unsigned char *buf)
604
{
605
int temp2;
606
unsigned long retnum;
607
unsigned char *oinput;
608
unsigned int oinptr,oendinptr;
609
	if(!isdigit(buf[0]))return 0;
610
	oinptr=inptr;
611
	oinput=input;
612
	oendinptr=endinptr;
613
	input=buf;
614
	inptr=0;
615
	endinptr=256;
616
	retnum=scannumber(&temp2);
617
	inptr=oinptr;
618
	input=oinput;
619
	endinptr=oendinptr;
620
	return retnum;
621
}
622
 
623
int SelectComand(char *pptr,int *count)
624
{
625
int i;
626
unsigned char neg=FALSE;
627
char *ptr;
628
int len;
629
	if((ptr=strchr(pptr,';'))!=NULL)*ptr=0;// ищем комментарий отсекаем все после него
630
        if((ptr=strchr(pptr,'='))!=NULL){ // ищем знак равенства
631
		*ptr=0; // делим
632
		ptr++;
633
	  strbtrim(ptr);	//убрать лишние пробелы
634
	}
635
  strbtrim(pptr);	//убрать лишние пробелы
636
	if(*pptr==0)return c_end+1;	//пустая строка
637
	if((i=strlen(pptr))>1&&pptr[i-1]=='-'){
638
		neg=TRUE;
639
		pptr[i-1]=0;
640
	}
641
	strupr(pptr);
642
	for(i=0;dir[i]!=NULL;i++){
643
		if(strcmp(dir[i],pptr)==0){
644
			if((i<=c_endinfo)&&count==0){
645
				char buf[80];
646
				sprintf(buf,"Option '%s' is used only in command line",dir[i]);
647
				preerror(buf);
648
				return i;
649
			}
650
			if(i<=c_endstart&¬doneprestuff!=TRUE){
651
errlate:
652
				char buf[80];
653
				sprintf(buf,"Too late used '#pragma option %s'",dir[i]);
654
				preerror(buf);
655
				return i;
656
			}
657
			switch(i){
658
				case c_j0: jumptomain=(unsigned char)(neg!=FALSE?CALL_NEAR:CALL_NONE); header=(unsigned char)0^neg; break;
659
				case c_j1: jumptomain=(unsigned char)CALL_SHORT; header=(unsigned char)1; break;
660
				case c_j2: jumptomain=(unsigned char)(neg==FALSE?CALL_NEAR:CALL_NONE); header=(unsigned char)1^neg; break;
661
				case c_ctrlc: killctrlc=(unsigned char)1^neg; break;
662
				case c_os: optimizespeed=(unsigned char)1^neg; break;
663
				case c_oc: optimizespeed=(unsigned char)0^neg; break;
664
				case c_r: resizemem=(unsigned char)1^neg; break;
665
				case c_p: parsecommandline=(unsigned char)1^neg; break;
666
				case c_a: alignword=(unsigned char)1^neg; break;
667
				case c_sym:
668
					startptr=0x100;
669
					comsymbios=TRUE;
670
					*count=*count+1;
671
          startsymbiosys(_Argv[*count]);
672
					break;
673
				case c_0: chip=0; break;
674
				case c_1: chip=1; break;
675
				case c_2: chip=2; break;
676
				case c_3: chip=3; break;
677
				case c_4: chip=4; break;
678
				case c_5: chip=5; break;
679
				case c_6: chip=6; break;	//MMX
680
				case c_7: chip=7; break;  //Pro
681
				case c_8: chip=8; break;  //PII
682
				case c_9: chip=9; break;  //PIII
683
				case c_x: header=(unsigned char)0^neg; break;
684
				case c_exe:
685
					comfile=file_exe;
686
					modelmem=SMALL;
687
					splitdata=TRUE;
688
					GetMemExeDat();
689
					if(extflag) strcpy(outext,"exe");
690
					startptr=0; 			// start address
691
					startptrdata=0; 	// data start address
692
					dos1=2;
693
					dos2=0;
694
					break;
695
				case c_sys:
696
					comfile=file_sys;
697
					if(extflag) strcpy(outext,"sys");
698
					startptr=0; 		// start address
699
					startptrdata=0; 	// data start address
700
					jumptomain=CALL_NONE;
701
					header=0;
702
					break;
703
				case c_sobj:
704
					sobj=TRUE;
705
					FixUp=TRUE;
706
					jumptomain=CALL_NONE;
707
				case c_obj:
708
					fobj=TRUE;
709
//					if(comfile==file_d32)FixUp=TRUE;
710
					FastCallApi=FALSE;
711
					break;
712
				case c_me:
713
					puts(meinfo);
714
					exit( e_ok );
715
				case c_key:
716
					int j,jj;
717
					puts("LIST OF RESERVED IDENTIFIERS:");
718
					numstr=1;
7700 leency 719
					ListId(53,(unsigned char *)id,idofs);
6446 GerdtR 720
					for(j=0;j
721
						puts(id2[j]);
722
//						CheckNumStr();
723
					}
724
					for(jj=0;jj<2;jj++){
725
						for(j=0;j<8;j++)printf("%s ",regs[jj][j]);
726
						puts("");
727
//						CheckNumStr();
728
					}
729
					for(j=0;j<8;j++)printf("%s ",begs[j]);
730
					puts("");
731
//					CheckNumStr();
732
					for(j=0;j<6;j++)printf("%s ",segs[j]);
733
					print8item("ST(%d) ");
734
					puts("ST");
735
					print8item("st(%d) ");
736
					puts("st");
737
					exit(e_ok);
738
				case c_lasm:
739
					puts("LIST OF SUPPORTED ASSEMBLER INSTRUCTIONS:");
740
					numstr=1;
741
					ListId(26,asmMnem,ofsmnem);
742
					exit(e_ok);
743
				case c_s:
744
					if(ptr==NULL)return c_end;
745
					if((stacksize=getnumber((unsigned char *)ptr))==0){
746
						puts("Bad stack size.");
747
						exit(e_unknowncommandline);
748
					}
749
					stacksize=Align(stacksize,4);
750
					break;
751
				case c_w:
752
					gwarning=(unsigned char)TRUE^neg;
753
					break;
754
				case c_wf:
755
					if(wartype.name)free(wartype.name);
756
					wartype.name=BackString(ptr);
757
					break;
758
				case c_de:
759
					divexpand=(unsigned char)TRUE^neg;
760
					break;
761
				case c_opnum:
762
					optnumber=(unsigned char)TRUE^neg;
763
					break;
764
				case c_ip:
765
					IncludePath(ptr);
766
					break;
767
				case c_arg:
768
					parsecommandline=(unsigned char)TRUE^neg;
769
					fargc=(unsigned char)TRUE^neg;
770
					break;
771
				case c_texe:
772
					if(extflag) strcpy(outext,"exe");
773
					comfile=file_exe;
774
					break;
775
				case c_rom:
776
					if(extflag) strcpy(outext,"rom");
777
					comfile=file_rom;
778
					startptr=0;
779
					startptrdata=0; 	// data start address
780
					GetMemExeDat();
781
					break;
782
				case c_dll:
783
					wconsole=TRUE;
784
					dllflag=TRUE;
785
					if(extflag) strcpy(outext,"dll");
786
					comfile=file_w32;
787
					FixUpTable=TRUE;
788
					goto nexpardll;
789
 
790
/*					FixUp=TRUE;
791
					startptrdata=startptr=0;
792
					am32=TRUE;
793
					if(chip<3)chip=3;
794
					if(FILEALIGN==0)FILEALIGN=512;
795
					break;*/
796
				case c_w32c:
797
					wconsole=TRUE;
798
					goto init_w32;
799
				case c_w32:
800
					wconsole=FALSE;
801
					dllflag=FALSE;
802
init_w32:
803
					comfile=file_w32;
804
					goto nexpar;
805
				case c_d32:
806
					comfile=file_d32;
807
nexpar:
808
					if(extflag) strcpy(outext,"exe");
809
nexpardll:
810
					FixUp=TRUE;
811
					startptrdata=startptr=0;
812
					am32=TRUE;
813
					if(chip<3)chip=3;
814
					if(FILEALIGN==0)FILEALIGN=512;
815
					break;
816
				case c_meos:
817
					comfile=file_meos;
818
					am32=TRUE;
819
					startptrdata=startptr=0;
820
					if(extflag) strcpy(outext,"");
821
					if(chip<3)chip=3;
822
					break;
823
				case c_b32:
824
					comfile=file_bin;
825
					am32=TRUE;
826
					startptrdata=startptr=0;
827
					if(extflag) strcpy(outext,"bin");
828
					FixUp=TRUE;
829
					ImageBase=0;
830
					if(chip<3)chip=3;
831
					break;
832
				case c_stub:
833
					if(stubfile)free(stubfile);
834
					stubfile=BackString(ptr);
835
					dpmistub=FALSE;
836
					if(stricmp(stubfile,"dpmi")==0){
837
						if(notdoneprestuff!=TRUE)goto errlate;
838
						dpmistub=TRUE;
839
						usestub=FALSE;
840
					}
841
					break;
842
				case c_ns:
843
					usestub=(unsigned char)0^neg;
844
					break;
845
				case c_ap:
846
					AlignProc=(unsigned char)1^neg;
847
					if(ptr!=NULL){
848
						alignproc=getnumber((unsigned char *)ptr);
849
						if(alignproc<1||alignproc>4096)alignproc=8;
850
					}
851
					break;
852
				case c_define:
853
					addconsttotree(ptr,TRUE);
854
					break;
855
				case c_ost:
856
					optstr=(unsigned char)TRUE^neg;
857
					break;
858
				case c_cri:
859
					crif=(unsigned char)1^neg;
860
					break;
861
				case c_ia:
862
					idasm=(unsigned char)1^neg;
863
					break;
864
				case c_dbg:
865
					dbg&=0xFE;
866
					char c;
867
					c=(unsigned char)1^neg;
868
					dbg|=c;
869
					if(!neg)InitDbg();
870
					break;
871
				case c_scd:
872
/*-----------------13.08.00 23:01-------------------
873
 будет введена после доработки динамических процедур
874
	--------------------------------------------------*/
875
					splitdata=(unsigned char)1^neg;
876
					if(modelmem==SMALL)splitdata=TRUE;
877
					break;
878
				case c_al:
879
					if(ptr==NULL)return c_end;
880
					aligner=(unsigned char)getnumber((unsigned char *)ptr);
881
					break;
882
				case c_at:
883
					atex=(unsigned char)1^neg;
884
					break;
885
				case c_wfa:
886
					FastCallApi=(unsigned char)1^neg;
887
					break;
888
				case c_wfu:
889
					FixUpTable=(unsigned char)1^neg;
890
					break;
891
				case c_wib:
892
					if(ptr==NULL)return c_end;
893
					ImageBase=getnumber((unsigned char *)ptr);
894
					break;
895
				case c_iv:
896
					notpost=(unsigned char)1^neg;
897
					break;
898
				case c_mer:
899
					if(ptr==NULL)return c_end;
900
					if((maxerrors=getnumber((unsigned char *)ptr))==0)maxerrors=16;
901
					break;
902
				case c_sa:
903
					if(ptr==NULL)return c_end;
904
					startptrdata=startptr=getnumber((unsigned char *)ptr);
905
					break;
906
				case c_stm:
907
					startuptomain=(unsigned char)1^neg;
908
					break;
909
				case c_suv:
910
					if(ptr==NULL)return c_end;
911
					startStartup=getnumber((unsigned char *)ptr);
912
					break;
913
				case c_wmb:
914
					WinMonoBlock=(unsigned char)1^neg;
915
					break;
916
				case c_ust:
917
					useStartup=(unsigned char)1^neg;
918
					break;
919
				case c_help:
920
				case c_h:
921
				case c_hh:
7700 leency 922
					PrintInfo((char **)usage);
6446 GerdtR 923
					exit(e_ok);
924
				case c_mif:
925
					if(ptr==NULL)return c_end;
926
					if(rawfilename!=NULL){
927
						free(rawfilename);
928
						rawfilename=NULL;
929
					}
930
					if(rawext!=NULL){
931
						free(rawext);
932
						rawext=NULL;
933
					}
934
					char *temp;
935
        	if((temp=strrchr(ptr,'.'))!=NULL){
936
						*temp++=0;
937
						rawext=BackString(temp);
938
						CheckExtenshions();
939
 	  	    }
940
					rawfilename=BackString(ptr);
941
					break;
942
				case c_ac:
943
					AlignCycle=(unsigned char)1^neg;
944
					if(ptr!=NULL){
945
						aligncycle=getnumber((unsigned char *)ptr);
7700 leency 946
						if(aligncycle<1&&aligncycle>4096)aligncycle=8;
6446 GerdtR 947
					}
948
					break;
949
				case c_ws:	//dos-stub for windows programs
950
					if(winstub)free(winstub);
951
					winstub=BackString(ptr);
952
					break;
953
				case c_ind:
954
					ImportName(ptr);
955
					break;
956
				case c_wbss:
957
					wbss=(unsigned char)1^neg;
958
					break;
959
				case c_wo:
960
					useordinal=(unsigned char)1^neg;
961
					break;
962
				case c_nw:
963
					if(ptr==NULL)return c_end;
964
					len=getnumber((unsigned char *)ptr);
965
					if(len>0&&len<=WARNCOUNT)wact[len-1].usewarn=(unsigned char)0^neg;
966
					break;
967
				case c_we:
968
					if(ptr==NULL)return c_end;
969
					len=getnumber((unsigned char *)ptr);
970
					if(len>0&&len<=WARNCOUNT){
971
						if(neg)wact[len-1].fwarn=warningprint;
972
						else wact[len-1].fwarn=preerror3;
973
					}
974
					break;
975
				case c_lst:
976
					SetLST(neg);
977
					break;
978
				case c_d4g:
979
					useDOS4GW=(unsigned char)1^neg;
980
					break;
981
				case c_env:
982
					use_env=(unsigned char)1^neg;
983
					break;
984
				case c_cpa:
985
					clearpost=(unsigned char)1^neg;
986
					break;
987
				case c_ul:
988
					uselea=(unsigned char)1^neg;
989
					break;
990
				case c_as:
991
					if(ptr){
992
						len=getnumber((unsigned char *)ptr);
993
						if(caselong(len)!=NUMNUM)strpackdef=len;
994
					}
995
					else strpackdef=(neg==FALSE?8:1);
996
					strpackcur=strpackdef;
997
					break;
998
				case c_lrs:
999
					regoverstack=(unsigned char)1^neg;
1000
					break;
1001
				case c_wsi:
1002
					shortimport=(unsigned char)1^neg;
1003
					break;
1004
				case c_waf:
1005
					if(ptr!=NULL){
1006
						FILEALIGN=Align(getnumber((unsigned char *)ptr),16);
1007
					}
1008
					break;
1009
				case c_sf:
1010
					if(ptr==NULL)return c_end;
1011
					namestartupfile=BackString(ptr);
1012
					break;
1013
				case c_oir:
1014
					optinitreg=(unsigned char)1^neg;
1015
					break;
1016
				case c_coff:
1017
					ocoff=(unsigned char)1^neg;
1018
					break;
1019
				case c_js:
1020
					addstack=(unsigned char)1^neg;
1021
					if(addstack==0)RestoreStack();
1022
					break;
1023
				case c_ba:
1024
					bytesize=(unsigned char)1^neg;
1025
					break;
1026
				case c_asp:
1027
					if(blockproc)goto errlate;
1028
					else ESPloc=(unsigned char)1^neg;
1029
					break;
1030
#ifdef OPTVARCONST
1031
				case c_orv:
1032
					replasevar=(unsigned char)1^neg;
1033
					if(replasevar&&listvic)ClearLVIC();
1034
					break;
1035
				case c_map:
1036
					mapfile=(unsigned char)1^neg;
1037
					break;
1038
#endif
1039
				case c_ext:     //***lev***
1040
					strcpy(outext,BackString(ptr)); //***lev***
1041
					extflag=FALSE; //чтобы расширение не перезабивалось другими ключами, если они идут позже
1042
					break;  //***lev***
1043
			}
1044
			break;
1045
		}
1046
	}
1047
	return i;
1048
}
1049
 
1050
void SetLST(unsigned char neg)
1051
{
1052
	if(((dbg&2)>>1)==neg){
1053
		dbg&=0xFD;
1054
		unsigned char c=(unsigned char)((1^neg)<<1);
1055
		dbg|=c;
1056
		if(neg){
1057
			if((dbg&0xFE)==0)dbgact=TRUE;
1058
			AddEndLine();
1059
		}
1060
		else{
1061
			InitDbg();
1062
			if(notdoneprestuff!=TRUE)dbgact=FALSE;	//startup cod
1063
		}
1064
	}
1065
}
1066
 
1067
void print8item(char *str)
1068
{
1069
//	CheckNumStr();
1070
	for(int j=0;j<8;j++)printf(str,j);
1071
	puts("");
1072
}
1073
 
1074
 
1075
 
1076
 
1077
void _loadIni(FILE *inih)
1078
{
1079
	char m1[256];
1080
	for(;;){
1081
		if(fgets(m1,255,inih)==NULL)break;
1082
		if(SelectComand(m1,0)==c_end)BadCommandLine(m1);
1083
	}
1084
	fclose(inih);
1085
}
1086
 
1087
void LoadIni(char *name)
1088
{
1089
FILE *inih;
1090
char m1[256];
1091
 
1092
							// load name
6447 GerdtR 1093
	if (inih = fopen(name,"rb"))
1094
	{_loadIni(inih);return;}
6446 GerdtR 1095
 
6447 GerdtR 1096
	if(strcmp(name,"c--.ini")!=0)
1097
			return;
6446 GerdtR 1098
 
1099
							//load findpath[0]\c--.ini
6447 GerdtR 1100
	if (findpath[0]!=0)
6446 GerdtR 1101
	{
6447 GerdtR 1102
		sprintf(m1,"%s%s",findpath[0],name);
6446 GerdtR 1103
		if (inih = fopen(m1,"rb"))
1104
		{_loadIni(inih);return;}
6447 GerdtR 1105
	}
6446 GerdtR 1106
							//load PATH[i=0..end]/c--.ini
6447 GerdtR 1107
	char* pth = getenv("PATH");
6446 GerdtR 1108
	if (pth != 0)
1109
	{
1110
		char* start;
1111
		int size;
1112
		start = pth;
1113
		while(*start)
1114
		{
1115
			size = 0;
1116
			char* endp = strchr(start, DIV_PATH);
1117
			size = (endp == 0)? strlen(start): endp-start;
1118
			strncpy(m1, start, size);
1119
			start += size + 1;
6447 GerdtR 1120
			if (m1[size - 1] != DIV_FOLD)
6446 GerdtR 1121
				m1[size++] = '/';
1122
 
1123
			strcpy(m1 + size,"c--.ini");
1124
			if (inih = fopen(m1,"rb"))
1125
			{_loadIni(inih);return;}
1126
		}
1127
	}
1128
#ifdef _KOS_
1129
								//for KolibriOS: load program_dir/c--.ini
1130
	int p;
1131
	strcpy(m1,__pgmname);
1132
	p = strlen(m1);
1133
	while ((*(m1+p)!='/') && (p != 0))
1134
		p--;
1135
	if (p){
1136
		p++;
1137
		strcpy(m1+p,"c--.ini");
6447 GerdtR 1138
		if (inih = fopen(m1,"rb"))
1139
		{_loadIni(inih);return;}
6446 GerdtR 1140
	}
6447 GerdtR 1141
								//for KolibriOS: load /rd/0/settings/c--.ini
6446 GerdtR 1142
	inih = fopen("/rd/1/settings/c--.ini","rb");
6447 GerdtR 1143
	for(;;){
1144
		if(fgets(m1,255,inih)==NULL)break;
1145
		if(SelectComand(m1,0)==c_end)BadCommandLine(m1);
1146
	}
6446 GerdtR 1147
	fclose(inih);
6447 GerdtR 1148
	return;
1149
#endif //_KOS_
6446 GerdtR 1150
}
1151
 
1152
/*****************************************************************************
1153
* .NAME   : MALLOC
1154
* .TITLE  : Выделяет память с обработкой ошибок.
1155
*****************************************************************************/
1156
void OutMemory()
1157
{
1158
	preerror("Compiler out of memory");
1159
	exit(e_outofmemory);
1160
}
1161
 
1162
void * MALLOC (unsigned long size)
1163
{
1164
void *mem;
1165
	mem=malloc(size);
1166
	if(mem==NULL)OutMemory();
7545 tsdima 1167
#ifdef _UNIX_
1168
	else memset(mem,0,size);
1169
#endif
6446 GerdtR 1170
 
1171
//	if(((unsigned long)mem+size)>maxusedmem)maxusedmem=(unsigned long)mem+size;
1172
 
1173
	return mem;
1174
}
1175
 
1176
void *REALLOC(void *block,unsigned long size)
1177
{
1178
void *mem;
1179
	mem=realloc(block,size);
1180
	if(mem==NULL)OutMemory();
1181
 
1182
//	if(((unsigned long)mem+size)>maxusedmem)maxusedmem=(unsigned long)mem+size;
1183
 
1184
	return mem;
1185
}
1186
 
1187
void IncludePath(char *buf)
1188
{
6447 GerdtR 1189
	char divfold[3];
1190
	sprintf(divfold,"%c",DIV_FOLD);
6446 GerdtR 1191
	if(numfindpath
1192
		int len=strlen(buf);
6447 GerdtR 1193
		if(buf[len-1]==DIV_FOLD)buf[len-1]=0;
6446 GerdtR 1194
		else len++;
1195
		char *a=(char *)MALLOC(len+1);
1196
		strcpy(a,buf);
6447 GerdtR 1197
		strcat(a,divfold);
6446 GerdtR 1198
		findpath[numfindpath]=a;
1199
		numfindpath++;
1200
		findpath[numfindpath]="";
1201
	}
1202
	else puts("Too many include paths");
1203
}
1204
 
1205
void doposts()
1206
{
1207
unsigned long addvalue,i,addval,addvalw32=0,addvalbss=0;
1208
	if(splitdata&&modelmem==TINY&&outptrdata){
1209
		memcpy((char *)&output[outptr],(char *)&outputdata[0],outptrdata);
1210
		addval=outptr;
1211
		outptr+=outptrdata;
1212
		outptrdata=outptr;
1213
	}
1214
	addvalue=outptrdata;
1215
	if(comfile==file_bin)addvalbss=addvalw32=ImageBase;
1216
	else if(comfile==file_w32){
1217
		addvalbss=addvalw32=ImageBase+vsizeheader;
1218
		if(postsize&&wbss){
1219
			addvalw32+=Align(postsize,OBJECTALIGN);
1220
			addvalue=0;
1221
		}
1222
	}
1223
	else{
1224
		if((outptrdata%2)==1){	/* alignment of entire post data block manditory */
1225
			addvalue++;	//начало неиниц.данных
1226
			postsize++;
1227
		}
1228
/*		if(am32&&(outptrdata%4)==2){
1229
			addvalue+=2;	//начало неиниц.данных
1230
			postsize+=2;
1231
		}*/
1232
	}
1233
	if(am32==0&&(MAXDATA-outptrdata)
1234
	for(i=0;i
1235
		switch((postbuf+i)->type){
1236
			case POST_VAR:
1237
				*(short *)&output[(postbuf+i)->loc]+=(short)addvalue;
1238
				break;
1239
			case POST_VAR32:
1240
				*(long *)&output[(postbuf+i)->loc]+=addvalue+addvalbss;
1241
				numrel++;
1242
				break;
1243
			case FIX_VAR32:
1244
			case FIX_CODE32:
1245
				*(long *)&output[(postbuf+i)->loc]+=addvalw32;
1246
				numrel++;
1247
				break;
1248
			case FIX_CODE_ADD:
1249
				if(am32){
1250
					*(long *)&output[(postbuf+i)->loc]+=addvalw32+(postbuf+i)->num;
1251
					(postbuf+i)->type=(unsigned short)FIX_VAR32;
1252
				}
1253
				else{
1254
					*(short *)&output[(postbuf+i)->loc]+=(short)(addval+(postbuf+i)->num);
1255
					(postbuf+i)->type=(unsigned short)FIX_VAR;
1256
				}
1257
				numrel++;
1258
				break;
1259
			case DATABLOCK_VAR:
1260
				*(short *)&output[(postbuf+i)->loc]+=(short)addval;
1261
				if(FixUp)(postbuf+i)->type=(unsigned short)FIX_VAR;
1262
				break;
1263
			case DATABLOCK_VAR32:
1264
				*(long *)&output[(postbuf+i)->loc]+=addval+addvalw32;
1265
				if(FixUp)(postbuf+i)->type=(unsigned short)FIX_VAR32;
1266
				numrel++;
1267
				break;
1268
		}
1269
	}
1270
	ooutptr=addvalue;	//сохранить начало post для debug;
1271
}
1272
 
1273
void GetMemExeDat()
1274
{
1275
	if(outputdata==output&&outputdata!=0)outputdata=(unsigned char *)MALLOC((size_t)MAXDATA);
1276
}
1277
 
1278
 
7700 leency 1279
 
6446 GerdtR 1280
int writeoutput()
1281
{
1282
EXE_DOS_HEADER exeheader;  // header for EXE format
1283
	if(fobj){
1284
		if(comfile==file_w32&&ocoff)return MakeCoff();
1285
		return MakeObj();
1286
	}
1287
	if(comfile==file_w32)return MakePE();
1288
	if(comfile==file_meos)return MakeMEOS();
1289
	if(comfile==file_bin)return MakeBin32();
1290
	memset(&exeheader,0,sizeof(EXE_DOS_HEADER));
1291
	if(comfile==file_d32){
1292
		if(usestub){
1293
			MakeLE();
1294
			runfilesize+=ftell(hout)-32;
1295
			goto savecode;
1296
		}
1297
		else goto exefile;
1298
	}
1299
	if(comfile==file_com||comfile==file_sys||comfile==file_rom){
1300
		hout=CreateOutPut(outext,"wb");
1301
		if(fwrite(output+startptr,comfile==file_rom?romsize:outptr-startptr,1,hout)!=1){
1302
			ErrWrite();
1303
			return(-1);
1304
		}
1305
	}
1306
	else if(comfile==file_exe){
1307
exefile:
1308
		hout=CreateOutPut(outext,"wb");
1309
		MakeExeHeader(&exeheader);
1310
		if(fwrite(&exeheader,sizeof(EXE_DOS_HEADER),1,hout)!=1){
1311
errwr:
1312
			fclose(hout);
1313
			hout=NULL;
1314
			ErrWrite();
1315
			return(-1);
1316
		}
1317
		outputcodestart=ftell(hout);
1318
savecode:
1319
		if(fwrite(output+startptr,outptr-startptr,1,hout)!=1)goto errwr;
1320
		if(modelmem==SMALL&&outptrdata!=0){
1321
			if(fwrite(outputdata,outptrdata,1,hout)!=1)goto errwr;
1322
		}
1323
	}
1324
	fclose(hout);
1325
	hout=NULL;
1326
	return(0);
1327
}
1328
 
1329
long CopyFile(FILE *in,FILE *out)
1330
{
1331
char tbuf[1024];
1332
long loads=0;
1333
unsigned int len;
1334
	do{
1335
		len=fread(tbuf,1,1024,in);
1336
		if(fwrite(tbuf,1,len,out)!=len){
1337
			ErrWrite();
1338
			return -1;
1339
		}
1340
		loads+=len;
1341
	}while(len==1024);
1342
	return loads;
1343
}
1344
 
1345
unsigned int EntryPoint()
1346
{
1347
ITOK btok;
1348
int bb=tk_id;
1349
unsigned char bufmain[]="main";
1350
unsigned char buf2[]="__startupproc";
1351
unsigned char *buf;
1352
	if(comfile==file_com)return startptr;
1353
	btok.number=0;
1354
//	if(jumptomain!=CALL_NONE||(comfile==file_w32&&dllflag))buf=buf2;
1355
//	else buf=bufmain;
1356
 
1357
	if(jumptomain==CALL_NONE){
1358
		if(useDOS4GW)buf=buf2;
1359
		else buf=bufmain;
1360
	}
1361
	else buf=buf2;
1362
 
1363
	searchtree(&btok,&bb,buf);
1364
	if(bb==tk_id){
1365
		if(comfile==file_w32&&dllflag)return 0xffffffff;
1366
		printf("Error! Entry point '%s' is not found.\n",buf);
1367
		exit(e_entrynotfound);
1368
	}
1369
	return btok.number;
1370
}
1371
 
1372
void MakeExeHeader(EXE_DOS_HEADER *exeheader)
1373
{
1374
long paragraphsrequired;
1375
unsigned short count,i;
1376
int pointstart;
1377
	exeheader->sign=0x5a4D;				 // MZ
1378
//	if(modelmem==TINY&&comfile==file_exe)pointstart=0x100;
1379
/*	else*/ pointstart=EntryPoint();
1380
	count=(unsigned short)(runfilesize%512);
1381
	i=(unsigned short)(runfilesize/512);
1382
	exeheader->numlastbyte=count;
1383
	exeheader->numpage=(unsigned short)(count==0?i:i+1);
1384
	exeheader->headsize=2; 		// size of header in paragraphs (2 paragraphs)
1385
	exeheader->initIP=(unsigned short)pointstart;	 // IP at entry (0x0000)
1386
	paragraphsrequired=(outptr+outptrdata+postsize+stacksize+15)/16;
1387
	if(modelmem==TINY&&comfile==file_exe){
1388
		exeheader->initSS=0xFFF0; 		 // displacement of SS
1389
		exeheader->initSP=0xFFFE; // intial value of SP
1390
		exeheader->initCS=0xfff0;						 // displacement of CS (0x0000)
1391
		if(!resizemem){
1392
			exeheader->minmem=0xfff;	// min-paragraphs
1393
			exeheader->maxmem=0xffff;	// max-paragraphs
1394
		}
1395
		else{
1396
			paragraphsrequired-=0x10;
1397
			exeheader->initSP=(unsigned short)(paragraphsrequired*16); // intial value of SP
1398
			exeheader->minmem=(unsigned short)paragraphsrequired;	// min-paragraphs
1399
			exeheader->maxmem=(unsigned short)paragraphsrequired;	// max-paragraphs
1400
		}
1401
	}
1402
	else if(comfile==file_d32){
1403
		exeheader->initSP=(unsigned short)stacksize; // intial value of SP
1404
		exeheader->initSS=(unsigned short)((outptr+postsize+15)/16); // displacement of SS
1405
		exeheader->initCS=(unsigned short)((pointstart/65536)*4096);
1406
		if(resizemem){
1407
			exeheader->minmem=(unsigned short)paragraphsrequired;	// min-paragraphs
1408
			exeheader->maxmem=(unsigned short)paragraphsrequired;	// max-paragraphs
1409
		}
1410
		else exeheader->maxmem=(unsigned short)0xFFFF;	// max-paragraphs
1411
	}
1412
	else{
1413
		exeheader->initSS=(unsigned short)(outptr/16); 		 // displacement of SS
1414
		exeheader->initSP=(unsigned short)(outptrdata+postsize+stacksize); // intial value of SP
1415
		exeheader->minmem=(unsigned short)paragraphsrequired;	// min-paragraphs
1416
		exeheader->maxmem=(unsigned short)paragraphsrequired;	// max-paragraphs
1417
	}
1418
	exeheader->ofsreloc=0x1c;						 // offset of first relocation item (0x0000)
1419
}
1420
 
1421
void startsymbiosys(char *symfile)
1422
{
1423
unsigned int size;
1424
int filehandle;
1425
long filesize;
1426
	outptr=startptr;
1427
	if((filehandle=open(symfile,O_BINARY|O_RDONLY))==-1){;
1428
		ErrOpenFile(symfile);
1429
		exit(e_symbioerror);
1430
	}
1431
	if((filesize=getfilelen(filehandle))!=-1L){
1432
		if(filesize+outptr
1433
			size=filesize;
1434
			if((unsigned int)read(filehandle,output+outptr,size)!=size){
1435
				close(filehandle);
1436
				puts("Error reading symbio COM file.");
1437
				exit(e_symbioerror);
1438
			}
1439
			outptr+=size;
1440
		}
1441
		else{
1442
			puts("Symbio COM file is too large.");
1443
			exit(e_symbioerror);
1444
		}
1445
	}
1446
	else{
1447
		puts("Unable to determine symbio COM file size.");
1448
		exit(e_symbioerror);
1449
	}
1450
	close(filehandle);
1451
	outptrdata=outptr;
1452
	outputcodestart=outptr-startptr;
1453
	addconsttotree("__comsymbios",TRUE);
1454
}
1455
 
1456
void BadCommandLine(char *str)
1457
{
1458
	printf("Unknown or bad command line option '%s'.\n",str);
1459
//					PrintInfo(usage);
1460
	exit(e_unknowncommandline);
1461
}
1462
 
1463
void warnunused(struct idrec *ptr)
1464
{
1465
//static count=0;
1466
	if(ptr!=NULL){
1467
		if(ptr->count==0&&startupfile!=ptr->file){
1468
			linenumber=ptr->line;
1469
			currentfileinfo=ptr->file;
1470
			int i=0;
1471
			switch(ptr->rectok){
1472
				case tk_proc:
1473
					if(ptr->recsegm!=NOT_DYNAMIC||strcmp(ptr->recid,mesmain)==0)break;
1474
					i++;
1475
				case tk_structvar:
1476
					i++;
1477
				case tk_charvar:
1478
				case tk_bytevar:
1479
				case tk_intvar:
1480
				case tk_wordvar:
1481
				case tk_longvar:
1482
				case tk_dwordvar:
1483
				case tk_floatvar:
1484
				case tk_pointer:
1485
				case tk_qword:
1486
				case tk_double:
1487
					if(i<=1&&(ptr->recpost==DYNAMIC_VAR||ptr->recpost==DYNAMIC_POST))break;
1488
					warningnotused(ptr->recid,i);
1489
					break;
1490
			}
1491
		}
1492
		warnunused(ptr ->left);
1493
		warnunused(ptr ->right);
1494
	}
1495
}
1496
 
1497
void WarnUnusedVar()//предупреждения о неиспользованных процедурах и переменных
1498
{
1499
	warnunused(treestart);
1500
	for(unsigned int i=0;istlist);
1501
}
1502
 
1503
void addinitvar()
1504
{
1505
unsigned int i;
1506
	if(numfloatconst){	//вставить константы float и привязать их
1507
		if(alignword||optimizespeed)AlignCD(DS,chip>5?16:4);
1508
		for(i=0;i
1509
			if((postbuf+i)->type==POST_FLOATNUM){
1510
				if(am32)*(unsigned long *)&output[(postbuf+i)->loc]=outptrdata+(postbuf+i)->num;
1511
				else *(unsigned short *)&output[(postbuf+i)->loc]=(unsigned short)(outptrdata+(postbuf+i)->num);
1512
				if(FixUp)(postbuf+i)->type=FIX_VAR32;
1513
				else killpost(i--);
1514
			}
1515
		}
1516
		for(i=0;i
1517
			if(dbg&2){
1518
				if((floatnum+i)->type==tk_float)sprintf((char *)string,"const float %f",(floatnum+i)->fnum);
1519
				else sprintf((char *)string,"const double %f",(floatnum+i)->dnum);
1520
				AddDataNullLine(4,(char *)string);
1521
			}
1522
			outdwordd((floatnum+i)->num[0]);
1523
			if((floatnum+i)->type!=tk_float){
1524
				outdwordd((floatnum+i)->num[1]);
1525
				datasize+=4;
1526
			}
1527
			datasize+=4;
1528
		}
1529
		free(floatnum);
1530
		numfloatconst=0;
1531
		floatnum=NULL;
1532
	}
1533
	for(i=0;i<(unsigned int)numswtable;i++){	//создать и вставить таблицы switch
1534
		int j;
1535
		FSWI *swt=swtables+i;
1536
		if(alignword)AlignCD(DS,swt->type);
1537
		if(dbg&2)AddDataNullLine((char)swt->type,"switch table address");
1538
		if(am32==FALSE){	//вставить в код адрес таблицы
1539
			*(unsigned short *)&output[swt->ptb]=(unsigned short)outptrdata;
1540
		}
1541
		else *(unsigned long *)&output[swt->ptb]=outptrdata;
1542
		unsigned char oam32=am32;
1543
		am32=(unsigned char)(swt->type/2-1);
1544
 
1545
		unsigned long val=swt->defal;
1546
		int oline=outptrdata;
1547
		for(j=0;jsizetab;j++){	//заполнить таблицу значениями по умолчанию
1548
//			if((swt->info+jj)->type==singlcase)
1549
			AddReloc(DS);
1550
			if(am32)outdwordd(val);
1551
			else outwordd(val);
1552
		}
1553
		if(swt->mode==2){
1554
			if(dbg&2)AddDataNullLine((char)swt->razr,"switch table value");
1555
			if(oam32==FALSE){	//вставить в код адрес таблицы
1556
				*(unsigned short *)&output[swt->ptv]=(unsigned short)outptrdata;
1557
			}
1558
			else *(unsigned long *)&output[swt->ptv]=outptrdata;
1559
		}
1560
		int ii=0;	//счетчик case
1561
		for(int jj=0;jjnumcase;jj++){
1562
			j=(swt->info+jj)->value;	//значение
1563
			val=(swt->info+jj)->postcase;
1564
			if((swt->info+jj)->type==singlcase){
1565
				if(swt->mode==1){
1566
					if(am32==FALSE)*(unsigned short *)&outputdata[oline+j*2]=(unsigned short)val;
1567
					else *(unsigned long *)&outputdata[oline+j*4]=val;
1568
				}
1569
				else{
1570
					if(am32==FALSE)*(unsigned short *)&outputdata[oline+ii*2]=(unsigned short)val;
1571
					else *(unsigned long *)&outputdata[oline+ii*4]=val;
1572
					switch(swt->razr){
1573
						case r8: opd(j); break;
1574
						case r16: outwordd(j); break;
1575
						case r32: outdwordd(j); break;
1576
					}
1577
					ii++;
1578
				}
1579
			}
1580
			else{
1581
				jj++;
1582
				for(;(unsigned int)j<=(swt->info+jj)->value;j++){
1583
					if(swt->mode==1){
1584
						if(am32==FALSE)*(unsigned short *)&outputdata[oline+j*2]=(unsigned short)val;
1585
						else *(unsigned long *)&outputdata[oline+j*4]=val;
1586
					}
1587
					else{
1588
						if(am32==FALSE)*(unsigned short *)&outputdata[oline+ii*2]=(unsigned short)val;
1589
						else *(unsigned long *)&outputdata[oline+ii*4]=val;
1590
						switch(swt->razr){
1591
							case r8: opd(j); break;
1592
							case r16: outwordd(j); break;
1593
							case r32: outdwordd(j); break;
1594
						}
1595
						ii++;
1596
					}
1597
				}
1598
			}
1599
		}
1600
		am32=oam32;
1601
		free(swt->info);
1602
	}
1603
	if(numswtable){
1604
		free(swtables);
1605
		numswtable=0;
1606
	}
1607
 
1608
	for(i=0;i
1609
		if((postbuf+i)->type==DIN_VAR||(postbuf+i)->type==DIN_VAR32){
1610
			idrec *ptr=(idrec *)(postbuf+i)->num;
1611
//			printf("post=%u num=%08X %s\n",ptr->recpost,ptr->recnumber,ptr->recid);
1612
			if(ptr->recpost==USED_DIN_VAR)setdindata(ptr,i);
1613
			else{
1614
				if((postbuf+i)->type==DIN_VAR){
1615
					*(unsigned short *)&output[(postbuf+i)->loc]+=(unsigned short)(ptr->recnumber);
1616
				}
1617
				else{
1618
//					printf("loc=%08X num=%08X\n",*(unsigned long *)&output[(postbuf+i)->loc],ptr->recnumber);
1619
					*(unsigned long *)&output[(postbuf+i)->loc]+=ptr->recnumber;
1620
				}
1621
			}
1622
			if(FixUp)(postbuf+i)->type=(unsigned short)((postbuf+i)->type==DIN_VAR?FIX_VAR:FIX_VAR32);
1623
			else killpost(i--);
1624
		}
1625
	}
1626
	dopoststrings();
1627
}
1628
 
1629
void setdindata(idrec *ptr,int i)
1630
{
1631
unsigned char *oldinput;
1632
unsigned int oldinptr,oldendinptr;
1633
unsigned char bcha;
1634
unsigned int oline,ofile;
1635
char *ostartline;
1636
	if(alignword){
1637
		if(ptr->rectok==tk_structvar)alignersize+=AlignCD(DS,2);	//выровнять
1638
		else alignersize+=AlignCD(DS,GetVarSize(ptr->rectok));
1639
	}
1640
//	printf("loc=%08X out=%08X num=%08X\n",*(unsigned long *)&output[(postbuf+i)->loc],outptrdata,ptr->recnumber);
1641
	if((postbuf+i)->type==DIN_VAR)*(unsigned short *)&output[(postbuf+i)->loc]+=(unsigned short)(outptrdata);
1642
	else *(unsigned long *)&output[(postbuf+i)->loc]+=outptrdata;
1643
	ptr->recpost=0;
1644
	ptr->recnumber+=outptrdata;
1645
	oline=linenum2;
1646
	ofile=currentfileinfo;
1647
	oldinput=input;
1648
	oldinptr=inptr2;
1649
	bcha=cha2;
1650
	oldendinptr=endinptr;
1651
	input=(unsigned char *)ptr->sbuf;
1652
	inptr2=1;
1653
	ostartline=startline;
1654
	startline=(char*)input;
1655
	cha2=input[0];
1656
	linenum2=ptr->line;
1657
	currentfileinfo=ptr->file;
1658
	endinptr=strlen((char *)input);
1659
	endinput=startline+endinptr;
1660
	endoffile=0;
1661
	tok=ptr->rectok;
1662
	if(tok==tk_structvar)datasize+=initstructvar((structteg *)ptr->newid,ptr->recrm);
1663
	else{
7700 leency 1664
long type = 0,ssize = 0;
1665
unsigned char typev = 0;
6446 GerdtR 1666
		if(tok>=tk_charvar&&tok<=tk_doublevar){
1667
			type=tok-(tk_charvar-tk_char);
1668
			typev=variable;
1669
			ssize=typesize(type);
1670
		}
1671
		else if(tok==tk_pointer){
1672
			typev=pointer;
1673
			type=itok.type;
1674
			if(am32==FALSE&&((itok.flag&f_far)==0))ssize=2;
1675
			else ssize=4;
1676
		}
1677
		datasize+=initglobalvar(type,ptr->recsize/ssize,ssize,typev);
1678
	}
1679
	free(input);
1680
	linenum2=oline;
1681
	currentfileinfo=ofile;
1682
	input=oldinput;
1683
	inptr2=oldinptr;
1684
	cha2=bcha;
1685
	endinptr=oldendinptr;
1686
	endoffile=0;
1687
	startline=ostartline;
1688
}
1689
 
1690
FILE *CreateOutPut(char *ext,char *mode)
1691
{
1692
char buf[256];
1693
FILE *diskout;
7700 leency 1694
	sprintf(buf,"%s.%s",rawfilename,ext);
6446 GerdtR 1695
	if((diskout=fopen(buf,mode))==NULL){
1696
		ErrOpenFile(buf);
1697
		exit(e_notcreateoutput);
1698
	}
1699
	return diskout;
1700
}
1701
 
1702
int numundefclassproc=0;
1703
idrec **undefclassproc;
1704
 
1705
void AddUndefClassProc()
1706
{
1707
	if(numundefclassproc==0)undefclassproc=(idrec **)MALLOC(sizeof(idrec **));
1708
	else undefclassproc=(idrec **)REALLOC(undefclassproc,sizeof(idrec **)*(numundefclassproc+1));
1709
	undefclassproc[numundefclassproc]=itok.rec;
1710
	numundefclassproc++;
1711
}
1712
 
1713
void CheckUndefClassProc()
1714
{
1715
	for(int i=0;i
1716
		idrec *ptr=undefclassproc[i];
1717
		if(ptr->rectok==tk_undefproc){
1718
			currentfileinfo=ptr->file;
1719
			linenumber=ptr->line;
1720
			thisundefined(ptr->recid);
1721
		}
1722
	}
1723
}