source: dev/trunk/abdev/BasicCompiler_Common/src/Source.cpp@ 308

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

非仮想関数のオーバーライドをエラー扱いにした

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