Subversion Repositories Kolibri OS

Rev

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

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