static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *type,
const char *name, int write_ptr, unsigned int *tfsoff);
static const var_t *find_array_or_string_in_struct(const type_t *type);
+static size_t write_string_tfs(FILE *file, const attr_list_t *attrs,
+ type_t *type,
+ const char *name, unsigned int *typestring_offset);
const char *string_of_type(unsigned char type)
{
else if (is_struct(type->type))
{
const var_t *field;
- if (type->fields) LIST_FOR_EACH_ENTRY( field, type->fields, const var_t, entry )
+ if (type->fields_or_args) LIST_FOR_EACH_ENTRY( field, type->fields_or_args, const var_t, entry )
{
if (type_has_pointers(field->type))
return TRUE;
const var_t *field;
if (type->type == RPC_FC_ENCAPSULATED_UNION)
{
- const var_t *uv = LIST_ENTRY(list_tail(type->fields), const var_t, entry);
- fields = uv->type->fields;
+ const var_t *uv = LIST_ENTRY(list_tail(type->fields_or_args), const var_t, entry);
+ fields = uv->type->fields_or_args;
}
else
- fields = type->fields;
+ fields = type->fields_or_args;
if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
{
if (field->type && type_has_pointers(field->type))
else if (is_struct(type->type))
{
const var_t *field;
- if (type->fields) LIST_FOR_EACH_ENTRY( field, type->fields, const var_t, entry )
+ if (type->fields_or_args) LIST_FOR_EACH_ENTRY( field, type->fields_or_args, const var_t, entry )
{
if (type_has_full_pointer(field->type))
return TRUE;
const var_t *field;
if (type->type == RPC_FC_ENCAPSULATED_UNION)
{
- const var_t *uv = LIST_ENTRY(list_tail(type->fields), const var_t, entry);
- fields = uv->type->fields;
+ const var_t *uv = LIST_ENTRY(list_tail(type->fields_or_args), const var_t, entry);
+ fields = uv->type->fields_or_args;
}
else
- fields = type->fields;
+ fields = type->fields_or_args;
if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
{
if (field->type && type_has_full_pointer(field->type))
{
const var_t *var;
- if (!is_void(func->def->type))
- write_var_init(file, indent, func->def->type, "_RetVal");
+ if (!is_void(get_func_return_type(func)))
+ write_var_init(file, indent, get_func_return_type(func), "_RetVal");
if (!func->args)
return;
&& !is_array(t));
}
-static size_t write_procformatstring_var(FILE *file, int indent,
- const var_t *var, int is_return)
+static size_t write_procformatstring_type(FILE *file, int indent,
+ const char *name,
+ const type_t *type,
+ const attr_list_t *attrs,
+ int is_return)
{
size_t size;
- const type_t *type = var->type;
- int is_in = is_attr(var->attrs, ATTR_IN);
- int is_out = is_attr(var->attrs, ATTR_OUT);
+ int is_in = is_attr(attrs, ATTR_IN);
+ int is_out = is_attr(attrs, ATTR_OUT);
if (!is_in && !is_out) is_in = TRUE;
}
else
{
- error("Unknown/unsupported type: %s (0x%02x)\n", var->name, type->type);
+ error("Unknown/unsupported type: %s (0x%02x)\n", name, type->type);
size = 0;
}
}
if (func->args)
{
LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry )
- write_procformatstring_var(file, indent, var, FALSE);
+ write_procformatstring_type(file, indent, var->name, var->type, var->attrs, FALSE);
}
/* emit return value data */
- var = func->def;
- if (is_void(var->type))
+ if (is_void(get_func_return_type(func)))
{
print_file(file, indent, "0x5b, /* FC_END */\n");
print_file(file, indent, "0x5c, /* FC_PAD */\n");
}
else
- write_procformatstring_var(file, indent, var, TRUE);
+ write_procformatstring_type(file, indent, "return value", get_func_return_type(func), NULL, TRUE);
}
}
}
size_t offset = 0;
const var_t *var;
- if (structure->fields) LIST_FOR_EACH_ENTRY( var, structure->fields, const var_t, entry )
+ if (structure->fields_or_args) LIST_FOR_EACH_ENTRY( var, structure->fields_or_args, const var_t, entry )
{
unsigned int align = 0;
/* FIXME: take alignment into account */
case RPC_FC_CSTRUCT:
case RPC_FC_PSTRUCT:
case RPC_FC_BOGUS_STRUCT:
- size = fields_memsize(t->fields, align);
+ size = fields_memsize(t->fields_or_args, align);
break;
case RPC_FC_ENCAPSULATED_UNION:
case RPC_FC_NON_ENCAPSULATED_UNION:
- size = union_memsize(t->fields, align);
+ size = union_memsize(t->fields_or_args, align);
break;
case RPC_FC_SMFARRAY:
case RPC_FC_LGFARRAY:
int is_full_pointer_function(const func_t *func)
{
const var_t *var;
- if (type_has_full_pointer(func->def->type))
+ if (type_has_full_pointer(get_func_return_type(func)))
return TRUE;
if (!func->args)
return FALSE;
return 4;
}
-static unsigned char conf_string_type_of_char_type(unsigned char t)
-{
- switch (t)
- {
- case RPC_FC_BYTE:
- case RPC_FC_CHAR:
- return RPC_FC_C_CSTRING;
- case RPC_FC_WCHAR:
- return RPC_FC_C_WSTRING;
- }
-
- error("string_type_of_char_type: unrecognized type %d\n", t);
- return 0;
-}
-
static unsigned int write_simple_pointer(FILE *file, const type_t *type)
{
- unsigned char fc
- = is_string_type(type->attrs, type)
- ? conf_string_type_of_char_type(type->ref->type)
- : type->ref->type;
+ unsigned char fc = type->ref->type;
+ /* for historical reasons, write_simple_pointer also handled string types,
+ * but no longer does. catch bad uses of the function with this check */
+ if (is_string_type(type->attrs, type))
+ error("write_simple_pointer: can't handle type %s which is a string type\n", type->name);
print_file(file, 2, "0x%02x, 0x8,\t/* %s [simple_pointer] */\n",
type->type, string_of_type(type->type));
print_file(file, 2, "0x%02x,\t/* %s */\n", fc, string_of_type(fc));
static void write_descriptors(FILE *file, type_t *type, unsigned int *tfsoff)
{
unsigned int offset = 0;
- var_list_t *fs = type->fields;
+ var_list_t *fs = type->fields_or_args;
var_t *f;
if (fs) LIST_FOR_EACH_ENTRY(f, fs, var_t, entry)
*typestring_offset += 6;
if (is_ptr(type))
- write_pointer_tfs(file, type, typestring_offset);
+ {
+ if (is_string_type(type->attrs, type))
+ write_string_tfs(file, NULL, type, NULL, typestring_offset);
+ else
+ write_pointer_tfs(file, type, typestring_offset);
+ }
else
{
unsigned absoff = type->typestring_offset;
if (is_non_complex_struct(type))
{
const var_t *v;
- LIST_FOR_EACH_ENTRY( v, type->fields, const var_t, entry )
+ LIST_FOR_EACH_ENTRY( v, type->fields_or_args, const var_t, entry )
written += write_no_repeat_pointer_descriptions(
file, v->type,
offset_in_memory, offset_in_buffer, typestring_offset);
}
*typestring_offset += 4;
- if (processed(type->ref) || is_base_type(type->ref->type))
+ if (is_string_type(attrs, type))
+ write_string_tfs(file, NULL, type, NULL, typestring_offset);
+ else if (processed(type->ref) || is_base_type(type->ref->type))
write_pointer_tfs(file, type, typestring_offset);
else
error("write_pointer_description_offsets: type format string unknown\n");
{
/* otherwise search for interesting fields to parse */
const var_t *v;
- LIST_FOR_EACH_ENTRY( v, type->fields, const var_t, entry )
+ LIST_FOR_EACH_ENTRY( v, type->fields_or_args, const var_t, entry )
{
written += write_pointer_description_offsets(
file, v->attrs, v->type, offset_in_memory, offset_in_buffer,
else if (is_struct(type->type))
{
const var_t *v;
- LIST_FOR_EACH_ENTRY( v, type->fields, const var_t, entry )
+ LIST_FOR_EACH_ENTRY( v, type->fields_or_args, const var_t, entry )
{
pointer_count += write_fixed_array_pointer_descriptions(
file, v->attrs, v->type, offset_in_memory, offset_in_buffer,
else if (is_struct(type->type))
{
const var_t *v;
- LIST_FOR_EACH_ENTRY( v, type->fields, const var_t, entry )
+ LIST_FOR_EACH_ENTRY( v, type->fields_or_args, const var_t, entry )
{
pointer_count += write_varying_array_pointer_descriptions(
file, v->attrs, v->type, offset_in_memory, offset_in_buffer,
static size_t write_string_tfs(FILE *file, const attr_list_t *attrs,
type_t *type,
- const char *name, unsigned int *typestring_offset,
- int toplevel)
+ const char *name, unsigned int *typestring_offset)
{
size_t start_offset;
unsigned char rtype;
- if (toplevel && is_declptr(type))
+ if (is_declptr(type))
{
unsigned char flag = is_conformant_array(type) ? 0 : RPC_FC_P_SIMPLEPOINTER;
int pointer_type = is_ptr(type) ? type->type : get_attrv(attrs, ATTR_POINTERTYPE);
if (!pointer_type)
pointer_type = RPC_FC_RP;
+ print_start_tfs_comment(file, type, *typestring_offset);
print_file(file, 2,"0x%x, 0x%x,\t/* %s%s */\n",
pointer_type, flag, string_of_type(pointer_type),
flag ? " [simple_pointer]" : "");
static const var_t *find_array_or_string_in_struct(const type_t *type)
{
- const var_t *last_field = LIST_ENTRY( list_tail(type->fields), const var_t, entry );
+ const var_t *last_field = LIST_ENTRY( list_tail(type->fields_or_args), const var_t, entry );
const type_t *ft = last_field->type;
if (ft->declarray && is_conformant_array(ft))
int salign = -1;
int padding;
- if (type->fields) LIST_FOR_EACH_ENTRY( field, type->fields, const var_t, entry )
+ if (type->fields_or_args) LIST_FOR_EACH_ENTRY( field, type->fields_or_args, const var_t, entry )
{
type_t *ft = field->type;
if (!ft->declarray || !is_conformant_array(ft))
error("structure size for %s exceeds %d bytes by %d bytes\n",
name, USHRT_MAX, total_size - USHRT_MAX);
- if (type->fields) LIST_FOR_EACH_ENTRY(f, type->fields, var_t, entry)
+ if (type->fields_or_args) LIST_FOR_EACH_ENTRY(f, type->fields_or_args, var_t, entry)
has_pointers |= write_embedded_types(file, f->attrs, f->type, f->name,
FALSE, tfsoff);
if (!has_pointers) has_pointers = type_has_pointers(type);
if (array && !processed(array->type))
array_offset
= is_attr(array->attrs, ATTR_STRING)
- ? write_string_tfs(file, array->attrs, array->type, array->name, tfsoff, FALSE)
+ ? write_string_tfs(file, array->attrs, array->type, array->name, tfsoff)
: write_array_tfs(file, array->attrs, array->type, array->name, tfsoff);
corroff = *tfsoff;
if (type->type == RPC_FC_BOGUS_STRUCT)
{
- const var_list_t *fs = type->fields;
+ const var_list_t *fs = type->fields_or_args;
const var_t *f;
type->ptrdesc = *tfsoff;
{
type_t *ft = f->type;
if (is_ptr(ft))
- write_pointer_tfs(file, ft, tfsoff);
+ {
+ if (is_string_type(f->attrs, ft))
+ write_string_tfs(file, f->attrs, ft, f->name, tfsoff);
+ else
+ write_pointer_tfs(file, ft, tfsoff);
+ }
else if (!ft->declarray && is_conformant_array(ft))
{
unsigned int absoff = ft->typestring_offset;
if (type->type == RPC_FC_ENCAPSULATED_UNION)
{
- const var_t *uv = LIST_ENTRY(list_tail(type->fields), const var_t, entry);
- fields = uv->type->fields;
+ const var_t *uv = LIST_ENTRY(list_tail(type->fields_or_args), const var_t, entry);
+ fields = uv->type->fields_or_args;
}
else
- fields = type->fields;
+ fields = type->fields_or_args;
if (fields) LIST_FOR_EACH_ENTRY(f, fields, var_t, entry)
{
print_start_tfs_comment(file, type, start_offset);
if (type->type == RPC_FC_ENCAPSULATED_UNION)
{
- const var_t *sv = LIST_ENTRY(list_head(type->fields), const var_t, entry);
+ const var_t *sv = LIST_ENTRY(list_head(type->fields_or_args), const var_t, entry);
const type_t *st = sv->type;
switch (st->type)
return type->typestring_offset;
}
- if ((last_ptr(type) || last_array(type)) && is_ptrchain_attr(var, ATTR_STRING))
- return write_string_tfs(file, var->attrs, type, var->name, typeformat_offset, TRUE);
+ if (is_string_type(var->attrs, type))
+ return write_string_tfs(file, var->attrs, type, var->name, typeformat_offset);
if (is_array(type))
{
{
write_user_tfs(file, type, tfsoff);
}
+ else if (is_string_type(attrs, type))
+ {
+ write_string_tfs(file, attrs, type, name, tfsoff);
+ }
else if (is_ptr(type))
{
type_t *ref = type->ref;
retmask |= 1;
}
}
- else if (last_array(type) && is_attr(attrs, ATTR_STRING))
- {
- write_string_tfs(file, attrs, type, name, tfsoff, FALSE);
- }
else if (type->declarray && is_conformant_array(type))
; /* conformant arrays and strings are handled specially */
else if (is_array(type))
{
if (is_local(func->def->attrs)) continue;
- if (!is_void(func->def->type))
- update_tfsoff(func->def->type,
+ if (!is_void(get_func_return_type(func)))
+ {
+ var_t v = *func->def;
+ v.type = get_func_return_type(func);
+ update_tfsoff(get_func_return_type(func),
write_typeformatstring_var(
- file, 2, NULL, func->def->type,
- func->def, &typeformat_offset),
+ file, 2, NULL, get_func_return_type(func),
+ &v, &typeformat_offset),
file);
+ }
current_func = func;
if (func->args)
{
size_t size = 0;
const var_t *field;
- if (!type->fields) return 0;
- LIST_FOR_EACH_ENTRY( field, type->fields, const var_t, entry )
+ if (!type->fields_or_args) return 0;
+ LIST_FOR_EACH_ENTRY( field, type->fields_or_args, const var_t, entry )
{
unsigned int alignment;
size += get_required_buffer_size_type(field->type, field->name,
const var_t *field;
unsigned int size = 36;
- if (!type->fields) return size;
- LIST_FOR_EACH_ENTRY( field, type->fields, const var_t, entry )
+ if (!type->fields_or_args) return size;
+ LIST_FOR_EACH_ENTRY( field, type->fields_or_args, const var_t, entry )
{
unsigned int align;
size += get_required_buffer_size_type(
unsigned int size = 36;
const var_t *field;
- if (!type->fields) return size;
- LIST_FOR_EACH_ENTRY( field, type->fields, const var_t, entry )
+ if (!type->fields_or_args) return size;
+ LIST_FOR_EACH_ENTRY( field, type->fields_or_args, const var_t, entry )
{
unsigned int align;
size += get_required_buffer_size_type(
}
}
- if (pass == PASS_OUT && !is_void(func->def->type))
+ if (pass == PASS_OUT && !is_void(get_func_return_type(func)))
{
- total_size += get_required_buffer_size(func->def, &alignment, PASS_RETURN);
+ var_t v = *func->def;
+ v.type = get_func_return_type(func);
+ total_size += get_required_buffer_size(&v, &alignment, PASS_RETURN);
total_size += alignment;
}
return total_size;
{
if (pass == PASS_IN)
{
+ /* if the context_handle attribute appears in the chain of types
+ * without pointers being followed, then the context handle must
+ * be direct, otherwise it is a pointer */
+ int is_ch_ptr = is_aliaschain_attr(type, ATTR_CONTEXTHANDLE) ? FALSE : TRUE;
print_file(file, indent, "NdrClientContextMarshall(\n");
print_file(file, indent + 1, "&_StubMsg,\n");
- print_file(file, indent + 1, "(NDR_CCONTEXT)%s%s,\n", is_ptr(type) ? "*" : "", var->name);
+ print_file(file, indent + 1, "(NDR_CCONTEXT)%s%s,\n", is_ch_ptr ? "*" : "", var->name);
print_file(file, indent + 1, "%s);\n", in_attr && out_attr ? "1" : "0");
}
else
{
var_t var;
var = *func->def;
+ var.type = get_func_return_type(func);
var.name = xstrdup( "_RetVal" );
write_remoting_arg( file, indent, func, pass, phase, &var );
free( var.name );
}
-size_t get_size_procformatstring_var(const var_t *var)
+size_t get_size_procformatstring_type(const char *name, const type_t *type, const attr_list_t *attrs)
{
- return write_procformatstring_var(NULL, 0, var, FALSE);
+ return write_procformatstring_type(NULL, 0, name, type, attrs, FALSE);
}
/* argument list size */
if (func->args)
LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry )
- size += get_size_procformatstring_var(var);
+ size += get_size_procformatstring_type(var->name, var->type, var->attrs);
/* return value size */
- if (is_void(func->def->type))
+ if (is_void(get_func_return_type(func)))
size += 2; /* FC_END and FC_PAD */
else
- size += get_size_procformatstring_var(func->def);
+ size += get_size_procformatstring_type("return value", get_func_return_type(func), NULL);
return size;
}
{
int in_attr, out_attr;
int i = 0;
- const var_t *def = func->def;
const var_t *var;
/* declare return value '_RetVal' */
- if (!is_void(def->type))
+ if (!is_void(get_func_return_type(func)))
{
print_file(file, indent, "");
- write_type_decl_left(file, def->type);
+ write_type_decl_left(file, get_func_return_type(func));
fprintf(file, " _RetVal;\n");
}
LIST_FOR_EACH_ENTRY(eval, &expr_eval_routines, struct expr_eval_routine, entry)
{
const char *name = eval->structure->name;
- const var_list_t *fields = eval->structure->fields;
+ const var_list_t *fields = eval->structure->fields_or_args;
result = 1;
print_file(file, 0, "static void __RPC_USER %s_%sExprEval_%04u(PMIDL_STUB_MESSAGE pStubMsg)\n",