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

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

・Compiler::IsDebugメソッドを導入した(bDebugCompileグローバル変数は廃止)。
・bStrictグローバル変数は意味を成さないので廃止した。

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