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

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