source: trunk/idl-compiler/c/nom-idl-compiler.c@ 263

Last change on this file since 263 was 263, checked in by cinc, 18 years ago

Bail out on duplicate method definition. MEthod overriding checks for method.

File size: 9.6 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#define INCL_DOSPROCESS
35#define INCL_DOS
36#define INCL_DOSPROFILE
37#define INCL_DOSERRORS
38
39#include <os2.h>
40#include <stdio.h>
41#include <stdlib.h>
42#include <string.h>
43
44#include <io.h>
45#include <fcntl.h>
46#include <sys\stat.h>
47
48#include <glib.h>
49#include <glib/gprintf.h>
50
51#include "nom.h"
52#include "nomtk.h"
53
54#include "parser.h"
55
56static gchar* chrOutputDir="";
57static gchar* chrOutputName="";
58static gboolean fOptionEmitH=FALSE;
59static gboolean fOptionEmitIH=FALSE;
60static gboolean fOptionEmitC=FALSE;
61
62/* Command line options */
63static GOptionEntry gOptionEntries[] =
64{
65 {"directory", 'd', 0, G_OPTION_ARG_FILENAME, &chrOutputDir, "Output directory", NULL},
66 {"emit-h", 0, 0, G_OPTION_ARG_NONE, &fOptionEmitH, "Emmit a header file (*.h)", NULL},
67 {"emit-ih", 0, 0, G_OPTION_ARG_NONE, &fOptionEmitIH, "Emmit an include header (*.ih)", NULL},
68 {"emit-c", 0, 0, G_OPTION_ARG_NONE, &fOptionEmitC, "Emmit an implementation template (*.c)", NULL},
69 {"output", 'o', 0, G_OPTION_ARG_FILENAME, &chrOutputName, "Output name", NULL},
70 {NULL}
71};
72
73static char* chrOutputFileName="";
74
75/* The pointer array holding the interfaces we found */
76GPtrArray* pInterfaceArray;
77
78/* Symbols defined for our IDL language.
79 Keep this in synch with the defined enums! */
80const SYMBOL idlSymbols[]={
81 {"interface", IDL_SYMBOL_INTERFACE, KIND_UNKNOWN}, /* 71 */
82 {"NOMCLASSVERSION", IDL_SYMBOL_CLSVERSION, KIND_UNKNOWN},
83 {"NOMINSTANCEVAR", IDL_SYMBOL_INSTANCEVAR, KIND_UNKNOWN},
84 {"NOMOVERRIDE", IDL_SYMBOL_OVERRIDE, KIND_UNKNOWN},
85 {"gulong", IDL_SYMBOL_GULONG, KIND_TYPESPEC},
86 {"gint", IDL_SYMBOL_GINT, KIND_TYPESPEC},
87 {"gpointer", IDL_SYMBOL_GPOINTER, KIND_TYPESPEC},
88 {"gboolean", IDL_SYMBOL_GBOOLEAN, KIND_TYPESPEC},
89 {"in", IDL_SYMBOL_IN, KIND_DIRECTION},
90 {"out", IDL_SYMBOL_OUT, KIND_DIRECTION},
91 {"inout", IDL_SYMBOL_INOUT, KIND_DIRECTION},
92 {"define", IDL_SYMBOL_DEFINE, KIND_UNKNOWN},
93 {"ifdef", IDL_SYMBOL_IFDEF, KIND_UNKNOWN},
94 {"endif", IDL_SYMBOL_ENDIF, KIND_UNKNOWN},
95 {NULL, 0, KIND_UNKNOWN}
96},*pSymbols=idlSymbols;
97
98GScanner *gScanner;
99GTokenType curToken=G_TOKEN_EOF;
100PINTERFACE pCurInterface=NULL;
101
102/* Holding info about current token. Referenced by gScanner. */
103SYMBOLINFO curSymbol;
104
105
106PINTERFACE findInterfaceFromName(gchar* chrName)
107{
108 int a;
109
110 for(a=0;a<pInterfaceArray->len;a++)
111 {
112 PINTERFACE pif=g_ptr_array_index(pInterfaceArray, a);
113 if(!strcmp(chrName, pif->chrName))
114 return pif;
115 }
116
117 return NULL;
118}
119
120
121gchar* getTypeSpecStringFromCurToken(void)
122{
123 GTokenValue value;
124
125 if(G_TOKEN_IDENTIFIER==curToken)
126 return g_strdup(value.v_identifier);
127 else
128 {
129 /* It's one of our symbols. */
130 PSYMBOLINFO psi;
131
132 if(curToken<=G_TOKEN_LAST)
133 g_scanner_unexp_token(gScanner,
134 G_TOKEN_SYMBOL,
135 NULL,
136 NULL,
137 NULL,
138 "Error in NOMINSTANCEVAR()",
139 TRUE); /* is_error */
140
141 psi=(PSYMBOLINFO)gScanner->user_data;
142 return psi->pSymbols[curToken-G_TOKEN_LAST-1].chrSymbolName;
143 }
144}
145
146
147/**
148 This is the root parse function. Here starts the fun...
149 */
150void parseIt(void)
151{
152 while(g_scanner_peek_next_token(gScanner) != G_TOKEN_EOF) {
153 GTokenType token;
154
155 curToken=g_scanner_get_next_token(gScanner);
156 token=curToken;
157 GTokenValue value=gScanner->value;
158
159 switch(curToken)
160 {
161 case IDL_SYMBOL_INTERFACE:
162 parseInterface(token);
163 break;
164
165#if 0
166 case G_TOKEN_IDENTIFIER:
167 g_message("Token: %d (G_TOKEN_IDENTIFIER)\t\t%s", token, value.v_identifier);
168 break;
169 case G_TOKEN_STRING:
170 g_message("Token: %d (G_TOKEN_STRING)\t\t\t%s", token, value.v_string);
171 break;
172 case G_TOKEN_LEFT_PAREN:
173 g_message("Token: %d (G_TOKEN_LEFT_PAREN)\t\t(", token);
174 break;
175 case G_TOKEN_RIGHT_PAREN:
176 g_message("Token: %d (G_TOKEN_RIGHT_PAREN)\t\t)", token);
177 break;
178 case ':':
179 g_message("Token: %d (colon)\t\t:", token);
180 break;
181 case ';':
182 g_message("Token: %d (semicolon)\t\t\t;", token);
183 break;
184 case '#':
185 g_message("Token: %d (hash)\t\t\t#", token);
186 break;
187 case '/':
188 g_message("Token: %d (slash)\t\t\t/ %s", token, value.v_comment);
189 break;
190 case G_TOKEN_COMMA:
191 g_message("Token: %d (G_TOKEN_COMMA)\t\t\t,", token);
192 break;
193 case G_TOKEN_INT:
194 g_message("Token: %d (G_TOKEN_INT)\t\t\t%ld", token, value.v_int);
195 break;
196 case IDL_SYMBOL_DEFINE:
197 g_message("Token: %d (IDL_SYMBOL_DEFINE)\t\t\t", token);
198 break;
199 case IDL_SYMBOL_IFDEF:
200 g_message("Token: %d (IDL_SYMBOL_IFDEF)\t\t\t", token);
201 break;
202 case IDL_SYMBOL_ENDIF:
203 g_message("Token: %d (IDL_SYMBOL_ENDIF)\t\t\t", token);
204 break;
205#endif
206 default:
207 printToken(curToken);
208 // g_message("Token: %d (---)\t\t\t%c (LINE %d)", token, token, g_scanner_cur_line(gScanner));
209 break;
210 }
211 }
212}
213
214/* Show help.
215 gContext must be valid.
216*/
217static void outputCompilerHelp(GOptionContext *gContext, gchar* chrExeName)
218{
219 GError *gError = NULL;
220 int argc2=2;
221 char *helpCmd[]={"","--help"};
222 char** argv2=helpCmd;
223 helpCmd[0]=chrExeName;
224
225 g_option_context_parse (gContext, &argc2, &argv2, &gError);
226}
227
228/*
229
230 */
231int main(int argc, char **argv)
232{
233 int a;
234 int fd;
235 int idScope=0;
236 GError *gError = NULL;
237 GOptionContext* gContext;
238
239 /* Parse command line options */
240 gContext = g_option_context_new ("file");
241 g_option_context_add_main_entries (gContext, gOptionEntries, NULL);
242
243 if(!g_option_context_parse (gContext, &argc, &argv, &gError))
244 {
245 outputCompilerHelp(gContext, argv[0]);
246 }
247
248 /* Correct emitter options? Exactly one emitter must be specified. */
249 a=0;
250 if(fOptionEmitH)
251 a++;
252 if(fOptionEmitIH)
253 a++;
254 if(fOptionEmitC)
255 a++;
256
257#if 0
258 if(!a){
259 g_printf("An emitter must be specified.\n\n");
260 outputCompilerHelp(gContext, argv[0]);
261 }
262 if(a>1){
263 g_printf("Only one emitter must be specified.\n\n");
264 outputCompilerHelp(gContext, argv[0]);
265 }
266#endif
267 g_option_context_free(gContext);
268
269
270 if(argc<2)
271 {
272 g_printf("No input file name given.\n\nUse %s --help for options.\n\n", argv[0]);
273 return 1;
274 }
275
276 for(a=0; a<argc; a++)
277 {
278 g_message("arg %d: %s", a, argv[a]);
279 }
280
281 /* Create output file name */
282
283 fd=open(argv[1], O_RDONLY);
284
285 if(-1==fd)
286 {
287 g_message("Can't open input file %s", argv[1]);
288 exit(1);
289 }
290
291 g_printf("\n");
292
293 gScanner=g_scanner_new(NULL);
294 gScanner->user_data=(gpointer)&curSymbol;
295 curSymbol.pSymbols=idlSymbols;
296
297 pInterfaceArray=g_ptr_array_new();
298
299 g_scanner_input_file(gScanner, fd);
300 /* No single line comments */
301 gScanner->config->skip_comment_single=FALSE;
302 gScanner->config->cpair_comment_single="";
303 /* This string is used in error messages of the parser */
304 gScanner->input_name=IDL_COMPILER_STRING;
305
306 g_scanner_set_scope(gScanner, idScope);
307 /* Load our own symbols into the scanner. We use the default scope for now. */
308 while(pSymbols->chrSymbolName)
309 {
310 g_scanner_scope_add_symbol(gScanner, idScope, pSymbols->chrSymbolName, GINT_TO_POINTER(pSymbols->uiSymbolToken));
311 pSymbols++;
312 }
313 gScanner->config->symbol_2_token=TRUE;
314
315 parseIt();
316
317 if(pInterfaceArray->len)
318 printInterface();
319
320 g_scanner_destroy(gScanner);
321 close(fd);
322
323 return 0;
324}
325
326#if 0
327 /* We are a folder somwhere in the chain */
328 nomRetval=WPFileSystem_wpQueryFileName((WPFileSystem*)wpParent, bFullPath, NULLHANDLE);
329
330 nomRetval=wpParent.wpQueryFileName(bFullPath, NULLHANDLE);
331
332 nomPath=NOMPathNew();
333 nomPath= (PNOMPath) NOMPath_assignCString(nomPath, _pszFullPath, ev);
334
335 return (PNOMPath)NOMPath_appendPath(nomRetval, nomPath, NULLHANDLE);
336
337#endif
Note: See TracBrowser for help on using the repository browser.