Subversion Repositories Kolibri OS

Rev

Rev 6447 | Go to most recent revision | Details | Last modification | View Log | RSS feed

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