Subversion Repositories Kolibri OS

Rev

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