PATCH: widl compiler from the rewind tree (Part 1)
Steven Edwards
Steven_Ed4153 at yahoo.com
Sun Jun 30 15:03:40 CDT 2002
I saved you the trouble and added the LGPL license statement to the files.
Changelog: Merge of widl compiler from X11 fork.
-------------- next part --------------
--- NUL Wed Dec 31 19:00:00 1969
+++ ppl.l Sun Jun 30 02:58:24 2002
@@ -0,0 +1,1510 @@
+/*
+ * Wrc preprocessor lexical analysis
+ *
+ * Copyright 1999-2000 Bertho A. Stultiens (BS)
+ *
+ * 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
+ *
+ *
+ * 24-Apr-2000 BS - Started from scratch to restructure everything
+ * and reintegrate the source into the wine-tree.
+ * 04-Jan-2000 BS - Added comments about the lexicographical
+ * grammar to give some insight in the complexity.
+ * 28-Dec-1999 BS - Eliminated backing-up of the flexer by running
+ * `flex -b' on the source. This results in some
+ * weirdo extra rules, but a much faster scanner.
+ * 23-Dec-1999 BS - Started this file
+ *
+ *-------------------------------------------------------------------------
+ * The preprocessor's lexographical grammar (approximately):
+ *
+ * pp := {ws} # {ws} if {ws} {expr} {ws} \n
+ * | {ws} # {ws} ifdef {ws} {id} {ws} \n
+ * | {ws} # {ws} ifndef {ws} {id} {ws} \n
+ * | {ws} # {ws} elif {ws} {expr} {ws} \n
+ * | {ws} # {ws} else {ws} \n
+ * | {ws} # {ws} endif {ws} \n
+ * | {ws} # {ws} include {ws} < {anytext} > \n
+ * | {ws} # {ws} include {ws} " {anytext} " \n
+ * | {ws} # {ws} define {ws} {anytext} \n
+ * | {ws} # {ws} define( {arglist} ) {ws} {expansion} \n
+ * | {ws} # {ws} pragma {ws} {anytext} \n
+ * | {ws} # {ws} ident {ws} {anytext} \n
+ * | {ws} # {ws} error {ws} {anytext} \n
+ * | {ws} # {ws} warning {ws} {anytext} \n
+ * | {ws} # {ws} line {ws} " {anytext} " {number} \n
+ * | {ws} # {ws} {number} " {anytext} " {number} [{number} [{number}]] \n
+ * | {ws} # {ws} \n
+ *
+ * ws := [ \t\r\f\v]*
+ *
+ * expr := {expr} [+-*%^/|&] {expr}
+ * | {expr} {logor|logand} {expr}
+ * | [!~+-] {expr}
+ * | {expr} ? {expr} : {expr}
+ *
+ * logor := ||
+ *
+ * logand := &&
+ *
+ * id := [a-zA-Z_][a-zA-Z0-9_]*
+ *
+ * anytext := [^\n]* (see note)
+ *
+ * arglist :=
+ * | {id}
+ * | {arglist} , {id}
+ * | {arglist} , {id} ...
+ *
+ * expansion := {id}
+ * | # {id}
+ * | {anytext}
+ * | {anytext} ## {anytext}
+ *
+ * number := [0-9]+
+ *
+ * Note: "anytext" is not always "[^\n]*". This is because the
+ * trailing context must be considered as well.
+ *
+ * The only certain assumption for the preprocessor to make is that
+ * directives start at the beginning of the line, followed by a '#'
+ * and end with a newline.
+ * Any directive may be suffixed with a line-continuation. Also
+ * classical comment / *...* / (note: no comments within comments,
+ * therefore spaces) is considered to be a line-continuation
+ * (according to gcc and egcs AFAIK, ANSI is a bit vague).
+ * Comments have not been added to the above grammer for simplicity
+ * reasons. However, it is allowed to enter comment anywhere within
+ * the directives as long as they do not interfere with the context.
+ * All comments are considered to be deletable whitespace (both
+ * classical form "/ *...* /" and C++ form "//...\n").
+ *
+ * All recursive scans, except for macro-expansion, are done by the
+ * parser, whereas the simple state transitions of non-recursive
+ * directives are done in the scanner. This results in the many
+ * exclusive start-conditions of the scanner.
+ *
+ * Macro expansions are slightly more difficult because they have to
+ * prescan the arguments. Parameter substitution is literal if the
+ * substitution is # or ## (either side). This enables new identifiers
+ * to be created (see 'info cpp' node Macro|Pitfalls|Prescan for more
+ * information).
+ *
+ * FIXME: Variable macro parameters is recognized, but not yet
+ * expanded. I have to reread the ANSI standard on the subject (yes,
+ * ANSI defines it).
+ *
+ * The following special defines are supported:
+ * __FILE__ -> "thissource.c"
+ * __LINE__ -> 123
+ * __DATE__ -> "May 1 2000"
+ * __TIME__ -> "23:59:59"
+ * These macros expand, as expected, into their ANSI defined values.
+ *
+ * The same include prevention is implemented as gcc and egcs does.
+ * This results in faster processing because we do not read the text
+ * at all. Some wine-sources attempt to include the same file 4 or 5
+ * times. This strategy also saves a lot blank output-lines, which in
+ * its turn improves the real resource scanner/parser.
+ *
+ */
+
+/*
+ * Special flex options and exclusive scanner start-conditions
+ */
+%option stack
+%option never-interactive
+
+%x pp_pp
+%x pp_eol
+%x pp_inc
+%x pp_dqs
+%x pp_sqs
+%x pp_iqs
+%x pp_comment
+%x pp_def
+%x pp_define
+%x pp_macro
+%x pp_mbody
+%x pp_macign
+%x pp_macscan
+%x pp_macexp
+%x pp_if
+%x pp_ifd
+%x pp_line
+%x pp_defined
+%x pp_ignore
+%x RCINCL
+
+ws [ \v\f\t\r]
+cident [a-zA-Z_][0-9a-zA-Z_]*
+ul [uUlL]|[uUlL][lL]|[lL][uU]|[lL][lL][uU]|[uU][lL][lL]|[lL][uU][lL]
+
+%{
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+
+#include "utils.h"
+#include "widl.h"
+#include "preproc.h"
+
+#include "ppy.tab.h"
+
+/*
+ * Make sure that we are running an appropriate version of flex.
+ */
+#if !defined(YY_FLEX_MAJOR_VERSION) || (1000 * YY_FLEX_MAJOR_VERSION + YY_FLEX_MINOR_VERSION < 2005)
+#error Must use flex version 2.5.1 or higher (yy_scan_* routines are required).
+#endif
+
+#define YY_USE_PROTOS
+#define YY_NO_UNPUT
+#define YY_READ_BUF_SIZE 65536 /* So we read most of a file at once */
+
+#define yy_current_state() YY_START
+#define yy_pp_state(x) yy_pop_state(); yy_push_state(x)
+
+/*
+ * Always update the current character position within a line
+ */
+#define YY_USER_ACTION char_number+=ppleng;
+
+/*
+ * Buffer management for includes and expansions
+ */
+#define MAXBUFFERSTACK 128 /* Nesting more than 128 includes or macro expansion textss is insane */
+
+typedef struct bufferstackentry {
+ YY_BUFFER_STATE bufferstate; /* Buffer to switch back to */
+ pp_entry_t *define; /* Points to expanding define or NULL if handling includes */
+ int line_number; /* Line that we were handling */
+ int char_number; /* The current position on that line */
+ char *filename; /* Filename that we were handling */
+ int if_depth; /* How many #if:s deep to check matching #endif:s */
+ int ncontinuations; /* Remember the continuation state */
+ int should_pop; /* Set if we must pop the start-state on EOF */
+ /* Include management */
+ int include_state;
+ char *include_ppp;
+ char *include_filename;
+ int include_ifdepth;
+ int seen_junk;
+ int pass_data;
+} bufferstackentry_t;
+
+#define ALLOCBLOCKSIZE (1 << 10) /* Allocate these chunks at a time for string-buffers */
+
+/*
+ * Macro expansion nesting
+ * We need the stack to handle expansions while scanning
+ * a macro's arguments. The TOS must always be the macro
+ * that receives the current expansion from the scanner.
+ */
+#define MAXMACEXPSTACK 128 /* Nesting more than 128 macro expansions is insane */
+
+typedef struct macexpstackentry {
+ pp_entry_t *ppp; /* This macro we are scanning */
+ char **args; /* With these arguments */
+ char **ppargs; /* Resulting in these preprocessed arguments */
+ int *nnls; /* Number of newlines per argument */
+ int nargs; /* And this many arguments scanned */
+ int parentheses; /* Nesting level of () */
+ int curargsize; /* Current scanning argument's size */
+ int curargalloc; /* Current scanning argument's block allocated */
+ char *curarg; /* Current scanning argument's content */
+} macexpstackentry_t;
+
+#define MACROPARENTHESES() (top_macro()->parentheses)
+
+/*
+ * Prototypes
+ */
+static void newline(int);
+static int make_number(int radix, YYSTYPE *val, char *str, int len);
+static void put_buffer(char *s, int len);
+/* Buffer management */
+static void push_buffer(pp_entry_t *ppp, char *filename, char *incname, int pop);
+static bufferstackentry_t *pop_buffer(void);
+/* String functions */
+static void new_string(void);
+static void add_string(char *str, int len);
+static char *get_string(void);
+static void put_string(void);
+static int string_start(void);
+/* Macro functions */
+static void push_macro(pp_entry_t *ppp);
+static macexpstackentry_t *top_macro(void);
+static macexpstackentry_t *pop_macro(void);
+static void free_macro(macexpstackentry_t *mep);
+static void add_text_to_macro(char *text, int len);
+static void macro_add_arg(int last);
+static void macro_add_expansion(void);
+/* Expansion */
+static void expand_special(pp_entry_t *ppp);
+static void expand_define(pp_entry_t *ppp);
+static void expand_macro(macexpstackentry_t *mep);
+
+/*
+ * Local variables
+ */
+static int ncontinuations;
+
+static int strbuf_idx = 0;
+static int strbuf_alloc = 0;
+static char *strbuffer = NULL;
+static int str_startline;
+
+static macexpstackentry_t *macexpstack[MAXMACEXPSTACK];
+static int macexpstackidx = 0;
+
+static bufferstackentry_t bufferstack[MAXBUFFERSTACK];
+static int bufferstackidx = 0;
+
+static int pass_data=1;
+
+/*
+ * Global variables
+ */
+/*
+ * Trace the include files to prevent double reading.
+ * This save 20..30% of processing time for most stuff
+ * that uses complex includes.
+ * States:
+ * -1 Don't track or seen junk
+ * 0 New include, waiting for "#ifndef __xxx_h"
+ * 1 Seen #ifndef, waiting for "#define __xxx_h ..."
+ * 2 Seen #endif, waiting for EOF
+ */
+int include_state = -1;
+char *include_ppp = NULL; /* The define to be set from the #ifndef */
+int include_ifdepth = 0; /* The level of ifs at the #ifdef */
+int seen_junk = 0; /* Set when junk is seen */
+includelogicentry_t *includelogiclist = NULL;
+
+%}
+
+/*
+ **************************************************************************
+ * The scanner starts here
+ **************************************************************************
+ */
+
+%%
+ /*
+ * Catch line-continuations.
+ * Note: Gcc keeps the line-continuations in, for example, strings
+ * intact. However, I prefer to remove them all so that the next
+ * scanner will not need to reduce the continuation state.
+ *
+ * <*>\\\n newline(0);
+ */
+
+ /*
+ * Detect the leading # of a preprocessor directive.
+ */
+<INITIAL,pp_ignore>^{ws}*# seen_junk++; yy_push_state(pp_pp);
+
+ /*
+ * Scan for the preprocessor directives
+ */
+<pp_pp>{ws}*include{ws}* if(yy_top_state() != pp_ignore) {yy_pp_state(pp_inc); return tINCLUDE;} else {yy_pp_state(pp_eol);}
+<pp_pp>{ws}*define{ws}* yy_pp_state(yy_current_state() != pp_ignore ? pp_def : pp_eol);
+<pp_pp>{ws}*error{ws}* yy_pp_state(pp_eol); if(yy_top_state() != pp_ignore) return tERROR;
+<pp_pp>{ws}*warning{ws}* yy_pp_state(pp_eol); if(yy_top_state() != pp_ignore) return tWARNING;
+<pp_pp>{ws}*pragma{ws}* yy_pp_state(pp_eol); if(yy_top_state() != pp_ignore) return tPRAGMA;
+<pp_pp>{ws}*ident{ws}* yy_pp_state(pp_eol); if(yy_top_state() != pp_ignore) return tPPIDENT;
+<pp_pp>{ws}*undef{ws}* if(yy_top_state() != pp_ignore) {yy_pp_state(pp_ifd); return tUNDEF;} else {yy_pp_state(pp_eol);}
+<pp_pp>{ws}*ifdef{ws}* yy_pp_state(pp_ifd); return tIFDEF;
+<pp_pp>{ws}*ifndef{ws}* seen_junk--; yy_pp_state(pp_ifd); return tIFNDEF;
+<pp_pp>{ws}*if{ws}* yy_pp_state(pp_if); return tIF;
+<pp_pp>{ws}*elif{ws}* yy_pp_state(pp_if); return tELIF;
+<pp_pp>{ws}*else{ws}* return tELSE;
+<pp_pp>{ws}*endif{ws}* return tENDIF;
+<pp_pp>{ws}*line{ws}* if(yy_top_state() != pp_ignore) {yy_pp_state(pp_line); return tLINE;} else {yy_pp_state(pp_eol);}
+<pp_pp>{ws}+ if(yy_top_state() != pp_ignore) {yy_pp_state(pp_line); return tGCCLINE;} else {yy_pp_state(pp_eol);}
+<pp_pp>{ws}*[a-z]+ pperror("Invalid preprocessor token '%s'", pptext);
+<pp_pp>\r?\n newline(1); yy_pop_state(); return tNL; /* This could be the null-token */
+<pp_pp>\\\r?\n newline(0);
+<pp_pp>\\\r? pperror("Preprocessor junk '%s'", pptext);
+<pp_pp>. return *pptext;
+
+ /*
+ * Handle #include and #line
+ */
+<pp_line>[0-9]+ return make_number(10, &pplval, pptext, ppleng);
+<pp_inc>\< new_string(); add_string(pptext, ppleng); yy_push_state(pp_iqs);
+<pp_inc,pp_line>\" new_string(); add_string(pptext, ppleng); yy_push_state(pp_dqs);
+<pp_inc,pp_line>{ws}+ ;
+<pp_inc,pp_line>\n newline(1); yy_pop_state(); return tNL;
+<pp_inc,pp_line>\\\r?\n newline(0);
+<pp_inc,pp_line>(\\\r?)|(.) pperror(yy_current_state() == pp_inc ? "Trailing junk in #include" : "Trailing junk in #line");
+
+ /*
+ * Ignore all input when a false clause is parsed
+ */
+<pp_ignore>[^#/\\\n]+ ;
+<pp_ignore>\n newline(1);
+<pp_ignore>\\\r?\n newline(0);
+<pp_ignore>(\\\r?)|(.) ;
+
+ /*
+ * Handle #if and #elif.
+ * These require conditionals to be evaluated, but we do not
+ * want to jam the scanner normally when we see these tokens.
+ * Note: tIDENT is handled below.
+ */
+
+<pp_if>0[0-7]*{ul}? return make_number(8, &pplval, pptext, ppleng);
+<pp_if>0[0-7]*[8-9]+{ul}? pperror("Invalid octal digit");
+<pp_if>[1-9][0-9]*{ul}? return make_number(10, &pplval, pptext, ppleng);
+<pp_if>0[xX][0-9a-fA-F]+{ul}? return make_number(16, &pplval, pptext, ppleng);
+<pp_if>0[xX] pperror("Invalid hex number");
+<pp_if>defined yy_push_state(pp_defined); return tDEFINED;
+<pp_if>"<<" return tLSHIFT;
+<pp_if>">>" return tRSHIFT;
+<pp_if>"&&" return tLOGAND;
+<pp_if>"||" return tLOGOR;
+<pp_if>"==" return tEQ;
+<pp_if>"!=" return tNE;
+<pp_if>"<=" return tLTE;
+<pp_if>">=" return tGTE;
+<pp_if>\n newline(1); yy_pop_state(); return tNL;
+<pp_if>\\\r?\n newline(0);
+<pp_if>\\\r? pperror("Junk in conditional expression");
+<pp_if>{ws}+ ;
+<pp_if>\' new_string(); add_string(pptext, ppleng); yy_push_state(pp_sqs);
+<pp_if>\" pperror("String constants not allowed in conditionals");
+<pp_if>. return *pptext;
+
+ /*
+ * Handle #ifdef, #ifndef and #undef
+ * to get only an untranslated/unexpanded identifier
+ */
+<pp_ifd>{cident} pplval.cptr = xstrdup(pptext); return tIDENT;
+<pp_ifd>{ws}+ ;
+<pp_ifd>\n newline(1); yy_pop_state(); return tNL;
+<pp_ifd>\\\r?\n newline(0);
+<pp_ifd>(\\\r?)|(.) pperror("Identifier expected");
+
+ /*
+ * Handle the special 'defined' keyword.
+ * This is necessary to get the identifier prior to any
+ * substitutions.
+ */
+<pp_defined>{cident} yy_pop_state(); pplval.cptr = xstrdup(pptext); return tIDENT;
+<pp_defined>{ws}+ ;
+<pp_defined>(\()|(\)) return *pptext;
+<pp_defined>\\\r?\n newline(0);
+<pp_defined>(\\.)|(\n)|(.) pperror("Identifier expected");
+
+ /*
+ * Handle #error, #warning, #pragma and #ident.
+ * Pass everything literally to the parser, which
+ * will act appropriately.
+ * Comments are stripped from the literal text.
+ */
+<pp_eol>[^/\\\n]+ if(yy_top_state() != pp_ignore) { pplval.cptr = xstrdup(pptext); return tLITERAL; }
+<pp_eol>\/[^/\\\n*]* if(yy_top_state() != pp_ignore) { pplval.cptr = xstrdup(pptext); return tLITERAL; }
+<pp_eol>(\\\r?)|(\/[^/*]) if(yy_top_state() != pp_ignore) { pplval.cptr = xstrdup(pptext); return tLITERAL; }
+<pp_eol>\n newline(1); yy_pop_state(); if(yy_current_state() != pp_ignore) { return tNL; }
+<pp_eol>\\\r?\n newline(0);
+
+ /*
+ * Handle left side of #define
+ */
+<pp_def>{cident}\( pplval.cptr = xstrdup(pptext); pplval.cptr[ppleng-1] = '\0'; yy_pp_state(pp_macro); return tMACRO;
+<pp_def>{cident} pplval.cptr = xstrdup(pptext); yy_pp_state(pp_define); return tDEFINE;
+<pp_def>{ws}+ ;
+<pp_def>\\\r?\n newline(0);
+<pp_def>(\\\r?)|(\n)|(.) perror("Identifier expected");
+
+ /*
+ * Scan the substitution of a define
+ */
+<pp_define>[^'"/\\\n]+ pplval.cptr = xstrdup(pptext); return tLITERAL;
+<pp_define>(\\\r?)|(\/[^/*]) pplval.cptr = xstrdup(pptext); return tLITERAL;
+<pp_define>\\\r?\n{ws}+ newline(0); pplval.cptr = xstrdup(" "); return tLITERAL;
+<pp_define>\\\r?\n newline(0);
+<pp_define>\n newline(1); yy_pop_state(); return tNL;
+<pp_define>\' new_string(); add_string(pptext, ppleng); yy_push_state(pp_sqs);
+<pp_define>\" new_string(); add_string(pptext, ppleng); yy_push_state(pp_dqs);
+
+ /*
+ * Scan the definition macro arguments
+ */
+<pp_macro>\){ws}* yy_pp_state(pp_mbody); return tMACROEND;
+<pp_macro>{ws}+ ;
+<pp_macro>{cident} pplval.cptr = xstrdup(pptext); return tIDENT;
+<pp_macro>, return ',';
+<pp_macro>"..." return tELIPSIS;
+<pp_macro>(\\\r?)|(\n)|(.)|(\.\.?) pperror("Argument identifier expected");
+<pp_macro>\\\r?\n newline(0);
+
+ /*
+ * Scan the substitution of a macro
+ */
+<pp_mbody>[^a-zA-Z0-9'"#/\\\n]+ pplval.cptr = xstrdup(pptext); return tLITERAL;
+<pp_mbody>{cident} pplval.cptr = xstrdup(pptext); return tIDENT;
+<pp_mbody>\#\# return tCONCAT;
+<pp_mbody>\# return tSTRINGIZE;
+<pp_mbody>[0-9][^'"#/\\\n]* pplval.cptr = xstrdup(pptext); return tLITERAL;
+<pp_mbody>(\\\r?)|(\/[^/*'"#\\\n]*) pplval.cptr = xstrdup(pptext); return tLITERAL;
+<pp_mbody>\\\r?\n{ws}+ newline(0); pplval.cptr = xstrdup(" "); return tLITERAL;
+<pp_mbody>\\\r?\n newline(0);
+<pp_mbody>\n newline(1); yy_pop_state(); return tNL;
+<pp_mbody>\' new_string(); add_string(pptext, ppleng); yy_push_state(pp_sqs);
+<pp_mbody>\" new_string(); add_string(pptext, ppleng); yy_push_state(pp_dqs);
+
+ /*
+ * Macro expansion text scanning.
+ * This state is active just after the identifier is scanned
+ * that triggers an expansion. We *must* delete the leading
+ * whitespace before we can start scanning for arguments.
+ *
+ * If we do not see a '(' as next trailing token, then we have
+ * a false alarm. We just continue with a nose-bleed...
+ */
+<pp_macign>{ws}*/\( yy_pp_state(pp_macscan);
+<pp_macign>{ws}*\n {
+ if(yy_top_state() != pp_macscan)
+ newline(0);
+ }
+<pp_macign>{ws}*\\\r?\n newline(0);
+<pp_macign>{ws}+|{ws}*\\\r?|. {
+ macexpstackentry_t *mac = pop_macro();
+ yy_pop_state();
+ put_buffer(mac->ppp->ident, strlen(mac->ppp->ident));
+ put_buffer(pptext, ppleng);
+ free_macro(mac);
+ }
+
+ /*
+ * Macro expansion argument text scanning.
+ * This state is active when a macro's arguments are being read for expansion.
+ */
+<pp_macscan>\( {
+ if(++MACROPARENTHESES() > 1)
+ add_text_to_macro(pptext, ppleng);
+ }
+<pp_macscan>\) {
+ if(--MACROPARENTHESES() == 0)
+ {
+ yy_pop_state();
+ macro_add_arg(1);
+ }
+ else
+ add_text_to_macro(pptext, ppleng);
+ }
+<pp_macscan>, {
+ if(MACROPARENTHESES() > 1)
+ add_text_to_macro(pptext, ppleng);
+ else
+ macro_add_arg(0);
+ }
+<pp_macscan>\" new_string(); add_string(pptext, ppleng); yy_push_state(pp_dqs);
+<pp_macscan>\' new_string(); add_string(pptext, ppleng); yy_push_state(pp_sqs);
+<pp_macscan>"/*" yy_push_state(pp_comment); add_text_to_macro(" ", 1);
+<pp_macscan>\n line_number++; char_number = 1; add_text_to_macro(pptext, ppleng);
+<pp_macscan>([^/(),\\\n"']+)|(\/[^/*(),\\\n'"]*)|(\\\r?)|(.) add_text_to_macro(pptext, ppleng);
+<pp_macscan>\\\r?\n newline(0);
+
+ /*
+ * Comment handling (almost all start-conditions)
+ */
+<INITIAL,pp_pp,pp_ignore,pp_eol,pp_inc,pp_if,pp_ifd,pp_defined,pp_def,pp_define,pp_macro,pp_mbody,RCINCL>"/*" yy_push_state(pp_comment);
+<pp_comment>[^*\n]*|"*"+[^*/\n]* ;
+<pp_comment>\n newline(0);
+<pp_comment>"*"+"/" yy_pop_state();
+
+ /*
+ * Remove C++ style comment (almost all start-conditions)
+ */
+<INITIAL,pp_pp,pp_ignore,pp_eol,pp_inc,pp_if,pp_ifd,pp_defined,pp_def,pp_define,pp_macro,pp_mbody,pp_macscan,RCINCL>"//"[^\n]* {
+ if(pptext[ppleng-1] == '\\')
+ ppwarning("C++ style comment ends with an escaped newline (escape ignored)");
+ }
+
+ /*
+ * Single, double and <> quoted constants
+ */
+<INITIAL,pp_macexp>\" seen_junk++; new_string(); add_string(pptext, ppleng); yy_push_state(pp_dqs);
+<INITIAL,pp_macexp>\' seen_junk++; new_string(); add_string(pptext, ppleng); yy_push_state(pp_sqs);
+<pp_dqs>[^"\\\n]+ add_string(pptext, ppleng);
+<pp_dqs>\" {
+ add_string(pptext, ppleng);
+ yy_pop_state();
+ switch(yy_current_state())
+ {
+ case pp_pp:
+ case pp_define:
+ case pp_mbody:
+ case pp_inc:
+ case pp_line:
+ case RCINCL:
+ if (yy_current_state()==RCINCL) yy_pop_state();
+ pplval.cptr = get_string();
+ return tDQSTRING;
+ default:
+ put_string();
+ }
+ }
+<pp_sqs>[^'\\\n]+ add_string(pptext, ppleng);
+<pp_sqs>\' {
+ add_string(pptext, ppleng);
+ yy_pop_state();
+ switch(yy_current_state())
+ {
+ case pp_if:
+ case pp_define:
+ case pp_mbody:
+ pplval.cptr = get_string();
+ return tSQSTRING;
+ default:
+ put_string();
+ }
+ }
+<pp_iqs>[^\>\\\n]+ add_string(pptext, ppleng);
+<pp_iqs>\> {
+ add_string(pptext, ppleng);
+ yy_pop_state();
+ pplval.cptr = get_string();
+ return tIQSTRING;
+ }
+<pp_dqs>\\\r?\n {
+ /*
+ * This is tricky; we need to remove the line-continuation
+ * from preprocessor strings, but OTOH retain them in all
+ * other strings. This is because the resource grammar is
+ * even more braindead than initially analysed and line-
+ * continuations in strings introduce, sigh, newlines in
+ * the output. There goes the concept of non-breaking, non-
+ * spacing whitespace.
+ */
+ switch(yy_top_state())
+ {
+ case pp_pp:
+ case pp_define:
+ case pp_mbody:
+ case pp_inc:
+ case pp_line:
+ newline(0);
+ break;
+ default:
+ add_string(pptext, ppleng);
+ newline(-1);
+ }
+ }
+<pp_iqs,pp_dqs,pp_sqs>\\. add_string(pptext, ppleng);
+<pp_iqs,pp_dqs,pp_sqs>\n {
+ newline(1);
+ add_string(pptext, ppleng);
+ ppwarning("Newline in string constant encounterd (started line %d)", string_start());
+ }
+
+ /*
+ * Identifier scanning
+ */
+<INITIAL,pp_if,pp_inc,pp_macexp>{cident} {
+ pp_entry_t *ppp;
+ seen_junk++;
+ if(!(ppp = pplookup(pptext)))
+ {
+ if(yy_current_state() == pp_inc)
+ pperror("Expected include filename");
+
+ if(yy_current_state() == pp_if)
+ {
+ pplval.cptr = xstrdup(pptext);
+ return tIDENT;
+ }
+ else {
+ if((yy_current_state()==INITIAL) && (strcasecmp(pptext,"RCINCLUDE")==0)){
+ yy_push_state(RCINCL);
+ return tRCINCLUDE;
+ }
+ else put_buffer(pptext, ppleng);
+ }
+ }
+ else if(!ppp->expanding)
+ {
+ switch(ppp->type)
+ {
+ case def_special:
+ expand_special(ppp);
+ break;
+ case def_define:
+ expand_define(ppp);
+ break;
+ case def_macro:
+ yy_push_state(pp_macign);
+ push_macro(ppp);
+ break;
+ default:
+ internal_error(__FILE__, __LINE__, "Invalid define type %d\n", ppp->type);
+ }
+ }
+ }
+
+ /*
+ * Everything else that needs to be passed and
+ * newline and continuation handling
+ */
+<INITIAL,pp_macexp>[^a-zA-Z_#'"/\\\n \r\t\f\v]+|(\/|\\)[^a-zA-Z_/*'"\\\n \r\t\v\f]* seen_junk++; put_buffer(pptext, ppleng);
+<INITIAL,pp_macexp>{ws}+ put_buffer(pptext, ppleng);
+<INITIAL>\n newline(1);
+<INITIAL>\\\r?\n newline(0);
+<INITIAL>\\\r? seen_junk++; put_buffer(pptext, ppleng);
+
+ /*
+ * Special catcher for macro argmument expansion to prevent
+ * newlines to propagate to the output or admin.
+ */
+<pp_macexp>(\n)|(.)|(\\\r?(\n|.)) put_buffer(pptext, ppleng);
+
+<RCINCL>[A-Za-z0-9_\.\\/]+ {
+ pplval.cptr=xstrdup(pptext);
+ yy_pop_state();
+ return tRCINCLUDEPATH;
+ }
+
+<RCINCL>{ws}+ ;
+
+<RCINCL>\" {
+ new_string(); add_string(pptext,ppleng);yy_push_state(pp_dqs);
+ }
+
+ /*
+ * This is a 'catch-all' rule to discover errors in the scanner
+ * in an orderly manner.
+ */
+<*>. seen_junk++; ppwarning("Unmatched text '%c' (0x%02x); please report\n", isprint(*pptext & 0xff) ? *pptext : ' ', *pptext);
+
+<<EOF>> {
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+ bufferstackentry_t *bep = pop_buffer();
+
+ if((!bep && get_if_depth()) || (bep && get_if_depth() != bep->if_depth))
+ ppwarning("Unmatched #if/#endif at end of file");
+
+ if(!bep)
+ {
+ if(YY_START != INITIAL)
+ pperror("Unexpected end of file during preprocessing");
+ yyterminate();
+ }
+ else if(bep->should_pop == 2)
+ {
+ macexpstackentry_t *mac;
+ mac = pop_macro();
+ expand_macro(mac);
+ }
+ pp_delete_buffer(b);
+ }
+
+%%
+/*
+ **************************************************************************
+ * Support functions
+ **************************************************************************
+ */
+
+#ifndef ppwrap
+int ppwrap(void)
+{
+ return 1;
+}
+#endif
+
+
+/*
+ *-------------------------------------------------------------------------
+ * Output newlines or set them as continuations
+ *
+ * Input: -1 - Don't count this one, but update local position (see pp_dqs)
+ * 0 - Line-continuation seen and cache output
+ * 1 - Newline seen and flush output
+ *-------------------------------------------------------------------------
+ */
+static void newline(int dowrite)
+{
+ line_number++;
+ char_number = 1;
+
+ if(dowrite == -1)
+ return;
+
+ ncontinuations++;
+ if(dowrite)
+ {
+ for(;ncontinuations; ncontinuations--)
+ put_buffer("\n", 1);
+ }
+}
+
+
+/*
+ *-------------------------------------------------------------------------
+ * Make a number out of an any-base and suffixed string
+ *
+ * Possible number extensions:
+ * - "" int
+ * - "L" long int
+ * - "LL" long long int
+ * - "U" unsigned int
+ * - "UL" unsigned long int
+ * - "ULL" unsigned long long int
+ * - "LU" unsigned long int
+ * - "LLU" unsigned long long int
+ * - "LUL" invalid
+ *
+ * FIXME:
+ * The sizes of resulting 'int' and 'long' are compiler specific.
+ * I depend on sizeof(int) > 2 here (although a relatively safe
+ * assumption).
+ * Long longs are not yet implemented because this is very compiler
+ * specific and I don't want to think too much about the problems.
+ *
+ *-------------------------------------------------------------------------
+ */
+static int make_number(int radix, YYSTYPE *val, char *str, int len)
+{
+ int is_l = 0;
+ int is_ll = 0;
+ int is_u = 0;
+ char ext[4];
+
+ ext[3] = '\0';
+ ext[2] = toupper(str[len-1]);
+ ext[1] = len > 1 ? toupper(str[len-2]) : ' ';
+ ext[0] = len > 2 ? toupper(str[len-3]) : ' ';
+
+ if(!strcmp(ext, "LUL"))
+ pperror("Invalid constant suffix");
+ else if(!strcmp(ext, "LLU") || !strcmp(ext, "ULL"))
+ {
+ is_ll++;
+ is_u++;
+ }
+ else if(!strcmp(ext+1, "LU") || !strcmp(ext+1, "UL"))
+ {
+ is_l++;
+ is_u++;
+ }
+ else if(!strcmp(ext+1, "LL"))
+ {
+ is_ll++;
+ }
+ else if(!strcmp(ext+2, "L"))
+ {
+ is_l++;
+ }
+ else if(!strcmp(ext+2, "U"))
+ {
+ is_u++;
+ }
+
+ if(is_ll)
+ internal_error(__FILE__, __LINE__, "long long constants not implemented yet");
+
+ if(is_u && is_l)
+ {
+ val->ulong = strtoul(str, NULL, radix);
+ return tULONG;
+ }
+ else if(!is_u && is_l)
+ {
+ val->slong = strtol(str, NULL, radix);
+ return tSLONG;
+ }
+ else if(is_u && !is_l)
+ {
+ val->uint = (unsigned int)strtoul(str, NULL, radix);
+ if(!win32 && val->uint > 65535)
+ {
+ pperror("Constant overflow");
+ }
+ return tUINT;
+ }
+
+ /* Else it must be an int... */
+ val->sint = (int)strtol(str, NULL, radix);
+ if(!win32 && (val->sint < -32768 || val->sint > 32768))
+ {
+ /*
+ * Note: test must be > 32768 because unary minus
+ * is handled as an expression! This can result in
+ * failure and must be checked in the parser.
+ */
+ pperror("Constant overflow");
+ }
+ return tSINT;
+}
+
+
+/*
+ *-------------------------------------------------------------------------
+ * Macro and define expansion support
+ *
+ * FIXME: Variable macro arguments.
+ *-------------------------------------------------------------------------
+ */
+static void expand_special(pp_entry_t *ppp)
+{
+ char *dbgtext = "?";
+ static char *buf = NULL;
+
+ assert(ppp->type == def_special);
+
+ if(!strcmp(ppp->ident, "__LINE__"))
+ {
+ dbgtext = "def_special(__LINE__)";
+ buf = xrealloc(buf, 32);
+ sprintf(buf, "%d", line_number);
+ }
+ else if(!strcmp(ppp->ident, "__FILE__"))
+ {
+ dbgtext = "def_special(__FILE__)";
+ buf = xrealloc(buf, strlen(input_name) + 3);
+ sprintf(buf, "\"%s\"", input_name);
+ }
+ else if(!strcmp(ppp->ident, "__DATE__"))
+ {
+ dbgtext = "def_special(__DATE__)";
+ buf = xrealloc(buf, 32);
+ strftime(buf, 32, "\"%b %d %Y\"", localtime(&now));
+ }
+ else if(!strcmp(ppp->ident, "__TIME__"))
+ {
+ dbgtext = "def_special(__TIME__)";
+ buf = xrealloc(buf, 32);
+ strftime(buf, 32, "\"%H:%M:%S\"", localtime(&now));
+ }
+ else
+ internal_error(__FILE__, __LINE__, "Special macro '%s' not found...\n", ppp->ident);
+
+ if(debuglevel & DEBUGLEVEL_PPLEX)
+ fprintf(stderr, "expand_special(%d): %s:%d: '%s' -> '%s'\n",
+ macexpstackidx,
+ input_name,
+ line_number,
+ ppp->ident,
+ buf ? buf : "");
+
+ if(buf && buf[0])
+ {
+ push_buffer(ppp, NULL, NULL, 0);
+ yy_scan_string(buf);
+ }
+}
+
+static void expand_define(pp_entry_t *ppp)
+{
+ assert(ppp->type == def_define);
+
+ if(debuglevel & DEBUGLEVEL_PPLEX)
+ fprintf(stderr, "expand_define(%d): %s:%d: '%s' -> '%s'\n",
+ macexpstackidx,
+ input_name,
+ line_number,
+ ppp->ident,
+ ppp->subst.text);
+ if(ppp->subst.text && ppp->subst.text[0])
+ {
+ push_buffer(ppp, NULL, NULL, 0);
+ yy_scan_string(ppp->subst.text);
+ }
+}
+
+static int curdef_idx = 0;
+static int curdef_alloc = 0;
+static char *curdef_text = NULL;
+
+static void add_text(char *str, int len)
+{
+ if(len == 0)
+ return;
+ if(curdef_idx >= curdef_alloc || curdef_alloc - curdef_idx < len)
+ {
+ curdef_alloc += (len + ALLOCBLOCKSIZE-1) & ~(ALLOCBLOCKSIZE-1);
+ curdef_text = xrealloc(curdef_text, curdef_alloc * sizeof(curdef_text[0]));
+ if(curdef_alloc > 65536)
+ ppwarning("Reallocating macro-expansion buffer larger than 64kB");
+ }
+ memcpy(&curdef_text[curdef_idx], str, len);
+ curdef_idx += len;
+}
+
+static mtext_t *add_expand_text(mtext_t *mtp, macexpstackentry_t *mep, int *nnl)
+{
+ char *cptr;
+ char *exp;
+ int tag;
+ int n;
+
+ if(mtp == NULL)
+ return NULL;
+
+ switch(mtp->type)
+ {
+ case exp_text:
+ if(debuglevel & DEBUGLEVEL_PPLEX)
+ fprintf(stderr, "add_expand_text: exp_text: '%s'\n", mtp->subst.text);
+ add_text(mtp->subst.text, strlen(mtp->subst.text));
+ break;
+
+ case exp_stringize:
+ if(debuglevel & DEBUGLEVEL_PPLEX)
+ fprintf(stderr, "add_expand_text: exp_stringize(%d): '%s'\n",
+ mtp->subst.argidx,
+ mep->args[mtp->subst.argidx]);
+ cptr = mep->args[mtp->subst.argidx];
+ add_text("\"", 1);
+ while(*cptr)
+ {
+ if(*cptr == '"' || *cptr == '\\')
+ add_text("\\", 1);
+ add_text(cptr, 1);
+ cptr++;
+ }
+ add_text("\"", 1);
+ break;
+
+ case exp_concat:
+ if(debuglevel & DEBUGLEVEL_PPLEX)
+ fprintf(stderr, "add_expand_text: exp_concat\n");
+ /* Remove trailing whitespace from current expansion text */
+ while(curdef_idx)
+ {
+ if(isspace(curdef_text[curdef_idx-1] & 0xff))
+ curdef_idx--;
+ else
+ break;
+ }
+ /* tag current position and recursively expand the next part */
+ tag = curdef_idx;
+ mtp = add_expand_text(mtp->next, mep, nnl);
+
+ /* Now get rid of the leading space of the expansion */
+ cptr = &curdef_text[tag];
+ n = curdef_idx - tag;
+ while(n)
+ {
+ if(isspace(*cptr & 0xff))
+ {
+ cptr++;
+ n--;
+ }
+ else
+ break;
+ }
+ if(cptr != &curdef_text[tag])
+ {
+ memmove(&curdef_text[tag], cptr, n);
+ curdef_idx -= (curdef_idx - tag) - n;
+ }
+ break;
+
+ case exp_subst:
+ if((mtp->next && mtp->next->type == exp_concat) || (mtp->prev && mtp->prev->type == exp_concat))
+ exp = mep->args[mtp->subst.argidx];
+ else
+ exp = mep->ppargs[mtp->subst.argidx];
+ if(exp)
+ {
+ add_text(exp, strlen(exp));
+ *nnl -= mep->nnls[mtp->subst.argidx];
+ cptr = strchr(exp, '\n');
+ while(cptr)
+ {
+ *cptr = ' ';
+ cptr = strchr(cptr+1, '\n');
+ }
+ mep->nnls[mtp->subst.argidx] = 0;
+ }
+ if(debuglevel & DEBUGLEVEL_PPLEX)
+ fprintf(stderr, "add_expand_text: exp_subst(%d): '%s'\n", mtp->subst.argidx, exp);
+ break;
+
+ default:
+ internal_error(__FILE__, __LINE__, "Invalid expansion type (%d) in macro expansion\n", mtp->type);
+ }
+ return mtp;
+}
+
+static void expand_macro(macexpstackentry_t *mep)
+{
+ mtext_t *mtp;
+ int n, k;
+ char *cptr;
+ int nnl = 0;
+ pp_entry_t *ppp = mep->ppp;
+ int nargs = mep->nargs;
+
+ assert(ppp->type == def_macro);
+ assert(ppp->expanding == 0);
+
+ if((ppp->nargs >= 0 && nargs != ppp->nargs) || (ppp->nargs < 0 && nargs < -ppp->nargs))
+ pperror("Too %s macro arguments (%d)", nargs < abs(ppp->nargs) ? "few" : "many", nargs);
+
+ for(n = 0; n < nargs; n++)
+ nnl += mep->nnls[n];
+
+ if(debuglevel & DEBUGLEVEL_PPLEX)
+ fprintf(stderr, "expand_macro(%d): %s:%d: '%s'(%d,%d) -> ...\n",
+ macexpstackidx,
+ input_name,
+ line_number,
+ ppp->ident,
+ mep->nargs,
+ nnl);
+
+ curdef_idx = 0;
+
+ for(mtp = ppp->subst.mtext; mtp; mtp = mtp->next)
+ {
+ if(!(mtp = add_expand_text(mtp, mep, &nnl)))
+ break;
+ }
+
+ for(n = 0; n < nnl; n++)
+ add_text("\n", 1);
+
+ /* To make sure there is room and termination (see below) */
+ add_text(" \0", 2);
+
+ /* Strip trailing whitespace from expansion */
+ for(k = curdef_idx, cptr = &curdef_text[curdef_idx-1]; k > 0; k--, cptr--)
+ {
+ if(!isspace(*cptr & 0xff))
+ break;
+ }
+
+ /*
+ * We must add *one* whitespace to make sure that there
+ * is a token-seperation after the expansion.
+ */
+ *(++cptr) = ' ';
+ *(++cptr) = '\0';
+ k++;
+
+ /* Strip leading whitespace from expansion */
+ for(n = 0, cptr = curdef_text; n < k; n++, cptr++)
+ {
+ if(!isspace(*cptr & 0xff))
+ break;
+ }
+
+ if(k - n > 0)
+ {
+ if(debuglevel & DEBUGLEVEL_PPLEX)
+ fprintf(stderr, "expand_text: '%s'\n", curdef_text + n);
+ push_buffer(ppp, NULL, NULL, 0);
+ /*yy_scan_bytes(curdef_text + n, k - n);*/
+ yy_scan_string(curdef_text + n);
+ }
+}
+
+/*
+ *-------------------------------------------------------------------------
+ * String collection routines
+ *-------------------------------------------------------------------------
+ */
+static void new_string(void)
+{
+#ifdef DEBUG
+ if(strbuf_idx)
+ ppwarning("new_string: strbuf_idx != 0");
+#endif
+ strbuf_idx = 0;
+ str_startline = line_number;
+}
+
+static void add_string(char *str, int len)
+{
+ if(len == 0)
+ return;
+ if(strbuf_idx >= strbuf_alloc || strbuf_alloc - strbuf_idx < len)
+ {
+ strbuf_alloc += (len + ALLOCBLOCKSIZE-1) & ~(ALLOCBLOCKSIZE-1);
+ strbuffer = xrealloc(strbuffer, strbuf_alloc * sizeof(strbuffer[0]));
+ if(strbuf_alloc > 65536)
+ ppwarning("Reallocating string buffer larger than 64kB");
+ }
+ memcpy(&strbuffer[strbuf_idx], str, len);
+ strbuf_idx += len;
+}
+
+static char *get_string(void)
+{
+ char *str = (char *)xmalloc(strbuf_idx + 1);
+ memcpy(str, strbuffer, strbuf_idx);
+ str[strbuf_idx] = '\0';
+#ifdef DEBUG
+ strbuf_idx = 0;
+#endif
+ return str;
+}
+
+static void put_string(void)
+{
+ put_buffer(strbuffer, strbuf_idx);
+#ifdef DEBUG
+ strbuf_idx = 0;
+#endif
+}
+
+static int string_start(void)
+{
+ return str_startline;
+}
+
+
+/*
+ *-------------------------------------------------------------------------
+ * Buffer management
+ *-------------------------------------------------------------------------
+ */
+static void push_buffer(pp_entry_t *ppp, char *filename, char *incname, int pop)
+{
+ if(ppdebug)
+ printf("push_buffer(%d): %p %p %p %d\n", bufferstackidx, ppp, filename, incname, pop);
+ if(bufferstackidx >= MAXBUFFERSTACK)
+ internal_error(__FILE__, __LINE__, "Buffer stack overflow");
+
+ memset(&bufferstack[bufferstackidx], 0, sizeof(bufferstack[0]));
+ bufferstack[bufferstackidx].bufferstate = YY_CURRENT_BUFFER;
+ bufferstack[bufferstackidx].define = ppp;
+ bufferstack[bufferstackidx].line_number = line_number;
+ bufferstack[bufferstackidx].char_number = char_number;
+ bufferstack[bufferstackidx].if_depth = get_if_depth();
+ bufferstack[bufferstackidx].should_pop = pop;
+ bufferstack[bufferstackidx].filename = input_name;
+ bufferstack[bufferstackidx].ncontinuations = ncontinuations;
+ bufferstack[bufferstackidx].include_state = include_state;
+ bufferstack[bufferstackidx].include_ppp = include_ppp;
+ bufferstack[bufferstackidx].include_filename = incname;
+ bufferstack[bufferstackidx].include_ifdepth = include_ifdepth;
+ bufferstack[bufferstackidx].seen_junk = seen_junk;
+ bufferstack[bufferstackidx].pass_data = pass_data;
+
+ if(ppp)
+ ppp->expanding = 1;
+ else if(filename)
+ {
+ /* These will track the pperror to the correct file and line */
+ line_number = 1;
+ char_number = 1;
+ input_name = filename;
+ ncontinuations = 0;
+ }
+ else if(!pop)
+ internal_error(__FILE__, __LINE__, "Pushing buffer without knowing where to go to");
+ bufferstackidx++;
+}
+
+static bufferstackentry_t *pop_buffer(void)
+{
+ if(bufferstackidx < 0)
+ internal_error(__FILE__, __LINE__, "Bufferstack underflow?");
+
+ if(bufferstackidx == 0)
+ return NULL;
+
+ bufferstackidx--;
+
+ if(bufferstack[bufferstackidx].define)
+ bufferstack[bufferstackidx].define->expanding = 0;
+ else
+ {
+ line_number = bufferstack[bufferstackidx].line_number;
+ char_number = bufferstack[bufferstackidx].char_number;
+ input_name = bufferstack[bufferstackidx].filename;
+ ncontinuations = bufferstack[bufferstackidx].ncontinuations;
+ if(!bufferstack[bufferstackidx].should_pop)
+ {
+ fclose(ppin);
+ fprintf(ppout, "# %d \"%s\" 2\n", line_number, input_name);
+
+ /* We have EOF, check the include logic */
+ if(include_state == 2 && !seen_junk && include_ppp)
+ {
+ pp_entry_t *ppp = pplookup(include_ppp);
+ if(ppp)
+ {
+ includelogicentry_t *iep = xmalloc(sizeof(includelogicentry_t));
+ iep->ppp = ppp;
+ ppp->iep = iep;
+ iep->filename = bufferstack[bufferstackidx].include_filename;
+ iep->next = includelogiclist;
+ if(iep->next)
+ iep->next->prev = iep;
+ includelogiclist = iep;
+ if(debuglevel & DEBUGLEVEL_PPMSG)
+ fprintf(stderr, "pop_buffer: %s:%d: includelogic added, include_ppp='%s', file='%s'\n", input_name, line_number, include_ppp, iep->filename);
+ }
+ else if(bufferstack[bufferstackidx].include_filename)
+ free(bufferstack[bufferstackidx].include_filename);
+ }
+ if(include_ppp)
+ free(include_ppp);
+ include_state = bufferstack[bufferstackidx].include_state;
+ include_ppp = bufferstack[bufferstackidx].include_ppp;
+ include_ifdepth = bufferstack[bufferstackidx].include_ifdepth;
+ seen_junk = bufferstack[bufferstackidx].seen_junk;
+ pass_data = bufferstack[bufferstackidx].pass_data;
+
+ }
+ }
+
+ if(ppdebug)
+ printf("pop_buffer(%d): %p %p (%d, %d, %d) %p %d\n",
+ bufferstackidx,
+ bufferstack[bufferstackidx].bufferstate,
+ bufferstack[bufferstackidx].define,
+ bufferstack[bufferstackidx].line_number,
+ bufferstack[bufferstackidx].char_number,
+ bufferstack[bufferstackidx].if_depth,
+ bufferstack[bufferstackidx].filename,
+ bufferstack[bufferstackidx].should_pop);
+
+ pp_switch_to_buffer(bufferstack[bufferstackidx].bufferstate);
+
+ if(bufferstack[bufferstackidx].should_pop)
+ {
+ if(yy_current_state() == pp_macexp)
+ macro_add_expansion();
+ else
+ internal_error(__FILE__, __LINE__, "Pop buffer and state without macro expansion state");
+ yy_pop_state();
+ }
+
+ return &bufferstack[bufferstackidx];
+}
+
+
+/*
+ *-------------------------------------------------------------------------
+ * Macro nestng support
+ *-------------------------------------------------------------------------
+ */
+static void push_macro(pp_entry_t *ppp)
+{
+ if(macexpstackidx >= MAXMACEXPSTACK)
+ pperror("Too many nested macros");
+
+ macexpstack[macexpstackidx] = xmalloc(sizeof(macexpstack[0][0]));
+
+ macexpstack[macexpstackidx]->ppp = ppp;
+ macexpstackidx++;
+}
+
+static macexpstackentry_t *top_macro(void)
+{
+ return macexpstackidx > 0 ? macexpstack[macexpstackidx-1] : NULL;
+}
+
+static macexpstackentry_t *pop_macro(void)
+{
+ if(macexpstackidx <= 0)
+ internal_error(__FILE__, __LINE__, "Macro expansion stack underflow\n");
+ return macexpstack[--macexpstackidx];
+}
+
+static void free_macro(macexpstackentry_t *mep)
+{
+ int i;
+
+ for(i = 0; i < mep->nargs; i++)
+ free(mep->args[i]);
+ if(mep->args)
+ free(mep->args);
+ if(mep->nnls)
+ free(mep->nnls);
+ if(mep->curarg)
+ free(mep->curarg);
+ free(mep);
+}
+
+static void add_text_to_macro(char *text, int len)
+{
+ macexpstackentry_t *mep = top_macro();
+
+ assert(mep->ppp->expanding == 0);
+
+ if(mep->curargalloc - mep->curargsize <= len+1) /* +1 for '\0' */
+ {
+ mep->curargalloc += max(ALLOCBLOCKSIZE, len+1);
+ mep->curarg = xrealloc(mep->curarg, mep->curargalloc * sizeof(mep->curarg[0]));
+ }
+ memcpy(mep->curarg + mep->curargsize, text, len);
+ mep->curargsize += len;
+ mep->curarg[mep->curargsize] = '\0';
+}
+
+static void macro_add_arg(int last)
+{
+ int nnl = 0;
+ char *cptr;
+ macexpstackentry_t *mep = top_macro();
+
+ assert(mep->ppp->expanding == 0);
+
+ mep->args = xrealloc(mep->args, (mep->nargs+1) * sizeof(mep->args[0]));
+ mep->ppargs = xrealloc(mep->ppargs, (mep->nargs+1) * sizeof(mep->ppargs[0]));
+ mep->nnls = xrealloc(mep->nnls, (mep->nargs+1) * sizeof(mep->nnls[0]));
+ mep->args[mep->nargs] = xstrdup(mep->curarg ? mep->curarg : "");
+ cptr = mep->args[mep->nargs]-1;
+ while((cptr = strchr(cptr+1, '\n')))
+ {
+ nnl++;
+ }
+ mep->nnls[mep->nargs] = nnl;
+ mep->nargs++;
+ free(mep->curarg);
+ mep->curargalloc = mep->curargsize = 0;
+ mep->curarg = NULL;
+
+ if(debuglevel & DEBUGLEVEL_PPLEX)
+ fprintf(stderr, "macro_add_arg: %s:%d: %d -> '%s'\n",
+ input_name,
+ line_number,
+ mep->nargs-1,
+ mep->args[mep->nargs-1]);
+
+ /* Each macro argument must be expanded to cope with stingize */
+ if(last || mep->args[mep->nargs-1][0])
+ {
+ yy_push_state(pp_macexp);
+ push_buffer(NULL, NULL, NULL, last ? 2 : 1);
+ yy_scan_string(mep->args[mep->nargs-1]);
+ /*mep->bufferstackidx = bufferstackidx; But not nested! */
+ }
+}
+
+static void macro_add_expansion(void)
+{
+ macexpstackentry_t *mep = top_macro();
+
+ assert(mep->ppp->expanding == 0);
+
+ mep->ppargs[mep->nargs-1] = xstrdup(mep->curarg ? mep->curarg : "");
+ free(mep->curarg);
+ mep->curargalloc = mep->curargsize = 0;
+ mep->curarg = NULL;
+
+ if(debuglevel & DEBUGLEVEL_PPLEX)
+ fprintf(stderr, "macro_add_expansion: %s:%d: %d -> '%s'\n",
+ input_name,
+ line_number,
+ mep->nargs-1,
+ mep->ppargs[mep->nargs-1]);
+}
+
+
+/*
+ *-------------------------------------------------------------------------
+ * Output management
+ *-------------------------------------------------------------------------
+ */
+static void put_buffer(char *s, int len)
+{
+ if(top_macro())
+ add_text_to_macro(s, len);
+ else {
+ if(pass_data)
+ fwrite(s, 1, len, ppout);
+ }
+}
+
+
+/*
+ *-------------------------------------------------------------------------
+ * Include management
+ *-------------------------------------------------------------------------
+ */
+int is_c_h_include(char *fname)
+{
+ int sl=strlen(fname);
+ if (sl < 2) return 0;
+ if ((toupper(fname[sl-1])!='H') && (toupper(fname[sl-1])!='C')) return 0;
+ if (fname[sl-2]!='.') return 0;
+ return 1;
+}
+
+void do_include(char *fname, int type)
+{
+ char *newpath;
+ int n;
+ includelogicentry_t *iep;
+
+ for(iep = includelogiclist; iep; iep = iep->next)
+ {
+ if(!strcmp(iep->filename, fname))
+ {
+ /*
+ * We are done. The file was included before.
+ * If the define was deleted, then this entry would have
+ * been deleted too.
+ */
+ return;
+ }
+ }
+
+ n = strlen(fname);
+
+ if(n <= 2)
+ pperror("Empty include filename");
+
+ /* Undo the effect of the quotation */
+ fname[n-1] = '\0';
+
+ if((ppin = open_include(fname+1, type, &newpath)) == NULL)
+ pperror("Unable to open include file %s", fname+1);
+
+ fname[n-1] = *fname; /* Redo the quotes */
+ push_buffer(NULL, newpath, fname, 0);
+ seen_junk = 0;
+ include_state = 0;
+ include_ppp = NULL;
+ if (is_c_h_include(newpath)) pass_data=0;
+ else pass_data=1;
+
+ if(debuglevel & DEBUGLEVEL_PPMSG)
+ fprintf(stderr, "do_include: %s:%d: include_state=%d, include_ppp='%s', include_ifdepth=%d ,pass_data=%d\n", input_name, line_number, include_state, include_ppp, include_ifdepth,pass_data);
+ pp_switch_to_buffer(pp_create_buffer(ppin, YY_BUF_SIZE));
+
+ fprintf(ppout, "# 1 \"%s\" 1%s\n", newpath, type ? "" : " 3");
+}
+
+/*
+ *-------------------------------------------------------------------------
+ * Push/pop preprocessor ignore state when processing conditionals
+ * which are false.
+ *-------------------------------------------------------------------------
+ */
+void push_ignore_state(void)
+{
+ yy_push_state(pp_ignore);
+}
+
+void pop_ignore_state(void)
+{
+ yy_pop_state();
+}
+
+
-------------- next part --------------
--- NUL Wed Dec 31 19:00:00 1969
+++ header.h Sun Jun 30 02:38:06 2002
@@ -0,0 +1,36 @@
+/*
+ * 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
+ */
+
+#ifndef __WIDL_HEADER_H
+#define __WIDL_HEADER_H
+
+extern int is_void(type_t *t, var_t *v);
+extern void write_name(FILE *h, var_t *v);
+extern char* get_name(var_t *v);
+extern void write_type(FILE *h, type_t *t, var_t *v, char *n);
+extern int is_object(attr_t *a);
+extern int is_local(attr_t *a);
+extern var_t *is_callas(attr_t *a);
+extern void write_method_args(FILE *h, var_t *arg, char *name);
+extern void write_forward(type_t *iface);
+extern void write_interface(type_t *iface);
+extern void write_typedef(type_t *type, var_t *names);
+
+#endif
-------------- next part --------------
--- NUL Wed Dec 31 19:00:00 1969
+++ Makefile.in Sat Jun 29 20:56:44 2002
@@ -0,0 +1,60 @@
+DEFS = -D__WINE__
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../..
+SRCDIR = @srcdir@
+VPATH = @srcdir@
+LEXOPT = -Cf #-w -b
+YACCOPT = #-v
+EXEEXT = @EXEEXT@
+
+PROGRAMS = widl$(EXEEXT)
+MODULE = none
+
+C_SRCS = \
+ header.c \
+ preproc.c \
+ proxy.c \
+ utils.c \
+ widl.c
+
+GEN_C_SRCS = ppy.tab.c lex.ppl.c
+EXTRA_SRCS = parser.y parser.l
+EXTRA_OBJS = y.tab.o @LEX_OUTPUT_ROOT at .o
+
+all: $(PROGRAMS)
+
+ at MAKE_RULES@
+
+widl: $(OBJS)
+ $(CC) $(CFLAGS) -o widl $(OBJS) $(LIBWINE) $(LIBUNICODE) $(LEXLIB) $(LDFLAGS)
+
+widl.exe: $(OBJS)
+ $(CC) $(CFLAGS) -o widl.exe $(OBJS) $(LIBWINE) $(LIBUNICODE) $(LEXLIB) -liberty $(LDFLAGS)
+
+$(TOPOBJDIR)/unicode/libwine_unicode.$(LIBEXT):
+ cd `dirname $@` && $(MAKE) `basename $@`
+
+y.tab.c y.tab.h: parser.y
+ $(YACC) $(YACCOPT) -d -t $(SRCDIR)/parser.y
+
+ppy.tab.c ppy.tab.h: ppy.y
+ $(YACC) $(YACCOPT) -bppy -ppp -d -t $(SRCDIR)/ppy.y
+
+ at LEX_OUTPUT_ROOT@.c: parser.l
+ $(LEX) $(LEXOPT) -d -8 $(SRCDIR)/parser.l
+
+lex.ppl.c: ppl.l
+ $(LEX) $(LEXOPT) -d -Ppp -8 -olex.ppl.c $(SRCDIR)/ppl.l
+
+clean::
+ $(RM) parser.output parser.tab.h lex.backup y.output
+
+install:: $(PROGRAMS)
+ $(MKINSTALLDIRS) $(bindir) $(mandir)/man$(prog_manext)
+ $(INSTALL_DATA) $(SRCDIR)/widl.man $(mandir)/man$(prog_manext)/widl.$(prog_manext)
+ $(INSTALL_PROGRAM) widl$(EXEEXT) $(bindir)/widl$(EXEEXT)
+
+uninstall::
+ $(RM) $(bindir)/widl$(EXEEXT) $(mandir)/man$(prog_manext)/widl.$(prog_manext)
+
+### Dependencies:
-------------- next part --------------
--- NUL Wed Dec 31 19:00:00 1969
+++ parser.h Sun Jun 30 02:39:50 2002
@@ -0,0 +1,41 @@
+/*
+ * 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
+ */
+
+#ifndef __WIDL_PARSER_H
+#define __WIDL_PARSER_H
+
+int yyparse(void);
+
+extern FILE *yyin;
+extern char *yytext;
+extern int yydebug;
+extern int yy_flex_debug;
+
+int yylex(void);
+
+extern int import_stack_ptr;
+void do_import(char *fname);
+void abort_import(void);
+
+#define parse_only import_stack_ptr
+
+int is_type(const char *name);
+
+#endif
-------------- next part --------------
--- NUL Wed Dec 31 19:00:00 1969
+++ parser.l Sun Jun 30 02:44:54 2002
@@ -0,0 +1,317 @@
+/*
+ * 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 "preproc.h"
+#include "parser.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;
+ 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((ppin = open_include(fname, 1, NULL)) == NULL)
+ yyerror("Unable to open include file %s", fname);
+
+ import_stack[ptr].temp_name = temp_name;
+ import_stack_ptr++;
+
+ if(!(temp_name = tmpnam(NULL)))
+ error("Could not generate a temp-name\n");
+ temp_name = xstrdup(temp_name);
+ if(!(ppout = fopen(temp_name, "wb")))
+ error("Could not create a temp-file\n");
+ fprintf(ppout, "# 1 \"%s\" 1\n", fname ? fname : "");
+ ret = ppparse();
+ fclose(ppin);
+ fclose(ppout);
+
+ 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);
+}
-------------- next part --------------
--- NUL Wed Dec 31 19:00:00 1969
+++ parser.y Sun Jun 30 02:42:28 2002
@@ -0,0 +1,680 @@
+%{
+/*
+ * 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
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+#include <string.h>
+#ifdef HAVE_ALLOCA_H
+#include <alloca.h>
+#endif
+
+#include "widl.h"
+#include "utils.h"
+#include "parser.h"
+#include "header.h"
+
+#if defined(YYBYACC)
+ /* Berkeley yacc (byacc) doesn't seem to know about these */
+ /* Some *BSD supplied versions do define these though */
+# ifndef YYEMPTY
+# define YYEMPTY (-1) /* Empty lookahead value of yychar */
+# endif
+# ifndef YYLEX
+# define YYLEX yylex()
+# endif
+
+#elif defined(YYBISON)
+ /* Bison was used for original development */
+ /* #define YYEMPTY -2 */
+ /* #define YYLEX yylex() */
+
+#else
+ /* No yacc we know yet */
+# if !defined(YYEMPTY) || !defined(YYLEX)
+# error Yacc version/type unknown. This version needs to be verified for settings of YYEMPTY and YYLEX.
+# elif defined(__GNUC__) /* gcc defines the #warning directive */
+# warning Yacc version/type unknown. It defines YYEMPTY and YYLEX, but is not tested
+ /* #else we just take a chance that it works... */
+# endif
+#endif
+
+static attr_t *make_attr(int type);
+static attr_t *make_attrv(int type, DWORD val);
+static attr_t *make_attrp(int type, void *val);
+static type_t *make_type(BYTE type, type_t *ref);
+static typeref_t *make_tref(char *name, type_t *ref);
+static typeref_t *uniq_tref(typeref_t *ref);
+static type_t *type_ref(typeref_t *ref);
+static void set_type(var_t *v, typeref_t *ref);
+static var_t *make_var(char *name);
+static func_t *make_func(var_t *def, var_t *args);
+
+static type_t *reg_type(type_t *type, char *name, int t);
+static type_t *reg_types(type_t *type, var_t *names, int t);
+static type_t *find_type(char *name, int t);
+static type_t *find_type2(char *name, int t);
+static type_t *get_type(BYTE type, char *name, int t);
+static type_t *get_typev(BYTE type, var_t *name, int t);
+
+#define tsENUM 1
+#define tsSTRUCT 2
+#define tsUNION 3
+
+static type_t std_int = { "int" };
+
+%}
+%union {
+ attr_t *attr;
+ type_t *type;
+ typeref_t *tref;
+ var_t *var;
+ func_t *func;
+ char *str;
+ int num;
+}
+
+%token <str> aIDENTIFIER
+%token <str> aKNOWNTYPE
+%token <num> aNUM
+%token <str> aSTRING
+%token <uuid> aUUID
+%token SHL SHR
+%token tAGGREGATABLE tALLOCATE tAPPOBJECT tARRAYS tASYNC tASYNCUUID
+%token tAUTOHANDLE tBINDABLE tBOOLEAN tBROADCAST tBYTE tBYTECOUNT
+%token tCALLAS tCALLBACK tCASE tCDECL tCHAR tCOCLASS tCODE tCOMMSTATUS
+%token tCONST tCONTEXTHANDLE tCONTEXTHANDLENOSERIALIZE
+%token tCONTEXTHANDLESERIALIZE tCONTROL tCPPQUOTE
+%token tDEFAULT
+%token tDOUBLE
+%token tENUM
+%token tEXTERN
+%token tFLOAT
+%token tHYPER
+%token tIIDIS
+%token tIMPORT tIMPORTLIB
+%token tIN tINCLUDE tINLINE
+%token tINT tINT64
+%token tINTERFACE
+%token tLENGTHIS
+%token tLOCAL
+%token tLONG
+%token tOBJECT tODL tOLEAUTOMATION
+%token tOUT
+%token tPOINTERDEFAULT
+%token tREF
+%token tSHORT
+%token tSIGNED
+%token tSIZEIS tSIZEOF
+%token tSTDCALL
+%token tSTRING tSTRUCT
+%token tSWITCH tSWITCHIS tSWITCHTYPE
+%token tTYPEDEF
+%token tUNION
+%token tUNIQUE
+%token tUNSIGNED
+%token tUUID
+%token tV1ENUM
+%token tVERSION
+%token tVOID
+%token tWCHAR tWIREMARSHAL
+
+/* used in attr_t */
+%token tPOINTERTYPE
+
+%type <attr> m_attributes attributes attrib_list attribute
+%type <type> inherit interface interfacedef
+%type <type> base_type int_std
+%type <type> enumdef structdef typedef uniondef
+%type <tref> type
+%type <var> m_args no_args args arg
+%type <var> fields field
+%type <var> m_ident t_ident ident p_ident pident pident_list
+%type <func> funcdef statements
+%type <num> expr pointer_type
+
+%left ','
+%left '|'
+%left '&'
+%left '-' '+'
+%left '*' '/'
+%left SHL SHR
+%right CAST
+%right PPTR
+%right NEG
+
+%%
+
+statements: { $$ = NULL; }
+ | statements funcdef ';' { LINK($2, $1); $$ = $2; }
+ | statements statement
+ ;
+
+statement: ';' {}
+ | constdef {}
+ | cppquote {}
+ | enumdef ';' { if (!parse_only) { write_type(header, $1, NULL, NULL); fprintf(header, ";\n"); } }
+ | externdef ';' {}
+ | import {}
+ | interface ';' {}
+ | interfacedef {}
+ | structdef ';' { if (!parse_only) { write_type(header, $1, NULL, NULL); fprintf(header, ";\n"); } }
+ | typedef ';' {}
+ | uniondef ';' { if (!parse_only) { write_type(header, $1, NULL, NULL); fprintf(header, ";\n"); } }
+ ;
+
+cppquote: tCPPQUOTE '(' aSTRING ')' { if (!parse_only) fprintf(header, "%s\n", $3); }
+;
+import: tIMPORT aSTRING ';' { do_import($2); }
+;
+
+m_args: { $$ = NULL; }
+ | args
+ ;
+
+no_args: tVOID { $$ = NULL; }
+ ;
+
+args: arg
+ | args ',' arg { LINK($3, $1); $$ = $3; }
+ | no_args
+ ;
+
+/* split into two rules to get bison to resolve a tVOID conflict */
+arg: attributes type pident array { $$ = $3;
+ set_type($$, $2);
+ $$->attrs = $1; /* FIXME: array */
+ }
+ | type pident array { $$ = $2;
+ set_type($$, $1); /* FIXME: array */
+ }
+ ;
+
+aexprs:
+ | aexpr_list
+ ;
+
+aexpr_list: aexpr
+ | aexprs ',' aexpr
+ ;
+
+aexpr: aNUM {}
+ | aIDENTIFIER {}
+ | aexpr '|' aexpr
+ | aexpr '&' aexpr
+ | aexpr '+' aexpr
+ | aexpr '-' aexpr
+ | aexpr '*' aexpr
+ | aexpr '/' aexpr
+ | '-' aexpr %prec NEG
+ | '*' aexpr %prec PPTR
+ | '(' type ')' aexpr %prec CAST
+ | '(' aexpr ')'
+ | tSIZEOF '(' type ')'
+ ;
+
+array:
+ | '[' aexprs ']'
+ | '[' '*' ']'
+ ;
+
+m_attributes: { $$ = NULL; }
+ | attributes
+ ;
+
+attributes:
+ m_attributes '[' attrib_list ']' { LINK_LAST($3, $1); $$ = $3; }
+ ;
+
+attrib_list: attribute
+ | attrib_list ',' attribute { LINK_SAFE($3, $1); $$ = $3; /* FIXME: don't use SAFE */ }
+ ;
+
+attribute:
+ tASYNC { $$ = make_attr(tASYNC); }
+ | tCALLAS '(' ident ')' { $$ = make_attrp(tCALLAS, $3); }
+ | tCASE '(' expr_list ')' { $$ = NULL; }
+ | tCONTEXTHANDLE { $$ = NULL; }
+ | tCONTEXTHANDLENOSERIALIZE { $$ = NULL; }
+ | tCONTEXTHANDLESERIALIZE { $$ = NULL; }
+ | tDEFAULT { $$ = make_attr(tDEFAULT); }
+ | tIIDIS '(' ident ')' { $$ = make_attrp(tIIDIS, $3); }
+ | tIN { $$ = make_attr(tIN); }
+ | tLENGTHIS '(' aexprs ')' { $$ = NULL; }
+ | tLOCAL { $$ = make_attr(tLOCAL); }
+ | tOBJECT { $$ = make_attr(tOBJECT); }
+ | tOLEAUTOMATION { $$ = make_attr(tOLEAUTOMATION); }
+ | tOUT { $$ = make_attr(tOUT); }
+ | tPOINTERDEFAULT '(' pointer_type ')' { $$ = make_attrv(tPOINTERDEFAULT, $3); }
+ | tSIZEIS '(' aexprs ')' { $$ = NULL; }
+ | tSTRING { $$ = make_attr(tSTRING); }
+ | tSWITCHIS '(' aexpr ')' { $$ = NULL; }
+ | tSWITCHTYPE '(' type ')' { $$ = NULL; }
+ | tUUID '(' aUUID ')' { $$ = NULL; }
+ | tV1ENUM { $$ = make_attr(tV1ENUM); }
+ | tVERSION '(' version ')' { $$ = NULL; }
+ | tWIREMARSHAL '(' type ')' { $$ = make_attrp(tWIREMARSHAL, type_ref($3)); }
+ | pointer_type { $$ = make_attrv(tPOINTERTYPE, $1); }
+ ;
+
+callconv:
+ | tSTDCALL
+ ;
+
+cases:
+ | cases case
+ ;
+
+case: tCASE expr ':' field
+ | tDEFAULT ':' field
+ ;
+
+constdef: tCONST type ident '=' expr
+ ;
+
+enums:
+ | enum_list ','
+ | enum_list
+ ;
+
+enum_list: enum
+ | enum_list ',' enum
+ ;
+
+enum: ident '=' expr {}
+ | ident {}
+ ;
+
+enumdef: tENUM t_ident '{' enums '}' { $$ = get_typev(RPC_FC_SHORT /* FIXME */, $2, tsENUM);
+ $$->defined = TRUE;
+ }
+ ;
+
+expr_list: expr {}
+ | expr_list ',' expr {}
+ ;
+
+expr: aNUM
+ | aIDENTIFIER {}
+ | expr '|' expr {}
+ | expr SHL expr {}
+ | expr SHR expr {}
+ | '-' expr %prec NEG {}
+ ;
+
+externdef: tEXTERN tCONST type ident
+ ;
+
+fields: { $$ = NULL; }
+ | fields field { LINK($2, $1); $$ = $2; }
+ ;
+
+field: m_attributes type pident array ';' { $$ = $3; set_type($$, $2); $$->attrs = $1; /* FIXME: array */ }
+ | m_attributes uniondef ';' { $$ = make_var(NULL); $$->type = $2; $$->attrs = $1; }
+ | attributes ';' { $$ = make_var(NULL); $$->attrs = $1; }
+ | ';' { $$ = NULL; }
+ ;
+
+funcdef:
+ m_attributes type callconv pident
+ '(' m_args ')' { set_type($4, $2);
+ $4->attrs = $1;
+ $$ = make_func($4, $6);
+ }
+ ;
+
+m_ident: { $$ = NULL; }
+ | ident
+ ;
+
+t_ident: { $$ = NULL; }
+ | aIDENTIFIER { $$ = make_var($1); }
+ | aKNOWNTYPE { $$ = make_var($1); }
+ ;
+
+ident: aIDENTIFIER { $$ = make_var($1); }
+ ;
+
+base_type: tBYTE { $$ = make_type(RPC_FC_BYTE, NULL); }
+ | tCHAR { $$ = make_type(RPC_FC_CHAR, NULL); }
+ | tUNSIGNED tCHAR { $$ = make_type(RPC_FC_CHAR, NULL); }
+ | tWCHAR { $$ = make_type(RPC_FC_WCHAR, NULL); }
+ | int_std
+ | tSIGNED int_std { $$ = $2; /* FIXME */ }
+ | tUNSIGNED int_std { $$ = $2; /* FIXME */ }
+ | tFLOAT { $$ = make_type(RPC_FC_FLOAT, NULL); }
+ | tDOUBLE { $$ = make_type(RPC_FC_DOUBLE, NULL); }
+ | tBOOLEAN { $$ = make_type(RPC_FC_BYTE, NULL); /* ? */ }
+ ;
+
+m_int:
+ | tINT
+ ;
+
+int_std: tINT { $$ = make_type(RPC_FC_LONG, &std_int); } /* win32 only */
+ | tSHORT m_int { $$ = make_type(RPC_FC_SHORT, NULL); }
+ | tLONG m_int { $$ = make_type(RPC_FC_LONG, NULL); }
+ | tHYPER m_int { $$ = make_type(RPC_FC_HYPER, NULL); }
+ | tINT64 { $$ = make_type(RPC_FC_HYPER, NULL); }
+ ;
+
+inherit: { $$ = NULL; }
+ | ':' aKNOWNTYPE { $$ = find_type2($2, 0); }
+ ;
+
+interface: tINTERFACE aIDENTIFIER { $$ = get_type(RPC_FC_IP, $2, 0); if (!parse_only) write_forward($$); }
+ | tINTERFACE aKNOWNTYPE { $$ = get_type(RPC_FC_IP, $2, 0); if (!parse_only) write_forward($$); }
+ ;
+
+interfacedef: attributes interface inherit
+ '{' statements '}' { $$ = $2;
+ if ($$->defined) yyerror("multiple definition error\n");
+ $$->ref = $3;
+ $$->attrs = $1;
+ $$->funcs = $5;
+ $$->defined = TRUE;
+ if (!parse_only) write_interface($$);
+ }
+ ;
+
+p_ident: '*' pident %prec PPTR { $$ = $2; $$->ptr_level++; }
+ | tCONST p_ident { $$ = $2; }
+ ;
+
+pident: ident
+ | p_ident
+ | '(' pident ')' { $$ = $2; }
+ ;
+
+pident_list:
+ pident
+ | pident_list ',' pident { LINK($3, $1); $$ = $3; }
+ ;
+
+pointer_type:
+ tREF { $$ = RPC_FC_RP; }
+ | tUNIQUE { $$ = RPC_FC_UP; }
+ ;
+
+structdef: tSTRUCT t_ident '{' fields '}' { $$ = get_typev(RPC_FC_STRUCT, $2, tsSTRUCT);
+ $$->fields = $4;
+ $$->defined = TRUE;
+ }
+ ;
+
+type: tVOID { $$ = make_tref(NULL, make_type(0, NULL)); }
+ | aKNOWNTYPE { $$ = make_tref($1, find_type($1, 0)); }
+ | base_type { $$ = make_tref(NULL, $1); }
+ | tCONST type { $$ = uniq_tref($2); $$->ref->is_const = TRUE; }
+ | enumdef { $$ = make_tref(NULL, $1); }
+ | tENUM aIDENTIFIER { $$ = make_tref(NULL, find_type2($2, tsENUM)); }
+ | structdef { $$ = make_tref(NULL, $1); }
+ | tSTRUCT aIDENTIFIER { $$ = make_tref(NULL, get_type(RPC_FC_STRUCT, $2, tsSTRUCT)); }
+ | uniondef { $$ = make_tref(NULL, $1); }
+ | tUNION aIDENTIFIER { $$ = make_tref(NULL, find_type2($2, tsUNION)); }
+ ;
+
+typedef: tTYPEDEF m_attributes type pident_list { typeref_t *tref = uniq_tref($3);
+ $4->tname = tref->name;
+ tref->name = NULL;
+ $$ = type_ref(tref);
+ $$->attrs = $2;
+ if (!parse_only) write_typedef($$, $4);
+ reg_types($$, $4, 0);
+ }
+ ;
+
+uniondef: tUNION t_ident '{' fields '}' { $$ = get_typev(RPC_FC_NON_ENCAPSULATED_UNION, $2, tsUNION);
+ $$->fields = $4;
+ $$->defined = TRUE;
+ }
+ | tUNION t_ident
+ tSWITCH '(' type ident ')'
+ m_ident '{' cases '}' { $$ = get_typev(RPC_FC_ENCAPSULATED_UNION, $2, tsUNION);
+ $$->defined = TRUE;
+ }
+ ;
+
+version:
+ aNUM {}
+ | aNUM '.' aNUM {}
+ ;
+
+%%
+
+static attr_t *make_attr(int type)
+{
+ attr_t *a = xmalloc(sizeof(attr_t));
+ a->type = type;
+ a->u.ival = 0;
+ return a;
+}
+
+static attr_t *make_attrv(int type, DWORD val)
+{
+ attr_t *a = xmalloc(sizeof(attr_t));
+ a->type = type;
+ a->u.ival = val;
+ return a;
+}
+
+static attr_t *make_attrp(int type, void *val)
+{
+ attr_t *a = xmalloc(sizeof(attr_t));
+ a->type = type;
+ a->u.pval = val;
+ return a;
+}
+
+static type_t *make_type(BYTE type, type_t *ref)
+{
+ type_t *t = xmalloc(sizeof(type_t));
+ t->name = NULL;
+ t->type = type;
+ t->ref = ref;
+ t->rname = NULL;
+ t->attrs = NULL;
+ t->funcs = NULL;
+ t->fields = NULL;
+ t->ignore = parse_only;
+ t->is_const = FALSE;
+ t->defined = FALSE;
+ t->written = FALSE;
+ INIT_LINK(t);
+ return t;
+}
+
+static typeref_t *make_tref(char *name, type_t *ref)
+{
+ typeref_t *t = xmalloc(sizeof(typeref_t));
+ t->name = name;
+ t->ref = ref;
+ t->uniq = ref ? 0 : 1;
+ return t;
+}
+
+static typeref_t *uniq_tref(typeref_t *ref)
+{
+ typeref_t *t = ref;
+ type_t *tp;
+ if (t->uniq) return t;
+ tp = make_type(0, t->ref);
+ tp->name = t->name;
+ t->name = NULL;
+ t->ref = tp;
+ t->uniq = 1;
+ return t;
+}
+
+static type_t *type_ref(typeref_t *ref)
+{
+ type_t *t = ref->ref;
+ if (ref->name) free(ref->name);
+ free(ref);
+ return t;
+}
+
+static void set_type(var_t *v, typeref_t *ref)
+{
+ v->type = ref->ref;
+ v->tname = ref->name;
+ ref->name = NULL;
+ free(ref);
+}
+
+static var_t *make_var(char *name)
+{
+ var_t *v = xmalloc(sizeof(var_t));
+ v->name = name;
+ v->ptr_level = 0;
+ v->type = NULL;
+ v->tname = NULL;
+ v->attrs = NULL;
+ INIT_LINK(v);
+ return v;
+}
+
+static func_t *make_func(var_t *def, var_t *args)
+{
+ func_t *f = xmalloc(sizeof(func_t));
+ f->def = def;
+ f->args = args;
+ f->ignore = parse_only;
+ f->idx = -1;
+ INIT_LINK(f);
+ return f;
+}
+
+struct rtype {
+ char *name;
+ type_t *type;
+ int t;
+ struct rtype *next;
+};
+
+struct rtype *first;
+
+static type_t *reg_type(type_t *type, char *name, int t)
+{
+ struct rtype *nt;
+ if (!name) {
+ yyerror("registering named type without name\n");
+ return type;
+ }
+ nt = xmalloc(sizeof(struct rtype));
+ nt->name = name;
+ nt->type = type;
+ nt->t = t;
+ nt->next = first;
+ first = nt;
+ return type;
+}
+
+static type_t *reg_types(type_t *type, var_t *names, int t)
+{
+ type_t *ptr = type;
+ int ptrc = 0;
+
+ while (names) {
+ var_t *next = NEXT_LINK(names);
+ if (names->name) {
+ type_t *cur = ptr;
+ int cptr = names->ptr_level;
+ if (cptr > ptrc) {
+ while (cptr > ptrc) {
+ cur = ptr = make_type(RPC_FC_FP, cur); /* FIXME: pointer type from attrs? */
+ ptrc++;
+ }
+ } else {
+ while (cptr < ptrc) {
+ cur = cur->ref;
+ cptr++;
+ }
+ }
+ reg_type(cur, names->name, t);
+ }
+ free(names);
+ names = next;
+ }
+ return type;
+}
+
+static type_t *find_type(char *name, int t)
+{
+ struct rtype *cur = first;
+ while (cur && (cur->t != t || strcmp(cur->name, name)))
+ cur = cur->next;
+ if (!cur) {
+ yyerror("type %s not found\n", name);
+ return NULL;
+ }
+ return cur->type;
+}
+
+static type_t *find_type2(char *name, int t)
+{
+ type_t *tp = find_type(name, t);
+ free(name);
+ return tp;
+}
+
+int is_type(const char *name)
+{
+ struct rtype *cur = first;
+ while (cur && (cur->t || strcmp(cur->name, name)))
+ cur = cur->next;
+ if (cur) return TRUE;
+ return FALSE;
+}
+
+static type_t *get_type(BYTE type, char *name, int t)
+{
+ struct rtype *cur = NULL;
+ type_t *tp;
+ if (name) {
+ cur = first;
+ while (cur && (cur->t != t || strcmp(cur->name, name)))
+ cur = cur->next;
+ }
+ if (cur) {
+ free(name);
+ return cur->type;
+ }
+ tp = make_type(type, NULL);
+ tp->name = name;
+ if (!name) return tp;
+ return reg_type(tp, name, t);
+}
+
+static type_t *get_typev(BYTE type, var_t *name, int t)
+{
+ char *sname = NULL;
+ if (name) {
+ sname = name->name;
+ free(name);
+ }
+ return get_type(type, sname, t);
+}
+
-------------- next part --------------
--- NUL Wed Dec 31 19:00:00 1969
+++ header.c Sun Jun 30 02:37:48 2002
@@ -0,0 +1,408 @@
+/*
+ * 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
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <assert.h>
+#include <ctype.h>
+#include <signal.h>
+
+#include "widl.h"
+#include "utils.h"
+#include "parser.h"
+#include "header.h"
+#include "proxy.h"
+#include "y.tab.h"
+
+static int indentation = 0;
+
+static void indent(int delta)
+{
+ int c;
+ if (delta < 0) indentation += delta;
+ for (c=0; c<indentation; c++) fprintf(header, " ");
+ if (delta > 0) indentation += delta;
+}
+
+int is_void(type_t *t, var_t *v)
+{
+ if (v && v->ptr_level) return 0;
+ if (!t->type && !t->ref) return 1;
+ return 0;
+}
+
+static void write_pident(var_t *v)
+{
+ int c;
+ for (c=0; c<v->ptr_level; c++) {
+ fprintf(header, "*");
+ }
+ if (v->name) fprintf(header, "%s", v->name);
+}
+
+void write_name(FILE *h, var_t *v)
+{
+ fprintf(h, "%s", v->name);
+}
+
+char* get_name(var_t *v)
+{
+ return v->name;
+}
+
+static void write_fields(FILE *h, var_t *v)
+{
+ if (!v) return;
+ while (NEXT_LINK(v)) v = NEXT_LINK(v);
+ while (v) {
+ if (v->type) {
+ indent(0);
+ write_type(h, v->type, NULL, v->tname);
+ if (get_name(v)) {
+ fprintf(header, " ");
+ write_pident(v);
+ }
+ fprintf(header, ";\n");
+ }
+ v = PREV_LINK(v);
+ }
+}
+
+void write_type(FILE *h, type_t *t, var_t *v, char *n)
+{
+ int c;
+
+ if (n) fprintf(h, "%s", n);
+ else {
+ if (t->is_const) fprintf(h, "const ");
+ if (t->type) {
+ switch (t->type) {
+ case RPC_FC_BYTE:
+ fprintf(h, "byte");
+ break;
+ case RPC_FC_CHAR:
+ fprintf(h, "char");
+ break;
+ case RPC_FC_USHORT:
+ fprintf(h, "unsigned ");
+ case RPC_FC_SHORT:
+ if (t->ref) fprintf(h, t->ref->name);
+ fprintf(h, "short");
+ break;
+ case RPC_FC_ULONG:
+ fprintf(h, "unsigned ");
+ case RPC_FC_LONG:
+ if (t->ref) fprintf(h, t->ref->name);
+ else fprintf(h, "long");
+ break;
+ case RPC_FC_STRUCT:
+ if (t->defined && !t->written) {
+ if (t->name) fprintf(h, "struct %s {\n", t->name);
+ else fprintf(h, "struct {\n");
+ indentation++;
+ write_fields(h, t->fields);
+ indent(-1);
+ fprintf(h, "}");
+ }
+ else fprintf(h, "struct %s", t->name);
+ break;
+ case RPC_FC_NON_ENCAPSULATED_UNION:
+ if (t->defined && !t->written) {
+ if (t->name) fprintf(h, "union %s {\n", t->name);
+ else fprintf(h, "union {\n");
+ indentation++;
+ write_fields(h, t->fields);
+ indent(-1);
+ fprintf(h, "}");
+ }
+ else fprintf(h, "union %s", t->name);
+ break;
+ default:
+ fprintf(h, "(unknown-type:%d)", t->type);
+ }
+ }
+ else {
+ if (t->ref) {
+ write_type(h, t->ref, NULL, t->name);
+ }
+ else fprintf(h, "void");
+ }
+ }
+ if (v) {
+ for (c=0; c<v->ptr_level; c++) {
+ fprintf(h, "*");
+ }
+ }
+}
+
+void write_typedef(type_t *type, var_t *names)
+{
+ char *tname = names->tname;
+ while (NEXT_LINK(names)) names = NEXT_LINK(names);
+ fprintf(header, "typedef ");
+ write_type(header, type, NULL, tname);
+ fprintf(header, " ");
+ while (names) {
+ write_pident(names);
+ if (PREV_LINK(names))
+ fprintf(header, ", ");
+ names = PREV_LINK(names);
+ }
+ fprintf(header, ";\n");
+}
+
+/********** INTERFACES **********/
+
+int is_object(attr_t *a)
+{
+ while (a) {
+ if (a->type == tOBJECT) return 1;
+ a = NEXT_LINK(a);
+ }
+ return 0;
+}
+
+int is_local(attr_t *a)
+{
+ while (a) {
+ if (a->type == tLOCAL) return 1;
+ a = NEXT_LINK(a);
+ }
+ return 0;
+}
+
+var_t *is_callas(attr_t *a)
+{
+ while (a) {
+ if (a->type == tCALLAS) return a->u.pval;
+ a = NEXT_LINK(a);
+ }
+ return NULL;
+}
+
+static void write_method_def(type_t *iface)
+{
+ func_t *cur = iface->funcs;
+ while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
+ fprintf(header, "#define %s_METHODS", iface->name);
+ while (cur) {
+ var_t *def = cur->def;
+ if (!is_callas(def->attrs)) {
+ var_t *arg = cur->args;
+ int argc = 0;
+ if (arg) {
+ argc++;
+ while (NEXT_LINK(arg)) {
+ arg = NEXT_LINK(arg);
+ argc++;
+ }
+ }
+ fprintf(header, " \\\n");
+ if (!is_void(def->type, def)) {
+ if (argc)
+ fprintf(header, " ICOM_METHOD%d (", argc);
+ else
+ fprintf(header, " ICOM_METHOD (");
+ write_type(header, def->type, def, def->tname);
+ fprintf(header, ",");
+ } else
+ if (argc)
+ fprintf(header, " ICOM_VMETHOD%d(", argc);
+ else
+ fprintf(header, " ICOM_VMETHOD (");
+ write_name(header, def);
+ while (arg) {
+ fprintf(header, ",");
+ write_type(header, arg->type, arg, arg->tname);
+ fprintf(header, ",");
+ write_name(header,arg);
+ arg = PREV_LINK(arg);
+ }
+ fprintf(header, ")");
+ }
+ cur = PREV_LINK(cur);
+ }
+ fprintf(header, "\n");
+}
+
+static int write_method_macro(type_t *iface, char *name)
+{
+ int idx;
+ func_t *cur = iface->funcs;
+ while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
+
+ if (iface->ref) idx = write_method_macro(iface->ref, name);
+ else idx = 0;
+ fprintf(header, "/*** %s methods ***/\n", iface->name);
+ while (cur) {
+ var_t *def = cur->def;
+ if (!is_callas(def->attrs)) {
+ var_t *arg = cur->args;
+ int argc = 0;
+ int c;
+ while (arg) {
+ arg = NEXT_LINK(arg);
+ argc++;
+ }
+
+ fprintf(header, "#define %s_", name);
+ write_name(header,def);
+ fprintf(header, "(p");
+ for (c=0; c<argc; c++)
+ fprintf(header, ",%c", c+'a');
+ fprintf(header, ") ");
+
+ if (argc)
+ fprintf(header, "ICOM_CALL%d(", argc);
+ else
+ fprintf(header, "ICOM_CALL(");
+ write_name(header,def);
+ fprintf(header, ",p");
+ for (c=0; c<argc; c++)
+ fprintf(header, ",%c", c+'a');
+ fprintf(header, ")\n");
+ if (cur->idx == -1) cur->idx = idx;
+ else if (cur->idx != idx) yyerror("BUG: method index mismatch in write_method_macro");
+ idx++;
+ }
+ cur = PREV_LINK(cur);
+ }
+ return idx;
+}
+
+void write_method_args(FILE *h, var_t *arg, char *name)
+{
+ if (arg) {
+ while (NEXT_LINK(arg))
+ arg = NEXT_LINK(arg);
+ }
+ fprintf(h, " %s* This", name);
+ while (arg) {
+ fprintf(h, ",\n ");
+ write_type(h, arg->type, arg, arg->tname);
+ fprintf(h, " ");
+ write_name(h,arg);
+ arg = PREV_LINK(arg);
+ }
+}
+
+static void write_method_proto(type_t *iface)
+{
+ func_t *cur = iface->funcs;
+ while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
+ while (cur) {
+ var_t *def = cur->def;
+ var_t *cas = is_callas(def->attrs);
+ if (!is_local(def->attrs)) {
+ /* proxy prototype */
+ write_type(header, def->type, def, def->tname);
+ fprintf(header, " CALLBACK %s_", iface->name);
+ write_name(header,def);
+ fprintf(header, "_Proxy(\n");
+ write_method_args(header, cur->args, iface->name);
+ fprintf(header, ");\n");
+ /* stub prototype */
+ fprintf(header, "void __RPC_STUB %s_", iface->name);
+ write_name(header,def);
+ fprintf(header, "_Stub(\n");
+ fprintf(header, " IRpcStubBuffer* This,\n");
+ fprintf(header, " IRpcChannelBuffer* pRpcChannelBuffer,\n");
+ fprintf(header, " PRPC_MESSAGE pRpcMessage,\n");
+ fprintf(header, " DWORD* pdwStubPhase);\n");
+ }
+ if (cas) {
+ func_t *m = iface->funcs;
+ while (m && strcmp(get_name(m->def), cas->name))
+ m = NEXT_LINK(m);
+ if (m) {
+ var_t *mdef = m->def;
+ /* proxy prototype - use local prototype */
+ write_type(header, mdef->type, mdef, mdef->tname);
+ fprintf(header, " CALLBACK %s_", iface->name);
+ write_name(header, mdef);
+ fprintf(header, "_Proxy(\n");
+ write_method_args(header, m->args, iface->name);
+ fprintf(header, ");\n");
+ /* stub prototype - use remotable prototype */
+ write_type(header, def->type, def, def->tname);
+ fprintf(header, " __RPC_STUB %s_", iface->name);
+ write_name(header, mdef);
+ fprintf(header, "_Stub(\n");
+ write_method_args(header, cur->args, iface->name);
+ fprintf(header, ");\n");
+ }
+ else {
+ yywarning("invalid call_as attribute (%s -> %s)\n", get_name(def), cas->name);
+ }
+ }
+
+ cur = PREV_LINK(cur);
+ }
+}
+
+void write_forward(type_t *iface)
+{
+ if (!iface->written) {
+ fprintf(header, "typedef struct %s %s;\n", iface->name, iface->name);
+ iface->written = TRUE;
+ }
+}
+
+void write_interface(type_t *iface)
+{
+ if (!is_object(iface->attrs)) {
+ if (!iface->funcs) return;
+ yywarning("RPC interfaces not supported yet\n");
+ return;
+ }
+
+ if (!iface->funcs) {
+ yywarning("%s has no methods", iface->name);
+ return;
+ }
+
+ fprintf(header, "/*****************************************************************************\n");
+ fprintf(header, " * %s interface\n", iface->name);
+ fprintf(header, " */\n");
+ write_forward(iface);
+ if (iface->ref)
+ fprintf(header, "#define ICOM_INTERFACE %s\n", iface->name);
+ write_method_def(iface);
+ fprintf(header, "#define %s_IMETHODS \\\n", iface->name);
+ if (iface->ref)
+ fprintf(header, " %s_IMETHODS \\\n", iface->ref->name);
+ fprintf(header, " %s_METHODS \\\n", iface->name);
+ if (iface->ref) {
+ fprintf(header, "ICOM_DEFINE(%s,%s)\n", iface->name, iface->ref->name);
+ fprintf(header, "#undef ICOM_INTERFACE\n");
+ }
+ fprintf(header, "\n");
+ write_method_macro(iface, iface->name);
+ fprintf(header, "\n");
+ write_method_proto(iface);
+ fprintf(header, "\n");
+
+ if (!is_local(iface->attrs))
+ write_proxy(iface);
+}
-------------- next part --------------
--- NUL Wed Dec 31 19:00:00 1969
+++ ppy.tab.h Sun Jun 30 02:59:04 2002
@@ -0,0 +1,84 @@
+/*
+ * 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
+ */
+
+#ifndef BISON_PPY_TAB_H
+# define BISON_PPY_TAB_H
+
+#ifndef YYSTYPE
+typedef union{
+ int sint;
+ unsigned int uint;
+ long slong;
+ unsigned long ulong;
+ wrc_sll_t sll;
+ wrc_ull_t ull;
+ int *iptr;
+ char *cptr;
+ cval_t cval;
+ marg_t *marg;
+ mtext_t *mtext;
+} yystype;
+# define YYSTYPE yystype
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+# define tRCINCLUDE 257
+# define tIF 258
+# define tIFDEF 259
+# define tIFNDEF 260
+# define tELSE 261
+# define tELIF 262
+# define tENDIF 263
+# define tDEFINED 264
+# define tNL 265
+# define tINCLUDE 266
+# define tLINE 267
+# define tGCCLINE 268
+# define tERROR 269
+# define tWARNING 270
+# define tPRAGMA 271
+# define tPPIDENT 272
+# define tUNDEF 273
+# define tMACROEND 274
+# define tCONCAT 275
+# define tELIPSIS 276
+# define tSTRINGIZE 277
+# define tIDENT 278
+# define tLITERAL 279
+# define tMACRO 280
+# define tDEFINE 281
+# define tDQSTRING 282
+# define tSQSTRING 283
+# define tIQSTRING 284
+# define tUINT 285
+# define tSINT 286
+# define tULONG 287
+# define tSLONG 288
+# define tULONGLONG 289
+# define tSLONGLONG 290
+# define tRCINCLUDEPATH 291
+# define tLOGOR 292
+# define tLOGAND 293
+# define tEQ 294
+# define tNE 295
+# define tLTE 296
+# define tGTE 297
+# define tLSHIFT 298
+# define tRSHIFT 299
+
+
+extern YYSTYPE pplval;
+
+#endif /* not BISON_PPY_TAB_H */
-------------- next part --------------
--- NUL Wed Dec 31 19:00:00 1969
+++ ppy.y Sun Jun 30 02:45:28 2002
@@ -0,0 +1,654 @@
+/*
+ * Wrc preprocessor syntax analysis
+ *
+ * Copyright 1999-2000 Bertho A. Stultiens (BS)
+ *
+ * 24-Apr-2000 BS Restructured the lot to fit the new scanner
+ * and reintegrate into the wine-tree.
+ * 01-Jan-2000 BS FIXME: win16 preprocessor calculates with
+ * 16 bit ints and overflows...?
+ * 26-Dec-1999 BS Started this file
+ *
+ * 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
+ */
+
+%{
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "utils.h"
+#include "widl.h"
+#include "preproc.h"
+
+
+#define UNARY_OP(r, v, OP) \
+ switch(v.type) \
+ { \
+ case cv_sint: r.val.si = OP v.val.si; break; \
+ case cv_uint: r.val.ui = OP v.val.ui; break; \
+ case cv_slong: r.val.sl = OP v.val.sl; break; \
+ case cv_ulong: r.val.ul = OP v.val.ul; break; \
+ case cv_sll: r.val.sll = OP v.val.sll; break; \
+ case cv_ull: r.val.ull = OP v.val.ull; break; \
+ }
+
+#define cv_signed(v) ((v.type & FLAG_SIGNED) != 0)
+
+#define BIN_OP_INT(r, v1, v2, OP) \
+ r.type = v1.type; \
+ if(cv_signed(v1) && cv_signed(v2)) \
+ r.val.si = v1.val.si OP v2.val.si; \
+ else if(cv_signed(v1) && !cv_signed(v2)) \
+ r.val.si = v1.val.si OP v2.val.ui; \
+ else if(!cv_signed(v1) && cv_signed(v2)) \
+ r.val.ui = v1.val.ui OP v2.val.si; \
+ else \
+ r.val.ui = v1.val.ui OP v2.val.ui;
+
+#define BIN_OP_LONG(r, v1, v2, OP) \
+ r.type = v1.type; \
+ if(cv_signed(v1) && cv_signed(v2)) \
+ r.val.sl = v1.val.sl OP v2.val.sl; \
+ else if(cv_signed(v1) && !cv_signed(v2)) \
+ r.val.sl = v1.val.sl OP v2.val.ul; \
+ else if(!cv_signed(v1) && cv_signed(v2)) \
+ r.val.ul = v1.val.ul OP v2.val.sl; \
+ else \
+ r.val.ul = v1.val.ul OP v2.val.ul;
+
+#define BIN_OP_LONGLONG(r, v1, v2, OP) \
+ r.type = v1.type; \
+ if(cv_signed(v1) && cv_signed(v2)) \
+ r.val.sll = v1.val.sll OP v2.val.sll; \
+ else if(cv_signed(v1) && !cv_signed(v2)) \
+ r.val.sll = v1.val.sll OP v2.val.ull; \
+ else if(!cv_signed(v1) && cv_signed(v2)) \
+ r.val.ull = v1.val.ull OP v2.val.sll; \
+ else \
+ r.val.ull = v1.val.ull OP v2.val.ull;
+
+#define BIN_OP(r, v1, v2, OP) \
+ switch(v1.type & SIZE_MASK) \
+ { \
+ case SIZE_INT: BIN_OP_INT(r, v1, v2, OP); break; \
+ case SIZE_LONG: BIN_OP_LONG(r, v1, v2, OP); break; \
+ case SIZE_LONGLONG: BIN_OP_LONGLONG(r, v1, v2, OP); break; \
+ default: internal_error(__FILE__, __LINE__, "Invalid type indicator (0x%04x)", v1.type); \
+ }
+
+
+/*
+ * Prototypes
+ */
+static int boolean(cval_t *v);
+static void promote_equal_size(cval_t *v1, cval_t *v2);
+static void cast_to_sint(cval_t *v);
+static void cast_to_uint(cval_t *v);
+static void cast_to_slong(cval_t *v);
+static void cast_to_ulong(cval_t *v);
+static void cast_to_sll(cval_t *v);
+static void cast_to_ull(cval_t *v);
+static marg_t *new_marg(char *str, def_arg_t type);
+static marg_t *add_new_marg(char *str, def_arg_t type);
+static int marg_index(char *id);
+static mtext_t *new_mtext(char *str, int idx, def_exp_t type);
+static mtext_t *combine_mtext(mtext_t *tail, mtext_t *mtp);
+static char *merge_text(char *s1, char *s2);
+
+/*
+ * Local variables
+ */
+static marg_t **macro_args; /* Macro parameters array while parsing */
+static int nmacro_args;
+
+%}
+
+%union{
+ int sint;
+ unsigned int uint;
+ long slong;
+ unsigned long ulong;
+ wrc_sll_t sll;
+ wrc_ull_t ull;
+ int *iptr;
+ char *cptr;
+ cval_t cval;
+ marg_t *marg;
+ mtext_t *mtext;
+}
+
+%token tRCINCLUDE
+%token tIF tIFDEF tIFNDEF tELSE tELIF tENDIF tDEFINED tNL
+%token tINCLUDE tLINE tGCCLINE tERROR tWARNING tPRAGMA tPPIDENT
+%token tUNDEF tMACROEND tCONCAT tELIPSIS tSTRINGIZE
+%token <cptr> tIDENT tLITERAL tMACRO tDEFINE
+%token <cptr> tDQSTRING tSQSTRING tIQSTRING
+%token <uint> tUINT
+%token <sint> tSINT
+%token <ulong> tULONG
+%token <slong> tSLONG
+%token <ull> tULONGLONG
+%token <sll> tSLONGLONG
+%token <cptr> tRCINCLUDEPATH
+
+%right '?' ':'
+%left tLOGOR
+%left tLOGAND
+%left '|'
+%left '^'
+%left '&'
+%left tEQ tNE
+%left '<' tLTE '>' tGTE
+%left tLSHIFT tRSHIFT
+%left '+' '-'
+%left '*' '/'
+%right '~' '!'
+
+%type <cval> pp_expr
+%type <marg> emargs margs
+%type <mtext> opt_mtexts mtexts mtext
+%type <sint> allmargs
+%type <cptr> opt_text text
+
+/*
+ **************************************************************************
+ * The parser starts here
+ **************************************************************************
+ */
+
+%%
+
+pp_file : /* Empty */
+ | pp_file preprocessor
+ ;
+
+preprocessor
+ : tINCLUDE tDQSTRING tNL { do_include($2, 1); }
+ | tINCLUDE tIQSTRING tNL { do_include($2, 0); }
+ | tIF pp_expr tNL { next_if_state(boolean(&$2)); }
+ | tIFDEF tIDENT tNL { next_if_state(pplookup($2) != NULL); free($2); }
+ | tIFNDEF tIDENT tNL {
+ int t = pplookup($2) == NULL;
+ if(include_state == 0 && t && !seen_junk)
+ {
+ include_state = 1;
+ include_ppp = $2;
+ include_ifdepth = get_if_depth();
+ }
+ else if(include_state != 1)
+ {
+ include_state = -1;
+ free($2);
+ }
+ else
+ free($2);
+ next_if_state(t);
+ if(debuglevel & DEBUGLEVEL_PPMSG)
+ fprintf(stderr, "tIFNDEF: %s:%d: include_state=%d, include_ppp='%s', include_ifdepth=%d\n", input_name, line_number, include_state, include_ppp, include_ifdepth);
+ }
+ | tELIF pp_expr tNL {
+ if_state_t s = pop_if();
+ switch(s)
+ {
+ case if_true:
+ case if_elif:
+ push_if(if_elif);
+ break;
+ case if_false:
+ push_if(boolean(&$2) ? if_true : if_false);
+ break;
+ case if_ignore:
+ push_if(if_ignore);
+ break;
+ case if_elsetrue:
+ case if_elsefalse:
+ pperror("#elif cannot follow #else");
+ default:
+ internal_error(__FILE__, __LINE__, "Invalid if_state (%d) in #elif directive", s);
+ }
+ }
+ | tELSE tNL {
+ if_state_t s = pop_if();
+ switch(s)
+ {
+ case if_true:
+ push_if(if_elsefalse);
+ break;
+ case if_elif:
+ push_if(if_elif);
+ break;
+ case if_false:
+ push_if(if_elsetrue);
+ break;
+ case if_ignore:
+ push_if(if_ignore);
+ break;
+ case if_elsetrue:
+ case if_elsefalse:
+ pperror("#else clause already defined");
+ default:
+ internal_error(__FILE__, __LINE__, "Invalid if_state (%d) in #else directive", s);
+ }
+ }
+ | tENDIF tNL {
+ pop_if();
+ if(include_ifdepth == get_if_depth() && include_state == 1)
+ {
+ include_state = 2;
+ seen_junk = 0;
+ }
+ else if(include_state != 1)
+ {
+ include_state = -1;
+ }
+ if(debuglevel & DEBUGLEVEL_PPMSG)
+ fprintf(stderr, "tENDIF: %s:%d: include_state=%d, include_ppp='%s', include_ifdepth=%d\n", input_name, line_number, include_state, include_ppp, include_ifdepth);
+ }
+ | tUNDEF tIDENT tNL { del_define($2); free($2); }
+ | tDEFINE opt_text tNL { add_define($1, $2); }
+ | tMACRO res_arg allmargs tMACROEND opt_mtexts tNL {
+ add_macro($1, macro_args, nmacro_args, $5);
+ }
+ | tLINE tSINT tDQSTRING tNL { fprintf(ppout, "# %d %s\n", $2 , $3); free($3); }
+ | tGCCLINE tSINT tDQSTRING tNL { fprintf(ppout, "# %d %s\n", $2 , $3); free($3); }
+ | tGCCLINE tSINT tDQSTRING tSINT tNL
+ { fprintf(ppout, "# %d %s %d\n", $2, $3, $4); free($3); }
+ | tGCCLINE tSINT tDQSTRING tSINT tSINT tNL
+ { fprintf(ppout, "# %d %s %d %d\n", $2 ,$3, $4, $5); free($3); }
+ | tGCCLINE tSINT tDQSTRING tSINT tSINT tSINT tNL
+ { fprintf(ppout, "# %d %s %d %d %d\n", $2 ,$3 ,$4 ,$5, $6); free($3); }
+ | tGCCLINE tSINT tDQSTRING tSINT tSINT tSINT tSINT tNL
+ { fprintf(ppout, "# %d %s %d %d %d %d\n", $2 ,$3 ,$4 ,$5, $6, $7); free($3); }
+ | tGCCLINE tNL /* The null-token */
+ | tERROR opt_text tNL { pperror("#error directive: '%s'", $2); if($2) free($2); }
+ | tWARNING opt_text tNL { ppwarning("#warning directive: '%s'", $2); if($2) free($2); }
+ | tPRAGMA opt_text tNL { if(pedantic) ppwarning("#pragma ignored (arg: '%s')", $2); if($2) free($2); }
+ | tPPIDENT opt_text tNL { if(pedantic) ppwarning("#ident ignored (arg: '%s')", $2); if($2) free($2); }
+ | tRCINCLUDE tRCINCLUDEPATH {
+ int nl=strlen($2) +3;
+ char *fn=xmalloc(nl);
+ snprintf(fn,nl,"\"%s\"",$2);
+ free($2);
+ do_include(fn,1);
+ }
+ | tRCINCLUDE tDQSTRING {
+ do_include($2,1);
+ }
+ /*| tNL*/
+ ;
+
+opt_text: /* Empty */ { $$ = NULL; }
+ | text { $$ = $1; }
+ ;
+
+text : tLITERAL { $$ = $1; }
+ | tDQSTRING { $$ = $1; }
+ | tSQSTRING { $$ = $1; }
+ | text tLITERAL { $$ = merge_text($1, $2); }
+ | text tDQSTRING { $$ = merge_text($1, $2); }
+ | text tSQSTRING { $$ = merge_text($1, $2); }
+ ;
+
+res_arg : /* Empty */ { macro_args = NULL; nmacro_args = 0; }
+ ;
+
+allmargs: /* Empty */ { $$ = 0; macro_args = NULL; nmacro_args = 0; }
+ | emargs { $$ = nmacro_args; }
+ ;
+
+emargs : margs { $$ = $1; }
+ | margs ',' tELIPSIS { $$ = add_new_marg(NULL, arg_list); nmacro_args *= -1; }
+ ;
+
+margs : margs ',' tIDENT { $$ = add_new_marg($3, arg_single); }
+ | tIDENT { $$ = add_new_marg($1, arg_single); }
+ ;
+
+opt_mtexts
+ : /* Empty */ { $$ = NULL; }
+ | mtexts {
+ for($$ = $1; $$ && $$->prev; $$ = $$->prev)
+ ;
+ }
+ ;
+
+mtexts : mtext { $$ = $1; }
+ | mtexts mtext { $$ = combine_mtext($1, $2); }
+ ;
+
+mtext : tLITERAL { $$ = new_mtext($1, 0, exp_text); }
+ | tDQSTRING { $$ = new_mtext($1, 0, exp_text); }
+ | tSQSTRING { $$ = new_mtext($1, 0, exp_text); }
+ | tCONCAT { $$ = new_mtext(NULL, 0, exp_concat); }
+ | tSTRINGIZE tIDENT {
+ int mat = marg_index($2);
+ if(mat < 0)
+ pperror("Stringification identifier must be an argument parameter");
+ $$ = new_mtext(NULL, mat, exp_stringize);
+ }
+ | tIDENT {
+ int mat = marg_index($1);
+ if(mat >= 0)
+ $$ = new_mtext(NULL, mat, exp_subst);
+ else
+ $$ = new_mtext($1, 0, exp_text);
+ }
+ ;
+
+pp_expr : tSINT { $$.type = cv_sint; $$.val.si = $1; }
+ | tUINT { $$.type = cv_uint; $$.val.ui = $1; }
+ | tSLONG { $$.type = cv_slong; $$.val.sl = $1; }
+ | tULONG { $$.type = cv_ulong; $$.val.ul = $1; }
+ | tSLONGLONG { $$.type = cv_sll; $$.val.sl = $1; }
+ | tULONGLONG { $$.type = cv_ull; $$.val.ul = $1; }
+ | tDEFINED tIDENT { $$.type = cv_sint; $$.val.si = pplookup($2) != NULL; }
+ | tDEFINED '(' tIDENT ')' { $$.type = cv_sint; $$.val.si = pplookup($3) != NULL; }
+ | tIDENT { $$.type = cv_sint; $$.val.si = 0; }
+ | pp_expr tLOGOR pp_expr { $$.type = cv_sint; $$.val.si = boolean(&$1) || boolean(&$3); }
+ | pp_expr tLOGAND pp_expr { $$.type = cv_sint; $$.val.si = boolean(&$1) && boolean(&$3); }
+ | pp_expr tEQ pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, ==) }
+ | pp_expr tNE pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, !=) }
+ | pp_expr '<' pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, <) }
+ | pp_expr '>' pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, >) }
+ | pp_expr tLTE pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, <=) }
+ | pp_expr tGTE pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, >=) }
+ | pp_expr '+' pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, +) }
+ | pp_expr '-' pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, -) }
+ | pp_expr '^' pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, ^) }
+ | pp_expr '&' pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, &) }
+ | pp_expr '|' pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, |) }
+ | pp_expr '*' pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, *) }
+ | pp_expr '/' pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, /) }
+ | pp_expr tLSHIFT pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, <<) }
+ | pp_expr tRSHIFT pp_expr { promote_equal_size(&$1, &$3); BIN_OP($$, $1, $3, >>) }
+ | '+' pp_expr { $$ = $2; }
+ | '-' pp_expr { UNARY_OP($$, $2, -) }
+ | '~' pp_expr { UNARY_OP($$, $2, ~) }
+ | '!' pp_expr { $$.type = cv_sint; $$.val.si = !boolean(&$2); }
+ | '(' pp_expr ')' { $$ = $2; }
+ | pp_expr '?' pp_expr ':' pp_expr { $$ = boolean(&$1) ? $3 : $5; }
+ ;
+
+%%
+
+/*
+ **************************************************************************
+ * Support functions
+ **************************************************************************
+ */
+
+static void cast_to_sint(cval_t *v)
+{
+ switch(v->type)
+ {
+ case cv_sint: break;
+ case cv_uint: break;
+ case cv_slong: v->val.si = v->val.sl; break;
+ case cv_ulong: v->val.si = v->val.ul; break;
+ case cv_sll: v->val.si = v->val.sll; break;
+ case cv_ull: v->val.si = v->val.ull; break;
+ }
+ v->type = cv_sint;
+}
+
+static void cast_to_uint(cval_t *v)
+{
+ switch(v->type)
+ {
+ case cv_sint: break;
+ case cv_uint: break;
+ case cv_slong: v->val.ui = v->val.sl; break;
+ case cv_ulong: v->val.ui = v->val.ul; break;
+ case cv_sll: v->val.ui = v->val.sll; break;
+ case cv_ull: v->val.ui = v->val.ull; break;
+ }
+ v->type = cv_uint;
+}
+
+static void cast_to_slong(cval_t *v)
+{
+ switch(v->type)
+ {
+ case cv_sint: v->val.sl = v->val.si; break;
+ case cv_uint: v->val.sl = v->val.ui; break;
+ case cv_slong: break;
+ case cv_ulong: break;
+ case cv_sll: v->val.sl = v->val.sll; break;
+ case cv_ull: v->val.sl = v->val.ull; break;
+ }
+ v->type = cv_slong;
+}
+
+static void cast_to_ulong(cval_t *v)
+{
+ switch(v->type)
+ {
+ case cv_sint: v->val.ul = v->val.si; break;
+ case cv_uint: v->val.ul = v->val.ui; break;
+ case cv_slong: break;
+ case cv_ulong: break;
+ case cv_sll: v->val.ul = v->val.sll; break;
+ case cv_ull: v->val.ul = v->val.ull; break;
+ }
+ v->type = cv_ulong;
+}
+
+static void cast_to_sll(cval_t *v)
+{
+ switch(v->type)
+ {
+ case cv_sint: v->val.sll = v->val.si; break;
+ case cv_uint: v->val.sll = v->val.ui; break;
+ case cv_slong: v->val.sll = v->val.sl; break;
+ case cv_ulong: v->val.sll = v->val.ul; break;
+ case cv_sll: break;
+ case cv_ull: break;
+ }
+ v->type = cv_sll;
+}
+
+static void cast_to_ull(cval_t *v)
+{
+ switch(v->type)
+ {
+ case cv_sint: v->val.ull = v->val.si; break;
+ case cv_uint: v->val.ull = v->val.ui; break;
+ case cv_slong: v->val.ull = v->val.sl; break;
+ case cv_ulong: v->val.ull = v->val.ul; break;
+ case cv_sll: break;
+ case cv_ull: break;
+ }
+ v->type = cv_ull;
+}
+
+
+static void promote_equal_size(cval_t *v1, cval_t *v2)
+{
+#define cv_sizeof(v) ((int)(v->type & SIZE_MASK))
+ int s1 = cv_sizeof(v1);
+ int s2 = cv_sizeof(v2);
+#undef cv_sizeof
+
+ if(s1 == s2)
+ return;
+ else if(s1 > s2)
+ {
+ switch(v1->type)
+ {
+ case cv_sint: cast_to_sint(v2); break;
+ case cv_uint: cast_to_uint(v2); break;
+ case cv_slong: cast_to_slong(v2); break;
+ case cv_ulong: cast_to_ulong(v2); break;
+ case cv_sll: cast_to_sll(v2); break;
+ case cv_ull: cast_to_ull(v2); break;
+ }
+ }
+ else
+ {
+ switch(v2->type)
+ {
+ case cv_sint: cast_to_sint(v1); break;
+ case cv_uint: cast_to_uint(v1); break;
+ case cv_slong: cast_to_slong(v1); break;
+ case cv_ulong: cast_to_ulong(v1); break;
+ case cv_sll: cast_to_sll(v1); break;
+ case cv_ull: cast_to_ull(v1); break;
+ }
+ }
+}
+
+
+static int boolean(cval_t *v)
+{
+ switch(v->type)
+ {
+ case cv_sint: return v->val.si != (int)0;
+ case cv_uint: return v->val.ui != (unsigned int)0;
+ case cv_slong: return v->val.sl != (long)0;
+ case cv_ulong: return v->val.ul != (unsigned long)0;
+ case cv_sll: return v->val.sll != (wrc_sll_t)0;
+ case cv_ull: return v->val.ull != (wrc_ull_t)0;
+ }
+ return 0;
+}
+
+static marg_t *new_marg(char *str, def_arg_t type)
+{
+ marg_t *ma = (marg_t *)xmalloc(sizeof(marg_t));
+ ma->arg = str;
+ ma->type = type;
+ return ma;
+}
+
+static marg_t *add_new_marg(char *str, def_arg_t type)
+{
+ marg_t *ma = new_marg(str, type);
+ nmacro_args++;
+ macro_args = (marg_t **)xrealloc(macro_args, nmacro_args * sizeof(macro_args[0]));
+ macro_args[nmacro_args-1] = ma;
+ return ma;
+}
+
+static int marg_index(char *id)
+{
+ int t;
+ for(t = 0; t < nmacro_args; t++)
+ {
+ if(!strcmp(id, macro_args[t]->arg))
+ break;
+ }
+ return t < nmacro_args ? t : -1;
+}
+
+static mtext_t *new_mtext(char *str, int idx, def_exp_t type)
+{
+ mtext_t *mt = (mtext_t *)xmalloc(sizeof(mtext_t));
+ if(str == NULL)
+ mt->subst.argidx = idx;
+ else
+ mt->subst.text = str;
+ mt->type = type;
+ return mt;
+}
+
+static mtext_t *combine_mtext(mtext_t *tail, mtext_t *mtp)
+{
+ if(!tail)
+ return mtp;
+
+ if(!mtp)
+ return tail;
+
+ if(tail->type == exp_text && mtp->type == exp_text)
+ {
+ tail->subst.text = xrealloc(tail->subst.text, strlen(tail->subst.text)+strlen(mtp->subst.text)+1);
+ strcat(tail->subst.text, mtp->subst.text);
+ free(mtp->subst.text);
+ free(mtp);
+ return tail;
+ }
+
+ if(tail->type == exp_concat && mtp->type == exp_concat)
+ {
+ free(mtp);
+ return tail;
+ }
+
+ if(tail->type == exp_concat && mtp->type == exp_text)
+ {
+ int len = strlen(mtp->subst.text);
+ while(len)
+ {
+/* FIXME: should delete space from head of string */
+ if(isspace(mtp->subst.text[len-1] & 0xff))
+ mtp->subst.text[--len] = '\0';
+ else
+ break;
+ }
+
+ if(!len)
+ {
+ free(mtp->subst.text);
+ free(mtp);
+ return tail;
+ }
+ }
+
+ if(tail->type == exp_text && mtp->type == exp_concat)
+ {
+ int len = strlen(tail->subst.text);
+ while(len)
+ {
+ if(isspace(tail->subst.text[len-1] & 0xff))
+ tail->subst.text[--len] = '\0';
+ else
+ break;
+ }
+
+ if(!len)
+ {
+ mtp->prev = tail->prev;
+ mtp->next = tail->next;
+ if(tail->prev)
+ tail->prev->next = mtp;
+ free(tail->subst.text);
+ free(tail);
+ return mtp;
+ }
+ }
+
+ tail->next = mtp;
+ mtp->prev = tail;
+
+ return mtp;
+}
+
+static char *merge_text(char *s1, char *s2)
+{
+ int l1 = strlen(s1);
+ int l2 = strlen(s2);
+ s1 = xrealloc(s1, l1+l2+1);
+ memcpy(s1+l1, s2, l2+1);
+ free(s2);
+ return s1;
+}
+
-------------- next part --------------
--- NUL Wed Dec 31 19:00:00 1969
+++ preproc.c Sun Jun 30 02:39:30 2002
@@ -0,0 +1,493 @@
+/*
+ * Copyright 1998 Bertho A. Stultiens (BS)
+ *
+ * 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
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "widl.h"
+#include "utils.h"
+#include "preproc.h"
+
+
+#define HASHKEY 2039
+static pp_entry_t *pp_defines[HASHKEY];
+
+#define MAXIFSTACK 64
+static if_state_t if_stack[MAXIFSTACK];
+static int if_stack_idx = 0;
+
+#if 0
+void pp_status(void) __attribute__((destructor));
+void pp_status(void)
+{
+ int i;
+ int sum;
+ int total = 0;
+ pp_entry_t *ppp;
+
+ fprintf(stderr, "Defines statistics:\n");
+ for(i = 0; i < HASHKEY; i++)
+ {
+ sum = 0;
+ for(ppp = pp_defines[i]; ppp; ppp = ppp->next)
+ sum++;
+ total += sum;
+ fprintf(stderr, "%4d, %3d\n", i, sum);
+ }
+ fprintf(stderr, "Total defines: %d\n", total);
+}
+#endif
+
+/* Don't comment on the hash, its primitive but functional... */
+int pphash(char *str)
+{
+ int sum = 0;
+ while(*str)
+ sum += *str++;
+ return sum % HASHKEY;
+}
+
+pp_entry_t *pplookup(char *ident)
+{
+ int idx = pphash(ident);
+ pp_entry_t *ppp;
+
+ for(ppp = pp_defines[idx]; ppp; ppp = ppp->next)
+ {
+ if(!strcmp(ident, ppp->ident))
+ return ppp;
+ }
+ return NULL;
+}
+
+void del_define(char *name)
+{
+ int idx;
+ pp_entry_t *ppp;
+
+ if((ppp = pplookup(name)) == NULL)
+ {
+ if(pedantic)
+ yywarning("%s was not defined", name);
+ return;
+ }
+
+ if(ppp->iep)
+ {
+ if(debuglevel & DEBUGLEVEL_PPMSG)
+ fprintf(stderr, "del_define: %s:%d: includelogic removed, include_ppp='%s', file=%s\n", input_name, line_number, name, ppp->iep->filename);
+ if(ppp->iep == includelogiclist)
+ {
+ includelogiclist = ppp->iep->next;
+ if(includelogiclist)
+ includelogiclist->prev = NULL;
+ }
+ else
+ {
+ ppp->iep->prev->next = ppp->iep->next;
+ if(ppp->iep->next)
+ ppp->iep->next->prev = ppp->iep->prev;
+ }
+ free(ppp->iep->filename);
+ free(ppp->iep);
+ }
+
+ idx = pphash(name);
+ if(pp_defines[idx] == ppp)
+ {
+ pp_defines[idx] = ppp->next;
+ if(pp_defines[idx])
+ pp_defines[idx]->prev = NULL;
+ }
+ else
+ {
+ ppp->prev->next = ppp->next;
+ if(ppp->next)
+ ppp->next->prev = ppp->prev;
+ }
+
+ free(ppp);
+
+ if(debuglevel & DEBUGLEVEL_PPMSG)
+ printf("Deleted (%s, %d) <%s>\n", input_name, line_number, name);
+}
+
+pp_entry_t *add_define(char *def, char *text)
+{
+ int len;
+ char *cptr;
+ int idx = pphash(def);
+ pp_entry_t *ppp;
+
+ if((ppp = pplookup(def)) != NULL)
+ {
+ if(pedantic)
+ yywarning("Redefinition of %s\n\tPrevious definition: %s:%d", def, ppp->filename, ppp->linenumber);
+ del_define(def);
+ }
+ ppp = (pp_entry_t *)xmalloc(sizeof(pp_entry_t));
+ ppp->ident = def;
+ ppp->type = def_define;
+ ppp->subst.text = text;
+ ppp->filename = input_name ? xstrdup(input_name) : "<internal or cmdline>";
+ ppp->linenumber = input_name ? line_number : 0;
+ ppp->next = pp_defines[idx];
+ pp_defines[idx] = ppp;
+ if(ppp->next)
+ ppp->next->prev = ppp;
+ if(text)
+ {
+ /* Strip trailing white space from subst text */
+ len = strlen(text);
+ while(len && strchr(" \t\r\n", text[len-1]))
+ {
+ text[--len] = '\0';
+ }
+ /* Strip leading white space from subst text */
+ for(cptr = text; *cptr && strchr(" \t\r", *cptr); cptr++)
+ ;
+ if(text != cptr)
+ memmove(text, cptr, strlen(cptr)+1);
+ }
+ if(debuglevel & DEBUGLEVEL_PPMSG)
+ printf("Added define (%s, %d) <%s> to <%s>\n", input_name, line_number, ppp->ident, text ? text : "(null)");
+
+ return ppp;
+}
+
+pp_entry_t *add_cmdline_define(char *set)
+{
+ char *cpy = xstrdup(set); /* Because gcc passes a R/O string */
+ char *cptr = strchr(cpy, '=');
+ if(cptr)
+ *cptr = '\0';
+ return add_define(cpy, xstrdup(cptr ? cptr+1 : ""));
+}
+
+pp_entry_t *add_special_define(char *id)
+{
+ pp_entry_t *ppp = add_define(xstrdup(id), xstrdup(""));
+ ppp->type = def_special;
+ return ppp;
+}
+
+pp_entry_t *add_macro(char *id, marg_t *args[], int nargs, mtext_t *exp)
+{
+ int idx = pphash(id);
+ pp_entry_t *ppp;
+
+ if((ppp = pplookup(id)) != NULL)
+ {
+ if(pedantic)
+ yywarning("Redefinition of %s\n\tPrevious definition: %s:%d", id, ppp->filename, ppp->linenumber);
+ del_define(id);
+ }
+ ppp = (pp_entry_t *)xmalloc(sizeof(pp_entry_t));
+ ppp->ident = id;
+ ppp->type = def_macro;
+ ppp->margs = args;
+ ppp->nargs = nargs;
+ ppp->subst.mtext= exp;
+ ppp->filename = input_name ? xstrdup(input_name) : "<internal or cmdline>";
+ ppp->linenumber = input_name ? line_number : 0;
+ ppp->next = pp_defines[idx];
+ pp_defines[idx] = ppp;
+ if(ppp->next)
+ ppp->next->prev = ppp;
+
+ if(debuglevel & DEBUGLEVEL_PPMSG)
+ {
+ fprintf(stderr, "Added macro (%s, %d) <%s(%d)> to <", input_name, line_number, ppp->ident, nargs);
+ for(; exp; exp = exp->next)
+ {
+ switch(exp->type)
+ {
+ case exp_text:
+ fprintf(stderr, " \"%s\" ", exp->subst.text);
+ break;
+ case exp_stringize:
+ fprintf(stderr, " #(%d) ", exp->subst.argidx);
+ break;
+ case exp_concat:
+ fprintf(stderr, "##");
+ break;
+ case exp_subst:
+ fprintf(stderr, " <%d> ", exp->subst.argidx);
+ break;
+ }
+ }
+ fprintf(stderr, ">\n");
+ }
+ return ppp;
+}
+
+
+/*
+ *-------------------------------------------------------------------------
+ * Include management
+ *-------------------------------------------------------------------------
+ */
+#if defined(_Windows) || defined(__MSDOS__)
+#define INCLUDESEPARATOR ";"
+#else
+#define INCLUDESEPARATOR ":"
+#endif
+
+static char **includepath;
+static int nincludepath = 0;
+
+void add_include_path(char *path)
+{
+ char *tok;
+ char *cpy = xstrdup(path);
+
+ tok = strtok(cpy, INCLUDESEPARATOR);
+ while(tok)
+ {
+ char *dir;
+ char *cptr;
+ if(strlen(tok) == 0)
+ continue;
+ dir = xstrdup(tok);
+ for(cptr = dir; *cptr; cptr++)
+ {
+ /* Convert to forward slash */
+ if(*cptr == '\\')
+ *cptr = '/';
+ }
+ /* Kill eventual trailing '/' */
+ if(*(cptr = dir + strlen(dir)-1) == '/')
+ *cptr = '\0';
+
+ /* Add to list */
+ nincludepath++;
+ includepath = (char **)xrealloc(includepath, nincludepath * sizeof(*includepath));
+ includepath[nincludepath-1] = dir;
+ tok = strtok(NULL, INCLUDESEPARATOR);
+ }
+ free(cpy);
+}
+
+FILE *open_include(const char *name, int search, char **newpath)
+{
+ char *cpy = xstrdup(name);
+ char *cptr;
+ FILE *fp;
+ int i;
+
+ for(cptr = cpy; *cptr; cptr++)
+ {
+ /* kill double backslash */
+ if(*cptr == '\\' && *(cptr+1) == '\\')
+ memmove(cptr, cptr+1, strlen(cptr));
+ /* Convert to forward slash */
+ if(*cptr == '\\')
+ *cptr = '/';
+ }
+
+ if(search)
+ {
+ /* Search current dir and then -I path */
+ fp = fopen(cpy, "rt");
+ if(fp)
+ {
+ if(debuglevel & DEBUGLEVEL_PPMSG)
+ printf("Going to include <%s>\n", name);
+ if(newpath)
+ *newpath = cpy;
+ else
+ free(cpy);
+ return fp;
+ }
+ }
+ /* Search -I path */
+ for(i = 0; i < nincludepath; i++)
+ {
+ char *path;
+ path = (char *)xmalloc(strlen(includepath[i]) + strlen(cpy) + 2);
+ strcpy(path, includepath[i]);
+ strcat(path, "/");
+ strcat(path, cpy);
+ fp = fopen(path, "rt");
+ if(fp && (debuglevel & DEBUGLEVEL_PPMSG))
+ printf("Going to include <%s>\n", path);
+ if(fp)
+ {
+ if(newpath)
+ *newpath = path;
+ else
+ free(path);
+ free(cpy);
+ return fp;
+ }
+ free(path);
+ }
+ free(cpy);
+ if(newpath)
+ *newpath = NULL;
+ return NULL;
+}
+
+/*
+ *-------------------------------------------------------------------------
+ * #if, #ifdef, #ifndef, #else, #elif and #endif state management
+ *
+ * #if state transitions are made on basis of the current TOS and the next
+ * required state. The state transitions are required to housekeep because
+ * #if:s can be nested. The ignore case is activated to prevent output from
+ * within a false clause.
+ * Some special cases come from the fact that the #elif cases are not
+ * binary, but three-state. The problem is that all other elif-cases must
+ * be false when one true one has been found. A second problem is that the
+ * #else clause is a final clause. No extra #else:s may follow.
+ *
+ * The states mean:
+ * if_true Process input to output
+ * if_false Process input but no output
+ * if_ignore Process input but no output
+ * if_elif Process input but no output
+ * if_elsefalse Process input but no output
+ * if_elsettrue Process input to output
+ *
+ * The possible state-sequences are [state(stack depth)] (rest can be deduced):
+ * TOS #if 1 #else #endif
+ * if_true(n) if_true(n+1) if_elsefalse(n+1)
+ * if_false(n) if_ignore(n+1) if_ignore(n+1)
+ * if_elsetrue(n) if_true(n+1) if_elsefalse(n+1)
+ * if_elsefalse(n) if_ignore(n+1) if_ignore(n+1)
+ * if_elif(n) if_ignore(n+1) if_ignore(n+1)
+ * if_ignore(n) if_ignore(n+1) if_ignore(n+1)
+ *
+ * TOS #if 1 #elif 0 #else #endif
+ * if_true(n) if_true(n+1) if_elif(n+1) if_elif(n+1)
+ * if_false(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1)
+ * if_elsetrue(n) if_true(n+1) if_elif(n+1) if_elif(n+1)
+ * if_elsefalse(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1)
+ * if_elif(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1)
+ * if_ignore(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1)
+ *
+ * TOS #if 0 #elif 1 #else #endif
+ * if_true(n) if_false(n+1) if_true(n+1) if_elsefalse(n+1)
+ * if_false(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1)
+ * if_elsetrue(n) if_false(n+1) if_true(n+1) if_elsefalse(n+1)
+ * if_elsefalse(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1)
+ * if_elif(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1)
+ * if_ignore(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1)
+ *
+ *-------------------------------------------------------------------------
+ */
+static char *if_state_str[] = {
+ "if_false",
+ "if_true",
+ "if_elif",
+ "if_elsefalse",
+ "if_elsetrue",
+ "if_ignore"
+};
+
+void push_if(if_state_t s)
+{
+ if(if_stack_idx >= MAXIFSTACK)
+ internal_error(__FILE__, __LINE__, "#if-stack overflow; #{if,ifdef,ifndef} nested too deeply (> %d)", MAXIFSTACK);
+
+ if(debuglevel & DEBUGLEVEL_PPLEX)
+ fprintf(stderr, "Push if %s:%d: %s(%d) -> %s(%d)\n", input_name, line_number, if_state_str[if_state()], if_stack_idx, if_state_str[s], if_stack_idx+1);
+
+ if_stack[if_stack_idx++] = s;
+
+ switch(s)
+ {
+ case if_true:
+ case if_elsetrue:
+ break;
+ case if_false:
+ case if_elsefalse:
+ case if_elif:
+ case if_ignore:
+ push_ignore_state();
+ break;
+ }
+}
+
+if_state_t pop_if(void)
+{
+ if(if_stack_idx <= 0)
+ yyerror("#{endif,else,elif} without #{if,ifdef,ifndef} (#if-stack underflow)");
+
+ switch(if_state())
+ {
+ case if_true:
+ case if_elsetrue:
+ break;
+ case if_false:
+ case if_elsefalse:
+ case if_elif:
+ case if_ignore:
+ pop_ignore_state();
+ break;
+ }
+
+ if(debuglevel & DEBUGLEVEL_PPLEX)
+ fprintf(stderr, "Pop if %s:%d: %s(%d) -> %s(%d)\n",
+ input_name,
+ line_number,
+ if_state_str[if_state()],
+ if_stack_idx,
+ if_state_str[if_stack[if_stack_idx <= 1 ? if_true : if_stack_idx-2]],
+ if_stack_idx-1);
+
+ return if_stack[--if_stack_idx];
+}
+
+if_state_t if_state(void)
+{
+ if(!if_stack_idx)
+ return if_true;
+ else
+ return if_stack[if_stack_idx-1];
+}
+
+
+void next_if_state(int i)
+{
+ switch(if_state())
+ {
+ case if_true:
+ case if_elsetrue:
+ push_if(i ? if_true : if_false);
+ break;
+ case if_false:
+ case if_elsefalse:
+ case if_elif:
+ case if_ignore:
+ push_if(if_ignore);
+ break;
+ default:
+ internal_error(__FILE__, __LINE__, "Invalid if_state (%d) in #{if,ifdef,ifndef} directive", (int)if_state());
+ }
+}
+
+int get_if_depth(void)
+{
+ return if_stack_idx;
+}
+
-------------- next part --------------
--- NUL Wed Dec 31 19:00:00 1969
+++ preproc.h Sun Jun 30 02:40:54 2002
@@ -0,0 +1,211 @@
+/*
+ * Copyright 1998 Bertho A. Stultiens (BS)
+ *
+ * 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
+ */
+
+#ifndef __WIDL_PREPROC_H
+#define __WIDL_PREPROC_H
+
+struct pp_entry; /* forward */
+/*
+ * Include logic
+ * A stack of files which are already included and
+ * are protected in the #ifndef/#endif way.
+ */
+typedef struct includelogicentry {
+ struct includelogicentry *next;
+ struct includelogicentry *prev;
+ struct pp_entry *ppp; /* The define which protects the file */
+ char *filename; /* The filename of the include */
+} includelogicentry_t;
+
+/*
+ * The arguments of a macrodefinition
+ */
+typedef enum {
+ arg_single,
+ arg_list
+} def_arg_t;
+
+typedef struct marg {
+ def_arg_t type; /* Normal or ... argument */
+ char *arg; /* The textual argument */
+ int nnl; /* Number of newlines in the text to subst */
+} marg_t;
+
+/*
+ * The expansiontext of a macro
+ */
+typedef enum {
+ exp_text, /* Simple text substitution */
+ exp_concat, /* Concat (##) operator requested */
+ exp_stringize, /* Stringize (#) operator requested */
+ exp_subst /* Substitute argument */
+} def_exp_t;
+
+typedef struct mtext {
+ struct mtext *next;
+ struct mtext *prev;
+ def_exp_t type;
+ union {
+ char *text;
+ int argidx; /* For exp_subst and exp_stringize reference */
+ } subst;
+} mtext_t;
+
+/*
+ * The define descriptor
+ */
+typedef enum {
+ def_none, /* Not-a-define; used as return value */
+ def_define, /* Simple defines */
+ def_macro, /* Macro defines */
+ def_special /* Special expansions like __LINE__ and __FILE__ */
+} def_type_t;
+
+typedef struct pp_entry {
+ struct pp_entry *next;
+ struct pp_entry *prev;
+ def_type_t type; /* Define or macro */
+ char *ident; /* The key */
+ marg_t **margs; /* Macro arguments array or NULL if none */
+ int nargs;
+ union {
+ mtext_t *mtext; /* The substitution sequence or NULL if none */
+ char *text;
+ } subst;
+ int expanding; /* Set when feeding substitution into the input */
+ char *filename; /* Filename where it was defined */
+ int linenumber; /* Linenumber where it was defined */
+ includelogicentry_t *iep; /* Points to the include it protects */
+} pp_entry_t;
+
+
+/*
+ * If logic
+ */
+#define MAXIFSTACK 64 /* If this isn't enough you should alter the source... */
+
+typedef enum {
+ if_false,
+ if_true,
+ if_elif,
+ if_elsefalse,
+ if_elsetrue,
+ if_ignore
+} if_state_t;
+
+/*
+ * I assume that 'long long' exists in the compiler when it has a size
+ * of 8 or bigger. If not, then we revert to a simple 'long' for now.
+ * This should prevent most unexpected things with other compilers than
+ * gcc and egcs for now.
+ * In the future it should be possible to use another way, like a
+ * structure, so that we can emulate the MS compiler.
+ */
+#if defined(SIZEOF_LONGLONG) && SIZEOF_LONGLONG >= 8
+typedef long long wrc_sll_t;
+typedef unsigned long long wrc_ull_t;
+#else
+typedef long wrc_sll_t;
+typedef unsigned long wrc_ull_t;
+#endif
+
+#define SIZE_CHAR 1
+#define SIZE_SHORT 2
+#define SIZE_INT 3
+#define SIZE_LONG 4
+#define SIZE_LONGLONG 5
+#define SIZE_MASK 0x00ff
+#define FLAG_SIGNED 0x0100
+
+typedef enum {
+#if 0
+ cv_schar = SIZE_CHAR + FLAG_SIGNED,
+ cv_uchar = SIZE_CHAR,
+ cv_sshort = SIZE_SHORT + FLAG_SIGNED,
+ cv_ushort = SIZE_SHORT,
+#endif
+ cv_sint = SIZE_INT + FLAG_SIGNED,
+ cv_uint = SIZE_INT,
+ cv_slong = SIZE_LONG + FLAG_SIGNED,
+ cv_ulong = SIZE_LONG,
+ cv_sll = SIZE_LONGLONG + FLAG_SIGNED,
+ cv_ull = SIZE_LONGLONG
+} ctype_t;
+
+typedef struct cval {
+ ctype_t type;
+ union {
+#if 0
+ signed char sc; /* Explicitely signed because compilers are stupid */
+ unsigned char uc;
+ short ss;
+ unsigned short us;
+#endif
+ int si;
+ unsigned int ui;
+ long sl;
+ unsigned long ul;
+ wrc_sll_t sll;
+ wrc_ull_t ull;
+ } val;
+} cval_t;
+
+
+
+pp_entry_t *pplookup(char *ident);
+pp_entry_t *add_define(char *def, char *text);
+pp_entry_t *add_cmdline_define(char *set);
+pp_entry_t *add_special_define(char *id);
+pp_entry_t *add_macro(char *ident, marg_t *args[], int nargs, mtext_t *exp);
+void del_define(char *name);
+FILE *open_include(const char *name, int search, char **newpath);
+void add_include_path(char *path);
+void push_if(if_state_t s);
+void next_if_state(int);
+if_state_t pop_if(void);
+if_state_t if_state(void);
+int get_if_depth(void);
+
+/*
+ * From ppl.l
+ */
+extern FILE *ppin;
+extern FILE *ppout;
+extern char *pptext;
+extern int pp_flex_debug;
+int pplex(void);
+
+void do_include(char *fname, int type);
+void push_ignore_state(void);
+void pop_ignore_state(void);
+
+extern int include_state;
+extern char *include_ppp;
+extern char *include_filename;
+extern int include_ifdepth;
+extern int seen_junk;
+extern includelogicentry_t *includelogiclist;
+
+/*
+ * From ppy.y
+ */
+int ppparse(void);
+extern int ppdebug;
+
+#endif
+
-------------- next part --------------
--- NUL Wed Dec 31 19:00:00 1969
+++ proxy.c Sun Jun 30 02:41:16 2002
@@ -0,0 +1,368 @@
+/*
+ * 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
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <assert.h>
+#include <ctype.h>
+#include <signal.h>
+
+#include "widl.h"
+#include "utils.h"
+#include "parser.h"
+#include "header.h"
+#include "y.tab.h"
+
+/* FIXME: support generation of stubless proxies */
+
+static void write_stubdesc(void)
+{
+ fprintf(proxy, "const MIDL_STUB_DESC Object_StubDesc = {\n");
+ fprintf(proxy, " 0,\n");
+ fprintf(proxy, " NdrOleAllocate,\n");
+ fprintf(proxy, " NdrOleFree,\n");
+ fprintf(proxy, " {0}, 0, 0, 0, 0,\n");
+ fprintf(proxy, " 0 /* __MIDL_TypeFormatString.Format */\n");
+ fprintf(proxy, "};\n");
+ fprintf(proxy, "\n");
+}
+
+static void init_proxy(void)
+{
+ if (proxy) return;
+ proxy = fopen(proxy_name, "w");
+ fprintf(proxy, "/*** Autogenerated by WIDL %s - Do not edit ***/\n", WIDL_FULLVERSION);
+ fprintf(proxy, "#include \"rpcproxy.h\"\n");
+ fprintf(proxy, "#include \"%s\"\n", header_name);
+ fprintf(proxy, "\n");
+ write_stubdesc();
+}
+
+static void gen_proxy(type_t *iface, func_t *cur, int idx)
+{
+ var_t *def = cur->def;
+ int has_ret = !is_void(def->type, def);
+
+ write_type(proxy, def->type, def, def->tname);
+ fprintf(proxy, " CALLBACK %s_", iface->name);
+ write_name(proxy, def);
+ fprintf(proxy, "_Proxy(\n");
+ write_method_args(proxy, cur->args, iface->name);
+ fprintf(proxy, ")\n");
+ fprintf(proxy, "{\n");
+ /* local variables */
+ if (has_ret) {
+ fprintf(proxy, " ");
+ write_type(proxy, def->type, def, def->tname);
+ fprintf(proxy, " _Ret;\n");
+ }
+ fprintf(proxy, " RPC_MESSAGE _Msg;\n");
+ fprintf(proxy, " MIDL_STUB_MESSAGE _StubMsg;\n");
+ fprintf(proxy, "\n");
+
+ /* FIXME: trace */
+ /* FIXME: clear output vars? */
+
+ fprintf(proxy, " NdrProxyInitialize(This, &_Msg, &_StubMsg, &Object_StubDesc, %d);\n", idx);
+
+ /* FIXME: size buffer */
+
+ fprintf(proxy, " NdrProxyGetBuffer(This, &_StubMsg);\n");
+
+ /* FIXME: marshall */
+
+ fprintf(proxy, " NdrProxySendReceive(This, &_StubMsg);\n");
+
+ /* FIXME: unmarshall */
+
+ fprintf(proxy, " NdrProxyFreeBuffer(This, &_StubMsg);\n");
+
+ if (has_ret) {
+ fprintf(proxy, " return _Ret;\n");
+ }
+ fprintf(proxy, "}\n");
+ fprintf(proxy, "\n");
+}
+
+static void gen_stub(type_t *iface, func_t *cur, char *cas)
+{
+ var_t *def = cur->def;
+ var_t *arg;
+ int has_ret = !is_void(def->type, def);
+
+ fprintf(proxy, "void __RPC_STUB %s_", iface->name);
+ write_name(proxy, def);
+ fprintf(proxy, "_Stub(\n");
+ fprintf(proxy, " IRpcStubBuffer* This,\n");
+ fprintf(proxy, " IRpcChannelBuffer* pRpcChannelBuffer,\n");
+ fprintf(proxy, " PRPC_MESSAGE pRpcMessage,\n");
+ fprintf(proxy, " DWORD* pdwStubPhase)\n");
+ fprintf(proxy, "{\n");
+ /* local variables */
+ if (has_ret) {
+ fprintf(proxy, " ");
+ write_type(proxy, def->type, def, def->tname);
+ fprintf(proxy, " _Ret;\n");
+ }
+ fprintf(proxy, " %s* _This = (%s*)((CStdStubBuffer*)This)->pvServerObject;\n", iface->name, iface->name);
+ fprintf(proxy, " MIDL_STUB_MESSAGE _StubMsg;\n");
+ arg = cur->args;
+ while (arg) {
+ fprintf(proxy, " ");
+ write_type(proxy, arg->type, arg, arg->tname);
+ fprintf(proxy, " ");
+ write_name(proxy, arg);
+ fprintf(proxy, ";\n");
+ arg = NEXT_LINK(arg);
+ }
+ fprintf(proxy, "\n");
+
+ /* FIXME: trace */
+ /* FIXME: clear output vars? */
+
+ fprintf(proxy, " NdrStubInitialize(pRpcMessage, &_StubMsg, &Object_StubDesc, pRpcChannelBuffer);\n");
+
+ /* FIXME: unmarshall */
+
+ fprintf(proxy, " *pdwStubPhase = STUB_CALL_SERVER;\n");
+ fprintf(proxy, " ");
+ if (has_ret) fprintf(proxy, "_Ret = ");
+ fprintf(proxy, "%s_", iface->name);
+ if (cas) fprintf(proxy, "%s_Stub", cas);
+ else write_name(proxy, def);
+ fprintf(proxy, "(_This");
+ arg = cur->args;
+ if (arg) {
+ while (NEXT_LINK(arg)) arg = NEXT_LINK(arg);
+ while (arg) {
+ fprintf(proxy, ", ");
+ write_name(proxy, arg);
+ arg = PREV_LINK(arg);
+ }
+ }
+ fprintf(proxy, ");\n");
+ fprintf(proxy, " *pdwStubPhase = STUB_MARSHAL;\n");
+
+ /* FIXME: size buffer */
+
+ fprintf(proxy, " NdrStubGetBuffer(This, pRpcChannelBuffer, &_StubMsg);\n");
+
+ /* FIXME: marshall */
+
+ fprintf(proxy, "}\n");
+ fprintf(proxy, "\n");
+}
+
+static int write_proxy_methods(type_t *iface)
+{
+ func_t *cur = iface->funcs;
+ int i = 0;
+ while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
+
+ if (iface->ref) i = write_proxy_methods(iface->ref);
+ while (cur) {
+ var_t *def = cur->def;
+ if (!is_callas(def->attrs)) {
+ if (i) fprintf(proxy, ",\n ");
+ fprintf(proxy, "%s_", iface->name);
+ write_name(proxy, def);
+ fprintf(proxy, "_Proxy");
+ i++;
+ }
+ cur = PREV_LINK(cur);
+ }
+ return i;
+}
+
+static int write_stub_methods(type_t *iface)
+{
+ func_t *cur = iface->funcs;
+ int i = 0;
+ while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
+
+ if (iface->ref) i = write_stub_methods(iface->ref);
+ else return i; /* skip IUnknown */
+ while (cur) {
+ var_t *def = cur->def;
+ if (!is_local(def->attrs)) {
+ if (i) fprintf(proxy, ",\n");
+ fprintf(proxy, " %s_", iface->name);
+ write_name(proxy, def);
+ fprintf(proxy, "_Stub");
+ i++;
+ }
+ cur = PREV_LINK(cur);
+ }
+ return i;
+}
+
+typedef struct _if_list if_list;
+struct _if_list {
+ type_t *iface;
+ DECL_LINK(if_list)
+};
+
+if_list *if_first;
+
+void write_proxy(type_t *iface)
+{
+ int midx = -1, stubs;
+ func_t *cur = iface->funcs;
+ if_list *if_cur;
+
+ if (!cur) {
+ yywarning("%s has no methods", iface->name);
+ return;
+ }
+
+ while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
+
+ /* FIXME: check for [oleautomation], shouldn't generate proxies/stubs if specified */
+
+ init_proxy();
+
+ if_cur = xmalloc(sizeof(if_list));
+ if_cur->iface = iface;
+ INIT_LINK(if_cur);
+ LINK(if_cur, if_first);
+ if_first = if_cur;
+
+ fprintf(proxy, "/*****************************************************************************\n");
+ fprintf(proxy, " * %s interface\n", iface->name);
+ fprintf(proxy, " */\n");
+ while (cur) {
+ var_t *def = cur->def;
+ if (!is_local(def->attrs)) {
+ var_t *cas = is_callas(def->attrs);
+ char *cname = cas ? cas->name : NULL;
+ int idx = cur->idx;
+ if (cname) {
+ func_t *m = iface->funcs;
+ while (m && strcmp(get_name(m->def), cname))
+ m = NEXT_LINK(m);
+ idx = m->idx;
+ }
+ gen_proxy(iface, cur, idx);
+ gen_stub(iface, cur, cname);
+ if (midx == -1) midx = idx;
+ else if (midx != idx) yyerror("method index mismatch in write_proxy");
+ midx++;
+ }
+ cur = PREV_LINK(cur);
+ }
+
+ /* proxy vtable */
+ fprintf(proxy, "const CINTERFACE_PROXY_VTABLE(%d) %sProxyVtbl = {\n", midx, iface->name);
+ fprintf(proxy, " {&IID_%s},\n", iface->name);
+ fprintf(proxy, " {");
+ write_proxy_methods(iface);
+ fprintf(proxy, "}\n");
+ fprintf(proxy, "};\n");
+ fprintf(proxy, "\n");
+
+ /* stub vtable */
+ fprintf(proxy, "static const PRPC_STUB_FUNCTION %s_table[] = {\n", iface->name);
+ stubs = write_stub_methods(iface);
+ fprintf(proxy, "\n");
+ fprintf(proxy, "};\n");
+ fprintf(proxy, "\n");
+ fprintf(proxy, "const CInterfaceStubVtbl %sStubVtbl = {\n", iface->name);
+ fprintf(proxy, " {&IID_%s,\n", iface->name);
+ fprintf(proxy, " 0,\n");
+ fprintf(proxy, " %d,\n", stubs+3);
+ fprintf(proxy, " &%s_table[-3]},\n", iface->name);
+ fprintf(proxy, " {CStdStubBuffer_METHODS}\n");
+ fprintf(proxy, "};\n");
+ fprintf(proxy, "\n");
+}
+
+void finish_proxy(void)
+{
+ if_list *lcur = if_first;
+ if_list *cur;
+ int c;
+
+ if (!lcur) return;
+ while (NEXT_LINK(lcur)) lcur = NEXT_LINK(lcur);
+
+ fprintf(proxy, "const CInterfaceProxyVtbl* _XXX_ProxyVtblList[] = {\n");
+ cur = lcur;
+ while (cur) {
+ fprintf(proxy, " (CInterfaceProxyVtbl*)&%sProxyVtbl,\n", cur->iface->name);
+ cur = PREV_LINK(cur);
+ }
+ fprintf(proxy, " 0\n");
+ fprintf(proxy, "};\n");
+ fprintf(proxy, "\n");
+
+ fprintf(proxy, "const CInterfaceStubVtbl* _XXX_StubVtblList[] = {\n");
+ cur = lcur;
+ while (cur) {
+ fprintf(proxy, " (CInterfaceStubVtbl*)&%sStubVtbl,\n", cur->iface->name);
+ cur = PREV_LINK(cur);
+ }
+ fprintf(proxy, " 0\n");
+ fprintf(proxy, "};\n");
+ fprintf(proxy, "\n");
+
+ fprintf(proxy, "const PCInterfaceName _XXX_InterfaceNamesList[] = {\n");
+ cur = lcur;
+ while (cur) {
+ fprintf(proxy, " \"%s\",\n", cur->iface->name);
+ cur = PREV_LINK(cur);
+ }
+ fprintf(proxy, " 0\n");
+ fprintf(proxy, "};\n");
+ fprintf(proxy, "\n");
+
+ fprintf(proxy, "#define _XXX_CHECK_IID(n) IID_GENERIC_CHECK_IID(_XXX, pIID, n)\n");
+ fprintf(proxy, "\n");
+ fprintf(proxy, "int __stdcall _XXX_IID_Lookup(const IID* pIID, int* pIndex)\n");
+ fprintf(proxy, "{\n");
+ cur = lcur;
+ c = 0;
+ while (cur) {
+ fprintf(proxy, " if (!_XXX_CHECK_IID(%d)) {\n", c);
+ fprintf(proxy, " *pIndex = %d\n", c);
+ fprintf(proxy, " return 1;\n");
+ fprintf(proxy, " }\n");
+ cur = PREV_LINK(cur);
+ c++;
+ }
+ fprintf(proxy, " return 0;\n");
+ fprintf(proxy, "}\n");
+ fprintf(proxy, "\n");
+
+ fprintf(proxy, "const ExtendedProxyFileInfo XXX_ProxyFileInfo = {\n");
+ fprintf(proxy, " (PCInterfaceProxyVtblList*)&_XXX_ProxyVtblList,\n");
+ fprintf(proxy, " (PCInterfaceStubVtblList*)&_XXX_StubVtblList,\n");
+ fprintf(proxy, " (const PCInterfaceName*)&_XXX_InterfaceNamesList,\n");
+ fprintf(proxy, " 0,\n");
+ fprintf(proxy, " &_XXX_IID_Lookup,\n");
+ fprintf(proxy, " %d,\n", c);
+ fprintf(proxy, " 1\n");
+ fprintf(proxy, "};\n");
+
+ fclose(proxy);
+}
-------------- next part --------------
--- NUL Wed Dec 31 19:00:00 1969
+++ proxy.h Sun Jun 30 02:41:34 2002
@@ -0,0 +1,27 @@
+/*
+ * 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
+ */
+
+#ifndef __WIDL_PROXY_H
+#define __WIDL_PROXY_H
+
+extern void write_proxy(type_t *iface);
+extern void finish_proxy(void);
+
+#endif
-------------- next part --------------
--- NUL Wed Dec 31 19:00:00 1969
+++ utils.c Sun Jun 30 02:38:32 2002
@@ -0,0 +1,418 @@
+/*
+ * Utility routines
+ *
+ * Copyright 1998 Bertho A. Stultiens
+ * 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
+ */
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include "wine/unicode.h"
+#include "widl.h"
+#include "utils.h"
+#include "parser.h"
+#include "preproc.h"
+
+/* #define WANT_NEAR_INDICATION */
+
+static const union cptable *current_codepage;
+
+#ifdef WANT_NEAR_INDICATION
+void make_print(char *str)
+{
+ while(*str)
+ {
+ if(!isprint(*str))
+ *str = ' ';
+ str++;
+ }
+}
+#endif
+
+static void generic_msg(const char *s, const char *t, const char *n, va_list ap)
+{
+ fprintf(stderr, "%s:%d:%d: %s: ", input_name ? input_name : "stdin", line_number, char_number, t);
+ vfprintf(stderr, s, ap);
+#ifdef WANT_NEAR_INDICATION
+ {
+ char *cpy;
+ if(n)
+ {
+ cpy = xstrdup(n);
+ make_print(cpy);
+ fprintf(stderr, " near '%s'", cpy);
+ free(cpy);
+ }
+ }
+#endif
+ fprintf(stderr, "\n");
+}
+
+
+int yyerror(const char *s, ...)
+{
+ va_list ap;
+ va_start(ap, s);
+ generic_msg(s, "Error", yytext, ap);
+ va_end(ap);
+ exit(1);
+ return 1;
+}
+
+int yywarning(const char *s, ...)
+{
+ va_list ap;
+ va_start(ap, s);
+ generic_msg(s, "Warning", yytext, ap);
+ va_end(ap);
+ return 0;
+}
+
+int pperror(const char *s, ...)
+{
+ va_list ap;
+ va_start(ap, s);
+ generic_msg(s, "Error", pptext, ap);
+ va_end(ap);
+ exit(1);
+ return 1;
+}
+
+int ppwarning(const char *s, ...)
+{
+ va_list ap;
+ va_start(ap, s);
+ generic_msg(s, "Warning", pptext, ap);
+ va_end(ap);
+ return 0;
+}
+
+
+void internal_error(const char *file, int line, const char *s, ...)
+{
+ va_list ap;
+ va_start(ap, s);
+ fprintf(stderr, "Internal error (please report) %s %d: ", file, line);
+ vfprintf(stderr, s, ap);
+ fprintf(stderr, "\n");
+ va_end(ap);
+ exit(3);
+}
+
+void error(const char *s, ...)
+{
+ va_list ap;
+ va_start(ap, s);
+ fprintf(stderr, "Error: ");
+ vfprintf(stderr, s, ap);
+ fprintf(stderr, "\n");
+ va_end(ap);
+ exit(2);
+}
+
+void warning(const char *s, ...)
+{
+ va_list ap;
+ va_start(ap, s);
+ fprintf(stderr, "Warning: ");
+ vfprintf(stderr, s, ap);
+ fprintf(stderr, "\n");
+ va_end(ap);
+}
+
+void chat(const char *s, ...)
+{
+ if(debuglevel & DEBUGLEVEL_CHAT)
+ {
+ va_list ap;
+ va_start(ap, s);
+ fprintf(stderr, "FYI: ");
+ vfprintf(stderr, s, ap);
+ fprintf(stderr, "\n");
+ va_end(ap);
+ }
+}
+
+char *dup_basename(const char *name, const char *ext)
+{
+ int namelen;
+ int extlen = strlen(ext);
+ char *base;
+ char *slash;
+
+ if(!name)
+ name = "widl.tab";
+
+ slash = strrchr(name, '/');
+ if (slash)
+ name = slash + 1;
+
+ namelen = strlen(name);
+
+ /* +4 for later extension and +1 for '\0' */
+ base = (char *)xmalloc(namelen +4 +1);
+ strcpy(base, name);
+ if(!strcasecmp(name + namelen-extlen, ext))
+ {
+ base[namelen - extlen] = '\0';
+ }
+ return base;
+}
+
+void *xmalloc(size_t size)
+{
+ void *res;
+
+ assert(size > 0);
+ res = malloc(size);
+ if(res == NULL)
+ {
+ error("Virtual memory exhausted.\n");
+ }
+ /*
+ * We set it to 0.
+ * This is *paramount* because we depend on it
+ * just about everywhere in the rest of the code.
+ */
+ memset(res, 0, size);
+ return res;
+}
+
+
+void *xrealloc(void *p, size_t size)
+{
+ void *res;
+
+ assert(size > 0);
+ res = realloc(p, size);
+ if(res == NULL)
+ {
+ error("Virtual memory exhausted.\n");
+ }
+ return res;
+}
+
+char *xstrdup(const char *str)
+{
+ char *s;
+
+ assert(str != NULL);
+ s = (char *)xmalloc(strlen(str)+1);
+ return strcpy(s, str);
+}
+
+short *dupcstr2wstr(const char *str)
+{
+ int len;
+ WCHAR *ws;
+
+ if (!current_codepage) set_language( LANG_NEUTRAL, SUBLANG_NEUTRAL );
+ len = cp_mbstowcs( current_codepage, 0, str, strlen(str), NULL, 0 );
+ ws = xmalloc( sizeof(WCHAR) * (len + 1) );
+ len = cp_mbstowcs( current_codepage, 0, str, strlen(str), ws, len );
+ ws[len] = 0;
+ return ws;
+}
+
+char *dupwstr2cstr(const short *str)
+{
+ int len;
+ char *cs;
+
+ if (!current_codepage) set_language( LANG_NEUTRAL, SUBLANG_NEUTRAL );
+ len = cp_wcstombs( current_codepage, 0, str, strlenW(str), NULL, 0, NULL, NULL );
+ cs = xmalloc( len + 1 );
+ len = cp_wcstombs( current_codepage, 0, str, strlenW(str), cs, len, NULL, NULL );
+ cs[len] = 0;
+ return cs;
+}
+
+#if 0
+/*
+ *****************************************************************************
+ * Function : compare_name_id
+ * Syntax : int compare_name_id(name_id_t *n1, name_id_t *n2)
+ * Input :
+ * Output :
+ * Description :
+ * Remarks :
+ *****************************************************************************
+*/
+int compare_name_id(name_id_t *n1, name_id_t *n2)
+{
+ if(n1->type == name_ord && n2->type == name_ord)
+ {
+ return n1->name.i_name - n2->name.i_name;
+ }
+ else if(n1->type == name_str && n2->type == name_str)
+ {
+ if(n1->name.s_name->type == str_char
+ && n2->name.s_name->type == str_char)
+ {
+ return strcasecmp(n1->name.s_name->str.cstr, n2->name.s_name->str.cstr);
+ }
+ else if(n1->name.s_name->type == str_unicode
+ && n2->name.s_name->type == str_unicode)
+ {
+ return strcmpiW(n1->name.s_name->str.wstr, n2->name.s_name->str.wstr);
+ }
+ else
+ {
+ internal_error(__FILE__, __LINE__, "Can't yet compare strings of mixed type");
+ }
+ }
+ else if(n1->type == name_ord && n2->type == name_str)
+ return 1;
+ else if(n1->type == name_str && n2->type == name_ord)
+ return -1;
+ else
+ internal_error(__FILE__, __LINE__, "Comparing name-ids with unknown types (%d, %d)",
+ n1->type, n2->type);
+
+ return 0; /* Keep the compiler happy */
+}
+
+string_t *convert_string(const string_t *str, enum str_e type)
+{
+ string_t *ret = xmalloc(sizeof(*ret));
+
+ if((str->type == str_char) && (type == str_unicode))
+ {
+ ret->str.wstr = dupcstr2wstr(str->str.cstr);
+ ret->type = str_unicode;
+ ret->size = strlenW(ret->str.wstr);
+ }
+ else if((str->type == str_unicode) && (type == str_char))
+ {
+ ret->str.cstr = dupwstr2cstr(str->str.wstr);
+ ret->type = str_char;
+ ret->size = strlen(ret->str.cstr);
+ }
+ else if(str->type == str_unicode)
+ {
+ ret->type = str_unicode;
+ ret->size = strlenW(str->str.wstr);
+ ret->str.wstr = xmalloc(sizeof(WCHAR)*(ret->size+1));
+ strcpyW(ret->str.wstr, str->str.wstr);
+ }
+ else /* str->type == str_char */
+ {
+ ret->type = str_char;
+ ret->size = strlen(str->str.cstr);
+ ret->str.cstr = xmalloc( ret->size + 1 );
+ strcpy(ret->str.cstr, str->str.cstr);
+ }
+ return ret;
+}
+#endif
+
+
+struct lang2cp
+{
+ unsigned short lang;
+ unsigned short sublang;
+ unsigned int cp;
+} lang2cp_t;
+
+/* language to codepage conversion table */
+/* specific sublanguages need only be specified if their codepage */
+/* differs from the default (SUBLANG_NEUTRAL) */
+static const struct lang2cp lang2cps[] =
+{
+ { LANG_AFRIKAANS, SUBLANG_NEUTRAL, 1252 },
+ { LANG_ALBANIAN, SUBLANG_NEUTRAL, 1250 },
+ { LANG_ARABIC, SUBLANG_NEUTRAL, 1256 },
+ { LANG_BASQUE, SUBLANG_NEUTRAL, 1252 },
+ { LANG_BRETON, SUBLANG_NEUTRAL, 1252 },
+ { LANG_BULGARIAN, SUBLANG_NEUTRAL, 1251 },
+ { LANG_BYELORUSSIAN, SUBLANG_NEUTRAL, 1251 },
+ { LANG_CATALAN, SUBLANG_NEUTRAL, 1252 },
+ { LANG_CHINESE, SUBLANG_NEUTRAL, 936 },
+ { LANG_CORNISH, SUBLANG_NEUTRAL, 1252 },
+ { LANG_CZECH, SUBLANG_NEUTRAL, 1250 },
+ { LANG_DANISH, SUBLANG_NEUTRAL, 1252 },
+ { LANG_DUTCH, SUBLANG_NEUTRAL, 1252 },
+ { LANG_ENGLISH, SUBLANG_NEUTRAL, 1252 },
+ { LANG_ESPERANTO, SUBLANG_NEUTRAL, 1252 },
+ { LANG_ESTONIAN, SUBLANG_NEUTRAL, 1257 },
+ { LANG_FAEROESE, SUBLANG_NEUTRAL, 1252 },
+ { LANG_FINNISH, SUBLANG_NEUTRAL, 1252 },
+ { LANG_FRENCH, SUBLANG_NEUTRAL, 1252 },
+ { LANG_GAELIC, SUBLANG_NEUTRAL, 1252 },
+ { LANG_GERMAN, SUBLANG_NEUTRAL, 1252 },
+ { LANG_GREEK, SUBLANG_NEUTRAL, 1253 },
+ { LANG_HEBREW, SUBLANG_NEUTRAL, 1255 },
+ { LANG_HUNGARIAN, SUBLANG_NEUTRAL, 1250 },
+ { LANG_ICELANDIC, SUBLANG_NEUTRAL, 1252 },
+ { LANG_INDONESIAN, SUBLANG_NEUTRAL, 1252 },
+ { LANG_ITALIAN, SUBLANG_NEUTRAL, 1252 },
+ { LANG_JAPANESE, SUBLANG_NEUTRAL, 932 },
+ { LANG_KOREAN, SUBLANG_NEUTRAL, 949 },
+ { LANG_LATVIAN, SUBLANG_NEUTRAL, 1257 },
+ { LANG_LITHUANIAN, SUBLANG_NEUTRAL, 1257 },
+ { LANG_MACEDONIAN, SUBLANG_NEUTRAL, 1251 },
+ { LANG_MALAY, SUBLANG_NEUTRAL, 1252 },
+ { LANG_NEUTRAL, SUBLANG_NEUTRAL, 1252 },
+ { LANG_NORWEGIAN, SUBLANG_NEUTRAL, 1252 },
+ { LANG_POLISH, SUBLANG_NEUTRAL, 1250 },
+ { LANG_PORTUGUESE, SUBLANG_NEUTRAL, 1252 },
+ { LANG_ROMANIAN, SUBLANG_NEUTRAL, 1250 },
+ { LANG_RUSSIAN, SUBLANG_NEUTRAL, 1251 },
+ { LANG_SERBO_CROATIAN, SUBLANG_NEUTRAL, 1250 },
+ { LANG_SERBO_CROATIAN, SUBLANG_SERBIAN, 1251 },
+ { LANG_SLOVAK, SUBLANG_NEUTRAL, 1250 },
+ { LANG_SLOVENIAN, SUBLANG_NEUTRAL, 1250 },
+ { LANG_SPANISH, SUBLANG_NEUTRAL, 1252 },
+ { LANG_SWEDISH, SUBLANG_NEUTRAL, 1252 },
+ { LANG_THAI, SUBLANG_NEUTRAL, 874 },
+ { LANG_TURKISH, SUBLANG_NEUTRAL, 1254 },
+ { LANG_UKRAINIAN, SUBLANG_NEUTRAL, 1251 },
+ { LANG_VIETNAMESE, SUBLANG_NEUTRAL, 1258 },
+ { LANG_WALON, SUBLANG_NEUTRAL, 1252 },
+ { LANG_WELSH, SUBLANG_NEUTRAL, 1252 }
+};
+
+void set_language( unsigned short lang, unsigned short sublang )
+{
+ unsigned int i;
+ unsigned int cp = 0, defcp = 0;
+
+ for (i = 0; i < sizeof(lang2cps)/sizeof(lang2cps[0]); i++)
+ {
+ if (lang2cps[i].lang != lang) continue;
+ if (lang2cps[i].sublang == sublang)
+ {
+ cp = lang2cps[i].cp;
+ break;
+ }
+ if (lang2cps[i].sublang == SUBLANG_NEUTRAL) defcp = lang2cps[i].cp;
+ }
+
+ if (!cp) cp = defcp;
+ if (!cp)
+ error( "No codepage value for language %04x", MAKELANGID(lang,sublang) );
+ if (!(current_codepage = cp_get_table( cp )))
+ error( "Bad codepage %d for language %04x", cp, MAKELANGID(lang,sublang) );
+}
-------------- next part --------------
--- NUL Wed Dec 31 19:00:00 1969
+++ utils.h Sun Jun 30 02:39:08 2002
@@ -0,0 +1,48 @@
+/*
+ * Utility routines' prototypes etc.
+ *
+ * Copyright 1998 Bertho A. Stultiens (BS)
+ *
+ * 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
+ */
+
+#ifndef __WIDL_UTILS_H
+#define __WIDL_UTILS_H
+
+#include "widltypes.h"
+
+#include <stddef.h> /* size_t */
+
+void *xmalloc(size_t);
+void *xrealloc(void *, size_t);
+char *xstrdup(const char *str);
+
+int pperror(const char *s, ...) __attribute__((format (printf, 1, 2)));
+int ppwarning(const char *s, ...) __attribute__((format (printf, 1, 2)));
+int yyerror(const char *s, ...) __attribute__((format (printf, 1, 2)));
+int yywarning(const char *s, ...) __attribute__((format (printf, 1, 2)));
+void internal_error(const char *file, int line, const char *s, ...) __attribute__((format (printf, 3, 4)));
+void error(const char *s, ...) __attribute__((format (printf, 1, 2)));
+void warning(const char *s, ...) __attribute__((format (printf, 1, 2)));
+void chat(const char *s, ...) __attribute__((format (printf, 1, 2)));
+
+char *dup_basename(const char *name, const char *ext);
+char *dupwstr2cstr(const short *str);
+short *dupcstr2wstr(const char *str);
+/* int compare_name_id(name_id_t *n1, name_id_t *n2);
+string_t *convert_string(const string_t *str, enum str_e type); */
+void set_language(unsigned short lang, unsigned short sublang);
+
+#endif
-------------- next part --------------
--- NUL Wed Dec 31 19:00:00 1969
+++ widl.c Sun Jun 30 02:38:52 2002
@@ -0,0 +1,214 @@
+/*
+ * IDL Compiler
+ *
+ * Copyright 2002 Ove Kaaven
+ * based on WRC code by Bertho Stultiens
+ *
+ * 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
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <assert.h>
+#include <ctype.h>
+#include <signal.h>
+
+#define WIDL_FULLVERSION "0.1"
+
+#include "widl.h"
+#include "utils.h"
+#include "preproc.h"
+#include "parser.h"
+#include "proxy.h"
+
+static char usage[] =
+"Usage: widl [options...] infile.idl\n"
+" -d n Set debug level to 'n'\n"
+" -D id[=val] Define preprocessor identifier id=val\n"
+" -E Preprocess only\n"
+" -H file Name of header file (default is infile.h)\n"
+" -I path Set include search dir to path (multiple -I allowed)\n"
+" -N Do not preprocess input\n"
+" -V Print version and exit\n"
+" -W Enable pedantic warnings\n"
+"Debug level 'n' is a bitmask with following meaning:\n"
+" * 0x01 Tell which resource is parsed (verbose mode)\n"
+" * 0x02 Dump internal structures\n"
+" * 0x04 Create a parser trace (yydebug=1)\n"
+" * 0x08 Preprocessor messages\n"
+" * 0x10 Preprocessor lex messages\n"
+" * 0x20 Preprocessor yacc trace\n"
+;
+
+char version_string[] = "Wine IDL Compiler Version " WIDL_FULLVERSION "\n"
+ "Copyright 2002 Ove Kaaven\n";
+
+int win32 = 1;
+int debuglevel = DEBUGLEVEL_NONE;
+
+int pedantic = 0;
+int preprocess_only = 0;
+int no_preprocess = 0;
+
+char *input_name;
+char *header_name;
+char *proxy_name;
+char *temp_name;
+
+int line_number = 1;
+int char_number = 1;
+
+FILE *header;
+FILE *proxy;
+
+time_t now;
+
+int getopt (int argc, char *const *argv, const char *optstring);
+static void rm_tempfile(void);
+static void segvhandler(int sig);
+
+int main(int argc,char *argv[])
+{
+ extern char* optarg;
+ extern int optind;
+ int optc;
+ int ret;
+
+ signal(SIGSEGV, segvhandler);
+
+ now = time(NULL);
+
+ while((optc = getopt(argc, argv, "d:D:EH:I:NVW")) != EOF) {
+ switch(optc) {
+ case 'd':
+ debuglevel = strtol(optarg, NULL, 0);
+ break;
+ case 'D':
+ add_cmdline_define(optarg);
+ break;
+ case 'E':
+ preprocess_only = 1;
+ break;
+ case 'H':
+ header_name = strdup(optarg);
+ break;
+ case 'I':
+ add_include_path(optarg);
+ break;
+ case 'N':
+ no_preprocess = 1;
+ break;
+ case 'V':
+ printf(version_string);
+ return 0;
+ case 'W':
+ pedantic = 1;
+ break;
+ default:
+ fprintf(stderr, usage);
+ return 1;
+ }
+ }
+
+ if(optind < argc) {
+ input_name = argv[optind];
+ }
+ else {
+ fprintf(stderr, usage);
+ return 1;
+ }
+
+ if(debuglevel)
+ {
+ setbuf(stdout,0);
+ setbuf(stderr,0);
+ }
+
+ yydebug = debuglevel & DEBUGLEVEL_TRACE ? 1 : 0;
+ yy_flex_debug = debuglevel & DEBUGLEVEL_TRACE ? 1 : 0;
+ ppdebug = debuglevel & DEBUGLEVEL_PPTRACE ? 1 : 0;
+ pp_flex_debug = debuglevel & DEBUGLEVEL_PPLEX ? 1 : 0;
+
+ if (!header_name) {
+ header_name = dup_basename(input_name, ".idl");
+ strcat(header_name, ".h");
+ }
+
+ if (!proxy_name) {
+ proxy_name = dup_basename(input_name, ".idl");
+ strcat(proxy_name, "_p.c");
+ }
+
+ atexit(rm_tempfile);
+ if (!no_preprocess) {
+ char *real_name;
+ chat("Starting preprocess");
+ if(!(temp_name = tmpnam(NULL)))
+ error("Could not generate a temp-name\n");
+ temp_name = xstrdup(temp_name);
+ if(!(ppout = fopen(temp_name, "wb")))
+ error("Could not create a temp-file\n");
+ real_name = input_name;
+ if(!(ppin = fopen(input_name, "rb")))
+ error("Could not open %s\n", input_name);
+ fprintf(ppout, "# 1 \"%s\" 1\n", input_name ? input_name : "");
+ ret = ppparse();
+ input_name = real_name;
+ fclose(ppin);
+ fclose(ppout);
+ input_name = temp_name;
+ if (ret)
+ exit(1);
+ }
+
+ if(!(yyin = fopen(input_name, "r"))) {
+ fprintf(stderr, "Could not open %s for input\n", input_name);
+ return 1;
+ }
+
+ header = fopen(header_name, "w");
+ fprintf(header, "/*** Autogenerated by WIDL %s - Do not edit ***/\n", WIDL_FULLVERSION);
+
+ ret = yyparse();
+
+ finish_proxy();
+ fclose(header);
+ fclose(yyin);
+
+ if(ret) {
+ exit(1);
+ }
+
+ return 0;
+}
+
+static void rm_tempfile(void)
+{
+ abort_import();
+ if(temp_name)
+ unlink(temp_name);
+}
+
+static void segvhandler(int sig)
+{
+ fprintf(stderr, "\n%s:%d: Oops, segment violation\n", input_name, line_number);
+ fflush(stdout);
+ fflush(stderr);
+ abort();
+}
-------------- next part --------------
--- NUL Wed Dec 31 19:00:00 1969
+++ widl.h Sun Jun 30 02:46:10 2002
@@ -0,0 +1,53 @@
+/*
+ * 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
+ */
+
+#ifndef __WIDL_WIDL_H
+#define __WIDL_WIDL_H
+
+#include "widltypes.h"
+
+#include <time.h>
+
+#define WIDL_FULLVERSION "0.1"
+
+extern int debuglevel;
+#define DEBUGLEVEL_NONE 0x0000
+#define DEBUGLEVEL_CHAT 0x0001
+#define DEBUGLEVEL_DUMP 0x0002
+#define DEBUGLEVEL_TRACE 0x0004
+#define DEBUGLEVEL_PPMSG 0x0008
+#define DEBUGLEVEL_PPLEX 0x0010
+#define DEBUGLEVEL_PPTRACE 0x0020
+
+extern int win32;
+extern int pedantic;
+
+extern char *input_name;
+extern char *header_name;
+extern char *proxy_name;
+extern time_t now;
+
+extern int line_number;
+extern int char_number;
+
+extern FILE* header;
+extern FILE* proxy;
+
+#endif
-------------- next part --------------
--- NUL Wed Dec 31 19:00:00 1969
+++ widltypes.h Sun Jun 30 02:46:28 2002
@@ -0,0 +1,97 @@
+/*
+ * 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
+ */
+
+#ifndef __WIDL_WIDLTYPES_H
+#define __WIDL_WIDLTYPES_H
+
+#include "windef.h"
+#include "oleauto.h"
+#include "wine/rpcfc.h"
+
+typedef struct _attr_t attr_t;
+typedef struct _type_t type_t;
+typedef struct _typeref_t typeref_t;
+typedef struct _var_t var_t;
+typedef struct _func_t func_t;
+
+#define DECL_LINK(type) \
+ type *l_next; \
+ type *l_prev;
+
+#define LINK(x,y) do { x->l_next = y; if (y) y->l_prev = x; } while (0)
+#define LINK_LAST(x,y) do { if (y) { typeof(x) _c = x; while (_c->l_next) _c = _c->l_next; LINK(_c, y); } } while (0)
+#define LINK_SAFE(x,y) do { if (x) LINK_LAST(x,y); else { x = y; } } while (0)
+
+#define INIT_LINK(x) do { x->l_next = NULL; x->l_prev = NULL; } while (0)
+#define NEXT_LINK(x) ((x)->l_next)
+#define PREV_LINK(x) ((x)->l_prev)
+
+struct _attr_t {
+ int type;
+ union {
+ DWORD ival;
+ void *pval;
+ } u;
+ /* parser-internal */
+ DECL_LINK(attr_t)
+};
+
+struct _type_t {
+ char *name;
+ BYTE type;
+ struct _type_t *ref;
+ char *rname;
+ attr_t *attrs;
+ func_t *funcs;
+ var_t *fields;
+ int ignore, is_const;
+ int defined, written;
+
+ /* parser-internal */
+ DECL_LINK(type_t)
+};
+
+struct _typeref_t {
+ char *name;
+ type_t *ref;
+ int uniq;
+};
+
+struct _var_t {
+ char *name;
+ int ptr_level;
+ type_t *type;
+ char *tname;
+ attr_t *attrs;
+
+ /* parser-internal */
+ DECL_LINK(var_t)
+};
+
+struct _func_t {
+ var_t *def;
+ var_t *args;
+ int ignore, idx;
+
+ /* parser-internal */
+ DECL_LINK(func_t)
+};
+
+#endif
More information about the wine-patches
mailing list