source: dev/trunk/abdev/BasicCompiler_Common/src/Source.cpp@ 424

Last change on this file since 424 was 402, checked in by dai_9181, 17 years ago

UserProc::SetParamsAndReturnTypeメソッドをリファクタリング
LexicalAnalysis.hのインクルードを除去した

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