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

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