Subversion Repositories Kolibri OS

Rev

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