Subversion Repositories Kolibri OS

Rev

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