Merged the IDL compiler written by Ove Kaaven.
diff --git a/tools/widl/parser.l b/tools/widl/parser.l
new file mode 100644
index 0000000..47a4748
--- /dev/null
+++ b/tools/widl/parser.l
@@ -0,0 +1,311 @@
+/*
+ * IDL Compiler
+ *
+ * Copyright 2002 Ove Kaaven
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+%option stack
+%option never-interactive
+
+nl \r?\n
+ws [ \f\t\r]
+cident [a-zA-Z_][0-9a-zA-Z_]*
+int [0-9]+
+hexd [0-9a-fA-F]
+hex 0x{hexd}+
+uuid {hexd}{8}-{hexd}{4}-{hexd}{4}-{hexd}{4}-{hexd}{12}
+
+%x QUOTE
+
+%{
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+
+#include "widl.h"
+#include "utils.h"
+#include "parser.h"
+#include "wpp.h"
+
+#include "y.tab.h"
+
+#define YY_USE_PROTOS
+#define YY_NO_UNPUT
+#define YY_NO_TOP_STATE
+
+extern char *temp_name;
+
+static void addcchar(char c);
+static char *get_buffered_cstring(void);
+
+static char *cbuffer;
+static int cbufidx;
+static int cbufalloc = 0;
+
+static int kw_token(const char *kw);
+
+#define MAX_IMPORT_DEPTH 10
+struct {
+ YY_BUFFER_STATE state;
+ char *temp_name;
+} import_stack[MAX_IMPORT_DEPTH];
+int import_stack_ptr = 0;
+
+static void pop_import(void);
+
+%}
+
+/*
+ **************************************************************************
+ * The flexer starts here
+ **************************************************************************
+ */
+%%
+^#.*
+\" yy_push_state(QUOTE); cbufidx = 0;
+<QUOTE>\" {
+ yy_pop_state();
+ yylval.str = get_buffered_cstring();
+ return aSTRING;
+ }
+<QUOTE>\\\\ |
+<QUOTE>\\\" addcchar(yytext[1]);
+<QUOTE>\\. addcchar('\\'); addcchar(yytext[1]);
+<QUOTE>. addcchar(yytext[0]);
+{uuid} return aUUID;
+{hex} return aNUM;
+{int} return aNUM;
+{cident} return kw_token(yytext);
+\n
+{ws}
+\<\< return SHL;
+\>\> return SHR;
+. return yytext[0];
+<<EOF>> {
+ if (import_stack_ptr) pop_import();
+ else yyterminate();
+ }
+%%
+
+#ifndef yywrap
+int yywrap(void)
+{
+ return 1;
+}
+#endif
+
+static struct {
+ const char *kw;
+ int token;
+ int val;
+} keywords[] = {
+ {"__cdecl", tCDECL},
+ {"__int64", tINT64},
+ {"__stdcall", tSTDCALL},
+ {"_stdcall", tSTDCALL},
+ {"aggregatable", tAGGREGATABLE},
+ {"allocate", tALLOCATE},
+ {"appobject", tAPPOBJECT},
+ {"arrays", tARRAYS},
+ {"async", tASYNC},
+ {"async_uuid", tASYNCUUID},
+ {"auto_handle", tAUTOHANDLE},
+ {"bindable", tBINDABLE},
+ {"boolean", tBOOLEAN},
+ {"broadcast", tBROADCAST},
+ {"byte", tBYTE},
+ {"byte_count", tBYTECOUNT},
+ {"call_as", tCALLAS},
+ {"callback", tCALLBACK},
+ {"case", tCASE},
+ {"char", tCHAR},
+ {"coclass", tCOCLASS},
+ {"code", tCODE},
+ {"comm_status", tCOMMSTATUS},
+ {"const", tCONST},
+ {"context_handle", tCONTEXTHANDLE},
+ {"context_handle_noserialize", tCONTEXTHANDLENOSERIALIZE},
+ {"context_handle_serialize", tCONTEXTHANDLENOSERIALIZE},
+ {"control", tCONTROL},
+ {"cpp_quote", tCPPQUOTE},
+/* ... */
+ {"default", tDEFAULT},
+/* ... */
+ {"double", tDOUBLE},
+/* ... */
+ {"enum", tENUM},
+/* ... */
+ {"extern", tEXTERN},
+/* ... */
+ {"float", tFLOAT},
+/* ... */
+ {"hyper", tHYPER},
+/* ... */
+ {"iid_is", tIIDIS},
+/* ... */
+ {"import", tIMPORT},
+ {"importlib", tIMPORTLIB},
+ {"in", tIN},
+ {"include", tINCLUDE},
+ {"in_line", tINLINE},
+ {"int", tINT},
+/* ... */
+ {"interface", tINTERFACE},
+/* ... */
+ {"length_is", tLENGTHIS},
+/* ... */
+ {"local", tLOCAL},
+ {"long", tLONG},
+/* ... */
+ {"object", tOBJECT},
+ {"odl", tODL},
+ {"oleautomation", tOLEAUTOMATION},
+/* ... */
+ {"out", tOUT},
+/* ... */
+ {"pointer_default", tPOINTERDEFAULT},
+/* ... */
+ {"ref", tREF},
+/* ... */
+ {"short", tSHORT},
+ {"signed", tSIGNED},
+ {"size_is", tSIZEIS},
+ {"sizeof", tSIZEOF},
+/* ... */
+ {"string", tSTRING},
+ {"struct", tSTRUCT},
+ {"switch", tSWITCH},
+ {"switch_is", tSWITCHIS},
+ {"switch_type", tSWITCHTYPE},
+/* ... */
+ {"typedef", tTYPEDEF},
+ {"union", tUNION},
+/* ... */
+ {"unique", tUNIQUE},
+ {"unsigned", tUNSIGNED},
+/* ... */
+ {"uuid", tUUID},
+ {"v1_enum", tV1ENUM},
+/* ... */
+ {"version", tVERSION},
+ {"void", tVOID},
+ {"wchar_t", tWCHAR},
+ {"wire_marshal", tWIREMARSHAL},
+ {NULL}
+};
+
+static int kw_token(const char *kw)
+{
+ int i;
+ for (i=0; keywords[i].kw; i++)
+ if (strcmp(kw, keywords[i].kw) == 0)
+ return keywords[i].token;
+ yylval.str = xstrdup(kw);
+ return is_type(kw) ? aKNOWNTYPE : aIDENTIFIER;
+}
+
+static void addcchar(char c)
+{
+ if(cbufidx >= cbufalloc)
+ {
+ cbufalloc += 1024;
+ cbuffer = xrealloc(cbuffer, cbufalloc * sizeof(cbuffer[0]));
+ if(cbufalloc > 65536)
+ yywarning("Reallocating string buffer larger than 64kB");
+ }
+ cbuffer[cbufidx++] = c;
+}
+
+static char *get_buffered_cstring(void)
+{
+ addcchar(0);
+ return xstrdup(cbuffer);
+}
+
+static void pop_import(void)
+{
+ int ptr = import_stack_ptr-1;
+
+ fclose(yyin);
+ yy_delete_buffer( YY_CURRENT_BUFFER );
+ yy_switch_to_buffer( import_stack[ptr].state );
+ if (temp_name) {
+ unlink(temp_name);
+ free(temp_name);
+ }
+ temp_name = import_stack[ptr].temp_name;
+ import_stack_ptr--;
+}
+
+struct imports {
+ char *name;
+ struct imports *next;
+} *first_import;
+
+void do_import(char *fname)
+{
+ FILE *f;
+ char *hname, *path;
+ struct imports *import;
+ int ptr = import_stack_ptr;
+ int ret;
+
+ if (!parse_only) {
+ hname = dup_basename(fname, ".idl");
+ strcat(hname, ".h");
+
+ fprintf(header, "#include \"%s\"\n", hname);
+ free(hname);
+ }
+
+ import = first_import;
+ while (import && strcmp(import->name, fname))
+ import = import->next;
+ if (import) return; /* already imported */
+
+ import = xmalloc(sizeof(struct imports));
+ import->name = xstrdup(fname);
+ import->next = first_import;
+ first_import = import;
+
+ if (!(path = wpp_find_include( fname, 1 )))
+ yyerror("Unable to open include file %s", fname);
+
+ import_stack[ptr].temp_name = temp_name;
+ import_stack_ptr++;
+
+ ret = wpp_parse_temp( path, &temp_name );
+ free( path );
+ if (ret) exit(1);
+
+ if((f = fopen(temp_name, "r")) == NULL)
+ yyerror("Unable to open %s", temp_name);
+
+ import_stack[ptr].state = YY_CURRENT_BUFFER;
+ yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE));
+}
+
+void abort_import(void)
+{
+ int ptr;
+
+ for (ptr=0; ptr<import_stack_ptr; ptr++)
+ unlink(import_stack[ptr].temp_name);
+}