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

Last change on this file since 700 was 700, checked in by イグトランス (egtra), 16 years ago

CRequireFilesの管理をhash_setベースへ。保存時にFileIndexの記録を行っていなかった問題を修正。rev.669でコミットし忘れのcompiler_x86/NumOpe.cppを追加。

File size: 21.7 KB
Line 
1#include "stdafx.h"
2#include <hash_set>
3
4const std::string BasicSource::generateDirectiveName = "#generate";
5
6
7class CDefine{
8 std::vector<std::string> names;
9public:
10 void Free();
11 void Init( bool isDebug, bool isDll, bool isUnicode, int majorVer );
12
13 BOOL add(char const *name);
14 BOOL undef(char const *name);
15 BOOL check(char const *name);
16 void preprocessor_ifdef(char *buffer,bool isNot);
17 void DirectiveIfdef(char *buffer);
18};
19CDefine objDefine;
20
21
22//////////////////////////////////////
23// #requireの管理
24//////////////////////////////////////
25namespace
26{
27class CRequireFiles{
28 stdext::hash_set<std::string> filepaths;
29public:
30 void clear(){
31 filepaths.clear();
32 }
33 //既に存在するものを追加しようとするとfalseを返す(旧IsIncludedと逆なことに注意)
34 bool TryAdd( const std::string &includeFilePath ){
35 char tempPath[MAX_PATH];
36 DWORD len = GetShortPathName(includeFilePath.c_str(), tempPath, MAX_PATH);
37 if (len >= MAX_PATH){
38 return false;
39 }
40 for( DWORD i = 0; i < len; ++i ){
41 char c = toupper(tempPath[i]);
42 if (c == '/'){
43 tempPath[i] = '\\';
44 }
45 else{
46 tempPath[i] = c;
47 }
48 }
49 return filepaths.insert( tempPath ).second;
50 }
51};
52CRequireFiles requireFiles;
53} //namespace
54
55//////////////////////////////////////
56// #define間するクラス
57//////////////////////////////////////
58
59void CDefine::Init( bool isDebug, bool isDll, bool isUnicode, int majorVer )
60{
61 names.clear();
62
63 if( isDebug )
64 {
65 add("_DEBUG");
66 }
67
68#ifdef _AMD64_
69 add("_WIN64");
70#endif
71
72 if( isDll )
73 {
74 add("_DLL");
75 }
76
77 if( isUnicode )
78 {
79 add( "UNICODE" );
80 }
81
82 char temporary[255];
83 sprintf(temporary,"_AB_VER%d",majorVer);
84 add(temporary);
85}
86BOOL CDefine::add(char const *name)
87{
88 //重複チェック
89 if(check(name)) return 0;
90
91 //追加
92 names.push_back( name );
93
94 return 1;
95}
96BOOL CDefine::undef(char const *name){
97 std::vector<std::string>::iterator i = names.begin();
98 BOOST_FOREACH( const std::string &temp, names ){
99 if( temp == name ){
100 names.erase( i );
101 return 1;
102 }
103 i++;
104 }
105
106 return 0;
107}
108BOOL CDefine::check(char const *name){
109
110 //重複チェック
111 BOOST_FOREACH( const std::string &temp, names ){
112 if( temp == name ){
113 return 1;
114 }
115 }
116 return 0;
117}
118
119int Search_endif(char const *buffer,int i, int *pLine = 0){
120 for(;;i++){
121 if(buffer[i]=='\0') break;
122
123 if( buffer[i] == '\n' ){
124 if( pLine ){
125 (*pLine)++;
126 }
127 }
128
129 if(buffer[i-1]=='\n'){
130 if(_memicmp(buffer+i,"#ifdef",6)==0||_memicmp(buffer+i,"#ifndef",7)==0){
131 i=Search_endif(buffer,i+6, pLine);
132 if(buffer[i]=='\0') break;
133 continue;
134 }
135 else if(_memicmp(buffer+i,"#endif",6)==0){
136 break;
137 }
138 }
139 }
140 return i;
141}
142
143void CDefine::preprocessor_ifdef(char *buffer,bool isNot){
144 int i,i2,i3;
145 char temporary[VN_SIZE];
146
147 if(isNot) i=strlen("#ifndef");
148 else i=strlen("#ifdef");
149 while(buffer[i]==' '||buffer[i]=='\t') i++;
150
151 for(i2=0;;i++,i2++){
152 if(buffer[i]=='\n'||buffer[i]=='\0'){
153 temporary[i2]=0;
154 break;
155 }
156 temporary[i2]=buffer[i];
157 }
158
159 int sw=0;
160 if(check(temporary)) sw=1;
161
162 if(isNot){
163 //#ifndefのとき(反対にする)
164 if(sw) sw=0;
165 else sw=1;
166 }
167
168 //#ifdefの行を消去
169 Text::SlideString(buffer+i,-i);
170 i=0;
171
172 BOOL bElse=0;
173 if(sw){
174 //TRUEのとき
175
176 //#else、#endifを探索
177 for(;;i++){
178 if(buffer[i]=='\0') break;
179
180 if(i==0||buffer[i-1]=='\n'){
181 if(memicmp(buffer+i,"#ifdef",6)==0||memicmp(buffer+i,"#ifndef",7)==0){
182 i=Search_endif(buffer,i+6);
183 if(buffer[i]=='\0') break;
184 continue;
185 }
186 else if(memicmp(buffer+i,"#else",5)==0){
187 i2=5;
188 bElse=1;
189 break;
190 }
191 else if(memicmp(buffer+i,"#endif",6)==0){
192 i2=6;
193 bElse=0;
194 break;
195 }
196 }
197 }
198
199 //行を消去
200 Text::SlideString(buffer+i+i2,-i2);
201
202 if(bElse){
203 //#elseがある場合はその区間を消去
204
205 for(i2=i,i3=0;;i2++){
206 if(buffer[i2]=='\0') break;
207
208 if(buffer[i2]=='\n') i3++;
209
210 if(i2==0||buffer[i2-1]=='\n'){
211 if(memicmp(buffer+i2,"#ifdef",6)==0||memicmp(buffer+i2,"#ifndef",7)==0){
212 i2=Search_endif(buffer,i2+6, &i3 );
213 if(buffer[i2]=='\0') break;
214 continue;
215 }
216 if(memicmp(buffer+i2,"#endif",6)==0){
217 i2+=6;
218 break;
219 }
220 }
221 }
222
223 //ソースコード区間を消去し、改行コードを挿入
224 Text::SlideString(buffer+i2,i-i2+i3);
225 memset(buffer+i,'\n',i3);
226 }
227 }
228 else{
229 //FALSEのとき
230
231 //#else、#endifを探索
232 for(i2=i,i3=0;;i2++){
233 if(buffer[i2]=='\0') break;
234
235 if(buffer[i2]=='\n') i3++;
236
237 if(i2==0||buffer[i2-1]=='\n'){
238 if(memicmp(buffer+i2,"#ifdef",6)==0||memicmp(buffer+i2,"#ifndef",7)==0){
239 i2=Search_endif(buffer,i2+6, &i3 );
240 if(buffer[i2]=='\0') break;
241 continue;
242 }
243 else if(memicmp(buffer+i2,"#else",5)==0){
244 i2+=5;
245 bElse=1;
246 break;
247 }
248 else if(memicmp(buffer+i2,"#endif",6)==0){
249 i2+=6;
250 bElse=0;
251 break;
252 }
253 }
254 }
255
256 //ソースコード区間を消去し、改行コードを挿入
257 Text::SlideString(buffer+i2,i-i2+i3);
258 memset(buffer+i,'\n',i3);
259
260 if(bElse){
261 //#endifを探索
262 for(;;i++){
263 if(buffer[i]=='\0') break;
264
265 if(i==0||buffer[i-1]=='\n'){
266 if(memicmp(buffer+i,"#ifdef",6)==0||memicmp(buffer+i,"#ifndef",7)==0){
267 i=Search_endif(buffer,i+6);
268 if(buffer[i]=='\0') break;
269 continue;
270 }
271 else if(memicmp(buffer+i,"#endif",6)==0){
272 i2=6;
273 bElse=0;
274 break;
275 }
276 }
277 }
278
279 //行を消去
280 Text::SlideString(buffer+i+i2,-i2);
281 }
282 }
283}
284
285
286void CDefine::DirectiveIfdef(char *buffer){
287 int i,i2,i3,sw;
288 char temporary[VN_SIZE];
289
290 for(i=0;;i++){
291 if(buffer[i]=='\0') break;
292
293 if(i==0||(i>=1&&buffer[i-1]=='\n')){
294 sw=0;
295 if(memicmp(buffer+i,"#define",7)==0){
296 i2=i+7;
297 while(buffer[i2]==' '||buffer[i2]=='\t') i2++;
298
299 for(i3=0;;i2++,i3++){
300 if(buffer[i2]=='\n'||buffer[i2]=='\0'){
301 temporary[i3]=0;
302 break;
303 }
304 temporary[i3]=buffer[i2];
305 }
306
307 add(temporary);
308
309 i2-=i;
310
311 //ディレクティブを消去
312 Text::SlideString(buffer+i+i2,-i2);
313 }
314 if(memicmp(buffer+i,"#undef",6)==0){
315 i2=i+7;
316 while(buffer[i2]==' '||buffer[i2]=='\t') i2++;
317
318 for(i3=0;;i2++,i3++){
319 if(buffer[i2]=='\n'||buffer[i2]=='\0'){
320 temporary[i3]=0;
321 break;
322 }
323 temporary[i3]=buffer[i2];
324 }
325
326 undef(temporary);
327
328 i2-=i;
329
330 //ディレクティブを消去
331 Text::SlideString(buffer+i+i2,-i2);
332 }
333 else if(memicmp(buffer+i,"#ifdef",6)==0){
334 preprocessor_ifdef(buffer+i,false);
335 continue;
336 }
337 else if(memicmp(buffer+i,"#ifndef",7)==0){
338 preprocessor_ifdef(buffer+i,true);
339 continue;
340 }
341 else continue;
342 }
343 }
344}
345
346
347
348
349bool Text::ReadFile( const std::string &filePath ){
350 //ファイルオープン
351 HANDLE hFile=CreateFile(filePath.c_str(),GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
352 if(hFile==INVALID_HANDLE_VALUE){
353 return false;
354 }
355
356 length = GetFileSize( hFile, NULL );
357
358 buffer = (char *)realloc( buffer, length + 1 );
359
360 //読み込み
361 DWORD dwAccBytes;
362 ::ReadFile(hFile,buffer,length,&dwAccBytes,0);
363 buffer[dwAccBytes]=0;
364
365 //ファイルクローズ
366 CloseHandle(hFile);
367
368 return true;
369}
370
371void BasicSource::ChangeReturnLineChar(){
372 int i,i2;
373
374 bool isMustChange = false;
375 for( i=0; ; i++ ){
376 if( buffer[i] == '\0' ){
377 break;
378 }
379 if( buffer[i]=='\n' )
380 {
381 if( i>0 )
382 {
383 if( buffer[i-1] == '\r' )
384 {
385 isMustChange = true;
386 }
387 }
388 }
389 }
390
391 if( !isMustChange )
392 {
393 // 改行コードの変換は必要ない
394 return;
395 }
396
397#ifdef _DEBUG
398 //改行コードの整合性チェック
399 for( i=0; ; i++ ){
400 if( buffer[i] == '\0' ){
401 break;
402 }
403 if( buffer[i]!='\r' && buffer[i+1]=='\n'
404 || buffer[i]=='\r' && buffer[i+1]!='\n' ){
405 char temporary[255];
406 strncpy( temporary, buffer + i-100, 130 );
407 temporary[130] = 0;
408 for(int i2=0; ;i2++){
409 if(temporary[i2]=='\r') temporary[i2]='A';
410 if(temporary[i2]=='\n') temporary[i2]='B';
411 if(temporary[i2]=='\0') break;
412 }
413
414 extern HWND hOwnerEditor;
415 MessageBox( hOwnerEditor, temporary, "改行コードの整合性チェック", MB_OK | MB_ICONEXCLAMATION );
416 }
417 }
418#endif
419
420 //改行コードのCRLFをLFに変換
421 for(i=0,i2=0;;i++,i2++){
422 if(buffer[i]=='\r'&&buffer[i+1]=='\n') i++;
423 buffer[i2]=buffer[i];
424 if(buffer[i]=='\0') break;
425 }
426
427 length = i;
428}
429
430void BasicSource::RemoveComments(){
431 int i,i2,i3,IsStr;
432 char *temporary=static_cast<char *>(malloc(strlen(buffer)+1));
433 for(i=0,i2=0,i3=0,IsStr=0;;i++,i2++){
434 if(buffer[i]=='\"') IsStr^=1;
435 if(buffer[i]=='\n'||buffer[i]=='\0'){
436 i2--;
437 while(temporary[i2]==' '||temporary[i2]=='\t') i2--;
438 i2++;
439
440 if(i3){
441 //複数行に渡る注釈文の中に改行が存在するとき
442 memset(temporary+i2,'\n',i3);
443 i2+=i3;
444 i3=0;
445 }
446 }
447 if(buffer[i]=='\''&&IsStr==0){
448 //注釈文
449 i2--;
450 while(temporary[i2]==' '||temporary[i2]=='\t') i2--;
451 i2++;
452 while(buffer[i]!='\n'&&buffer[i]!='\0') i++;
453 }
454 if(buffer[i]=='/'&&buffer[i+1]=='*'&&IsStr==0){
455 //注釈文(複数行)
456 i+=2;
457 i3=0;
458 while(!(buffer[i]=='*'&&buffer[i+1]=='/')){
459 if(buffer[i]=='\n') i3++;
460 if(buffer[i]=='\0') break;
461 i++;
462 }
463 if(buffer[i]){
464 i+=2;
465 }
466 i--;
467 i2--;
468 continue;
469 }
470 temporary[i2]=buffer[i];
471 if(buffer[i]=='\0') break;
472 }
473 strcpy(buffer,temporary);
474 free(temporary);
475}
476
477bool BasicSource::ReadFile_InIncludeDirective( const std::string &filePath ){
478 if( !Text::ReadFile( filePath ) ){
479 return false;
480 }
481
482 // 改行コードをCRLFからLFに変換
483 ChangeReturnLineChar();
484
485 // コメントを削除
486 RemoveComments();
487
488 // #ifdefディレクティブを処理
489 objDefine.DirectiveIfdef( buffer );
490
491 // アンダーバーによる改行を正規表現に戻す
492 RemoveReturnLineUnderbar();
493
494 // ダミー改行をセット
495 Realloc( length + 2 );
496 Text::SlideString( buffer, 2 );
497 buffer[0] = '\n';
498 buffer[1] = '\n';
499
500 return true;
501}
502
503void BasicSource::DirectiveIncludeOrRequire( const std::string &mainSourceFilePath, const std::string &includeDirPath )
504{
505 int i,i2,i3,sw1,LineNum,FileLayer[255],layer,LastFileByte[255];
506 char temporary[MAX_PATH],temp2[MAX_PATH+255],*LayerDir[255];
507
508 layer=0;
509 FileLayer[layer]=0;
510 LastFileByte[layer]=GetLength();
511 LineNum=0;
512
513 if( includedFilesRelation.GetLineCounts() != 0 )
514 {
515 Jenga::Throw( "インクルードファイル構造の初期値が不正" );
516 }
517
518 // メインソースコード
519 FileLayer[layer] = includedFilesRelation.AddFile( mainSourceFilePath );
520
521 //参照ディレクトリ
522 std::string mainSourceFileDir = Jenga::Common::Path::ExtractDirPath( mainSourceFilePath );
523 LayerDir[0]=(char *)malloc(mainSourceFileDir.size()+1);
524 strcpy(LayerDir[0],mainSourceFileDir.c_str());
525
526 for(i=0;;i++){
527 if(buffer[i]=='\0'){
528 break;
529 }
530 if(buffer[i]=='\n'){
531 includedFilesRelation.AddLine( FileLayer[layer] );
532 }
533 if(i>LastFileByte[layer]){
534 free(LayerDir[layer]);
535 LayerDir[layer]=0;
536 layer--;
537 }
538 if((buffer[i-1]=='\n'||i==0)&&buffer[i]=='#'){
539 bool isRequire = false;
540
541 int includeDirectiveLength;
542
543 char findStr[1024];
544 if(memcmp( buffer + i + 1, "include", 7 ) == 0
545 || memcmp( buffer + i + 1, "require", 7 ) == 0)
546 {
547 //#requireの場合
548 if( buffer[i + 1] == 'r' ) isRequire = true;
549
550 i2=i+8;
551 while(buffer[i2]==' '||buffer[i2]=='\t') i2++;
552
553 if(buffer[i2]=='\"') sw1=0;
554 else if(buffer[i2]=='<') sw1=1;
555 i2++;
556
557 for(i3=0;;i2++,i3++){
558 if((buffer[i2]=='\"'&&sw1==0)||(buffer[i2]=='>'&&sw1==1)||buffer[i2]=='\n'||buffer[i2]=='\0'){
559 temporary[i3]=0;
560 break;
561 }
562 temporary[i3]=buffer[i2];
563 }
564 while(buffer[i2]!='\n'&&buffer[i2]!='\0') i2++;
565
566 includeDirectiveLength = i2 - i;
567
568 if(sw1){
569 sprintf(temp2,"%s\\%s", includeDirPath.c_str(), temporary );
570 strcpy(findStr,temp2);
571 }
572 else{
573 Jenga::Common::Directory dir( LayerDir[layer] );
574 strcpy( findStr, dir.GetFullPath( temporary ).c_str() );
575 }
576 }
577 else if(memcmp(buffer+i+1,"prompt",6)==0){
578 includeDirectiveLength = 7;
579 sprintf(findStr,"%s\\basic\\prompt.sbp", includeDirPath.c_str() );
580 }
581 else if(memcmp(buffer+i+1,"N88BASIC",8)==0){
582 includeDirectiveLength = 9;
583 sprintf(findStr,"%s\\basic\\prompt.sbp", includeDirPath.c_str() );
584 }
585 else if(memcmp(buffer+i+1,"console",7)==0){
586 //サブシステム タイプをCUIに変更
587 extern unsigned short TypeOfSubSystem;
588 TypeOfSubSystem=IMAGE_SUBSYSTEM_WINDOWS_CUI;
589
590 includeDirectiveLength = 8;
591 sprintf(findStr,"%s\\basic\\dos_console.sbp", includeDirPath.c_str() );
592 }
593 else continue;
594
595 // インクルードファイルを列挙(ワイルドカード指定を想定)
596 Jenga::Common::Strings resultOfFullPath;
597// Jenga::Common::FileSystem::SearchFiles( resultOfFullPath, findStr );
598 resultOfFullPath.push_back(findStr);
599
600 if( resultOfFullPath.empty() )
601 {
602 this->cannotIncludePath = findStr;
603 this->cannotIncludeSourcePos = i;
604 includedFilesRelation.AddLine( FileLayer[layer] );
605 break;
606 }
607
608 for( int j=static_cast<int>(resultOfFullPath.size()-1); j>=0; j-- )
609 {
610 const std::string &sourceFilePath = resultOfFullPath[j];
611
612 const int headIndex = i;
613
614 if( headIndex == 0 && Jenga::Common::Path( sourceFilePath ).GetFileName() == "basic" )
615 {
616 // basic.sbpインクルード時は何もしない
617 // ワイルドカードで複数ファイルを指定した場合、2つ目以上のファイルの場合もこちら
618 }
619 else
620 {
621 //ディレクティブが消えるため、一行減ってしまうのを防ぐ(basic.sbpを除く)
622 Text::SlideString( buffer + headIndex + includeDirectiveLength, 1 );
623 buffer[headIndex+includeDirectiveLength]='\n';
624 for(i3=0;i3<=layer;i3++) LastFileByte[i3]++;
625 }
626
627 layer++;
628 FileLayer[layer] = includedFilesRelation.AddFile( sourceFilePath );
629
630 //#requireの場合では、既に読み込まれているファイルは読み込まないようにする
631/*
632 bool isFake = false;
633 if( isRequire ){
634 if( requireFiles.TryAdd( sourceFilePath ) ){
635 //既に読み込まれているとき
636 isFake = true;
637 }
638 }
639
640 BasicSource source;
641
642 if( isFake ){
643 //既に読み込まれているときは空データ
644 source.SetBuffer( "" );
645 }
646 else{
647 //取り込まれたファイルを収集する
648 requireFiles.Add( sourceFilePath );
649
650 //インクルードファイルを読み込む
651 if( !source.ReadFile_InIncludeDirective( sourceFilePath ) )
652 {
653 throw;
654 }
655 }
656*/
657 BasicSource source;
658
659 if( !requireFiles.TryAdd( sourceFilePath ) && isRequire ){
660 //既に読み込まれているときは空データ
661 source.SetBuffer( "" );
662 }
663 else{
664 //インクルードファイルを読み込む
665 if( !source.ReadFile_InIncludeDirective( sourceFilePath ) )
666 {
667 throw;
668 }
669 }
670
671 Realloc( strlen(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 strcat(temp2,temp4);
686 LayerDir[layer]=(char *)malloc(strlen(temp2)+1);
687 strcpy(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 = strlen(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 = strlen(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( strlen(buffer)>0 && buffer[strlen(buffer)-1] != '\n' )
843 {
844 Realloc( length + 1 );
845 strcat( buffer, "\n" );
846 }
847
848 // アンダーバーによる改行を正規表現に戻す
849 RemoveReturnLineUnderbar();
850}
851
852void BasicSource::SetBuffer( const char *buffer ){
853 this->buffer = (char *)calloc( strlen(buffer) + 1, 1 );
854 strcpy( this->buffer, buffer );
855 length = strlen(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 + strlen(headCode) );
877 Text::SlideString( buffer, strlen(headCode) );
878 memcpy( buffer, headCode, strlen(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 strcat( 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 + strlen(buffer) );
915 strcat( 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.