source: dev/BasicCompiler_Common/preprocessor.cpp@ 55

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

・コマンドラインオプション "/unicode" に対応。
・Unicode文字セットを使用する場合に "UNICODE" が自動的に#defineされるようにしました。
・SByte型(8ビット符号付き整数型)を追加。
・Char型を文字型に変更。
・プロジェクトオプションから「Unicode文字セットを使用する」チェックを選択できるようにしました。

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