-/* main.cc -- entry point for the interface compiler
- *
- * Written by Scott Wood <scott@buserror.net>
- *
- * The idlc program implements two main functions. One is to turn
- * .idl files into binary type descriptions. The other is to turn
- * those type descriptions into language-specific stubs (though a
- * compiler/interpreter could also just read the binary types
- * directly, as the ORB does).
- *
- * For the former function, it is necessary to do the work in multiple
- * passes, as not all information is available the first time through due
- * to the absence of forward declarations. The passes are as follows:
- *
- * 1: Parse the input text, and determine which symbols exist in
- * which namespaces. At this point, no non-namespace-qualified
- * symbol lookups will be done (though namespace-qualified lookups
- * are done, such as to check for duplicate symbols).
- *
- * Objects will be created for each entity (Interface, Struct,
- * Datum, Alias, etc.), but any reference to another entity will be
- * stored as a StrList, not as an object pointer. This must be the
- * case even if a lookup during this pass would have found
- * something, as on the second pass it might find a "closer"
- * matching symbol added later.
- *
- * The StrList will later be looked up with only the entity
- * containing the reference as context, so namespace search rules
- * must not depend on anything else.
- *
- * This is the only pass that involves actually reading and
- * parsing the input file(s).
- *
- * 2: Look up the namespace names of using namespace.* statements.
- * These are the only lookups where order of the statements in the
- * file matters, and it alters the result of a lookup, so it must be
- * completed before chain lookups are done.
- *
- * 3: Look up the symbol names recorded in pass 1 for aliases, and
- * typedefs, and const datum initializers and types. This is done
- * before the rest of the lookups, so there will always be a
- * complete chain to follow in subsequent passes.
- *
- * This is done by calling the virtual lookup_chain() method on
- * the root namespace, which recursively calls it on all of its
- * contents.
- *
- * 4: Look up other symbol names recorded in pass 1. At this point,
- * unresolved alias chains may still exist and must be handled,
- * though they should be fixed during this phase so that they do not
- * appear in phase 4. Typedefs will remain fully chained, as the
- * chain is semantically meaningful and must be preserved in the
- * output.
- *
- * Const datum initializers are looked up in this pass despite being
- * chains, since aliases aren't resolved in pass 2, and it's
- * (slightly) easier to do the lookup in pass 3 and resolve the
- * chain in pass 4 than to store a Symbol reference in pass 2,
- * get the concerete sym in pass 3, and still have to either
- * concrete-ize other Datums' initializers or wait until pass 4
- * to resolve the chain.
- *
- * This is done by calling the virtual lookup_misc() method on the
- * root namespace, which recursively calls it on all of its
- * contents. Upon receiving this call, each entity object should
- * call lookup_sym() or lookup_type() on the various StrLists it has
- * stored, but should not do anything with the object pointer
- * until pass 4 (unless the object was satisfactorily initialized
- * in pass 1).
- *
- * 5: Perform any remaining semantic analysis, now that all references
- * to other entities have been looked up.
- *
- * This is done by calling the virtual final_analysis() method on
- * the root namespace, which recursively calls it on all of its
- * contents.
- *
- * 6: Generate output.
- * This is done by calling the virtual output() method on
- * the root namespace, which recursively calls it on all of its
- * contents.
- *
- * All circular dependencies must be contained within the set of files
- * passed to the compiler in one invocation. Supporting circular
- * dependencies over multiple invocations of the compiler would require
- * explicitly running only certain passes, then compiling the other
- * batch, and then finishing the original batch. It could be done with
- * some pain (intermediate states would need to be serialized), but I
- * only want to do it if there's a real need. Circular dependencies
- * ought to be isolated fairly locally...
- */
+// Entry point for the interface compiler
+//
+// This software is copyright (c) 2006 Scott Wood <scott@buserror.net>.
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors or contributors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is hereby granted to everyone, free of charge, to use, copy,
+// modify, prepare derivative works of, publish, distribute, perform,
+// sublicense, and/or sell copies of the Software, provided that the above
+// copyright notice and disclaimer of warranty be included in all copies or
+// substantial portions of this software.
+//
+// The idlc program implements two main functions. One is to turn
+// .idl files into binary type descriptions. The other is to turn
+// those type descriptions into language-specific stubs (though a
+// compiler/interpreter could also just read the binary types
+// directly, as the ORB does).
+//
+// For the former function, it is necessary to do the work in multiple
+// passes, as not all information is available the first time through due
+// to the absence of forward declarations. The passes are as follows:
+//
+// 1: Parse the input text, and determine which symbols exist in
+// which namespaces. At this point, no non-namespace-qualified
+// symbol lookups will be done (though namespace-qualified lookups
+// are done, such as to check for duplicate symbols).
+//
+// Objects will be created for each entity (Interface, Struct,
+// Datum, Alias, etc.), but any reference to another entity will be
+// stored as a StrList, not as an object pointer. This must be the
+// case even if a lookup during this pass would have found
+// something, as on the second pass it might find a "closer"
+// matching symbol added later.
+//
+// The StrList will later be looked up with only the entity
+// containing the reference as context, so namespace search rules
+// must not depend on anything else.
+//
+// This is the only pass that involves actually reading and
+// parsing the input file(s).
+//
+// 2: Look up the namespace names of using namespace.* statements.
+// These are the only lookups where order of the statements in the
+// file matters, and it alters the result of a lookup, so it must be
+// completed before chain lookups are done.
+//
+// 3: Look up the symbol names recorded in pass 1 for aliases, and
+// typedefs, and const datum initializers and types. This is done
+// before the rest of the lookups, so there will always be a
+// complete chain to follow in subsequent passes.
+//
+// This is done by calling the virtual lookup_chain() method on
+// the root namespace, which recursively calls it on all of its
+// contents.
+//
+// 4: Look up other symbol names recorded in pass 1. At this point,
+// unresolved alias chains may still exist and must be handled,
+// though they should be fixed during this phase so that they do not
+// appear in phase 4. Typedefs will remain fully chained, as the
+// chain is semantically meaningful and must be preserved in the
+// output.
+//
+// Const datum initializers are looked up in this pass despite being
+// chains, since aliases aren't resolved in pass 2, and it's
+// (slightly) easier to do the lookup in pass 3 and resolve the
+// chain in pass 4 than to store a Symbol reference in pass 2,
+// get the concerete sym in pass 3, and still have to either
+// concrete-ize other Datums' initializers or wait until pass 4
+// to resolve the chain.
+//
+// This is done by calling the virtual lookup_misc() method on the
+// root namespace, which recursively calls it on all of its
+// contents. Upon receiving this call, each entity object should
+// call lookup_sym() or lookup_type() on the various StrLists it has
+// stored, but should not do anything with the object pointer
+// until pass 4 (unless the object was satisfactorily initialized
+// in pass 1).
+//
+// 5: Perform any remaining semantic analysis, now that all references
+// to other entities have been looked up.
+//
+// This is done by calling the virtual final_analysis() method on
+// the root namespace, which recursively calls it on all of its
+// contents.
+//
+// 6: Generate output.
+// This is done by calling the virtual output() method on
+// the root namespace, which recursively calls it on all of its
+// contents.
+//
+// All circular dependencies must be contained within the set of files
+// passed to the compiler in one invocation. Supporting circular
+// dependencies over multiple invocations of the compiler would require
+// explicitly running only certain passes, then compiling the other
+// batch, and then finishing the original batch. It could be done with
+// some pain (intermediate states would need to be serialized), but I
+// only want to do it if there's a real need. Circular dependencies
+// ought to be isolated fairly locally...
#include <climits>
#include <cstdio>
list<const char *> inputs;
list<NameSpaceRef> nspace_stack;
Language *first_lang, *output_lang;
-Interface *System_Object;
-Struct *System_VStruct;
+InterfaceRef System_Object;
+StructRef System_VStruct;
AutoReleasePool autorelease_pool;
void print_usage()
} else if (!strcmp(s, "show-targets")) {
printf("Supported target architectures:\n");
for (int i = 1; i <= max_target; i++)
- printf(" %s\n", targets[i].name);
+ printf(" %s\n", targets[i].name);
printf("\n");
exit(0);
} else if (!strcmp(s, "server")) {
}
static int global_argc;
-static const char **global_argv;
+static char **global_argv;
static int got_dashdash;
static void process_args(void)
for (i = 1; i < global_argc; i++) {
if (global_argv[i][0] == '-' && global_argv[i][1] && !got_dashdash) {
- const char *opt = global_argv[i];
+ char *opt = global_argv[i];
if (opt[1] == '-') {
if (!opt[2]) {
autorelease_pool.clean();
}
-int run_idlc(int argc, const char **argv)
+int run_idlc(int argc, char **argv)
{
global_argc = argc;
global_argv = argv;
return 0;
}
-int main(int argc, const char **argv)
+int main(int argc, char **argv)
{
int ret = run_idlc(argc, argv);
autorelease_pool.clean();
+
return ret;
}
extern char *yytext;
-void idl_error(char *s)
+void idl_error(const char *s)
{
if (strlen(yytext))
fprintf(stderr, "%s:%d: %s at \"%s\".\n", cur_input_file, curline, s, yytext);