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

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

BasicSource::DirectiveIncludeOrRequire内で発生したエラーのエラー出力を呼び出し元で行うようにした。

File size: 20.4 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( !Jenga::Common::Path( temporary ).IsExistFile() )
624 {
625 this->cannotIncludePath = temporary;
626 this->cannotIncludeSourcePos = i;
627 includedFilesRelation.AddLine( FileLayer[layer] );
628 break;
629 }
630
631 if( i == 0 && Jenga::Common::Path(temporary).GetFileName() == "basic" )
632 {
633 }
634 else
635 {
636 //ディレクティブが消えるため、一行減ってしまうのを防ぐ(basic.sbpを除く)
637 Text::SlideString(buffer+i2,1);
638 buffer[i2]='\n';
639 for(i3=0;i3<=layer;i3++) LastFileByte[i3]++;
640 }
641
642 layer++;
643 FileLayer[layer] = includedFilesRelation.AddFile( temporary );
644
645 //#requireの場合では、既に読み込まれているファイルは読み込まないようにする
646 bool isFake = false;
647 if( isRequire ){
648 if( requireFiles.IsIncluded( temporary ) ){
649 //既に読み込まれているとき
650 isFake = true;
651 }
652 }
653
654 BasicSource source;
655
656 if( isFake ){
657 //既に読み込まれているときは空データ
658 source.SetBuffer( "" );
659 }
660 else{
661 //取り込まれたファイルを収集する
662 requireFiles.Add( temporary );
663
664 //インクルードファイルを読み込む
665 if( !source.ReadFile_InIncludeDirective( temporary ) )
666 {
667 throw;
668 }
669 }
670
671 i3=lstrlen(buffer)+source.GetLength();
672 Realloc( i3 );
673 Text::SlideString(buffer+i2,source.GetLength()+(i-i2));
674 memcpy(buffer+i,source.GetBuffer(),source.GetLength());
675
676 //新しい参照ディレクトリをセット
677 char temp4[MAX_PATH];
678 _splitpath(temporary,temp2,temp4,0,0);
679 lstrcat(temp2,temp4);
680 LayerDir[layer]=(char *)malloc(lstrlen(temp2)+1);
681 lstrcpy(LayerDir[layer],temp2);
682
683 //ファイル範囲をスライド
684 LastFileByte[layer]=i+source.GetLength()-1;
685 for(i3=0;i3<layer;i3++) LastFileByte[i3]+=source.GetLength()+(i-i2);
686
687 i--;
688 }
689 }
690
691 free(LayerDir[0]);
692
693 length = lstrlen(buffer);
694}
695
696int KillReturnCode_InParameter(char *buffer,int *pRnum,char cBeginPare,char cEndPare){
697 int i,i2,i3,IsStr;
698
699 //カッコ'('直下の改行
700 while(buffer[0]=='\n'){
701 Text::SlideString(buffer+1,-1);
702 (*pRnum)++;
703 }
704
705 for(i=0,IsStr=0;;i++){
706 if(IsDBCSLeadByte(buffer[i])&&buffer[i+1]){
707 i++;
708 continue;
709 }
710
711 if(buffer[i]=='\"') IsStr^=1;
712
713 if(buffer[i]=='\0') break; //エラー
714 if(buffer[i]=='\n'){
715 i2=0;
716 i3=0;
717 while(buffer[i+i2]=='\n'){
718 i2++;
719 i3++;
720 while(buffer[i+i2]==' '||buffer[i+i2]=='\t') i2++;
721 }
722 while(buffer[i+i2]==' '||buffer[i+i2]=='\t') i2++;
723
724 if(buffer[i+i2]==cEndPare){
725 Text::SlideString(buffer+i+i2,-i2);
726 (*pRnum)+=i3;
727 break;
728 }
729
730 //エラー
731 break;
732 }
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]=='['&&IsStr==0){
742 i++;
743 i2=KillReturnCode_InParameter(buffer+i,pRnum,'[',']');
744 i+=i2;
745 if(buffer[i]!=']') break;
746 continue;
747 }
748 if(buffer[i]==cEndPare&&IsStr==0) break;
749
750 if(buffer[i]==','&&buffer[i+1]=='\n'&&IsStr==0){
751 i++;
752 while(buffer[i]=='\n'){
753 Text::SlideString(buffer+i+1,-1);
754 (*pRnum)++;
755 }
756 i--;
757 }
758 }
759 return i;
760}
761void BasicSource::RemoveReturnLineUnderbar(){
762 int i,i2;
763
764 //アンダーバーによる改行
765 for(i=0;;i++){
766 i2=0;
767 while(buffer[i]=='_'&&buffer[i+1]=='\n'){
768 i2++;
769 Text::SlideString(buffer+i+2,-2);
770 while(buffer[i]=='\n'){
771 Text::SlideString(buffer+i+1,-1);
772 i2++;
773 }
774 for(;;i++){
775 if(buffer[i]=='_'&&buffer[i+1]=='\n') break;
776 if(buffer[i]=='\n'||buffer[i]=='\0'){
777 Text::SlideString(buffer+i,i2);
778 memset(buffer+i,'\n',i2);
779 break;
780 }
781 }
782 }
783 if(buffer[i]=='\0') break;
784 }
785
786 //カッコ内パラメータの改行
787 int IsStr,rnum;
788 for(i=0,IsStr=0,rnum=0;;i++){
789 if(IsDBCSLeadByte(buffer[i])&&buffer[i+1]){
790 i++;
791 continue;
792 }
793 if(buffer[i]=='\0') break;
794 if(buffer[i]=='\n'){
795 if(rnum){
796 Text::SlideString(buffer+i+1,rnum);
797 memset(buffer+i+1,'\n',rnum);
798 rnum=0;
799 }
800 }
801 if(buffer[i]=='\"') IsStr^=1;
802 if(buffer[i]=='('&&IsStr==0){
803 i++;
804 i2=KillReturnCode_InParameter(buffer+i,&rnum,'(',')');
805 i+=i2;
806 if(buffer[i]!=')') break;
807 }
808 if(buffer[i]=='['&&IsStr==0){
809 i++;
810 i2=KillReturnCode_InParameter(buffer+i,&rnum,'[',']');
811 i+=i2;
812 if(buffer[i]!=']') break;
813 }
814 }
815
816 length = lstrlen(buffer);
817}
818
819void BasicSource::Initialize( const std::string &source )
820{
821 Clear();
822 Add( source );
823
824 // 改行コードをCRLFからLFに変換
825 ChangeReturnLineChar();
826
827 // コメントを削除
828 RemoveComments();
829
830 //最終行には文字を含ませないようにする
831 if( lstrlen(buffer)>0 && buffer[lstrlen(buffer)-1] != '\n' )
832 {
833 Realloc( length + 1 );
834 lstrcat( buffer, "\n" );
835 }
836
837 // アンダーバーによる改行を正規表現に戻す
838 RemoveReturnLineUnderbar();
839}
840
841void BasicSource::SetBuffer( const char *buffer ){
842 this->buffer = (char *)calloc( lstrlen(buffer) + 1, 1 );
843 lstrcpy( this->buffer, buffer );
844 length = lstrlen(buffer);
845
846 // ダミー改行をセット
847 Realloc( length + 2 );
848 Text::SlideString( this->buffer, 2 );
849 this->buffer[0] = '\n';
850 this->buffer[1] = '\n';
851}
852
853bool BasicSource::ReadFile( const std::string &filePath, bool isDebug, bool isDll, bool isUnicode, int majorVer ){
854 if( !Text::ReadFile( filePath ) ){
855 return false;
856 }
857
858 // 改行コードをCRLFからLFに変換
859 ChangeReturnLineChar();
860
861 // basic.sbpをインクルード
862 //const char *headCode = "#include <basic.sbp>\n";
863 const char *headCode = "";
864 Realloc( length + lstrlen(headCode) );
865 Text::SlideString( buffer, lstrlen(headCode) );
866 memcpy( buffer, headCode, lstrlen(headCode) );
867
868 // #defineと#requireを初期化
869 // TODO: バージョン番号の識別子defineが未完成
870 objDefine.Init( isDebug, isDll, isUnicode, majorVer );
871 requireFiles.clear();
872
873 // コメントを削除
874 RemoveComments();
875
876 // #ifdefディレクティブを処理
877 objDefine.DirectiveIfdef( buffer );
878
879 //最終行には文字を含ませないようにする
880 Realloc( length + 1 );
881 lstrcat( buffer, "\n" );
882
883 // #include / #require ディレクティブを処理
884 DirectiveIncludeOrRequire();
885
886 // アンダーバーによる改行を正規表現に戻す
887 RemoveReturnLineUnderbar();
888
889 // ダミー改行をセット
890 Realloc( length + 2 );
891 Text::SlideString( buffer, 2 );
892 buffer[0] = '\n';
893 buffer[1] = '\n';
894
895 extern char *basbuf;
896 basbuf = GetBuffer();
897
898 return true;
899}
900
901void BasicSource::Addition( const char *buffer ){
902 Realloc( length + lstrlen(buffer) );
903 lstrcat( this->buffer, buffer );
904}
905
906bool BasicSource::GetLineInfo( int sourceCodePos, int &line, std::string &filePath ) const
907{
908 int i2,i3,i4,i5;
909
910 const char *buffer = GetBuffer();
911 int i = sourceCodePos;
912
913 if(buffer[i]=='\n') i--;
914 for(i3=0,i2=0;i3<i;i3++){
915 if(buffer[i3]=='\n') i2++;
916 if(buffer[i3]=='\0') return 0;
917 }
918
919 if( includedFilesRelation.GetLineCounts() < i2 )
920 {
921 //Jenga::Throw( "BasicSource::GetLineInfoメソッドで不正な行の情報を取得しようとした" );
922
923 //ファイル・行番号を特定できなかった場合
924 line = -1;
925 filePath = "";
926 return false;
927 }
928
929 i4=0;
930 while( includedFilesRelation.GetFileNumber( i2 ) != includedFilesRelation.GetFileNumber( i4 ) )
931 {
932 i4++;
933 }
934 for(i3=0,i5=0;i5<i4;i3++){
935 if(buffer[i3]=='\n') i5++;
936 if(buffer[i3]=='\0') return 0;
937 }
938 for(i5=0;i4<i2;i3++){
939 if(buffer[i3]=='\n'){
940 i4++;
941 i5++;
942 if( includedFilesRelation.GetFileNumber( i2 ) < includedFilesRelation.GetFileNumber( i4 ) )
943 {
944 for( ;includedFilesRelation.GetFileNumber( i2 ) != includedFilesRelation.GetFileNumber( i4 ); i3++ ){
945 if(buffer[i3]=='\n') i4++;
946 }
947 }
948 }
949 if(buffer[i3]=='\0') return 0;
950 }
951
952 //行番号をセット
953 line = i5;
954
955 //ファイル名をセット
956 filePath = includedFilesRelation.GetFilePath( i2 );
957
958 return 1;
959}
Note: See TracBrowser for help on using the repository browser.