source: dev/trunk/jenga/src/smoothie/Source.cpp@ 170

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

ベースを作成中...

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