source: dev/trunk/abdev/ProjectEditor/EndPairCommandComplement.cpp @ 364

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

Throw→Catch間のパラメータ引渡しに対応。
グローバル領域でのTryスコープを可能にした。これで例外処理機構実装完了。
エディタの補間機能にTry/Catch/Finally/EndTryを追加。

File size: 12.1 KB
Line 
1#include "common.h"
2
3///////////////////////////////////////////////////////////////////
4// ここから、ペアステートメント補完を行うための関数郡
5///////////////////////////////////////////////////////////////////
6
7int GetStartCommandId_FromBuffer(char *buffer){
8    int i;
9    char temporary[VN_SIZE];
10
11    for(i=0;;i++){
12        if(!IsVariableChar(buffer[i])){
13            temporary[i]=0;
14            break;
15        }
16        temporary[i]=buffer[i];
17    }
18
19    if(lstrcmpi(temporary,"If")==0){
20        //If文の場合はブロック形式の有無を判定
21
22        int IsStr=0;
23        for(;;i++){
24            if(buffer[i]=='\"') IsStr^=1;
25            if((buffer[i]=='\''||IsCommandDelimitation(buffer,i))&&IsStr==0){
26                i--;
27                break;
28            }
29        }
30
31        while(buffer[i]==' '||buffer[i]=='\t') i--;
32
33        if(memicmp(buffer+i-3,"Then",4)==0){
34            //ブロック形式のIf
35            return COM_IF;
36        }
37        else{
38            //一行のみのIf
39            return 0;
40        }
41    }
42
43    if(lstrcmpi(temporary,"Virtual")==0||
44        lstrcmpi(temporary,"Override")==0||
45        lstrcmpi(temporary,"Static")==0){
46        if(temporary[0]=='s'||temporary[0]=='S')
47            i=7;
48        else if(temporary[0]=='v'||temporary[0]=='V')
49            i=8;
50        else i=9;
51
52        while(buffer[i]==' '||buffer[i]=='\t') i++;
53
54        int i2;
55        for(i2=0;;i++,i2++){
56            if(!IsVariableChar(buffer[i])){
57                temporary[i2]=0;
58                break;
59            }
60            temporary[i2]=buffer[i];
61        }
62
63        if(lstrcmpi(temporary,"Function")==0) return COM_FUNCTION;
64        if(lstrcmpi(temporary,"Sub")==0) return COM_SUB;
65        return 0;
66    }
67
68    if(lstrcmpi(temporary,"Class")==0) return COM_CLASS;
69    if(lstrcmpi(temporary,"Interface")==0) return COM_INTERFACE;
70    if(lstrcmpi(temporary,"Do")==0) return COM_DO;
71    if(lstrcmpi(temporary,"Enum")==0) return COM_ENUM;
72    if(lstrcmpi(temporary,"For")==0) return COM_FOR;
73    if(lstrcmpi(temporary,"Function")==0) return COM_FUNCTION;
74    if(lstrcmpi(temporary,"Namespace")==0) return COM_NAMESPACE;
75    if(lstrcmpi(temporary,"Select")==0) return COM_SELECT;
76    if(lstrcmpi(temporary,"Sub")==0) return COM_SUB;
77    if(lstrcmpi(temporary,"Try")==0) return COM_TRY;
78    if(lstrcmpi(temporary,"Type")==0) return COM_TYPE;
79    if(lstrcmpi(temporary,"While")==0) return COM_WHILE;
80    if(lstrcmpi(temporary,"With")==0) return COM_WITH;
81
82    return 0;
83}
84int GetEndCommandId_FromBuffer(char *buffer){
85    int i,i2;
86    char temporary[VN_SIZE];
87
88    for(i=0,i2=0;;i++,i2++){
89        if(!IsVariableChar(buffer[i])){
90            temporary[i2]=0;
91
92            if(lstrcmpi(temporary,"End")==0&&
93                (buffer[i]==' '||buffer[i]=='\t')){
94                while(buffer[i]==' '||buffer[i]=='\t') i++;
95                i--;
96                i2--;
97                continue;
98            }
99
100            break;
101        }
102        temporary[i2]=buffer[i];
103    }
104
105    if(lstrcmpi(temporary,"EndClass")==0) return COM_CLASS;
106    if(lstrcmpi(temporary,"EndInterface")==0) return COM_INTERFACE;
107    if(lstrcmpi(temporary,"Loop")==0) return COM_DO;
108    if(lstrcmpi(temporary,"EndEnum")==0) return COM_ENUM;
109    if(lstrcmpi(temporary,"Next")==0) return COM_FOR;
110    if(lstrcmpi(temporary,"EndFunction")==0) return COM_FUNCTION;
111    if(lstrcmpi(temporary,"EndIf")==0) return COM_IF;
112    if(lstrcmpi(temporary,"EndNamespace")==0) return COM_NAMESPACE;
113    if(lstrcmpi(temporary,"EndSelect")==0) return COM_SELECT;
114    if(lstrcmpi(temporary,"EndSub")==0) return COM_SUB;
115    if(lstrcmpi(temporary,"EndType")==0) return COM_TYPE;
116    if(lstrcmpi(temporary,"Wend")==0) return COM_WHILE;
117    if(lstrcmpi(temporary,"EndWith")==0) return COM_WITH;
118
119    return 0;
120}
121void GetNameOfEndCommand(int CmdId,char *buffer){
122    switch(CmdId){
123        case COM_CLASS:
124            lstrcpy(buffer,"End Class");
125            break;
126        case COM_INTERFACE:
127            lstrcpy(buffer,"End Interface");
128            break;
129        case COM_DO:
130            lstrcpy(buffer,"Loop");
131            break;
132        case COM_ENUM:
133            lstrcpy(buffer,"End Enum");
134            break;
135        case COM_FOR:
136            lstrcpy(buffer,"Next");
137            break;
138        case COM_FUNCTION:
139            lstrcpy(buffer,"End Function");
140            break;
141        case COM_IF:
142            lstrcpy(buffer,"End If");
143            break;
144        case COM_NAMESPACE:
145            lstrcpy(buffer,"End Namespace");
146            break;
147        case COM_SELECT:
148            lstrcpy(buffer,"End Select");
149            break;
150        case COM_SUB:
151            lstrcpy(buffer,"End Sub");
152            break;
153        case COM_TRY:
154            lstrcpy(buffer,"End Try");
155            break;
156        case COM_TYPE:
157            lstrcpy(buffer,"End Type");
158            break;
159        case COM_WHILE:
160            lstrcpy(buffer,"Wend");
161            break;
162        case COM_WITH:
163            lstrcpy(buffer,"End With");
164            break;
165    }
166}
167BOOL IsIntoStringQuotes(char *buffer,int i){
168    int i2;
169
170    i2=i;
171    while(i2&&buffer[i2]!='\n') i2--;
172    if(i2==-1) i2=0;
173    if(buffer[i2]=='\n') i2++;
174
175    int IsStr=0;
176    for(;i2<i;i2++){
177        if(buffer[i2]=='\"') IsStr^=1;
178    }
179    return IsStr;
180}
181BOOL GetEndPairCommandInfo(char *buffer,int p){
182    int i,i2,i3,CmdId;
183    char epcName[32];
184    char indent[255],LineNum;
185
186    int stack[255];
187    int sp;
188
189    CmdId=0;
190    LineNum=0;
191    sp=-1;
192
193    i=p;
194
195    //入力中の行を除く
196    for(i--;i>=0;i--){
197        i2=IsCommandDelimitation(buffer,i);
198        if(i2) break;
199    }
200
201    while(1){
202
203        //i2に一行前の先頭位置を格納
204        for(i--;i>=0;i--){
205            i2=IsCommandDelimitation(buffer,i);
206            if(i2){
207                if(IsIntoStringQuotes(buffer,i)){
208                    //文字列中の場合
209                    continue;
210                }
211
212                if(i2==1) i2=i+1;
213                else{
214                    i2=i+2;
215                    LineNum++;
216
217                    if(LineNum>pobj_nv->BackNum_PairStatementComplement){
218                        //設定された行数を超えた場合
219                        return 0;
220                    }
221                }
222
223                break;
224            }
225        }
226        if(i==-1) i2=i+1;
227
228        //インデント文字列をindentにコピー
229        for(i3=0;;i2++,i3++){
230            if(buffer[i2]!='\t'){
231                indent[i3]=0;
232                break;
233            }
234            indent[i3]=buffer[i2];
235        }
236
237        //空白文字を飛び越す
238        while(buffer[i2]==' '||buffer[i2]=='\t') i2++;
239
240        //終了コマンドを取得(End Class、End Sub、Next、Wendなど…)
241        i3=GetEndCommandId_FromBuffer(buffer+i2);
242        if(i3){
243            sp++;
244            stack[sp]=i3;
245        }
246
247        //開始コマンドを取得(Class、Sub、For、Whileなど…)
248        i3=GetStartCommandId_FromBuffer(buffer+i2);
249        if(i3){
250            if(sp==-1){
251                CmdId=i3;
252                break;
253            }
254
255            if(stack[sp]!=i3) return 0;
256            sp--;
257        }
258
259        if(i<=0) break;
260    }
261
262    if(!CmdId) return 0;
263
264    extern HANDLE hHeap;
265    extern COMPLEMENT_WINDOW_INFO ComplementWndInfo;
266    if(CmdId==COM_IF){
267        //Else、ElseIf、End Ifをリストに追加
268
269        ///////////////////////
270        // 補完情報
271        ///////////////////////
272
273        ComplementWndInfo.pMemberInfo=(MEMBERINFO *)HeapAlloc(hHeap,0,sizeof(MEMBERINFO)*2);
274        ComplementWndInfo.MemberNum=2;
275
276        ComplementWndInfo.pMemberInfo[0].pName=(char *)HeapAlloc(hHeap,0,5);
277        lstrcpy(ComplementWndInfo.pMemberInfo[0].pName,"Else");
278        ComplementWndInfo.pMemberInfo[0].dwProc=0;
279        ComplementWndInfo.pMemberInfo[0].dwAccess=ACCESS_PAIRCOMMAND;
280
281        ComplementWndInfo.pMemberInfo[1].pName=(char *)HeapAlloc(hHeap,0,7);
282        lstrcpy(ComplementWndInfo.pMemberInfo[1].pName,"End If");
283        ComplementWndInfo.pMemberInfo[1].dwProc=0;
284        ComplementWndInfo.pMemberInfo[1].dwAccess=ACCESS_PAIRCOMMAND;
285    }
286    else if(CmdId==COM_CLASS){
287        ComplementWndInfo.pMemberInfo=(MEMBERINFO *)HeapAlloc(hHeap,0,sizeof(MEMBERINFO)*4);
288        ComplementWndInfo.MemberNum=4;
289
290        ComplementWndInfo.pMemberInfo[0].pName=(char *)HeapAlloc(hHeap,0,10);
291        lstrcpy(ComplementWndInfo.pMemberInfo[0].pName,"End Class");
292        ComplementWndInfo.pMemberInfo[0].dwProc=0;
293        ComplementWndInfo.pMemberInfo[0].dwAccess=ACCESS_PAIRCOMMAND;
294
295        ComplementWndInfo.pMemberInfo[1].pName=(char *)HeapAlloc(hHeap,0,8);
296        lstrcpy(ComplementWndInfo.pMemberInfo[1].pName,"Private");
297        ComplementWndInfo.pMemberInfo[1].dwProc=0;
298        ComplementWndInfo.pMemberInfo[1].dwAccess=ACCESS_PAIRCOMMAND;
299
300        ComplementWndInfo.pMemberInfo[2].pName=(char *)HeapAlloc(hHeap,0,10);
301        lstrcpy(ComplementWndInfo.pMemberInfo[2].pName,"Protected");
302        ComplementWndInfo.pMemberInfo[2].dwProc=0;
303        ComplementWndInfo.pMemberInfo[2].dwAccess=ACCESS_PAIRCOMMAND;
304
305        ComplementWndInfo.pMemberInfo[3].pName=(char *)HeapAlloc(hHeap,0,7);
306        lstrcpy(ComplementWndInfo.pMemberInfo[3].pName,"Public");
307        ComplementWndInfo.pMemberInfo[3].dwProc=0;
308        ComplementWndInfo.pMemberInfo[3].dwAccess=ACCESS_PAIRCOMMAND;
309    }
310    else if(CmdId==COM_SELECT){
311        ComplementWndInfo.pMemberInfo=(MEMBERINFO *)HeapAlloc(hHeap,0,sizeof(MEMBERINFO)*4);
312        ComplementWndInfo.MemberNum=2;
313
314        ComplementWndInfo.pMemberInfo[0].pName=(char *)HeapAlloc(hHeap,0,10);
315        lstrcpy(ComplementWndInfo.pMemberInfo[0].pName,"End Select");
316        ComplementWndInfo.pMemberInfo[0].dwProc=0;
317        ComplementWndInfo.pMemberInfo[0].dwAccess=ACCESS_PAIRCOMMAND;
318
319        ComplementWndInfo.pMemberInfo[1].pName=(char *)HeapAlloc(hHeap,0,8);
320        lstrcpy(ComplementWndInfo.pMemberInfo[1].pName,"Case");
321        ComplementWndInfo.pMemberInfo[1].dwProc=0;
322        ComplementWndInfo.pMemberInfo[1].dwAccess=ACCESS_PAIRCOMMAND;
323    }
324    else if(CmdId==COM_TRY){
325        ComplementWndInfo.pMemberInfo=(MEMBERINFO *)HeapAlloc(hHeap,0,sizeof(MEMBERINFO)*4);
326        ComplementWndInfo.MemberNum=3;
327
328        ComplementWndInfo.pMemberInfo[0].pName=(char *)HeapAlloc(hHeap,0,10);
329        lstrcpy(ComplementWndInfo.pMemberInfo[0].pName,"End Try");
330        ComplementWndInfo.pMemberInfo[0].dwProc=0;
331        ComplementWndInfo.pMemberInfo[0].dwAccess=ACCESS_PAIRCOMMAND;
332
333        ComplementWndInfo.pMemberInfo[1].pName=(char *)HeapAlloc(hHeap,0,10);
334        lstrcpy(ComplementWndInfo.pMemberInfo[1].pName,"Catch");
335        ComplementWndInfo.pMemberInfo[1].dwProc=0;
336        ComplementWndInfo.pMemberInfo[1].dwAccess=ACCESS_PAIRCOMMAND;
337
338        ComplementWndInfo.pMemberInfo[2].pName=(char *)HeapAlloc(hHeap,0,8);
339        lstrcpy(ComplementWndInfo.pMemberInfo[2].pName,"Finally");
340        ComplementWndInfo.pMemberInfo[2].dwProc=0;
341        ComplementWndInfo.pMemberInfo[2].dwAccess=ACCESS_PAIRCOMMAND;
342    }
343    else{
344        //その他のコマンド
345
346        //エンドペアステートメントの名前を取得
347        GetNameOfEndCommand(CmdId,epcName);
348
349
350        ///////////////////////
351        // 補完情報
352        ///////////////////////
353
354        ComplementWndInfo.pMemberInfo=(MEMBERINFO *)HeapAlloc(hHeap,0,sizeof(MEMBERINFO));
355        ComplementWndInfo.MemberNum=1;
356
357        ComplementWndInfo.pMemberInfo[0].pName=(char *)HeapAlloc(hHeap,0,lstrlen(epcName)+1);
358        lstrcpy(ComplementWndInfo.pMemberInfo[0].pName,epcName);
359
360        ComplementWndInfo.pMemberInfo[0].dwProc=0;
361        ComplementWndInfo.pMemberInfo[0].dwAccess=ACCESS_PAIRCOMMAND;
362    }
363    lstrcpy(ComplementWndInfo.szIndent,indent);
364
365
366    return 1;
367}
368BOOL IsNeedNewIndentCommand(char *name){
369    if(lstrcmpi(name,"Case")==0) return 1;
370    return 0;
371}
372
373
374
375///////////////////////////////////////////////
376// Withで構成されるオブジェクト識別子を取得
377///////////////////////////////////////////////
378
379void GetWithObjectVariable(char *buffer,int p,char *pObjectVar){
380    int i,i2,i3,i4,CmdId;
381    char LineNum;
382    char temporary[VN_SIZE];
383
384    int stack[255];
385    int sp;
386
387    CmdId=0;
388    LineNum=0;
389    sp=-1;
390    pObjectVar[0]=0;
391
392    i=p;
393
394    //入力中の行を除く
395    for(i--;i>=0;i--){
396        i2=IsCommandDelimitation(buffer,i);
397        if(i2) break;
398    }
399
400    while(1){
401
402        //i2に一行前の先頭位置を格納
403        for(i--;i>=0;i--){
404            i2=IsCommandDelimitation(buffer,i);
405            if(i2){
406                if(i2==1) i2=i+1;
407                else{
408                    i2=i+2;
409                    LineNum++;
410
411                    if(LineNum>pobj_nv->BackNum_PairStatementComplement){
412                        //設定された行数を超えた場合
413                        return;
414                    }
415                }
416
417                break;
418            }
419        }
420        if(i==-1) i2=i+1;
421
422        //インデントを飛び越す
423        while(buffer[i2]==' '||buffer[i2]=='\t') i2++;
424
425        //終了コマンドを取得(End Class、End Sub、Next、Wendなど…)
426        CmdId=GetEndCommandId_FromBuffer(buffer+i2);
427        if(CmdId){
428            sp++;
429            stack[sp]=CmdId;
430        }
431
432        //開始コマンドを取得(Class、Sub、For、Whileなど…)
433        CmdId=GetStartCommandId_FromBuffer(buffer+i2);
434        if(CmdId){
435            if(sp==-1){
436                if(CmdId==COM_WITH){
437                    //オブジェクト識別子を付加
438                    i2+=5;
439                    while(buffer[i2]==' '||buffer[i2]=='\t') i2++;
440
441                    for(i3=0;;i2++,i3++){
442                        if(buffer[i2]=='-'&&buffer[i2+1]=='>'){
443                            temporary[i3++]=buffer[i2++];
444                            temporary[i3]=buffer[i2];
445                            continue;
446                        }
447                        if(buffer[i2]=='['){
448                            i4=GetStringInBracket(temporary+i3,buffer+i2);
449                            i2+=i4-1;
450                            i3+=i4-1;
451                            continue;
452                        }
453                        if(buffer[i2]=='('){
454                            i4=GetStringInPare(temporary+i3,buffer+i2);
455                            i2+=i4-1;
456                            i3+=i4-1;
457                            continue;
458                        }
459                        if(!(IsVariableChar(buffer[i2])||buffer[i2]=='.')){
460                            temporary[i3]=0;
461                            break;
462                        }
463                        temporary[i3]=buffer[i2];
464                    }
465                    lstrcat(temporary,pObjectVar);
466                    lstrcpy(pObjectVar,temporary);
467                }
468            }
469            else{
470                if(stack[sp]!=CmdId){
471                    pObjectVar[0]=0;
472                    break;
473                }
474                sp--;
475            }
476        }
477
478        if(i<=0) break;
479    }
480}
Note: See TracBrowser for help on using the repository browser.