Subversion Repositories Kolibri OS

Rev

Rev 9705 | Details | Compare with Previous | Last modification | View Log | RSS feed

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