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

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