Added "generate headers only" command-line option. Implemented imports
from inside interface definitions. Fixed a few problems with generating header files for COM interfaces.
This commit is contained in:
parent
1a665058e8
commit
189397795d
|
@ -425,8 +425,8 @@ static void write_method_proto(type_t *iface)
|
|||
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, " struct IRpcStubBuffer* This,\n");
|
||||
fprintf(header, " struct IRpcChannelBuffer* pRpcChannelBuffer,\n");
|
||||
fprintf(header, " PRPC_MESSAGE pRpcMessage,\n");
|
||||
fprintf(header, " DWORD* pdwStubPhase);\n");
|
||||
}
|
||||
|
@ -462,7 +462,12 @@ static void write_method_proto(type_t *iface)
|
|||
|
||||
void write_forward(type_t *iface)
|
||||
{
|
||||
if (is_object(iface->attrs) && !iface->written) {
|
||||
/* C/C++ forwards should only be written for object interfaces, so if we
|
||||
* have a full definition we only write one if we find [object] among the
|
||||
* attributes - however, if we don't have a full definition at this point
|
||||
* (i.e. this is an IDL forward), then we also assume that it is an object
|
||||
* interface, since non-object interfaces shouldn't need forwards */
|
||||
if ((!iface->defined || is_object(iface->attrs)) && !iface->written) {
|
||||
fprintf(header, "typedef struct %s %s;\n", iface->name, iface->name);
|
||||
iface->written = TRUE;
|
||||
}
|
||||
|
@ -500,7 +505,7 @@ void write_interface(type_t *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);
|
||||
fprintf(header, " %s_METHODS\n", iface->name);
|
||||
if (iface->ref)
|
||||
fprintf(header, "ICOM_DEFINE(%s,%s)\n", iface->name, iface->ref->name);
|
||||
else
|
||||
|
|
|
@ -130,7 +130,10 @@ static uuid_t* parse_uuid(const char*u)
|
|||
\>\> return SHR;
|
||||
. return yytext[0];
|
||||
<<EOF>> {
|
||||
if (import_stack_ptr) pop_import();
|
||||
if (import_stack_ptr) {
|
||||
pop_import();
|
||||
return aEOF;
|
||||
}
|
||||
else yyterminate();
|
||||
}
|
||||
%%
|
||||
|
|
|
@ -109,6 +109,7 @@ static type_t std_int = { "int" };
|
|||
%token <num> aNUM
|
||||
%token <str> aSTRING
|
||||
%token <uuid> aUUID
|
||||
%token aEOF
|
||||
%token SHL SHR
|
||||
%token tAGGREGATABLE tALLOCATE tAPPOBJECT tARRAYS tASYNC tASYNCUUID
|
||||
%token tAUTOHANDLE tBINDABLE tBOOLEAN tBROADCAST tBYTE tBYTECOUNT
|
||||
|
@ -154,7 +155,7 @@ static type_t std_int = { "int" };
|
|||
|
||||
%type <attr> m_attributes attributes attrib_list attribute
|
||||
%type <expr> aexprs aexpr_list aexpr array
|
||||
%type <type> inherit interface interfacedef lib_statements
|
||||
%type <type> inherit interface interfacehdr interfacedef lib_statements
|
||||
%type <type> base_type int_std
|
||||
%type <type> enumdef structdef typedef uniondef
|
||||
%type <tref> type
|
||||
|
@ -180,18 +181,12 @@ input: lib_statements { /* FIXME */ }
|
|||
;
|
||||
|
||||
lib_statements: { $$ = NULL; }
|
||||
| lib_statements import
|
||||
| lib_statements interface ';'
|
||||
| lib_statements interface ';' { if (!parse_only) write_forward($2); }
|
||||
| lib_statements interfacedef { LINK($2, $1); $$ = $2; }
|
||||
/* | lib_statements librarydef (when implemented) */
|
||||
| lib_statements statement
|
||||
;
|
||||
|
||||
/* we can't import from inside interfaces yet
|
||||
* (it's not entirely clear how Microsoft manages that yet,
|
||||
* but in MIDL you can derive a class from a base class and then
|
||||
* import the base class definition from inside the interface,
|
||||
* which I don't quite know how to pull off in yacc/bison yet) */
|
||||
int_statements: { $$ = NULL; }
|
||||
| int_statements funcdef ';' { LINK($2, $1); $$ = $2; }
|
||||
| int_statements statement
|
||||
|
@ -202,7 +197,7 @@ statement: ';' {}
|
|||
| cppquote {}
|
||||
| enumdef ';' { if (!parse_only) { write_type(header, $1, NULL, NULL); fprintf(header, ";\n\n"); } }
|
||||
| externdef ';' {}
|
||||
/* | import {} */
|
||||
| import {}
|
||||
/* | interface ';' {} */
|
||||
/* | interfacedef {} */
|
||||
| structdef ';' { if (!parse_only) { write_type(header, $1, NULL, NULL); fprintf(header, ";\n\n"); } }
|
||||
|
@ -211,9 +206,11 @@ statement: ';' {}
|
|||
;
|
||||
|
||||
cppquote: tCPPQUOTE '(' aSTRING ')' { if (!parse_only) fprintf(header, "%s\n", $3); }
|
||||
;
|
||||
import: tIMPORT aSTRING ';' { do_import($2); }
|
||||
;
|
||||
;
|
||||
import_start: tIMPORT aSTRING ';' { do_import($2); }
|
||||
;
|
||||
import: import_start input aEOF {}
|
||||
;
|
||||
|
||||
m_args: { $$ = NULL; }
|
||||
| args
|
||||
|
@ -429,17 +426,31 @@ 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($$); }
|
||||
interface: tINTERFACE aIDENTIFIER { $$ = get_type(RPC_FC_IP, $2, 0); }
|
||||
| tINTERFACE aKNOWNTYPE { $$ = get_type(RPC_FC_IP, $2, 0); }
|
||||
;
|
||||
|
||||
interfacedef: attributes interface inherit
|
||||
'{' int_statements '}' { $$ = $2;
|
||||
interfacehdr: attributes interface { $$ = $2;
|
||||
if ($$->defined) yyerror("multiple definition error\n");
|
||||
$$->ref = $3;
|
||||
$$->attrs = $1;
|
||||
$$->funcs = $5;
|
||||
$$->defined = TRUE;
|
||||
if (!parse_only) write_forward($$);
|
||||
}
|
||||
;
|
||||
|
||||
interfacedef: interfacehdr inherit
|
||||
'{' int_statements '}' { $$ = $1;
|
||||
$$->ref = $2;
|
||||
$$->funcs = $4;
|
||||
if (!parse_only) write_interface($$);
|
||||
}
|
||||
/* MIDL is able to import the definition of a base class from inside the
|
||||
* definition of a derived class, I'll try to support it with this rule */
|
||||
| interfacehdr ':' aIDENTIFIER
|
||||
'{' import int_statements '}' { $$ = $1;
|
||||
$$->ref = find_type2($3, 0);
|
||||
if (!$$->ref) yyerror("base class %s not found in import\n", $3);
|
||||
$$->funcs = $6;
|
||||
if (!parse_only) write_interface($$);
|
||||
}
|
||||
;
|
||||
|
|
|
@ -237,6 +237,8 @@ void write_proxy(type_t *iface)
|
|||
return;
|
||||
}
|
||||
|
||||
if (header_only) return;
|
||||
|
||||
while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
|
||||
|
||||
/* FIXME: check for [oleautomation], shouldn't generate proxies/stubs if specified */
|
||||
|
|
|
@ -44,6 +44,7 @@ static char usage[] =
|
|||
" -d n Set debug level to 'n'\n"
|
||||
" -D id[=val] Define preprocessor identifier id=val\n"
|
||||
" -E Preprocess only\n"
|
||||
" -h Generate headers 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"
|
||||
|
@ -66,6 +67,7 @@ int debuglevel = DEBUGLEVEL_NONE;
|
|||
|
||||
int pedantic = 0;
|
||||
int preprocess_only = 0;
|
||||
int header_only = 0;
|
||||
int no_preprocess = 0;
|
||||
|
||||
char *input_name;
|
||||
|
@ -114,7 +116,7 @@ int main(int argc,char *argv[])
|
|||
|
||||
now = time(NULL);
|
||||
|
||||
while((optc = getopt(argc, argv, "d:D:EH:I:NVW")) != EOF) {
|
||||
while((optc = getopt(argc, argv, "d:D:EhH:I:NVW")) != EOF) {
|
||||
switch(optc) {
|
||||
case 'd':
|
||||
debuglevel = strtol(optarg, NULL, 0);
|
||||
|
@ -125,6 +127,9 @@ int main(int argc,char *argv[])
|
|||
case 'E':
|
||||
preprocess_only = 1;
|
||||
break;
|
||||
case 'h':
|
||||
header_only = 1;
|
||||
break;
|
||||
case 'H':
|
||||
header_name = strdup(optarg);
|
||||
break;
|
||||
|
|
|
@ -38,6 +38,7 @@ extern int debuglevel;
|
|||
|
||||
extern int win32;
|
||||
extern int pedantic;
|
||||
extern int header_only;
|
||||
|
||||
extern char *input_name;
|
||||
extern char *header_name;
|
||||
|
|
Loading…
Reference in New Issue