Commit d0264588 authored by Robert Shearman's avatar Robert Shearman Committed by Alexandre Julliard

- Output prototypes for user marshal functions at the end of the

header and by use. - Add support for range and ptr attributes and for the "small" base type.
parent 635d8166
...@@ -308,6 +308,72 @@ void write_type(FILE *h, type_t *t, var_t *v, const char *n) ...@@ -308,6 +308,72 @@ void write_type(FILE *h, type_t *t, var_t *v, const char *n)
} }
} }
struct user_type
{
struct user_type *next;
char name[1];
};
static struct user_type *user_type_list;
static int user_type_registered(const char *name)
{
struct user_type *ut;
for (ut = user_type_list; ut; ut = ut->next)
if (!strcmp(name, ut->name))
return 1;
return 0;
}
static void check_for_user_types(var_t *v)
{
while (v) {
type_t *type = v->type;
const char *name = v->tname;
for (type = v->type; type; type = type->ref) {
if (type->user_types_registered) continue;
type->user_types_registered = 1;
if (is_attr(type->attrs, ATTR_WIREMARSHAL)) {
if (!user_type_registered(name))
{
struct user_type *ut = xmalloc(sizeof(struct user_type) + strlen(name));
strcpy(ut->name, name);
ut->next = user_type_list;
user_type_list = ut;
}
/* don't carry on parsing fields within this type as we are already
* using a wire marshaled type */
break;
}
else if (type->fields)
{
var_t *fields = type->fields;
while (NEXT_LINK(fields)) fields = NEXT_LINK(fields);
check_for_user_types(fields);
}
/* the wire_marshal attribute is always at least one reference away
* from the name of the type, so update it after the rest of the
* processing above */
if (type->name) name = type->name;
}
v = PREV_LINK(v);
}
}
void write_user_types(void)
{
struct user_type *ut;
for (ut = user_type_list; ut; ut = ut->next)
{
const char *name = ut->name;
fprintf(header, "unsigned long __RPC_USER %s_UserSize (unsigned long *, unsigned long, %s *);\n", name, name);
fprintf(header, "unsigned char * __RPC_USER %s_UserMarshal (unsigned long *, unsigned char *, %s *);\n", name, name);
fprintf(header, "unsigned char * __RPC_USER %s_UserUnmarshal(unsigned long *, unsigned char *, %s *);\n", name, name);
fprintf(header, "void __RPC_USER %s_UserFree (unsigned long *, %s *);\n", name, name);
}
}
void write_typedef(type_t *type, var_t *names) void write_typedef(type_t *type, var_t *names)
{ {
char *tname = names->tname; char *tname = names->tname;
...@@ -324,22 +390,6 @@ void write_typedef(type_t *type, var_t *names) ...@@ -324,22 +390,6 @@ void write_typedef(type_t *type, var_t *names)
names = PREV_LINK(names); names = PREV_LINK(names);
} }
fprintf(header, ";\n"); fprintf(header, ";\n");
if (get_attrp(type->attrs, ATTR_WIREMARSHAL)) {
names = lname;
while (names) {
char *name = get_name(names);
fprintf(header, "unsigned long __RPC_USER %s_UserSize (unsigned long *, unsigned long, %s *);\n", name, name);
fprintf(header, "unsigned char * __RPC_USER %s_UserMarshal (unsigned long *, unsigned char *, %s *);\n", name, name);
fprintf(header, "unsigned char * __RPC_USER %s_UserUnmarshal(unsigned long *, unsigned char *, %s *);\n", name, name);
fprintf(header, "void __RPC_USER %s_UserFree (unsigned long *, %s *);\n", name, name);
if (PREV_LINK(names))
fprintf(header, ", ");
names = PREV_LINK(names);
}
}
fprintf(header, "\n");
} }
static void do_write_expr(FILE *h, expr_t *e, int p) static void do_write_expr(FILE *h, expr_t *e, int p)
...@@ -625,6 +675,7 @@ static void write_method_proto(type_t *iface) ...@@ -625,6 +675,7 @@ static void write_method_proto(type_t *iface)
while (cur) { while (cur) {
var_t *def = cur->def; var_t *def = cur->def;
var_t *cas = is_callas(def->attrs); var_t *cas = is_callas(def->attrs);
var_t *args;
if (!is_local(def->attrs)) { if (!is_local(def->attrs)) {
/* proxy prototype */ /* proxy prototype */
write_type(header, def->type, def, def->tname); write_type(header, def->type, def, def->tname);
...@@ -641,6 +692,13 @@ static void write_method_proto(type_t *iface) ...@@ -641,6 +692,13 @@ static void write_method_proto(type_t *iface)
fprintf(header, " struct IRpcChannelBuffer* pRpcChannelBuffer,\n"); fprintf(header, " struct IRpcChannelBuffer* pRpcChannelBuffer,\n");
fprintf(header, " PRPC_MESSAGE pRpcMessage,\n"); fprintf(header, " PRPC_MESSAGE pRpcMessage,\n");
fprintf(header, " DWORD* pdwStubPhase);\n"); fprintf(header, " DWORD* pdwStubPhase);\n");
args = cur->args;
if (args) {
while (NEXT_LINK(args))
args = NEXT_LINK(args);
}
check_for_user_types(args);
} }
if (cas) { if (cas) {
func_t *m = iface->funcs; func_t *m = iface->funcs;
......
...@@ -41,5 +41,6 @@ extern void write_expr(FILE *h, expr_t *e); ...@@ -41,5 +41,6 @@ extern void write_expr(FILE *h, expr_t *e);
extern void write_constdef(var_t *v); extern void write_constdef(var_t *v);
extern void write_externdef(var_t *v); extern void write_externdef(var_t *v);
extern void write_library(const char *name, attr_t *attr); extern void write_library(const char *name, attr_t *attr);
extern void write_user_types(void);
#endif #endif
...@@ -274,8 +274,10 @@ static struct keyword { ...@@ -274,8 +274,10 @@ static struct keyword {
{"propget", tPROPGET}, {"propget", tPROPGET},
{"propput", tPROPPUT}, {"propput", tPROPPUT},
{"propputref", tPROPPUTREF}, {"propputref", tPROPPUTREF},
{"ptr", tPTR},
/* ... */ /* ... */
{"public", tPUBLIC}, {"public", tPUBLIC},
{"range", tRANGE},
/* ... */ /* ... */
{"readonly", tREADONLY}, {"readonly", tREADONLY},
{"ref", tREF}, {"ref", tREF},
...@@ -288,6 +290,7 @@ static struct keyword { ...@@ -288,6 +290,7 @@ static struct keyword {
{"single", tSINGLE}, {"single", tSINGLE},
{"size_is", tSIZEIS}, {"size_is", tSIZEIS},
{"sizeof", tSIZEOF}, {"sizeof", tSIZEOF},
{"small", tSMALL},
/* ... */ /* ... */
{"source", tSOURCE}, {"source", tSOURCE},
/* ... */ /* ... */
......
...@@ -164,7 +164,9 @@ static type_t std_uhyper = { "MIDL_uhyper" }; ...@@ -164,7 +164,9 @@ static type_t std_uhyper = { "MIDL_uhyper" };
%token tPOINTERDEFAULT %token tPOINTERDEFAULT
%token tPROPERTIES %token tPROPERTIES
%token tPROPGET tPROPPUT tPROPPUTREF %token tPROPGET tPROPPUT tPROPPUTREF
%token tPTR
%token tPUBLIC %token tPUBLIC
%token tRANGE
%token tREADONLY tREF %token tREADONLY tREF
%token tRESTRICTED %token tRESTRICTED
%token tRETVAL %token tRETVAL
...@@ -172,6 +174,7 @@ static type_t std_uhyper = { "MIDL_uhyper" }; ...@@ -172,6 +174,7 @@ static type_t std_uhyper = { "MIDL_uhyper" };
%token tSIGNED %token tSIGNED
%token tSINGLE %token tSINGLE
%token tSIZEIS tSIZEOF %token tSIZEIS tSIZEOF
%token tSMALL
%token tSOURCE %token tSOURCE
%token tSTDCALL %token tSTDCALL
%token tSTRING tSTRUCT %token tSTRING tSTRUCT
...@@ -377,6 +380,7 @@ attribute: ...@@ -377,6 +380,7 @@ attribute:
| tPROPPUT { $$ = make_attr(ATTR_PROPPUT); } | tPROPPUT { $$ = make_attr(ATTR_PROPPUT); }
| tPROPPUTREF { $$ = make_attr(ATTR_PROPPUTREF); } | tPROPPUTREF { $$ = make_attr(ATTR_PROPPUTREF); }
| tPUBLIC { $$ = make_attr(ATTR_PUBLIC); } | tPUBLIC { $$ = make_attr(ATTR_PUBLIC); }
| tRANGE '(' expr_const ',' expr_const ')' { LINK($5, $3); $$ = make_attrp(ATTR_RANGE, $5); }
| tREADONLY { $$ = make_attr(ATTR_READONLY); } | tREADONLY { $$ = make_attr(ATTR_READONLY); }
| tRESTRICTED { $$ = make_attr(ATTR_RESTRICTED); } | tRESTRICTED { $$ = make_attr(ATTR_RESTRICTED); }
| tRETVAL { $$ = make_attr(ATTR_RETVAL); } | tRETVAL { $$ = make_attr(ATTR_RETVAL); }
...@@ -545,6 +549,7 @@ ident: aIDENTIFIER { $$ = make_var($1); } ...@@ -545,6 +549,7 @@ ident: aIDENTIFIER { $$ = make_var($1); }
| aKNOWNTYPE { $$ = make_var($<str>1); } | aKNOWNTYPE { $$ = make_var($<str>1); }
| tASYNC { $$ = make_var($<str>1); } | tASYNC { $$ = make_var($<str>1); }
| tID { $$ = make_var($<str>1); } | tID { $$ = make_var($<str>1); }
| tRANGE { $$ = make_var($<str>1); }
| tRETVAL { $$ = make_var($<str>1); } | tRETVAL { $$ = make_var($<str>1); }
| tVERSION { $$ = make_var($<str>1); } | tVERSION { $$ = make_var($<str>1); }
; ;
...@@ -580,6 +585,7 @@ m_int: ...@@ -580,6 +585,7 @@ m_int:
int_std: tINT { $$ = make_type(RPC_FC_LONG, &std_int); } /* win32 only */ int_std: tINT { $$ = make_type(RPC_FC_LONG, &std_int); } /* win32 only */
| tSHORT m_int { $$ = make_type(RPC_FC_SHORT, NULL); } | tSHORT m_int { $$ = make_type(RPC_FC_SHORT, NULL); }
| tSMALL { $$ = make_type(RPC_FC_SHORT, NULL); }
| tLONG m_int { $$ = make_type(RPC_FC_LONG, NULL); } | tLONG m_int { $$ = make_type(RPC_FC_LONG, NULL); }
| tHYPER m_int { $$ = make_type(RPC_FC_HYPER, NULL); } | tHYPER m_int { $$ = make_type(RPC_FC_HYPER, NULL); }
| tINT64 { $$ = make_type(RPC_FC_HYPER, &std_int64); } | tINT64 { $$ = make_type(RPC_FC_HYPER, &std_int64); }
...@@ -719,6 +725,7 @@ pident_list: ...@@ -719,6 +725,7 @@ pident_list:
pointer_type: pointer_type:
tREF { $$ = RPC_FC_RP; } tREF { $$ = RPC_FC_RP; }
| tUNIQUE { $$ = RPC_FC_UP; } | tUNIQUE { $$ = RPC_FC_UP; }
| tPTR { $$ = RPC_FC_FP; }
; ;
structdef: tSTRUCT t_ident '{' fields '}' { $$ = get_typev(RPC_FC_STRUCT, $2, tsSTRUCT); structdef: tSTRUCT t_ident '{' fields '}' { $$ = get_typev(RPC_FC_STRUCT, $2, tsSTRUCT);
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include "utils.h" #include "utils.h"
#include "parser.h" #include "parser.h"
#include "wine/wpp.h" #include "wine/wpp.h"
#include "header.h"
/* future options to reserve characters for: */ /* future options to reserve characters for: */
/* a = alignment of structures */ /* a = alignment of structures */
...@@ -310,6 +311,12 @@ int main(int argc,char *argv[]) ...@@ -310,6 +311,12 @@ int main(int argc,char *argv[])
ret = yyparse(); ret = yyparse();
if(do_header) { if(do_header) {
fprintf(header, "/* Begin additional prototypes for all interfaces */\n");
fprintf(header, "\n");
write_user_types();
fprintf(header, "\n");
fprintf(header, "/* End additional prototypes */\n");
fprintf(header, "\n");
fprintf(header, "#ifdef __cplusplus\n"); fprintf(header, "#ifdef __cplusplus\n");
fprintf(header, "}\n"); fprintf(header, "}\n");
fprintf(header, "#endif\n"); fprintf(header, "#endif\n");
......
...@@ -99,6 +99,7 @@ enum attr_type ...@@ -99,6 +99,7 @@ enum attr_type
ATTR_PROPPUT, ATTR_PROPPUT,
ATTR_PROPPUTREF, ATTR_PROPPUTREF,
ATTR_PUBLIC, ATTR_PUBLIC,
ATTR_RANGE,
ATTR_READONLY, ATTR_READONLY,
ATTR_RESTRICTED, ATTR_RESTRICTED,
ATTR_RETVAL, ATTR_RETVAL,
...@@ -185,7 +186,7 @@ struct _type_t { ...@@ -185,7 +186,7 @@ struct _type_t {
func_t *funcs; func_t *funcs;
var_t *fields; var_t *fields;
int ignore, is_const, sign; int ignore, is_const, sign;
int defined, written; int defined, written, user_types_registered;
int typelib_idx; int typelib_idx;
/* parser-internal */ /* parser-internal */
DECL_LINK(type_t) DECL_LINK(type_t)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment