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

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

ヘッダファイルを整理中

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