source: trunk/idl-compiler/parser_c/method_parser.c

Last change on this file was 326, checked in by cinc, 17 years ago

Portability patches for Windows, Linux, Darwin by Bird.

File size: 8.7 KB
Line 
1/* ***** BEGIN LICENSE BLOCK *****
2* Version: CDDL 1.0/LGPL 2.1
3*
4* The contents of this file are subject to the COMMON DEVELOPMENT AND
5* DISTRIBUTION LICENSE (CDDL) Version 1.0 (the "License"); you may not use
6* this file except in compliance with the License. You may obtain a copy of
7* the License at http://www.sun.com/cddl/
8*
9* Software distributed under the License is distributed on an "AS IS" basis,
10* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11* for the specific language governing rights and limitations under the
12* License.
13*
14* The Original Code is "NOM" Netlabs Object Model
15*
16* The Initial Developer of the Original Code is
17* netlabs.org: Chris Wohlgemuth <cinc-ml@netlabs.org>.
18* Portions created by the Initial Developer are Copyright (C) 2007
19* the Initial Developer. All Rights Reserved.
20*
21* Contributor(s):
22*
23* Alternatively, the contents of this file may be used under the terms of
24* the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
25* case the provisions of the LGPL are applicable instead of those above. If
26* you wish to allow use of your version of this file only under the terms of
27* the LGPL, and not to allow others to use your version of this file under
28* the terms of the CDDL, indicate your decision by deleting the provisions
29* above and replace them with the notice and other provisions required by the
30* LGPL. If you do not delete the provisions above, a recipient may use your
31* version of this file under the terms of any one of the CDDL or the LGPL.
32*
33* ***** END LICENSE BLOCK ***** */
34#ifdef __OS2__
35# include <os2.h>
36#endif /* __OS2__ */
37
38#include <stdlib.h>
39
40#include <glib.h>
41#include <glib/gprintf.h>
42#include "parser.h"
43
44extern GScanner *gScanner;
45extern GTokenType curToken;
46extern PPARSEINFO pParseInfo;
47
48/* In override_parser.c */
49extern PINTERFACE findInterfaceForMethod(PINTERFACE pStartInterface, gchar* chrMethodName);
50
51static PMETHOD createMethodStruct()
52{
53 PMETHOD pMethod=g_malloc0(sizeof(METHOD));
54
55 pMethod->pParamArray=g_ptr_array_new();
56
57 return pMethod;
58}
59
60/*
61 Parse one or more method parameters. Note that the check for '(' and ')' is
62 done in the calling function.
63
64 MPARAMS:= DIRECTION TS G_TOKEN_IDENTIFIER
65 | MPARAMS ',' MPARAMS
66 */
67static void parseMethodParams(PMETHOD pMethod)
68{
69 GTokenValue value;
70 PMETHODPARAM pParam;
71 PSYMBOL pCurSymbol;
72
73 do{
74 pParam=g_malloc0(sizeof(METHODPARAM));
75
76 /* Direction */
77 if(!matchNextKind(KIND_DIRECTION)) /* Be aware that we don't compare types here */
78 {
79 getNextToken(); /* Make sure error references the correct token */
80 g_scanner_unexp_token(gScanner,
81 G_TOKEN_IDENTIFIER,
82 NULL,
83 NULL,
84 NULL,
85 "Error in method declaration, direction (in|out|inout) is not specified.",
86 TRUE); /* is_error */
87 exit(1);
88 }
89
90 value=gScanner->value;
91 pCurSymbol=value.v_symbol;
92 switch(pCurSymbol->uiSymbolToken)
93 {
94 case IDL_SYMBOL_IN:
95 pParam->uiDirection=PARM_DIRECTION_IN;
96 break;
97 case IDL_SYMBOL_OUT:
98 pParam->uiDirection=PARM_DIRECTION_OUT;
99 break;
100 case IDL_SYMBOL_INOUT:
101 pParam->uiDirection=PARM_DIRECTION_INOUT;
102 break;
103 default:
104 break;
105 }
106
107 /* Typespec */
108 if(matchNextKind(KIND_TYPESPEC)) /* Be aware that we don't compare types here */
109 parseTypeSpec(pParam);
110 else
111 {
112 getNextToken(); /* Make sure error references the correct token */
113 g_scanner_unexp_token(gScanner,
114 G_TOKEN_IDENTIFIER,
115 NULL,
116 NULL,
117 NULL,
118 "Error in method declaration, Unknown type specification.",
119 TRUE); /* is_error */
120 exit(1);
121 }
122
123 //pParam->chrType=getTypeSpecStringFromCurToken();
124 //g_printf("%s %d", __FUNCTION__, __LINE__);
125 //printToken(curToken);
126
127 if(!matchNext(G_TOKEN_IDENTIFIER))
128 {
129 getNextToken(); /* Make sure error references the correct token */
130 //g_printf("%s %d", __FUNCTION__, __LINE__);
131 //printToken(curToken);
132 g_scanner_unexp_token(gScanner,
133 G_TOKEN_IDENTIFIER,
134 NULL,
135 NULL,
136 NULL,
137 "Error in method declaration, parameter name is wrong.",
138 TRUE); /* is_error */
139 exit(1);
140 }
141 value=gScanner->value;
142 pParam->chrName=g_strdup(value.v_identifier);
143
144 g_ptr_array_add(pMethod->pParamArray , (gpointer) pParam);
145 }while(matchNext(','));
146}
147
148
149/*
150 Current token is the typespec.
151
152 TS:= TYPE_SPEC //typespec, see elsewhere
153 | TYPE_SPEC '*'
154
155 M:= TS G_TOKEN_IDENTIFIER '(' ')' ';' // method
156 | TS G_TOKEN_IDENTIFIER '(' MPARMS ')' ';' // method
157 */
158void parseMethod(void)
159{
160 GTokenValue value;
161 PMETHOD pMethod=createMethodStruct();
162 PINTERFACE pif;
163 //g_printf("%s %d: ", __FUNCTION__, __LINE__);
164 //printToken(curToken);
165
166 /* Do type spec */
167 parseTypeSpec(&pMethod->mpReturn);
168
169 /* Method name */
170 if(!matchNext(G_TOKEN_IDENTIFIER))
171 {
172 getNextToken(); /* Make sure error references the correct token */
173 g_scanner_unexp_token(gScanner,
174 G_TOKEN_IDENTIFIER,
175 NULL,
176 NULL,
177 NULL,
178 "Error in method declaration",
179 TRUE); /* is_error */
180 exit(1);
181 }
182 value=gScanner->value;
183 pMethod->chrName=g_strdup(value.v_identifier);
184
185 /* Now check if the method was introduced by some parent. The interface struct contains
186 the parent name if any and the function will follow the chain of parents. */
187 if((pif=findInterfaceForMethod(pParseInfo->pCurInterface, pMethod->chrName))!=NULL)
188 {
189 gchar* chrMessage;
190 chrMessage=g_strdup_printf("A method '%s' is already present in interface '%s'.",
191 pMethod->chrName, pif->chrName);
192
193 g_scanner_unexp_token(gScanner,
194 G_TOKEN_IDENTIFIER,
195 NULL,
196 NULL,
197 NULL,
198 chrMessage,
199 TRUE); /* is_error */
200 exit(1);
201 }
202
203 /* Handle parameters if any */
204 if(!matchNext('('))
205 {
206 getNextToken(); /* Make sure error references the correct token */
207 g_scanner_unexp_token(gScanner,
208 '(',
209 NULL,
210 NULL,
211 NULL,
212 "Error in method declaration",
213 TRUE); /* is_error */
214 exit(1);
215 }
216
217 /* No parameters */
218 if(matchNext(')'))
219 {
220 if(!matchNext(';'))
221 {
222 getNextToken(); /* Make sure error references the correct token */
223 g_scanner_unexp_token(gScanner,
224 ';',
225 NULL,
226 NULL,
227 NULL,
228 "Missing semicolon.",
229 TRUE); /* is_error */
230 exit(1);
231 }
232 g_ptr_array_add( pParseInfo->pCurInterface->pMethodArray, (gpointer) pMethod);
233 return;
234 }
235
236 /* This parses all the parameters */
237 parseMethodParams(pMethod);
238
239 if(!matchNext(')'))
240 {
241 getNextToken(); /* Make sure error references the correct token */
242 g_scanner_unexp_token(gScanner,
243 ')',
244 NULL,
245 NULL,
246 NULL,
247 "Error in method declaration",
248 TRUE); /* is_error */
249 exit(1);
250 }
251
252 if(!matchNext(';'))
253 {
254 getNextToken(); /* Make sure error references the correct token */
255 g_scanner_unexp_token(gScanner,
256 ';',
257 NULL,
258 NULL,
259 NULL,
260 "Error in method declaration, Missing semicolon",
261 TRUE); /* is_error */
262 exit(1);
263 }
264
265 g_ptr_array_add( pParseInfo->pCurInterface->pMethodArray, (gpointer) pMethod);
266}
Note: See TracBrowser for help on using the repository browser.