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, 15 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.