source: dev/BasicCompiler_Common/src/Source.cpp@ 89

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

実行時型情報の生成に対応。
関数の戻り値の型に抽象クラスを指定できるようにした。

File size: 19.5 KB
Line 
1#include <Source.h>
2
3#include "../common.h"
4#include <windows.h>
5
6
7const string BasicSource::generateDirectiveName = "#generate";
8
9
10class CDefine{
11 vector<string> names;
12public:
13 CDefine();
14 ~CDefine();
15 void Free();
16 void Init();
17
18 BOOL add(char *name);
19 BOOL undef(char *name);
20 BOOL check(char *name);
21 void preprocessor_ifdef(char *buffer,bool isNot);
22 void DirectiveIfdef(char *buffer);
23};
24CDefine objDefine;
25
26
27//////////////////////////////////////
28// #requireの管理
29//////////////////////////////////////
30class CRequireFiles{
31 char **ppFilePath;
32 int count;
33public:
34 CRequireFiles(){
35 ppFilePath = (char **)malloc( 1 );
36 count = 0;
37 }
38 ~CRequireFiles(){
39 for( int i = 0; i < count; i++ ){
40 free( ppFilePath[i] );
41 }
42 free( ppFilePath );
43 }
44 void clear(){
45 for( int i = 0; i < count; i++ ){
46 free( ppFilePath[i] );
47 }
48 free( ppFilePath );
49
50 ppFilePath = (char **)malloc( 1 );
51 count = 0;
52 }
53 bool IsIncluded( const char *includeFilePath ){
54 // '/' → '\\'
55 char tempPath[MAX_PATH];
56 lstrcpy( tempPath, includeFilePath );
57 for( int i=0; tempPath[i]; i++ ){
58 if( tempPath[i] == '/' ){
59 tempPath[i] = '\\';
60 }
61 }
62
63 for( int i=0; i<count; i++ ){
64 if( lstrcmpi( ppFilePath[i], tempPath ) == 0 ){
65 return true;
66 }
67 }
68 return false;
69 }
70 void Add( const char *includeFilePath ){
71 // '/' → '\\'
72 char tempPath[MAX_PATH];
73 lstrcpy( tempPath, includeFilePath );
74 for( int i=0; tempPath[i]; i++ ){
75 if( tempPath[i] == '/' ){
76 tempPath[i] = '\\';
77 }
78 }
79
80 //既に読み込まれているとき
81 if( IsIncluded( tempPath ) ) return;
82
83 //追加
84 ppFilePath = (char **)realloc(ppFilePath, ( count + 1 ) * sizeof(char *) );
85 ppFilePath[count] = (char *)malloc( lstrlen(tempPath) + 1 );
86 lstrcpy( ppFilePath[count], tempPath );
87 count++;
88 }
89};
90CRequireFiles requireFiles;
91
92
93//////////////////////////////////////
94// #define間するクラス
95//////////////////////////////////////
96
97CDefine::CDefine(){
98 Init();
99}
100CDefine::~CDefine(){
101}
102void CDefine::Init(){
103 names.clear();
104
105 extern BOOL bDebugCompile;
106 if(bDebugCompile) add("_DEBUG");
107
108#ifdef _AMD64_
109 add("_WIN64");
110#endif
111
112 extern BOOL bDll;
113 if( bDll ){
114 add("_DLL");
115 }
116
117 extern bool isUnicode;
118 if( isUnicode ){
119 add( "UNICODE" );
120 }
121
122 char temporary[255];
123 sprintf(temporary,"_AB_VER%d",MAJOR_VER);
124 add(temporary);
125}
126BOOL CDefine::add(char *name){
127 extern HANDLE hHeap;
128
129 //重複チェック
130 if(check(name)) return 0;
131
132 //追加
133 names.push_back( name );
134
135 return 1;
136}
137BOOL CDefine::undef(char *name){
138 vector<string>::iterator i = names.begin();
139 foreach( const string &temp, names ){
140 if( temp == name ){
141 names.erase( i );
142 return 1;
143 }
144 i++;
145 }
146
147 return 0;
148}
149BOOL CDefine::check(char *name){
150
151 //重複チェック
152 foreach( const string &temp, names ){
153 if( temp == name ){
154 return 1;
155 }
156 }
157 return 0;
158}
159
160int Search_endif(char *buffer,int i, int *pLine = 0){
161 for(;;i++){
162 if(buffer[i]=='\0') break;
163
164 if( buffer[i] == '\n' ){
165 if( pLine ){
166 (*pLine)++;
167 }
168 }
169
170 if(buffer[i-1]=='\n'){
171 if(memicmp(buffer+i,"#ifdef",6)==0||memicmp(buffer+i,"#ifndef",7)==0){
172 i=Search_endif(buffer,i+6, pLine);
173 if(buffer[i]=='\0') break;
174 continue;
175 }
176 else if(memicmp(buffer+i,"#endif",6)==0){
177 break;
178 }
179 }
180 }
181 return i;
182}
183
184void CDefine::preprocessor_ifdef(char *buffer,bool isNot){
185 int i,i2,i3;
186 char temporary[VN_SIZE];
187
188 if(isNot) i=lstrlen("#ifndef");
189 else i=lstrlen("#ifdef");
190 while(buffer[i]==' '||buffer[i]=='\t') i++;
191
192 for(i2=0;;i++,i2++){
193 if(buffer[i]=='\n'||buffer[i]=='\0'){
194 temporary[i2]=0;
195 break;
196 }
197 temporary[i2]=buffer[i];
198 }
199
200 int sw=0;
201 if(check(temporary)) sw=1;
202
203 if(isNot){
204 //#ifndefのとき(反対にする)
205 if(sw) sw=0;
206 else sw=1;
207 }
208
209 //#ifdefの行を消去
210 SlideString(buffer+i,-i);
211 i=0;
212
213 BOOL bElse=0;
214 if(sw){
215 //TRUEのとき
216
217 //#else、#endifを探索
218 for(;;i++){
219 if(buffer[i]=='\0') break;
220
221 if(i==0||buffer[i-1]=='\n'){
222 if(memicmp(buffer+i,"#ifdef",6)==0||memicmp(buffer+i,"#ifndef",7)==0){
223 i=Search_endif(buffer,i+6);
224 if(buffer[i]=='\0') break;
225 continue;
226 }
227 else if(memicmp(buffer+i,"#else",5)==0){
228 i2=5;
229 bElse=1;
230 break;
231 }
232 else if(memicmp(buffer+i,"#endif",6)==0){
233 i2=6;
234 bElse=0;
235 break;
236 }
237 }
238 }
239
240 //行を消去
241 SlideString(buffer+i+i2,-i2);
242
243 if(bElse){
244 //#elseがある場合はその区間を消去
245
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, &i3 );
254 if(buffer[i2]=='\0') break;
255 continue;
256 }
257 if(memicmp(buffer+i2,"#endif",6)==0){
258 i2+=6;
259 break;
260 }
261 }
262 }
263
264 //ソースコード区間を消去し、改行コードを挿入
265 SlideString(buffer+i2,i-i2+i3);
266 memset(buffer+i,'\n',i3);
267 }
268 }
269 else{
270 //FALSEのとき
271
272 //#else、#endifを探索
273 for(i2=i,i3=0;;i2++){
274 if(buffer[i2]=='\0') break;
275
276 if(buffer[i2]=='\n') i3++;
277
278 if(i2==0||buffer[i2-1]=='\n'){
279 if(memicmp(buffer+i2,"#ifdef",6)==0||memicmp(buffer+i2,"#ifndef",7)==0){
280 i2=Search_endif(buffer,i2+6, &i3 );
281 if(buffer[i2]=='\0') break;
282 continue;
283 }
284 else if(memicmp(buffer+i2,"#else",5)==0){
285 i2+=5;
286 bElse=1;
287 break;
288 }
289 else if(memicmp(buffer+i2,"#endif",6)==0){
290 i2+=6;
291 bElse=0;
292 break;
293 }
294 }
295 }
296
297 //ソースコード区間を消去し、改行コードを挿入
298 SlideString(buffer+i2,i-i2+i3);
299 memset(buffer+i,'\n',i3);
300
301 if(bElse){
302 //#endifを探索
303 for(;;i++){
304 if(buffer[i]=='\0') break;
305
306 if(i==0||buffer[i-1]=='\n'){
307 if(memicmp(buffer+i,"#ifdef",6)==0||memicmp(buffer+i,"#ifndef",7)==0){
308 i=Search_endif(buffer,i+6);
309 if(buffer[i]=='\0') break;
310 continue;
311 }
312 else if(memicmp(buffer+i,"#endif",6)==0){
313 i2=6;
314 bElse=0;
315 break;
316 }
317 }
318 }
319
320 //行を消去
321 SlideString(buffer+i+i2,-i2);
322 }
323 }
324}
325
326
327void CDefine::DirectiveIfdef(char *buffer){
328 int i,i2,i3,sw;
329 char temporary[VN_SIZE];
330
331 for(i=0;;i++){
332 if(buffer[i]=='\0') break;
333
334 if(i==0||(i>=1&&buffer[i-1]=='\n')){
335 sw=0;
336 if(memicmp(buffer+i,"#define",7)==0){
337 i2=i+7;
338 while(buffer[i2]==' '||buffer[i2]=='\t') i2++;
339
340 for(i3=0;;i2++,i3++){
341 if(buffer[i2]=='\n'||buffer[i2]=='\0'){
342 temporary[i3]=0;
343 break;
344 }
345 temporary[i3]=buffer[i2];
346 }
347
348 add(temporary);
349
350 i2-=i;
351
352 //ディレクティブを消去
353 SlideString(buffer+i+i2,-i2);
354 }
355 if(memicmp(buffer+i,"#undef",6)==0){
356 i2=i+7;
357 while(buffer[i2]==' '||buffer[i2]=='\t') i2++;
358
359 for(i3=0;;i2++,i3++){
360 if(buffer[i2]=='\n'||buffer[i2]=='\0'){
361 temporary[i3]=0;
362 break;
363 }
364 temporary[i3]=buffer[i2];
365 }
366
367 undef(temporary);
368
369 i2-=i;
370
371 //ディレクティブを消去
372 SlideString(buffer+i+i2,-i2);
373 }
374 else if(memicmp(buffer+i,"#ifdef",6)==0){
375 preprocessor_ifdef(buffer+i,false);
376 continue;
377 }
378 else if(memicmp(buffer+i,"#ifndef",7)==0){
379 preprocessor_ifdef(buffer+i,true);
380 continue;
381 }
382 else continue;
383 }
384 }
385}
386
387
388
389
390bool Text::ReadFile( const string &filePath ){
391 //ファイルオープン
392 HANDLE hFile=CreateFile(filePath.c_str(),GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
393 if(hFile==INVALID_HANDLE_VALUE){
394 return false;
395 }
396
397 length = GetFileSize( hFile, NULL );
398
399 buffer = (char *)realloc( buffer, length + 1 );
400
401 //読み込み
402 DWORD dwAccBytes;
403 ::ReadFile(hFile,buffer,length,&dwAccBytes,0);
404 buffer[dwAccBytes]=0;
405
406 //ファイルクローズ
407 CloseHandle(hFile);
408
409 return true;
410}
411
412void BasicSource::ChangeReturnLineChar(){
413 int i,i2;
414
415#ifdef _DEBUG
416 //改行コードの整合性チェック
417 for( i=0; ; i++ ){
418 if( buffer[i] == '\0' ){
419 break;
420 }
421 if( buffer[i]!='\r' && buffer[i+1]=='\n'
422 || buffer[i]=='\r' && buffer[i+1]!='\n' ){
423 char temporary[255];
424 strncpy( temporary, buffer + i-100, 130 );
425 temporary[130] = 0;
426 for(int i2=0; ;i2++){
427 if(temporary[i2]=='\r') temporary[i2]='A';
428 if(temporary[i2]=='\n') temporary[i2]='B';
429 if(temporary[i2]=='\0') break;
430 }
431
432 extern HWND hOwnerEditor;
433 MessageBox( hOwnerEditor, temporary, "改行コードの整合性チェック", MB_OK | MB_ICONEXCLAMATION );
434 }
435 }
436#endif
437
438 //改行コードのCRLFをLFに変換
439 for(i=0,i2=0;;i++,i2++){
440 if(buffer[i]=='\r'&&buffer[i+1]=='\n') i++;
441 buffer[i2]=buffer[i];
442 if(buffer[i]=='\0') break;
443 }
444
445 length = i;
446}
447
448void BasicSource::RemoveComments(){
449 int i,i2,i3,IsStr;
450 char *temporary;
451 temporary=(char *)GlobalAlloc(GMEM_FIXED,lstrlen(buffer)+1);
452 for(i=0,i2=0,i3=0,IsStr=0;;i++,i2++){
453 if(buffer[i]=='\"') IsStr^=1;
454 if(buffer[i]=='\n'||buffer[i]=='\0'){
455 i2--;
456 while(temporary[i2]==' '||temporary[i2]=='\t') i2--;
457 i2++;
458
459 if(i3){
460 //複数行に渡る注釈文の中に改行が存在するとき
461 memset(temporary+i2,'\n',i3);
462 i2+=i3;
463 i3=0;
464 }
465 }
466 if(buffer[i]=='\''&&IsStr==0){
467 //注釈文
468 i2--;
469 while(temporary[i2]==' '||temporary[i2]=='\t') i2--;
470 i2++;
471 while(buffer[i]!='\n'&&buffer[i]!='\0') i++;
472 }
473 if(buffer[i]=='/'&&buffer[i+1]=='*'&&IsStr==0){
474 //注釈文(複数行)
475 i+=2;
476 i3=0;
477 while(!(buffer[i]=='*'&&buffer[i+1]=='/')){
478 if(buffer[i]=='\n') i3++;
479 if(buffer[i]=='\0') break;
480 i++;
481 }
482 if(buffer[i]){
483 i+=2;
484 }
485 i--;
486 i2--;
487 continue;
488 }
489 temporary[i2]=buffer[i];
490 if(buffer[i]=='\0') break;
491 }
492 lstrcpy(buffer,temporary);
493 GlobalFree(temporary);
494}
495
496bool BasicSource::ReadFile_InIncludeDirective( const string &filePath ){
497 if( !Text::ReadFile( filePath ) ){
498 return false;
499 }
500
501 // 改行コードをCRLFからLFに変換
502 ChangeReturnLineChar();
503
504 // コメントを削除
505 RemoveComments();
506
507 // #ifdefディレクティブを処理
508 objDefine.DirectiveIfdef( buffer );
509
510 // アンダーバーによる改行を正規表現に戻す
511 RemoveReturnLineUnderbar();
512
513 // ダミー改行をセット
514 Realloc( length + 2 );
515 SlideString( buffer, 2 );
516 buffer[0] = '\n';
517 buffer[1] = '\n';
518
519 return true;
520}
521
522void BasicSource::DirectiveIncludeOrRequire(){
523 extern HANDLE hHeap;
524 extern char szIncludeDir[MAX_PATH];
525 extern char BasicCurDir[MAX_PATH];
526 extern INCLUDEFILEINFO IncludeFileInfo;
527 int i,i2,i3,sw1,LineNum,FileLayer[255],layer,LastFileByte[255];
528 char temporary[MAX_PATH],temp2[MAX_PATH+255],*LayerDir[255];
529
530 IncludeFileInfo.ppFileNames=(char **)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,sizeof(char *));
531 extern char SourceFileName[MAX_PATH];
532 IncludeFileInfo.ppFileNames[0]=(char *)HeapAlloc(hHeap,0,lstrlen(SourceFileName)+1);
533 lstrcpy(IncludeFileInfo.ppFileNames[0],SourceFileName);
534 IncludeFileInfo.FilesNum=1;
535
536 layer=0;
537 FileLayer[layer]=0;
538 LastFileByte[layer]=GetLength();
539 LineNum=0;
540
541 //参照ディレクトリ
542 LayerDir[0]=(char *)HeapAlloc(hHeap,0,lstrlen(BasicCurDir)+1);
543 lstrcpy(LayerDir[0],BasicCurDir);
544
545 for(i=0;;i++){
546 if(buffer[i]=='\0'){
547 IncludeFileInfo.LineOfFile[LineNum]=-1;
548 break;
549 }
550 if(buffer[i]=='\n'){
551 IncludeFileInfo.LineOfFile[LineNum]=FileLayer[layer];
552 LineNum++;
553 }
554 if(i>LastFileByte[layer]){
555 HeapDefaultFree(LayerDir[layer]);
556 LayerDir[layer]=0;
557 layer--;
558 }
559 if((buffer[i-1]=='\n'||i==0)&&buffer[i]=='#'){
560 bool isRequire = false;
561 if(memcmp( buffer + i + 1, "include", 7 ) == 0
562 || memcmp( buffer + i + 1, "require", 7 ) == 0){
563
564 //#requireの場合
565 if( buffer[i + 1] == 'r' ) isRequire = true;
566
567 i2=i+8;
568 while(buffer[i2]==' '||buffer[i2]=='\t') i2++;
569
570 if(buffer[i2]=='\"') sw1=0;
571 else if(buffer[i2]=='<') sw1=1;
572 i2++;
573
574 for(i3=0;;i2++,i3++){
575 if((buffer[i2]=='\"'&&sw1==0)||(buffer[i2]=='>'&&sw1==1)||buffer[i2]=='\n'||buffer[i2]=='\0'){
576 temporary[i3]=0;
577 break;
578 }
579 temporary[i3]=buffer[i2];
580 }
581 while(buffer[i2]!='\n'&&buffer[i2]!='\0') i2++;
582
583 if(sw1){
584 sprintf(temp2,"%s%s",szIncludeDir,temporary);
585 lstrcpy(temporary,temp2);
586 }
587 else GetFullPath(temporary,LayerDir[layer]);
588 }
589 else if(memcmp(buffer+i+1,"prompt",6)==0){
590 i2=i+7;
591 sprintf(temporary,"%sbasic\\prompt.sbp",szIncludeDir);
592 }
593 else if(memcmp(buffer+i+1,"N88BASIC",8)==0){
594 i2=i+9;
595 sprintf(temporary,"%sbasic\\prompt.sbp",szIncludeDir);
596 }
597 else if(memcmp(buffer+i+1,"console",7)==0){
598 //サブシステム タイプをCUIに変更
599 extern unsigned short TypeOfSubSystem;
600 TypeOfSubSystem=IMAGE_SUBSYSTEM_WINDOWS_CUI;
601
602 i2=i+8;
603 sprintf(temporary,"%sbasic\\dos_console.sbp",szIncludeDir);
604 }
605 else continue;
606
607 if(i){
608 //ディレクティブが消えるため、一行減ってしまうのを防ぐ(basic.sbpを除く)
609 SlideString(buffer+i2,1);
610 buffer[i2]='\n';
611 for(i3=0;i3<=layer;i3++) LastFileByte[i3]++;
612 }
613
614 IncludeFileInfo.ppFileNames=(char **)HeapReAlloc(hHeap,0,IncludeFileInfo.ppFileNames,(IncludeFileInfo.FilesNum+1)*sizeof(char *));
615 IncludeFileInfo.ppFileNames[IncludeFileInfo.FilesNum]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
616 lstrcpy(IncludeFileInfo.ppFileNames[IncludeFileInfo.FilesNum],temporary);
617
618 layer++;
619 FileLayer[layer]=IncludeFileInfo.FilesNum;
620 IncludeFileInfo.FilesNum++;
621
622 //#requireの場合では、既に読み込まれているファイルは読み込まないようにする
623 bool isFake = false;
624 if( isRequire ){
625 if( requireFiles.IsIncluded( temporary ) ){
626 //既に読み込まれているとき
627 isFake = true;
628 }
629 }
630
631 BasicSource source;
632
633 if( isFake ){
634 //既に読み込まれているときは空データ
635 source.SetBuffer( "" );
636 }
637 else{
638 //取り込まれたファイルを収集する
639 requireFiles.Add( temporary );
640
641 //インクルードファイルを読み込む
642 if( !source.ReadFile_InIncludeDirective( temporary ) ){
643 sprintf(temp2,"インクルードファイル \"%s\" をオープンできません",temporary);
644 SetError(-1,temp2,i);
645 break;
646 }
647 }
648
649 i3=lstrlen(buffer)+source.GetLength();
650 Realloc( i3 );
651 SlideString(buffer+i2,source.GetLength()+(i-i2));
652 memcpy(buffer+i,source.GetBuffer(),source.GetLength());
653
654 //新しい参照ディレクトリをセット
655 char temp4[MAX_PATH];
656 _splitpath(temporary,temp2,temp4,0,0);
657 lstrcat(temp2,temp4);
658 LayerDir[layer]=(char *)HeapAlloc(hHeap,0,lstrlen(temp2)+1);
659 lstrcpy(LayerDir[layer],temp2);
660
661 //ファイル範囲をスライド
662 LastFileByte[layer]=i+source.GetLength()-1;
663 for(i3=0;i3<layer;i3++) LastFileByte[i3]+=source.GetLength()+(i-i2);
664
665 i--;
666 }
667 }
668
669 HeapDefaultFree(LayerDir[0]);
670
671 length = lstrlen(buffer);
672}
673
674int KillReturnCode_InParameter(char *buffer,int *pRnum,char cBeginPare,char cEndPare){
675 int i,i2,i3,IsStr;
676
677 //カッコ'('直下の改行
678 while(buffer[0]=='\n'){
679 SlideString(buffer+1,-1);
680 (*pRnum)++;
681 }
682
683 for(i=0,IsStr=0;;i++){
684 if(IsDBCSLeadByte(buffer[i])&&buffer[i+1]){
685 i++;
686 continue;
687 }
688
689 if(buffer[i]=='\"') IsStr^=1;
690
691 if(buffer[i]=='\0') break; //エラー
692 if(buffer[i]=='\n'){
693 i2=0;
694 i3=0;
695 while(buffer[i+i2]=='\n'){
696 i2++;
697 i3++;
698 while(buffer[i+i2]==' '||buffer[i+i2]=='\t') i2++;
699 }
700 while(buffer[i+i2]==' '||buffer[i+i2]=='\t') i2++;
701
702 if(buffer[i+i2]==cEndPare){
703 SlideString(buffer+i+i2,-i2);
704 (*pRnum)+=i3;
705 break;
706 }
707
708 //エラー
709 break;
710 }
711
712 if(buffer[i]==cBeginPare&&IsStr==0){
713 i++;
714 i2=KillReturnCode_InParameter(buffer+i,pRnum,cBeginPare,cEndPare);
715 i+=i2;
716 if(buffer[i]!=cEndPare) break;
717 continue;
718 }
719 if(buffer[i]==cEndPare&&IsStr==0) break;
720
721 if(buffer[i]==','&&buffer[i+1]=='\n'&&IsStr==0){
722 i++;
723 while(buffer[i]=='\n'){
724 SlideString(buffer+i+1,-1);
725 (*pRnum)++;
726 }
727 i--;
728 }
729 }
730 return i;
731}
732void BasicSource::RemoveReturnLineUnderbar(){
733 int i,i2;
734
735 //アンダーバーによる改行
736 for(i=0;;i++){
737 i2=0;
738 while(buffer[i]=='_'&&buffer[i+1]=='\n'){
739 i2++;
740 SlideString(buffer+i+2,-2);
741 while(buffer[i]=='\n'){
742 SlideString(buffer+i+1,-1);
743 i2++;
744 }
745 for(;;i++){
746 if(buffer[i]=='_'&&buffer[i+1]=='\n') break;
747 if(buffer[i]=='\n'||buffer[i]=='\0'){
748 SlideString(buffer+i,i2);
749 memset(buffer+i,'\n',i2);
750 break;
751 }
752 }
753 }
754 if(buffer[i]=='\0') break;
755 }
756
757 //カッコ内パラメータの改行
758 int IsStr,rnum;
759 for(i=0,IsStr=0,rnum=0;;i++){
760 if(IsDBCSLeadByte(buffer[i])&&buffer[i+1]){
761 i++;
762 continue;
763 }
764 if(buffer[i]=='\0') break;
765 if(buffer[i]=='\n'){
766 if(rnum){
767 SlideString(buffer+i+1,rnum);
768 memset(buffer+i+1,'\n',rnum);
769 rnum=0;
770 }
771 }
772 if(buffer[i]=='\"') IsStr^=1;
773 if(buffer[i]=='('&&IsStr==0){
774 i++;
775 i2=KillReturnCode_InParameter(buffer+i,&rnum,'(',')');
776 i+=i2;
777 if(buffer[i]!=')') break;
778 }
779 if(buffer[i]=='['&&IsStr==0){
780 i++;
781 i2=KillReturnCode_InParameter(buffer+i,&rnum,'[',']');
782 i+=i2;
783 if(buffer[i]!=']') break;
784 }
785 }
786
787 length = lstrlen(buffer);
788}
789
790void BasicSource::SetBuffer( const char *buffer ){
791 this->buffer = (char *)calloc( lstrlen(buffer) + 1, 1 );
792 lstrcpy( this->buffer, buffer );
793 length = lstrlen(buffer);
794
795 // ダミー改行をセット
796 Realloc( length + 2 );
797 SlideString( this->buffer, 2 );
798 this->buffer[0] = '\n';
799 this->buffer[1] = '\n';
800}
801
802bool BasicSource::ReadFile( const string &filePath ){
803 if( !Text::ReadFile( filePath ) ){
804 return false;
805 }
806
807 // 改行コードをCRLFからLFに変換
808 ChangeReturnLineChar();
809
810 // basic.sbpをインクルード
811 const char *headCode = "#include <basic.sbp>\n";
812 Realloc( length + lstrlen(headCode) );
813 SlideString( buffer, lstrlen(headCode) );
814 memcpy( buffer, headCode, lstrlen(headCode) );
815
816 // #defineと#requireを初期化
817 objDefine.Init();
818 requireFiles.clear();
819
820 // コメントを削除
821 RemoveComments();
822
823 // #ifdefディレクティブを処理
824 objDefine.DirectiveIfdef( buffer );
825
826 //最終行には文字を含ませないようにする
827 Realloc( length + 1 );
828 lstrcat( buffer, "\n" );
829
830 // #include / #require ディレクティブを処理
831 DirectiveIncludeOrRequire();
832
833 // アンダーバーによる改行を正規表現に戻す
834 RemoveReturnLineUnderbar();
835
836 // ダミー改行をセット
837 Realloc( length + 2 );
838 SlideString( buffer, 2 );
839 buffer[0] = '\n';
840 buffer[1] = '\n';
841
842 extern char *basbuf;
843 basbuf = GetBuffer();
844
845 return true;
846}
847
848bool BasicSource::Generate( const string &genName, const char *genBuffer ){
849 const int genBufferLength = lstrlen( genBuffer );
850
851#ifdef _DEBUG
852 // 挿入ソースに改行コードが含まれていないかを検査する
853 for( int i=0; genBuffer[i] ; i++ ){
854 if( genBuffer[i] == '\n' ){
855 SetError();
856 break;
857 }
858 }
859#endif
860
861 bool isFound = false;
862
863 for( int i=0; ; i++ ){
864 if( i == 0 || buffer[i] == '\n' ){
865 if( buffer[i] == '\n' ){
866 i++;
867 }
868 while( IsBlank( buffer[i] ) ){
869 i++;
870 }
871
872 int startIndex = i;
873
874 if( memicmp( buffer + i, generateDirectiveName.c_str(), generateDirectiveName.size() ) == 0 ){
875 i += (int)generateDirectiveName.size();
876 while( IsBlank( buffer[i] ) ){
877 i++;
878 }
879
880 char temporary[VN_SIZE];
881 for( int i2=0; ; i++, i2++ ){
882 if( buffer[i] == '\n' ){
883 temporary[i2] = 0;
884 break;
885 }
886 temporary[i2] = buffer[i];
887 }
888 if( genName == temporary ){
889 // 一致
890
891 int endIndex = i;
892
893 int lengthOffset = genBufferLength - ( endIndex - startIndex );
894
895 Realloc( length + lengthOffset );
896 SlideString( buffer + endIndex, lengthOffset );
897 memcpy( buffer + startIndex, genBuffer, genBufferLength );
898
899 isFound = true;
900
901 break;
902 }
903 }
904 }
905 }
906
907 return isFound;
908}
909
910void BasicSource::Addition( const char *buffer ){
911 Realloc( length + lstrlen(buffer) );
912 lstrcat( this->buffer, buffer );
913}
Note: See TracBrowser for help on using the repository browser.