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

Last change on this file since 754 was 739, checked in by dai, 16 years ago

BasicSource::GetLineFromIndex関数を導入。

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