source: dev/trunk/abdev/BasicCompiler_Common/Compile.cpp@ 372

Last change on this file since 372 was 372, checked in by dai_9181, 16 years ago

Foreachステートメントを実装中…

File size: 17.7 KB
Line 
1#include "stdafx.h"
2
3#include <jenga/include/smoothie/Smoothie.h>
4#include <jenga/include/smoothie/LexicalAnalysis.h>
5#include <jenga/include/smoothie/SmoothieException.h>
6
7#include <LexicalScope.h>
8#include <CodeGenerator.h>
9#include <Compiler.h>
10#include <NamespaceSupporter.h>
11
12#include "../BasicCompiler_Common/common.h"
13
14#ifdef _AMD64_
15#include "../BasicCompiler64/opcode.h"
16#else
17#include "../BasicCompiler32/opcode.h"
18#endif
19
20#include <Exception.h>
21
22//With情報
23WITHINFO WithInfo;
24
25//デバッグ用行番号情報
26SourceLines oldSourceLines;
27
28
29
30///////////////////////////////////////////////////
31// トークンを取得
32///////////////////////////////////////////////////
33void GetIdentifierToken( char *token, const char *source, int &pos )
34{
35 for( int i=0; ; i++, pos++ ){
36 if( ! IsVariableChar( source[pos] ) ){
37 token[i] = 0;
38 break;
39 }
40 token[i] = source[pos];
41 }
42}
43void GetCommandToken( char *token, const char *source, int &pos )
44{
45 for( int i=0; ; i++, pos++ ){
46 if( IsCommandDelimitation( source[pos] ) ){
47 token[i] = 0;
48 break;
49 }
50 token[i] = source[pos];
51 }
52}
53
54
55///////////////////////////////////////////////////
56// ジェネリクスのクラス型記述を分析
57///////////////////////////////////////////////////
58void SplitGenericClassInstance( const char *fullName, char *className, Jenga::Common::Strings &typeParameters )
59{
60 int i = 0;
61 typeParameters.clear();
62
63 //クラス名を取得
64 GetIdentifierToken( className, fullName, i );
65
66
67 /////////////////////////////////////////////////////////
68 // ☆★☆ ジェネリクスサポート ☆★☆
69 if( fullName[i] == '<' )
70 {
71 while( true )
72 {
73 i++;
74
75 // 型パラメータを取得
76 char temporary[VN_SIZE];
77 GetIdentifierToken( temporary, fullName, i );
78 if( temporary[0] == '\0' )
79 {
80 extern int cp;
81 SetError(1,NULL,cp);
82 }
83
84 typeParameters.push_back( temporary );
85
86 if( fullName[i] == ',' )
87 {
88 continue;
89 }
90 else if( fullName[i] == '>' )
91 {
92 break;
93 }
94 else
95 {
96 extern int cp;
97 SetError(1,NULL,cp);
98 }
99 }
100 }
101 /////////////////////////////////////////////////////////
102}
103
104
105///////////////////////////////////////////////////
106// 対になっているステートメントを飛び越す
107// ※グローバル領域用
108///////////////////////////////////////////////////
109int JumpStatement(const char *source, int &pos){
110 if( source[pos] != 1 ) return 0;
111
112 if( ! IsCommandDelimitation( source[pos - 1] ) ){
113 //直前がコマンド区切りではない場合
114 return 0;
115 }
116
117 char cStatement = source[pos + 1];
118
119 char cEnd = GetEndXXXCommand( cStatement );
120 if( cEnd == 0 ) return 0;
121
122 pos += 2;
123 while( ! ( source[pos] == 1 && source[pos + 1] == cEnd ) ){
124
125 if( source[pos] == '\0' ){
126 char temporary[64];
127 GetDefaultNameFromES( cStatement, temporary );
128 SetError( 22, temporary, pos );
129 return -1;
130 }
131
132 pos++;
133 }
134 if( ! ( source[pos] == '\0' || source[pos + 2] == '\0' ) ){
135 pos += 2;
136 }
137
138 return 1;
139}
140
141void Compile( const char *source )
142{
143 char *temporary = (char *)malloc( lstrlen( source ) + 8192 );
144 lstrcpy( temporary, source );
145 int backCp = cp;
146 MakeMiddleCode( temporary );
147 ChangeOpcode( temporary );
148 cp = backCp;
149 free( temporary );
150}
151
152void ChangeOpcode(char *Command){
153 extern HANDLE hHeap;
154
155 if(Command[0]=='\0')
156 {
157 return;
158 }
159
160 trace_for_sourcecodestep( FormatEscapeSequenceStringToDefaultString(Command) );
161
162 if(Command[0]=='*'&&IsVariableTopChar(Command[1])){
163 //Goto先ラベル
164 compiler.codeGenerator.gotoLabels.push_back( GotoLabel( Command + 1, compiler.codeGenerator.GetNativeCodeSize() ) );
165
166 //書き込みスケジュール
167 GotoLabelSchedules::iterator it = compiler.codeGenerator.gotoLabelSchedules.begin();
168 while( it != compiler.codeGenerator.gotoLabelSchedules.end() )
169 {
170 if( (*it)->GetName() == Command+1 )
171 {
172 compiler.codeGenerator.opfix_JmpPertialSchedule( (*it) );
173
174 //詰める
175 it = compiler.codeGenerator.gotoLabelSchedules.erase( it );
176 }
177 else
178 {
179 it++;
180 }
181 }
182 return;
183 }
184 if(Command[0]==1){
185 switch(Command[1]){
186 case ESC_CONST:
187 OpcodeDim(Command+2, DIMFLAG_CONST);
188 break;
189
190 case ESC_TYPEDEF:
191 if( UserProc::IsLocalAreaCompiling() ){
192 // ローカル領域をコンパイルしているとき
193 SetError(65,"TypeDef",cp );
194 }
195
196 //既に収集済み
197 break;
198
199 case ESC_DELEGATE:
200 if( UserProc::IsLocalAreaCompiling() ){
201 // ローカル領域をコンパイルしているとき
202 SetError(65,"Delegate",cp );
203 }
204
205 //既に収集済み
206 break;
207
208 case ESC_STATIC:
209 OpcodeDim(Command+2,DIMFLAG_STATIC);
210 break;
211
212 case ESC_IF:
213 OpcodeIf(Command+2);
214 break;
215 case ESC_EXITWHILE:
216 {
217 LexicalScope *pScope = compiler.codeGenerator.lexicalScopes.SearchScope( LexicalScope::SCOPE_TYPE_WHILE );
218 if( !pScope ){
219 SetError(12,"Exit While",cp);
220 return;
221 }
222 pScope->Break();
223 }
224 break;
225 case ESC_EXITFOR:
226 {
227 LexicalScope *pScope = compiler.codeGenerator.lexicalScopes.SearchScope( LexicalScope::SCOPE_TYPE_FOR );
228 if( !pScope ){
229 SetError(12,"Exit For",cp);
230 return;
231 }
232 pScope->Break();
233 }
234 break;
235 case ESC_EXITDO:
236 {
237 LexicalScope *pScope = compiler.codeGenerator.lexicalScopes.SearchScope( LexicalScope::SCOPE_TYPE_DO );
238 if( !pScope ){
239 SetError(12,"Exit Do",cp);
240 return;
241 }
242 pScope->Break();
243 }
244 break;
245 case ESC_CONTINUE:
246 OpcodeContinue();
247 break;
248
249 case ESC_EXITSUB:
250 case ESC_EXITFUNCTION:
251 case ESC_EXITMACRO:
252 OpcodeExitSub();
253 break;
254
255 case ESC_SELECTCASE:
256 OpcodeSelect(Command+2);
257 break;
258 case ESC_CASE:
259 case ESC_CASEELSE:
260 OpcodeCase(Command+2);
261 break;
262
263 case ESC_WITH:
264 extern WITHINFO WithInfo;
265
266 WithInfo.ppName=(char **)HeapReAlloc(hHeap,0,WithInfo.ppName,(WithInfo.num+1)*sizeof(char **));
267 WithInfo.ppName[WithInfo.num]=(char *)HeapAlloc(hHeap,0,lstrlen(Command+2)+1);
268 lstrcpy(WithInfo.ppName[WithInfo.num],Command+2);
269
270 WithInfo.pWithCp=(int *)HeapReAlloc(hHeap,0,WithInfo.pWithCp,(WithInfo.num+1)*sizeof(int));
271 WithInfo.pWithCp[WithInfo.num]=cp;
272
273 WithInfo.num++;
274 break;
275 case ESC_ENDWITH:
276 if(WithInfo.num<=0){
277 SetError(12,"End With",cp);
278 return;
279 }
280 WithInfo.num--;
281 HeapDefaultFree(WithInfo.ppName[WithInfo.num]);
282 break;
283 case ESC_DECLARE:
284 if( UserProc::IsLocalAreaCompiling() ){
285 // ローカル領域をコンパイルしているとき
286 SetError(65,"Declare",cp );
287 }
288 break;
289
290 case ESC_NAMESPACE:
291 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes().push_back( Command + 2 );
292 break;
293 case ESC_ENDNAMESPACE:
294 if( compiler.GetNamespaceSupporter().GetLivingNamespaceScopes().size() <= 0 ){
295 SetError(12,"End Namespace",cp);
296 }
297 compiler.GetNamespaceSupporter().GetLivingNamespaceScopes().pop_back();
298 break;
299 case ESC_IMPORTS:
300 compiler.GetNamespaceSupporter().ImportsNamespace( Command + 2 );
301 break;
302 case ESC_CLEARNAMESPACEIMPORTED:
303 compiler.GetNamespaceSupporter().GetImportedNamespaces().clear();
304 break;
305
306 //Tryによる例外処理
307 case ESC_TRY:
308 Exception::TryCommand();
309 break;
310 case ESC_CATCH:
311 Exception::CatchCommand( Command + 2 );
312 break;
313 case ESC_FINALLY:
314 Exception::FinallyCommand();
315 break;
316 case ESC_ENDTRY:
317 Exception::EndTryCommand();
318 break;
319 case ESC_THROW:
320 Exception::ThrowCommand( Command + 2 );
321 break;
322
323 default:
324 char temporary[64];
325 GetDefaultNameFromES(Command[1],temporary);
326 SetError(30,temporary,cp);
327 break;
328 }
329 return;
330 }
331 switch(MAKEWORD(Command[1],Command[0])){
332 case COM_DIM:
333 OpcodeDim(Command+2,0);
334 break;
335 case COM_DELETE:
336 OpcodeDelete(Command+2, false);
337 break;
338 case COM_SWEEPINGDELETE:
339 OpcodeDelete(Command+2, true);
340 break;
341
342 case COM_GOTO:
343 OpcodeGoto(Command+2);
344 break;
345 case COM_WHILE:
346 OpcodeWhile(Command+2);
347 break;
348 case COM_FOR:
349 OpcodeFor(Command+2);
350 break;
351 case COM_FOREACH:
352 OpcodeForeach(Command+2);
353 break;
354 case COM_DO:
355 OpcodeDo(Command+2);
356 break;
357
358 case COM_GOSUB:
359 OpcodeGosub(Command+2);
360 break;
361 case COM_RETURN:
362 OpcodeReturn(Command+2);
363 break;
364
365 case COM_SETDOUBLE:
366 OpcodeSetPtrData(Command+2,DEF_DOUBLE);
367 break;
368 case COM_SETSINGLE:
369 OpcodeSetPtrData(Command+2,DEF_SINGLE);
370 break;
371 case COM_SETQWORD:
372 OpcodeSetPtrData(Command+2,DEF_QWORD);
373 break;
374 case COM_SETDWORD:
375 OpcodeSetPtrData(Command+2,DEF_DWORD);
376 break;
377 case COM_SETWORD:
378 OpcodeSetPtrData(Command+2,DEF_WORD);
379 break;
380 case COM_SETBYTE:
381 OpcodeSetPtrData(Command+2,DEF_BYTE);
382 break;
383
384 case COM_DEBUG:
385 extern BOOL bDebugCompile;
386 //int 3
387 if(bDebugCompile)
388 {
389 breakpoint;
390 }
391 else
392 {
393//#if defined(_DEBUG)
394 breakpoint;
395//#endif
396 }
397 break;
398
399 case COM_LET:
400 OpcodeCalc(Command+2);
401 break;
402 default:
403 OpcodeOthers(Command);
404 break;
405 }
406}
407
408void GetGlobalDataForDll(void){
409 extern char *basbuf;
410 extern HANDLE hHeap;
411 int i2,BufferSize;
412 char *Command;
413 DWORD dwRetCode;
414
415 dwRetCode=0;
416 BufferSize=128;
417 Command=(char *)HeapAlloc(hHeap,0,BufferSize);
418 for(cp++,i2=0;;cp++,i2++){
419 if(i2>=BufferSize){
420 //バッファ領域が足りなくなった場合はバッファを増量する
421 BufferSize+=128;
422 Command=(char *)HeapReAlloc(hHeap,0,Command,BufferSize);
423 }
424 if(basbuf[cp]=='\"'){
425 Command[i2]=basbuf[cp];
426 for(cp++,i2++;;cp++,i2++){
427 if(i2>=BufferSize){
428 //バッファ領域が足りなくなった場合はバッファを増量する
429 BufferSize+=128;
430 Command=(char *)HeapReAlloc(hHeap,0,Command,BufferSize);
431 }
432 Command[i2]=basbuf[cp];
433 if(basbuf[cp]=='\"') break;
434 }
435 continue;
436 }
437 if(IsCommandDelimitation(basbuf[cp])){
438 Command[i2]=0;
439
440 if(Command[0]==1&&Command[1]==ESC_SUB){
441 i2=cp;
442 while(!(basbuf[cp]==1&&basbuf[cp+1]==ESC_ENDSUB)){
443 if(basbuf[cp]=='\0'){
444 SetError(22,"Sub",i2);
445 break;
446 }
447 cp++;
448 }
449 if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break;
450 cp+=2;
451 i2=-1;
452 continue;
453 }
454 if(Command[0]==1&&Command[1]==ESC_FUNCTION){
455 i2=cp;
456 while(!(basbuf[cp]==1&&basbuf[cp+1]==ESC_ENDFUNCTION)){
457 if(basbuf[cp]=='\0'){
458 SetError(22,"Function",i2);
459 break;
460 }
461 cp++;
462 }
463 if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break;
464 cp+=2;
465 i2=-1;
466 continue;
467 }
468 if(Command[0]==1&&Command[1]==ESC_MACRO){
469 i2=cp;
470 while(!(basbuf[cp]==1&&basbuf[cp+1]==ESC_ENDMACRO)){
471 if(basbuf[cp]=='\0'){
472 SetError(22,"Macro",i2);
473 break;
474 }
475 cp++;
476 }
477 if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break;
478 cp+=2;
479 i2=-1;
480 continue;
481 }
482 if(Command[0]==1&&Command[1]==ESC_TYPE){
483 i2=cp;
484 while(!(basbuf[cp]==1&&basbuf[cp+1]==ESC_ENDTYPE)){
485 if(basbuf[cp]=='\0'){
486 SetError(22,"Type",i2);
487 break;
488 }
489 cp++;
490 }
491 if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break;
492 cp+=2;
493 i2=-1;
494 continue;
495 }
496 if(Command[0]==1&&Command[1]==ESC_CLASS){
497 i2=cp;
498 while(!(basbuf[cp]==1&&basbuf[cp+1]==ESC_ENDCLASS)){
499 if(basbuf[cp]=='\0'){
500 SetError(22,"Class",i2);
501 break;
502 }
503 cp++;
504 }
505 if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break;
506 cp+=2;
507 i2=-1;
508 continue;
509 }
510 if(Command[0]==1&&Command[1]==ESC_INTERFACE){
511 i2=cp;
512 while(!(basbuf[cp]==1&&basbuf[cp+1]==ESC_ENDINTERFACE)){
513 if(basbuf[cp]=='\0'){
514 SetError(22,"Interface",i2);
515 break;
516 }
517 cp++;
518 }
519 if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break;
520 cp+=2;
521 i2=-1;
522 continue;
523 }
524
525 //DLLのグローバルデータに必要なコマンドだけ
526 if(MAKEWORD(Command[1],Command[0])==COM_DIM)
527 OpcodeDim(Command+2,0);
528
529 if(basbuf[cp]=='\0') break;
530 i2=-1;
531 continue;
532 }
533 Command[i2]=basbuf[cp];
534 }
535 HeapDefaultFree(Command);
536}
537DWORD CompileBuffer(char Return_Sequence,WORD Return_Command){
538 extern char *basbuf;
539 extern HANDLE hHeap;
540 int i,i2,i3,i4,BufferSize,ScopeStart;
541 char *Command,temporary[VN_SIZE],*temp2,temp3[32];
542 DWORD dwRetCode;
543
544 ScopeStart=cp;
545
546 dwRetCode=0;
547 BufferSize=128;
548 Command=(char *)HeapAlloc(hHeap,0,BufferSize);
549
550 for(cp++,i2=0;;cp++,i2++){
551 if(i2>=BufferSize){
552 //バッファ領域が足りなくなった場合はバッファを増量する
553 BufferSize+=128;
554 Command=(char *)HeapReAlloc(hHeap,0,Command,BufferSize);
555 }
556 if(basbuf[cp]=='\"'){
557 Command[i2]=basbuf[cp];
558 for(cp++,i2++;;cp++,i2++){
559 if(i2>=BufferSize){
560 //バッファ領域が足りなくなった場合はバッファを増量する
561 BufferSize+=128;
562 Command=(char *)HeapReAlloc(hHeap,0,Command,BufferSize);
563 }
564 Command[i2]=basbuf[cp];
565 if(basbuf[cp]=='\"') break;
566 }
567 continue;
568 }
569 if(IsCommandDelimitation(basbuf[cp])){
570 Command[i2]=0;
571
572 if(Command[0]==1&&Command[1]==ESC_LINENUM){
573 for(i=2,i2=0;;i++,i2++){
574 if(Command[i]==','){
575 temporary[i2]=0;
576 break;
577 }
578 temporary[i2]=Command[i];
579 }
580 i3=atoi(temporary);
581 i4=i+1;
582
583 //Goto先ラベル
584 compiler.codeGenerator.gotoLabels.push_back( GotoLabel( (long)i3, compiler.codeGenerator.GetNativeCodeSize() ) );
585
586 //書き込みスケジュール
587 GotoLabelSchedules::iterator it = compiler.codeGenerator.gotoLabelSchedules.begin();
588 while( it != compiler.codeGenerator.gotoLabelSchedules.end() )
589 {
590 if( (*it)->GetName().size() == 0 && (*it)->GetLineNum() == i3 )
591 {
592 compiler.codeGenerator.opfix_JmpPertialSchedule( (*it) );
593
594 //詰める
595 it = compiler.codeGenerator.gotoLabelSchedules.erase( it );
596 }
597 else
598 {
599 it++;
600 }
601 }
602
603 temp2=(char *)HeapAlloc(hHeap,0,lstrlen(Command+i4)+1);
604 lstrcpy(temp2,Command+i4);
605 lstrcpy(Command,temp2);
606 HeapDefaultFree(temp2);
607 }
608
609 if(Command[0]==1&&
610 (((Command[1]==ESC_VIRTUAL||Command[1]==ESC_OVERRIDE)&&Command[2]==1&&(Command[3]==ESC_SUB||Command[3]==ESC_FUNCTION))||
611 Command[1]==ESC_SUB||
612 Command[1]==ESC_FUNCTION||
613 Command[1]==ESC_MACRO||
614 Command[1]==ESC_TYPE||
615 Command[1]==ESC_CLASS||
616 Command[1]==ESC_INTERFACE||
617 Command[1]==ESC_ENUM||
618 (Command[1]==ESC_CONST&&Command[2]==1&&Command[3]==ESC_ENUM)
619 )
620 ){
621 if(Command[1]==ESC_VIRTUAL||Command[1]==ESC_OVERRIDE||Command[1]==ESC_CONST){
622 GetDefaultNameFromES(Command[3],temporary);
623 }
624 else{
625 GetDefaultNameFromES(Command[1],temporary);
626 }
627 if(Return_Sequence){
628 SetError(12,temporary,cp);
629 break;
630 }
631
632 if(Command[1]==ESC_CONST) i3=GetEndXXXCommand(Command[3]);
633 else i3=GetEndXXXCommand(Command[1]);
634 for(i2=cp;;cp++){
635 if(basbuf[cp]==1){
636 if(basbuf[cp+1]==i3) break;
637 if(Command[1]==ESC_CLASS||Command[1]==ESC_INTERFACE){
638 //クラス、インターフェイスではSub、Functionの定義を可能にしておく
639 if(basbuf[cp+1]==ESC_MACRO||
640 basbuf[cp+1]==ESC_TYPE||
641 basbuf[cp+1]==ESC_CLASS||
642 basbuf[cp+1]==ESC_INTERFACE||
643 basbuf[cp+1]==ESC_ENUM){
644 GetDefaultNameFromES(basbuf[cp+1],temp3);
645 SetError(12,temp3,cp);
646 }
647 }
648 else{
649 if(basbuf[cp-1]!='*'&&(
650 basbuf[cp+1]==ESC_VIRTUAL||
651 basbuf[cp+1]==ESC_OVERRIDE||
652 basbuf[cp+1]==ESC_SUB||
653 basbuf[cp+1]==ESC_FUNCTION||
654 basbuf[cp+1]==ESC_MACRO||
655 basbuf[cp+1]==ESC_TYPE||
656 basbuf[cp+1]==ESC_CLASS||
657 basbuf[cp+1]==ESC_INTERFACE||
658 basbuf[cp+1]==ESC_ENUM)){
659 GetDefaultNameFromES(basbuf[cp+1],temp3);
660 SetError(12,temp3,cp);
661 }
662 }
663 }
664 if(basbuf[cp]=='\0'){
665 //error
666 //既にエラー発行済みのため、何もせずに抜ける
667 break;
668 }
669 }
670 if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break;
671 cp+=2;
672 i2=-1;
673 continue;
674 }
675
676 if(Command[0]==0x10||Command[0]==0x11){
677 //Wend、Next、Loopなど
678 if(Return_Command==MAKEWORD(Command[1],Command[0])){
679 if(Return_Command==COM_NEXT){
680 //Nextの場合は、パラメータ(省略化)の整合性を判断する必要がある(OpcodeFor関数を参照)
681 extern char szNextVariable[VN_SIZE];
682 if(Command[2]) lstrcpy(szNextVariable,Command+2);
683 else szNextVariable[0]=0;
684 }
685 break;
686 }
687 }
688
689 compiler.codeGenerator.NextSourceLine();
690
691 if(Command[0]==1){
692 if(Return_Sequence==ESC_ENDIF&&Command[1]==ESC_ELSE){
693 dwRetCode=ESC_ELSE;
694 break;
695 }
696
697 if(Command[1]==Return_Sequence){
698 dwRetCode=Command[1];
699 break;
700 }
701 }
702
703 try
704 {
705 ChangeOpcode(Command);
706 }
707 catch( const SmoothieException &smoothieException )
708 {
709 SetError(
710 smoothieException.GetErrorCode(),
711 smoothieException.GetKeyword(),
712 smoothieException.GetNowLine()
713 );
714 }
715
716
717 epi_check();
718
719
720 //コンパイルを中断するとき
721 extern BOOL bStopCompile;
722 if(bStopCompile) return 0;
723
724 if(basbuf[cp]=='\0'){
725 switch(Return_Command){
726 case COM_WEND:
727 SetError(4,"\"While\" - \"Wend\" ",ScopeStart);
728 break;
729 case COM_NEXT:
730 SetError(4,"\"For\" - \"Next\" ",ScopeStart);
731 break;
732 case COM_LOOP:
733 SetError(4,"\"Do\" - \"Loop\" ",ScopeStart);
734 break;
735 }
736 switch(Return_Sequence){
737 case ESC_ENDSUB:
738 SetError(4,"\"Sub\" - \"End Sub\" ",ScopeStart);
739 break;
740 case ESC_ENDFUNCTION:
741 SetError(4,"\"Function\" - \"End Function\" ",ScopeStart);
742 break;
743 case ESC_ENDMACRO:
744 SetError(4,"\"Macro\" - \"End Macro\" ",ScopeStart);
745 break;
746 case ESC_ENDIF:
747 SetError(22,"If",ScopeStart);
748 break;
749 }
750 break;
751 }
752 i2=-1;
753 continue;
754 }
755 Command[i2]=basbuf[cp];
756 }
757 HeapDefaultFree(Command);
758
759 return dwRetCode;
760}
Note: See TracBrowser for help on using the repository browser.