Subversion Repositories Kolibri OS

Rev

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

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