source: dev/BasicCompiler_Common/preprocessor.cpp@ 68

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

#84の対応(64bitでの動作確認はまだ)。
Stringクラスのコンストラクタにリテラル文字列が渡せないバグを修正。
STRING_IS_NOT_ALWAYS_UNICODEを暗黙的に定義するようにした(暫定対応)。

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