Subversion Repositories Kolibri OS

Rev

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

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