Subversion Repositories Kolibri OS

Rev

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