source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/src/Source.cpp@ 554

Last change on this file since 554 was 554, checked in by dai_9181, 16 years ago

CDefine::Initメソッドで使用するCompilerクラス依存のフラグを外部から引き渡すようにした。

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