source: dev/BasicCompiler_Common/preprocessor.cpp@ 43

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