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

Last change on this file since 467 was 467, checked in by dai_9181, 15 years ago

いくつかのグローバル変数をProgram/Debuggerクラスにまとめた。

File size: 22.5 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 BasicCurDir[MAX_PATH];
559    int i,i2,i3,sw1,LineNum,FileLayer[255],layer,LastFileByte[255];
560    char temporary[MAX_PATH],temp2[MAX_PATH+255],*LayerDir[255];
561
562    layer=0;
563    FileLayer[layer]=0;
564    LastFileByte[layer]=GetLength();
565    LineNum=0;
566
567    if( includedFilesRelation.GetLineCounts() != 0 )
568    {
569        Jenga::Throw( "インクルードファイル構造の初期値が不正" );
570    }
571
572    // メインソースコード
573    FileLayer[layer] = includedFilesRelation.AddFile( program.GetSourceFilePath() );
574
575    //参照ディレクトリ
576    LayerDir[0]=(char *)malloc(lstrlen(BasicCurDir)+1);
577    lstrcpy(LayerDir[0],BasicCurDir);
578
579    for(i=0;;i++){
580        if(buffer[i]=='\0'){
581            break;
582        }
583        if(buffer[i]=='\n'){
584            includedFilesRelation.AddLine( FileLayer[layer] );
585        }
586        if(i>LastFileByte[layer]){
587            free(LayerDir[layer]);
588            LayerDir[layer]=0;
589            layer--;
590        }
591        if((buffer[i-1]=='\n'||i==0)&&buffer[i]=='#'){
592            bool isRequire = false;
593            if(memcmp( buffer + i + 1, "include", 7 ) == 0
594                || memcmp( buffer + i + 1, "require", 7 ) == 0){
595
596                    //#requireの場合
597                    if( buffer[i + 1] == 'r' ) isRequire = true;
598
599                    i2=i+8;
600                    while(buffer[i2]==' '||buffer[i2]=='\t') i2++;
601
602                    if(buffer[i2]=='\"') sw1=0;
603                    else if(buffer[i2]=='<') sw1=1;
604                    i2++;
605
606                    for(i3=0;;i2++,i3++){
607                        if((buffer[i2]=='\"'&&sw1==0)||(buffer[i2]=='>'&&sw1==1)||buffer[i2]=='\n'||buffer[i2]=='\0'){
608                            temporary[i3]=0;
609                            break;
610                        }
611                        temporary[i3]=buffer[i2];
612                    }
613                    while(buffer[i2]!='\n'&&buffer[i2]!='\0') i2++;
614
615                    if(sw1){
616                        sprintf(temp2,"%s%s", program.GetIncludeDir().c_str(), temporary );
617                        lstrcpy(temporary,temp2);
618                    }
619                    else{
620                        Jenga::Common::Directory dir( LayerDir[layer] );
621                        lstrcpy( temporary, dir.GetFullPath( temporary ).c_str() );
622                    }
623            }
624            else if(memcmp(buffer+i+1,"prompt",6)==0){
625                i2=i+7;
626                sprintf(temporary,"%sbasic\\prompt.sbp", program.GetIncludeDir().c_str() );
627            }
628            else if(memcmp(buffer+i+1,"N88BASIC",8)==0){
629                i2=i+9;
630                sprintf(temporary,"%sbasic\\prompt.sbp", program.GetIncludeDir().c_str() );
631            }
632            else if(memcmp(buffer+i+1,"console",7)==0){
633                //サブシステム タイプをCUIに変更
634                extern unsigned short TypeOfSubSystem;
635                TypeOfSubSystem=IMAGE_SUBSYSTEM_WINDOWS_CUI;
636
637                i2=i+8;
638                sprintf(temporary,"%sbasic\\dos_console.sbp", program.GetIncludeDir().c_str() );
639            }
640            else continue;
641
642            if( i == 0 && Jenga::Common::Path(temporary).GetFileName() == "basic" )
643            {
644            }
645            else
646            {
647                //ディレクティブが消えるため、一行減ってしまうのを防ぐ(basic.sbpを除く)
648                Text::SlideString(buffer+i2,1);
649                buffer[i2]='\n';
650                for(i3=0;i3<=layer;i3++) LastFileByte[i3]++;
651            }
652
653            layer++;
654            FileLayer[layer] = includedFilesRelation.AddFile( temporary );
655
656            //#requireの場合では、既に読み込まれているファイルは読み込まないようにする
657            bool isFake = false;
658            if( isRequire ){
659                if( requireFiles.IsIncluded( temporary ) ){
660                    //既に読み込まれているとき
661                    isFake = true;
662                }
663            }
664
665            BasicSource source;
666
667            if( isFake ){
668                //既に読み込まれているときは空データ
669                source.SetBuffer( "" );
670            }
671            else{
672                //取り込まれたファイルを収集する
673                requireFiles.Add( temporary );
674
675                //インクルードファイルを読み込む
676                if( !source.ReadFile_InIncludeDirective( temporary ) ){
677                    sprintf(temp2,"インクルードファイル \"%s\" をオープンできません",temporary);
678                    compiler.errorMessenger.Output(-1,temp2,i);
679                    break;
680                }
681            }
682
683            i3=lstrlen(buffer)+source.GetLength();
684            Realloc( i3 );
685            Text::SlideString(buffer+i2,source.GetLength()+(i-i2));
686            memcpy(buffer+i,source.GetBuffer(),source.GetLength());
687
688            //新しい参照ディレクトリをセット
689            char temp4[MAX_PATH];
690            _splitpath(temporary,temp2,temp4,0,0);
691            lstrcat(temp2,temp4);
692            LayerDir[layer]=(char *)malloc(lstrlen(temp2)+1);
693            lstrcpy(LayerDir[layer],temp2);
694
695            //ファイル範囲をスライド
696            LastFileByte[layer]=i+source.GetLength()-1;
697            for(i3=0;i3<layer;i3++) LastFileByte[i3]+=source.GetLength()+(i-i2);
698
699            i--;
700        }
701    }
702
703    free(LayerDir[0]);
704
705    length = lstrlen(buffer);
706}
707
708int KillReturnCode_InParameter(char *buffer,int *pRnum,char cBeginPare,char cEndPare){
709    int i,i2,i3,IsStr;
710
711    //カッコ'('直下の改行
712    while(buffer[0]=='\n'){
713        Text::SlideString(buffer+1,-1);
714        (*pRnum)++;
715    }
716
717    for(i=0,IsStr=0;;i++){
718        if(IsDBCSLeadByte(buffer[i])&&buffer[i+1]){
719            i++;
720            continue;
721        }
722
723        if(buffer[i]=='\"') IsStr^=1;
724
725        if(buffer[i]=='\0') break;  //エラー
726        if(buffer[i]=='\n'){
727            i2=0;
728            i3=0;
729            while(buffer[i+i2]=='\n'){
730                i2++;
731                i3++;
732                while(buffer[i+i2]==' '||buffer[i+i2]=='\t') i2++;
733            }
734            while(buffer[i+i2]==' '||buffer[i+i2]=='\t') i2++;
735
736            if(buffer[i+i2]==cEndPare){
737                Text::SlideString(buffer+i+i2,-i2);
738                (*pRnum)+=i3;
739                break;
740            }
741
742            //エラー
743            break;
744        }
745
746        if(buffer[i]=='('&&IsStr==0){
747            i++;
748            i2=KillReturnCode_InParameter(buffer+i,pRnum,'(',')');
749            i+=i2;
750            if(buffer[i]!=')') break;
751            continue;
752        }
753        if(buffer[i]=='['&&IsStr==0){
754            i++;
755            i2=KillReturnCode_InParameter(buffer+i,pRnum,'[',']');
756            i+=i2;
757            if(buffer[i]!=']') break;
758            continue;
759        }
760        if(buffer[i]==cEndPare&&IsStr==0) break;
761
762        if(buffer[i]==','&&buffer[i+1]=='\n'&&IsStr==0){
763            i++;
764            while(buffer[i]=='\n'){
765                Text::SlideString(buffer+i+1,-1);
766                (*pRnum)++;
767            }
768            i--;
769        }
770    }
771    return i;
772}
773void BasicSource::RemoveReturnLineUnderbar(){
774    int i,i2;
775
776    //アンダーバーによる改行
777    for(i=0;;i++){
778        i2=0;
779        while(buffer[i]=='_'&&buffer[i+1]=='\n'){
780            i2++;
781            Text::SlideString(buffer+i+2,-2);
782            while(buffer[i]=='\n'){
783                Text::SlideString(buffer+i+1,-1);
784                i2++;
785            }
786            for(;;i++){
787                if(buffer[i]=='_'&&buffer[i+1]=='\n') break;
788                if(buffer[i]=='\n'||buffer[i]=='\0'){
789                    Text::SlideString(buffer+i,i2);
790                    memset(buffer+i,'\n',i2);
791                    break;
792                }
793            }
794        }
795        if(buffer[i]=='\0') break;
796    }
797
798    //カッコ内パラメータの改行
799    int IsStr,rnum;
800    for(i=0,IsStr=0,rnum=0;;i++){
801        if(IsDBCSLeadByte(buffer[i])&&buffer[i+1]){
802            i++;
803            continue;
804        }
805        if(buffer[i]=='\0') break;
806        if(buffer[i]=='\n'){
807            if(rnum){
808                Text::SlideString(buffer+i+1,rnum);
809                memset(buffer+i+1,'\n',rnum);
810                rnum=0;
811            }
812        }
813        if(buffer[i]=='\"') IsStr^=1;
814        if(buffer[i]=='('&&IsStr==0){
815            i++;
816            i2=KillReturnCode_InParameter(buffer+i,&rnum,'(',')');
817            i+=i2;
818            if(buffer[i]!=')') break;
819        }
820        if(buffer[i]=='['&&IsStr==0){
821            i++;
822            i2=KillReturnCode_InParameter(buffer+i,&rnum,'[',']');
823            i+=i2;
824            if(buffer[i]!=']') break;
825        }
826    }
827
828    length = lstrlen(buffer);
829}
830
831void BasicSource::Initialize( const std::string &source )
832{
833    Clear();
834    Add( source );
835
836    // 改行コードをCRLFからLFに変換
837    ChangeReturnLineChar();
838
839    // コメントを削除
840    RemoveComments();
841
842    //最終行には文字を含ませないようにする
843    if( lstrlen(buffer)>0 && buffer[lstrlen(buffer)-1] != '\n' )
844    {
845        Realloc( length + 1 );
846        lstrcat( buffer, "\n" );
847    }
848
849    // アンダーバーによる改行を正規表現に戻す
850    RemoveReturnLineUnderbar();
851}
852
853void BasicSource::SetBuffer( const char *buffer ){
854    this->buffer = (char *)calloc( lstrlen(buffer) + 1, 1 );
855    lstrcpy( this->buffer, buffer );
856    length = lstrlen(buffer);
857
858    // ダミー改行をセット
859    Realloc( length + 2 );
860    Text::SlideString( this->buffer, 2 );
861    this->buffer[0] = '\n';
862    this->buffer[1] = '\n';
863}
864
865bool BasicSource::ReadFile( const string &filePath ){
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(0);
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();
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
913bool BasicSource::Generate( const string &genName, const char *genBuffer ){
914    const int genBufferLength = lstrlen( genBuffer );
915
916#ifdef _DEBUG
917    // 挿入ソースに改行コードが含まれていないかを検査する
918    for( int i=0; genBuffer[i] ; i++ ){
919        if( genBuffer[i] == '\n' ){
920            compiler.errorMessenger.OutputFatalError();
921            break;
922        }
923    }
924#endif
925
926    bool isFound = false;
927
928    for( int i=0; ; i++ ){
929        if( i == 0 || buffer[i] == '\n' ){
930            if( buffer[i] == '\n' ){
931                i++;
932            }
933            while( IsBlank( buffer[i] ) ){
934                i++;
935            }
936
937            int startIndex = i;
938
939            if( memicmp( buffer + i, generateDirectiveName.c_str(), generateDirectiveName.size() ) == 0 ){
940                i += (int)generateDirectiveName.size();
941                while( IsBlank( buffer[i] ) ){
942                    i++;
943                }
944
945                char temporary[VN_SIZE];
946                for( int i2=0; ; i++, i2++ ){
947                    if( buffer[i] == '\n' ){
948                        temporary[i2] = 0;
949                        break;
950                    }
951                    temporary[i2] = buffer[i];
952                }
953                if( genName == temporary ){
954                    // 一致
955
956                    int endIndex = i;
957
958                    int lengthOffset = genBufferLength - ( endIndex - startIndex );
959
960                    Realloc( length + lengthOffset );
961                    Text::SlideString( buffer + endIndex, lengthOffset );
962                    memcpy( buffer + startIndex, genBuffer, genBufferLength );
963
964                    isFound = true;
965
966                    break;
967                }
968            }
969        }
970    }
971
972    return isFound;
973}
974
975void BasicSource::Addition( const char *buffer ){
976    Realloc( length + lstrlen(buffer) );
977    lstrcat( this->buffer, buffer );
978}
979
980bool BasicSource::GetLineInfo( int sourceCodePos, int &line, std::string &filePath ) const
981{
982    int i2,i3,i4,i5;
983
984    const char *buffer = GetBuffer();
985    int i = sourceCodePos;
986
987    if(buffer[i]=='\n') i--;
988    for(i3=0,i2=0;i3<i;i3++){
989        if(buffer[i3]=='\n') i2++;
990        if(buffer[i3]=='\0') return 0;
991    }
992
993    if( includedFilesRelation.GetLineCounts() < i2 )
994    {
995        //Jenga::Throw( "BasicSource::GetLineInfoメソッドで不正な行の情報を取得しようとした" );
996
997        //ファイル・行番号を特定できなかった場合
998        line = -1;
999        filePath = "";
1000        return false;
1001    }
1002
1003    i4=0;
1004    while( includedFilesRelation.GetFileNumber( i2 ) != includedFilesRelation.GetFileNumber( i4 ) )
1005    {
1006        i4++;
1007    }
1008    for(i3=0,i5=0;i5<i4;i3++){
1009        if(buffer[i3]=='\n') i5++;
1010        if(buffer[i3]=='\0') return 0;
1011    }
1012    for(i5=0;i4<i2;i3++){
1013        if(buffer[i3]=='\n'){
1014            i4++;
1015            i5++;
1016            if( includedFilesRelation.GetFileNumber( i2 ) < includedFilesRelation.GetFileNumber( i4 ) )
1017            {
1018                for( ;includedFilesRelation.GetFileNumber( i2 ) != includedFilesRelation.GetFileNumber( i4 ); i3++ ){
1019                    if(buffer[i3]=='\n') i4++;
1020                }
1021            }
1022        }
1023        if(buffer[i3]=='\0') return 0;
1024    }
1025
1026    //行番号をセット
1027    line = i5;
1028
1029    //ファイル名をセット
1030    filePath = includedFilesRelation.GetFilePath( i2 );
1031
1032    return 1;
1033}
1034
1035
1036SourceTemplate::SourceTemplate( const std::string &filePath )
1037{
1038    Jenga::Common::File file = Jenga::Common::File( GetApplicationBaseFullPath( filePath ) );
1039    source = file.Read();
1040}
1041std::string SourceTemplate::GetResult( const std::map<std::string,std::string> &values )
1042{
1043    std::string result = source;
1044
1045    std::map<std::string,std::string>::const_iterator it = values.begin();
1046    while( it != values.end() )
1047    {
1048        while( true )
1049        {
1050            std::string::size_type index = result.find( it->first );
1051            if( index == std::string::npos )
1052            {
1053                break;
1054            }
1055
1056            result = result.substr( 0, index ) + it->second + result.substr( index + it->first.length() );
1057        }
1058        it++;
1059    }
1060
1061    return result;
1062}
Note: See TracBrowser for help on using the repository browser.