source: dev/BasicCompiler_Common/preprocessor.cpp@ 69

Last change on this file since 69 was 69, checked in by dai_9181, 17 years ago

一時文字列をNewしたときに、bUseHeapフラグを立たせないようにした(bUseHeapが立つのは一時構造体のときのみ)。
DEF_PTR_CHARを廃止し、typeOfPtrCharを導入。

File size: 13.5 KB
Line 
1#include "../BasicCompiler_Common/common.h"
2
3#ifdef _AMD64_
4#include "../BasicCompiler64/opcode.h"
5#else
6#include "../BasicCompiler32/opcode.h"
7#endif
8
9
10
11//////////////////////////////////////
12// #requireの管理
13//////////////////////////////////////
14class CRequireFiles{
15 char **ppFilePath;
16 int count;
17public:
18 CRequireFiles(){
19 ppFilePath = (char **)malloc( 1 );
20 count = 0;
21 }
22 ~CRequireFiles(){
23 for( int i = 0; i < count; i++ ){
24 free( ppFilePath[i] );
25 }
26 free( ppFilePath );
27 }
28 bool IsIncluded( const char *includeFilePath ){
29 // '/' → '\\'
30 char tempPath[MAX_PATH];
31 lstrcpy( tempPath, includeFilePath );
32 for( int i=0; tempPath[i]; i++ ){
33 if( tempPath[i] == '/' ){
34 tempPath[i] = '\\';
35 }
36 }
37
38 for( int i=0; i<count; i++ ){
39 if( lstrcmpi( ppFilePath[i], tempPath ) == 0 ){
40 return true;
41 }
42 }
43 return false;
44 }
45 void Add( const char *includeFilePath ){
46 // '/' → '\\'
47 char tempPath[MAX_PATH];
48 lstrcpy( tempPath, includeFilePath );
49 for( int i=0; tempPath[i]; i++ ){
50 if( tempPath[i] == '/' ){
51 tempPath[i] = '\\';
52 }
53 }
54
55 //既に読み込まれているとき
56 if( IsIncluded( tempPath ) ) return;
57
58 //追加
59 ppFilePath = (char **)realloc(ppFilePath, ( count + 1 ) * sizeof(char *) );
60 ppFilePath[count] = (char *)malloc( lstrlen(tempPath) + 1 );
61 lstrcpy( ppFilePath[count], tempPath );
62 count++;
63 }
64};
65CRequireFiles *pRequireFiles;
66
67
68//////////////////////////////////////
69// #define間するクラス
70//////////////////////////////////////
71class CDefine{
72 int num;
73 char **ppNames;
74public:
75 CDefine();
76 ~CDefine();
77
78 BOOL add(char *name);
79 BOOL undef(char *name);
80 BOOL check(char *name);
81};
82CDefine::CDefine(){
83 extern HANDLE hHeap;
84 ppNames=(char **)HeapAlloc(hHeap,0,1);
85 num=0;
86
87 extern BOOL bDebugCompile;
88 if(bDebugCompile) add("_DEBUG");
89
90#ifdef _AMD64_
91 add("_WIN64");
92#endif
93
94 extern BOOL bDll;
95 if( bDll ){
96 add("_DLL");
97 }
98
99 extern bool isUnicode;
100 if( isUnicode ){
101 add( "UNICODE" );
102 }
103
104 char temporary[255];
105 sprintf(temporary,"_AB_VER%d",MAJOR_VER);
106 add(temporary);
107}
108CDefine::~CDefine(){
109 int i;
110 for(i=0;i<num;i++){
111 HeapDefaultFree(ppNames[i]);
112 }
113 HeapDefaultFree(ppNames);
114}
115BOOL CDefine::add(char *name){
116 extern HANDLE hHeap;
117
118 //重複チェック
119 if(check(name)) return 0;
120
121 //追加
122 ppNames=(char **)HeapReAlloc(hHeap,0,ppNames,(num+1)*sizeof(char *));
123 ppNames[num]=(char *)HeapAlloc(hHeap,0,lstrlen(name)+1);
124 lstrcpy(ppNames[num],name);
125
126 num++;
127
128 return 1;
129}
130BOOL CDefine::undef(char *name){
131 extern HANDLE hHeap;
132 int i;
133
134 for(i=0;i<num;i++){
135 if(lstrcmp(ppNames[i],name)==0) break;
136 }
137 if(i==num) return 0;
138
139 HeapDefaultFree(ppNames[i]);
140
141 num--;
142 for(;i<num;i++){
143 ppNames[i]=ppNames[i+1];
144 }
145
146 return 1;
147}
148BOOL CDefine::check(char *name){
149 extern HANDLE hHeap;
150 int i;
151
152 //重複チェック
153 for(i=0;i<num;i++){
154 if(lstrcmp(ppNames[i],name)==0) return 1;
155 }
156 return 0;
157}
158
159//#define情報
160CDefine *pobj_define;
161
162int Search_endif(char *buffer,int i, int *pLine = 0){
163 for(;;i++){
164 if(buffer[i]=='\0') break;
165
166 if( buffer[i] == '\n' ){
167 if( pLine ){
168 (*pLine)++;
169 }
170 }
171
172 if(buffer[i-1]=='\n'){
173 if(_memicmp(buffer+i,"#ifdef",6)==0||_memicmp(buffer+i,"#ifndef",7)==0){
174 i=Search_endif(buffer,i+6, pLine);
175 if(buffer[i]=='\0') break;
176 continue;
177 }
178 else if(_memicmp(buffer+i,"#endif",6)==0){
179 break;
180 }
181 }
182 }
183 return i;
184}
185
186void preprocessor_ifdef(char *buffer,bool isNot){
187 int i,i2,i3;
188 char temporary[VN_SIZE];
189
190 if(isNot) i=lstrlen("#ifndef");
191 else i=lstrlen("#ifdef");
192 while(buffer[i]==' '||buffer[i]=='\t') i++;
193
194 for(i2=0;;i++,i2++){
195 if(buffer[i]=='\n'||buffer[i]=='\0'){
196 temporary[i2]=0;
197 break;
198 }
199 temporary[i2]=buffer[i];
200 }
201
202 int sw=0;
203 if(pobj_define->check(temporary)) sw=1;
204
205 if(isNot){
206 //#ifndefのとき(反対にする)
207 if(sw) sw=0;
208 else sw=1;
209 }
210
211 //#ifdefの行を消去
212 SlideString(buffer+i,-i);
213 i=0;
214
215 BOOL bElse=0;
216 if(sw){
217 //TRUEのとき
218
219 //#else、#endifを探索
220 for(;;i++){
221 if(buffer[i]=='\0') break;
222
223 if(i==0||buffer[i-1]=='\n'){
224 if(_memicmp(buffer+i,"#ifdef",6)==0||_memicmp(buffer+i,"#ifndef",7)==0){
225 i=Search_endif(buffer,i+6);
226 if(buffer[i]=='\0') break;
227 continue;
228 }
229 else if(_memicmp(buffer+i,"#else",5)==0){
230 i2=5;
231 bElse=1;
232 break;
233 }
234 else if(_memicmp(buffer+i,"#endif",6)==0){
235 i2=6;
236 bElse=0;
237 break;
238 }
239 }
240 }
241
242 //行を消去
243 SlideString(buffer+i+i2,-i2);
244
245 if(bElse){
246 //#elseがある場合はその区間を消去
247
248 for(i2=i,i3=0;;i2++){
249 if(buffer[i2]=='\0') break;
250
251 if(buffer[i2]=='\n') i3++;
252
253 if(i2==0||buffer[i2-1]=='\n'){
254 if(_memicmp(buffer+i2,"#ifdef",6)==0||_memicmp(buffer+i2,"#ifndef",7)==0){
255 i2=Search_endif(buffer,i2+6, &i3 );
256 if(buffer[i2]=='\0') break;
257 continue;
258 }
259 if(_memicmp(buffer+i2,"#endif",6)==0){
260 i2+=6;
261 break;
262 }
263 }
264 }
265
266 //ソースコード区間を消去し、改行コードを挿入
267 SlideString(buffer+i2,i-i2+i3);
268 memset(buffer+i,'\n',i3);
269 }
270 }
271 else{
272 //FALSEのとき
273
274 //#else、#endifを探索
275 for(i2=i,i3=0;;i2++){
276 if(buffer[i2]=='\0') break;
277
278 if(buffer[i2]=='\n') i3++;
279
280 if(i2==0||buffer[i2-1]=='\n'){
281 if(_memicmp(buffer+i2,"#ifdef",6)==0||_memicmp(buffer+i2,"#ifndef",7)==0){
282 i2=Search_endif(buffer,i2+6, &i3 );
283 if(buffer[i2]=='\0') break;
284 continue;
285 }
286 else if(_memicmp(buffer+i2,"#else",5)==0){
287 i2+=5;
288 bElse=1;
289 break;
290 }
291 else if(_memicmp(buffer+i2,"#endif",6)==0){
292 i2+=6;
293 bElse=0;
294 break;
295 }
296 }
297 }
298
299 //ソースコード区間を消去し、改行コードを挿入
300 SlideString(buffer+i2,i-i2+i3);
301 memset(buffer+i,'\n',i3);
302
303 if(bElse){
304 //#endifを探索
305 for(;;i++){
306 if(buffer[i]=='\0') break;
307
308 if(i==0||buffer[i-1]=='\n'){
309 if(_memicmp(buffer+i,"#ifdef",6)==0||_memicmp(buffer+i,"#ifndef",7)==0){
310 i=Search_endif(buffer,i+6);
311 if(buffer[i]=='\0') break;
312 continue;
313 }
314 else if(_memicmp(buffer+i,"#endif",6)==0){
315 i2=6;
316 bElse=0;
317 break;
318 }
319 }
320 }
321
322 //行を消去
323 SlideString(buffer+i+i2,-i2);
324 }
325 }
326}
327
328
329void DirectiveIfdef(char *buffer){
330 int i,i2,i3,sw;
331 char temporary[VN_SIZE];
332
333 for(i=0;;i++){
334 if(buffer[i]=='\0') break;
335
336 if(i==0||buffer[i-1]=='\n'){
337 sw=0;
338 if(_memicmp(buffer+i,"#define",7)==0){
339 i2=i+7;
340 while(buffer[i2]==' '||buffer[i2]=='\t') i2++;
341
342 for(i3=0;;i2++,i3++){
343 if(buffer[i2]=='\n'||buffer[i2]=='\0'){
344 temporary[i3]=0;
345 break;
346 }
347 temporary[i3]=buffer[i2];
348 }
349
350 pobj_define->add(temporary);
351
352 i2-=i;
353
354 //ディレクティブを消去
355 SlideString(buffer+i+i2,-i2);
356 }
357 if(_memicmp(buffer+i,"#undef",6)==0){
358 i2=i+7;
359 while(buffer[i2]==' '||buffer[i2]=='\t') i2++;
360
361 for(i3=0;;i2++,i3++){
362 if(buffer[i2]=='\n'||buffer[i2]=='\0'){
363 temporary[i3]=0;
364 break;
365 }
366 temporary[i3]=buffer[i2];
367 }
368
369 pobj_define->undef(temporary);
370
371 i2-=i;
372
373 //ディレクティブを消去
374 SlideString(buffer+i+i2,-i2);
375 }
376 else if(_memicmp(buffer+i,"#ifdef",6)==0){
377 preprocessor_ifdef(buffer+i,false);
378 continue;
379 }
380 else if(_memicmp(buffer+i,"#ifndef",7)==0){
381 preprocessor_ifdef(buffer+i,true);
382 continue;
383 }
384 else continue;
385 }
386 }
387}
388
389char *IncludeFiles(char *base){
390 extern HANDLE hHeap;
391 extern char szIncludeDir[MAX_PATH];
392 extern char BasicCurDir[MAX_PATH];
393 extern INCLUDEFILEINFO IncludeFileInfo;
394 int i,i2,i3,sw1,FileSize,LineNum,FileLayer[255],layer,LastFileByte[255];
395 char *buffer,temporary[MAX_PATH],temp2[MAX_PATH+255],*LayerDir[255];
396
397 IncludeFileInfo.ppFileNames=(char **)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,sizeof(char *));
398 extern char SourceFileName[MAX_PATH];
399 IncludeFileInfo.ppFileNames[0]=(char *)HeapAlloc(hHeap,0,lstrlen(SourceFileName)+1);
400 lstrcpy(IncludeFileInfo.ppFileNames[0],SourceFileName);
401 IncludeFileInfo.FilesNum=1;
402
403 buffer=base+2;
404 layer=0;
405 FileLayer[layer]=0;
406 LastFileByte[layer]=lstrlen(buffer);
407 LineNum=0;
408
409 //参照ディレクトリ
410 LayerDir[0]=(char *)HeapAlloc(hHeap,0,lstrlen(BasicCurDir)+1);
411 lstrcpy(LayerDir[0],BasicCurDir);
412
413 for(i=0;;i++){
414 if(buffer[i]=='\0'){
415 IncludeFileInfo.LineOfFile[LineNum]=-1;
416 break;
417 }
418 if(buffer[i]=='\n'){
419 IncludeFileInfo.LineOfFile[LineNum]=FileLayer[layer];
420 LineNum++;
421 }
422 if(i>LastFileByte[layer]){
423 HeapDefaultFree(LayerDir[layer]);
424 layer--;
425 }
426 if(buffer[i-1]=='\n'&&buffer[i]=='#'){
427 bool isRequire = false;
428 if(memcmp( buffer + i + 1, "include", 7 ) == 0
429 || memcmp( buffer + i + 1, "require", 7 ) == 0){
430
431 //#requireの場合
432 if( buffer[i + 1] == 'r' ) isRequire = true;
433
434 i2=i+8;
435 while(buffer[i2]==' '||buffer[i2]=='\t') i2++;
436
437 if(buffer[i2]=='\"') sw1=0;
438 else if(buffer[i2]=='<') sw1=1;
439 i2++;
440
441 for(i3=0;;i2++,i3++){
442 if((buffer[i2]=='\"'&&sw1==0)||(buffer[i2]=='>'&&sw1==1)||buffer[i2]=='\n'||buffer[i2]=='\0'){
443 temporary[i3]=0;
444 break;
445 }
446 temporary[i3]=buffer[i2];
447 }
448 while(buffer[i2]!='\n'&&buffer[i2]!='\0') i2++;
449
450 if(sw1){
451 sprintf(temp2,"%s%s",szIncludeDir,temporary);
452 lstrcpy(temporary,temp2);
453 }
454 else GetFullPath(temporary,LayerDir[layer]);
455 }
456 else if(memcmp(buffer+i+1,"prompt",6)==0){
457 i2=i+7;
458 sprintf(temporary,"%sbasic\\prompt.sbp",szIncludeDir);
459 }
460 else if(memcmp(buffer+i+1,"N88BASIC",8)==0){
461 i2=i+9;
462 sprintf(temporary,"%sbasic\\prompt.sbp",szIncludeDir);
463 }
464 else if(memcmp(buffer+i+1,"console",7)==0){
465 //サブシステム タイプをCUIに変更
466 extern unsigned short TypeOfSubSystem;
467 TypeOfSubSystem=IMAGE_SUBSYSTEM_WINDOWS_CUI;
468
469 i2=i+8;
470 sprintf(temporary,"%sbasic\\dos_console.sbp",szIncludeDir);
471 }
472 else continue;
473
474 if(i){
475 //ディレクティブが消えるため、一行減ってしまうのを防ぐ(basic.sbpを除く)
476 SlideString(buffer+i2,1);
477 buffer[i2]='\n';
478 for(i3=0;i3<=layer;i3++) LastFileByte[i3]++;
479 }
480
481 IncludeFileInfo.ppFileNames=(char **)HeapReAlloc(hHeap,0,IncludeFileInfo.ppFileNames,(IncludeFileInfo.FilesNum+1)*sizeof(char *));
482 IncludeFileInfo.ppFileNames[IncludeFileInfo.FilesNum]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
483 lstrcpy(IncludeFileInfo.ppFileNames[IncludeFileInfo.FilesNum],temporary);
484
485 layer++;
486 FileLayer[layer]=IncludeFileInfo.FilesNum;
487 IncludeFileInfo.FilesNum++;
488
489 //#requireの場合では、既に読み込まれているファイルは読み込まないようにする
490 bool isFake = false;
491 if( isRequire ){
492 if( pRequireFiles->IsIncluded( temporary ) ){
493 //既に読み込まれているとき
494 isFake = true;
495 }
496 }
497
498 char *temp3;
499 if( isFake ){
500 //既に読み込まれているときは空データを生成
501 temp3 = (char *)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,1);;
502 FileSize = 0;
503 }
504 else{
505 //取り込まれたファイルを収集する
506 pRequireFiles->Add( temporary );
507
508 //インクルードファイルを読み込む
509 DWORD AccBytes;
510 HANDLE hFile=CreateFile(temporary,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
511 if(hFile==INVALID_HANDLE_VALUE){
512 sprintf(temp2,"インクルードファイル \"%s\" をオープンできません",temporary);
513 extern char *basbuf;
514 basbuf=base+2;
515 SetError(-1,temp2,i);
516 break;
517 }
518 FileSize=GetFileSize(hFile,NULL);
519
520 //読み込み
521 temp3=(char *)HeapAlloc(hHeap,0,FileSize+1);
522 ReadFile(hFile,temp3,FileSize,&AccBytes,NULL);
523 temp3[AccBytes]=0;
524 CloseHandle(hFile);
525
526 //CRLFをLFに変換
527 ChangeReturnCode(temp3);
528
529 //コメント削除
530 DeleteComment(temp3);
531
532 //#ifdefディレクティブ
533 DirectiveIfdef(temp3);
534
535 FileSize=lstrlen(temp3);
536 }
537
538 i3=lstrlen(buffer)+FileSize;
539 base=(char *)HeapReAlloc(hHeap,HEAP_ZERO_MEMORY,base,i3*2);
540 buffer=base+2;
541 SlideString(buffer+i2,FileSize+(i-i2));
542 memcpy(buffer+i,temp3,FileSize);
543
544 //クローズ
545 HeapDefaultFree(temp3);
546
547 //新しい参照ディレクトリをセット
548 char temp4[MAX_PATH];
549 _splitpath(temporary,temp2,temp4,0,0);
550 lstrcat(temp2,temp4);
551 LayerDir[layer]=(char *)HeapAlloc(hHeap,0,lstrlen(temp2)+1);
552 lstrcpy(LayerDir[layer],temp2);
553
554 //ファイル範囲をスライド
555 LastFileByte[layer]=i+FileSize-1;
556 for(i3=0;i3<layer;i3++) LastFileByte[i3]+=FileSize+(i-i2);
557
558 i--;
559 }
560 }
561
562 HeapDefaultFree(LayerDir[0]);
563
564 return base;
565}
566char *OpenBasicFile(char *FileName){
567 extern HANDLE hHeap;
568 char *base,*buffer;
569 DWORD dwFileSize,dwAccBytes;
570 HANDLE hFile;
571
572 //ファイルオープン
573 hFile=CreateFile(FileName,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
574 if(hFile==INVALID_HANDLE_VALUE) return 0;
575
576 //#define情報を初期化
577 pobj_define=new CDefine;
578
579 //バッファ領域確保
580 dwFileSize=GetFileSize(hFile,0);
581 base=(char *)HeapAlloc(hHeap,0,dwFileSize*2+255);
582 base[0]='\n';
583 base[1]='\n';
584 buffer=base+2;
585 lstrcpy(buffer,"#include <basic.sbp>\n");
586 buffer+=lstrlen(buffer);
587
588 //読み込み
589 ReadFile(hFile,buffer,dwFileSize,&dwAccBytes,0);
590 buffer[dwAccBytes]=0;
591
592 //CRLFをLFに変換
593 ChangeReturnCode(buffer);
594
595 //コメント削除
596 DeleteComment(buffer);
597
598 //#ifdefディレクティブ
599 DirectiveIfdef(buffer);
600
601 //最終行には文字を含ませないようにする
602 lstrcat(buffer,"\n");
603
604 //ファイルクローズ
605 CloseHandle(hFile);
606
607 //インクルードファイルを読み込む
608 pRequireFiles = new CRequireFiles();
609 base=IncludeFiles(base);
610 delete pRequireFiles;
611
612 //#define情報を破棄
613 delete pobj_define;
614 pobj_define=0;
615
616 return base;
617}
Note: See TracBrowser for help on using the repository browser.