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

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

smoothieプロジェクトが不要になったため、破棄。

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