- 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.
oldstable
Robert Shearman 2005-09-12 20:13:40 +00:00 committed by Alexandre Julliard
parent 635d81660c
commit d026458860
6 changed files with 94 additions and 17 deletions

View File

@ -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)
{
char *tname = names->tname;
@ -324,22 +390,6 @@ void write_typedef(type_t *type, var_t *names)
names = PREV_LINK(names);
}
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)
@ -625,6 +675,7 @@ static void write_method_proto(type_t *iface)
while (cur) {
var_t *def = cur->def;
var_t *cas = is_callas(def->attrs);
var_t *args;
if (!is_local(def->attrs)) {
/* proxy prototype */
write_type(header, def->type, def, def->tname);
@ -641,6 +692,13 @@ static void write_method_proto(type_t *iface)
fprintf(header, " struct IRpcChannelBuffer* pRpcChannelBuffer,\n");
fprintf(header, " PRPC_MESSAGE pRpcMessage,\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) {
func_t *m = iface->funcs;

View File

@ -41,5 +41,6 @@ extern void write_expr(FILE *h, expr_t *e);
extern void write_constdef(var_t *v);
extern void write_externdef(var_t *v);
extern void write_library(const char *name, attr_t *attr);
extern void write_user_types(void);
#endif

View File

@ -274,8 +274,10 @@ static struct keyword {
{"propget", tPROPGET},
{"propput", tPROPPUT},
{"propputref", tPROPPUTREF},
{"ptr", tPTR},
/* ... */
{"public", tPUBLIC},
{"range", tRANGE},
/* ... */
{"readonly", tREADONLY},
{"ref", tREF},
@ -288,6 +290,7 @@ static struct keyword {
{"single", tSINGLE},
{"size_is", tSIZEIS},
{"sizeof", tSIZEOF},
{"small", tSMALL},
/* ... */
{"source", tSOURCE},
/* ... */

View File

@ -164,7 +164,9 @@ static type_t std_uhyper = { "MIDL_uhyper" };
%token tPOINTERDEFAULT
%token tPROPERTIES
%token tPROPGET tPROPPUT tPROPPUTREF
%token tPTR
%token tPUBLIC
%token tRANGE
%token tREADONLY tREF
%token tRESTRICTED
%token tRETVAL
@ -172,6 +174,7 @@ static type_t std_uhyper = { "MIDL_uhyper" };
%token tSIGNED
%token tSINGLE
%token tSIZEIS tSIZEOF
%token tSMALL
%token tSOURCE
%token tSTDCALL
%token tSTRING tSTRUCT
@ -377,6 +380,7 @@ attribute:
| tPROPPUT { $$ = make_attr(ATTR_PROPPUT); }
| tPROPPUTREF { $$ = make_attr(ATTR_PROPPUTREF); }
| tPUBLIC { $$ = make_attr(ATTR_PUBLIC); }
| tRANGE '(' expr_const ',' expr_const ')' { LINK($5, $3); $$ = make_attrp(ATTR_RANGE, $5); }
| tREADONLY { $$ = make_attr(ATTR_READONLY); }
| tRESTRICTED { $$ = make_attr(ATTR_RESTRICTED); }
| tRETVAL { $$ = make_attr(ATTR_RETVAL); }
@ -545,6 +549,7 @@ ident: aIDENTIFIER { $$ = make_var($1); }
| aKNOWNTYPE { $$ = make_var($<str>1); }
| tASYNC { $$ = make_var($<str>1); }
| tID { $$ = make_var($<str>1); }
| tRANGE { $$ = make_var($<str>1); }
| tRETVAL { $$ = make_var($<str>1); }
| tVERSION { $$ = make_var($<str>1); }
;
@ -580,6 +585,7 @@ m_int:
int_std: tINT { $$ = make_type(RPC_FC_LONG, &std_int); } /* win32 only */
| 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); }
| tHYPER m_int { $$ = make_type(RPC_FC_HYPER, NULL); }
| tINT64 { $$ = make_type(RPC_FC_HYPER, &std_int64); }
@ -719,6 +725,7 @@ pident_list:
pointer_type:
tREF { $$ = RPC_FC_RP; }
| tUNIQUE { $$ = RPC_FC_UP; }
| tPTR { $$ = RPC_FC_FP; }
;
structdef: tSTRUCT t_ident '{' fields '}' { $$ = get_typev(RPC_FC_STRUCT, $2, tsSTRUCT);

View File

@ -38,6 +38,7 @@
#include "utils.h"
#include "parser.h"
#include "wine/wpp.h"
#include "header.h"
/* future options to reserve characters for: */
/* a = alignment of structures */
@ -310,6 +311,12 @@ int main(int argc,char *argv[])
ret = yyparse();
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, "}\n");
fprintf(header, "#endif\n");

View File

@ -99,6 +99,7 @@ enum attr_type
ATTR_PROPPUT,
ATTR_PROPPUTREF,
ATTR_PUBLIC,
ATTR_RANGE,
ATTR_READONLY,
ATTR_RESTRICTED,
ATTR_RETVAL,
@ -185,7 +186,7 @@ struct _type_t {
func_t *funcs;
var_t *fields;
int ignore, is_const, sign;
int defined, written;
int defined, written, user_types_registered;
int typelib_idx;
/* parser-internal */
DECL_LINK(type_t)