source: dev/trunk/ab5.0/abdev/ab_common/src/Lexical/Source.cpp@ 696

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

#require/#includeディレクティブにて、ワイルドカード指定を可能にした。

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