Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
2b3659f3
Commit
2b3659f3
authored
Nov 07, 2009
by
Rob Shearman
Committed by
Alexandre Julliard
Nov 09, 2009
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
widl: Implement [range] attribute.
parent
c3676245
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
197 additions
and
14 deletions
+197
-14
server.c
dlls/rpcrt4/tests/server.c
+19
-0
server.idl
dlls/rpcrt4/tests/server.idl
+15
-0
parser.y
tools/widl/parser.y
+37
-0
typegen.c
tools/widl/typegen.c
+125
-14
typegen.h
tools/widl/typegen.h
+1
-0
No files found.
dlls/rpcrt4/tests/server.c
View file @
2b3659f3
...
...
@@ -571,6 +571,16 @@ s_get_filename(void)
return
(
char
*
)
__FILE__
;
}
int
s_echo_ranged_int
(
int
n
)
{
return
n
;
}
void
s_get_ranged_enum
(
renum_t
*
re
)
{
*
re
=
RE3
;
}
void
s_context_handle_test
(
void
)
{
...
...
@@ -762,6 +772,7 @@ basic_tests(void)
wstr_struct_t
ws
=
{
wstring
};
str_t
str
;
se_t
se
;
renum_t
re
;
ok
(
int_return
()
==
INT_CODE
,
"RPC int_return
\n
"
);
...
...
@@ -869,6 +880,14 @@ basic_tests(void)
str
=
get_filename
();
ok
(
!
strcmp
(
str
,
__FILE__
),
"get_filename() returned %s instead of %s
\n
"
,
str
,
__FILE__
);
midl_user_free
(
str
);
x
=
echo_ranged_int
(
0
);
ok
(
x
==
0
,
"echo_ranged_int() returned %d instead of 0
\n
"
,
x
);
x
=
echo_ranged_int
(
100
);
ok
(
x
==
100
,
"echo_ranged_int() returned %d instead of 100
\n
"
,
x
);
get_ranged_enum
(
&
re
);
ok
(
re
==
RE3
,
"get_ranged_enum() returned %d instead of RE3
\n
"
,
re
);
}
static
void
...
...
dlls/rpcrt4/tests/server.idl
View file @
2b3659f3
...
...
@@ -339,6 +339,21 @@ cpp_quote("#endif")
void
get_numbers_struct
(
[
out
]
numbers_struct_t
**
ns
)
;
str_t
get_filename
(
void
)
;
enum
renum
{
RE0
,
RE1
,
RE2
,
RE3
,
}
;
const
int
RE_MIN
=
RE0
;
const
int
RE_MAX
=
RE3
;
typedef
[
range
(
RE_MIN
,
RE_MAX
)
]
enum
renum
renum_t
;
typedef
[
range
(
0
,
100
)
]
int
rint_t
;
rint_t
echo_ranged_int
(
[
range
(
0
,
100
)
]
int
n
)
;
void
get_ranged_enum
(
[
out
]
renum_t
*
re
)
;
void
context_handle_test
(
void
)
;
void
stop
(
void
)
;
}
tools/widl/parser.y
View file @
2b3659f3
...
...
@@ -1274,6 +1274,37 @@ static void type_function_add_head_arg(type_t *type, var_t *arg)
list_add_head( type->details.function->args, &arg->entry );
}
static int is_allowed_range_type(const type_t *type)
{
switch (type_get_type(type))
{
case TYPE_ENUM:
return TRUE;
case TYPE_BASIC:
switch (type_basic_get_type(type))
{
case TYPE_BASIC_INT8:
case TYPE_BASIC_INT16:
case TYPE_BASIC_INT32:
case TYPE_BASIC_INT64:
case TYPE_BASIC_INT:
case TYPE_BASIC_BYTE:
case TYPE_BASIC_CHAR:
case TYPE_BASIC_WCHAR:
case TYPE_BASIC_HYPER:
return TRUE;
case TYPE_BASIC_FLOAT:
case TYPE_BASIC_DOUBLE:
case TYPE_BASIC_ERROR_STATUS_T:
case TYPE_BASIC_HANDLE:
return FALSE;
}
return FALSE;
default:
return FALSE;
}
}
static type_t *append_ptrchain_type(type_t *ptrchain, type_t *type)
{
type_t *ptrchain_type;
...
...
@@ -1363,6 +1394,10 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
error_loc("'%s': [v1_enum] attribute applied to non-enum type\n", v->name);
}
if (is_attr(v->attrs, ATTR_RANGE) && !is_allowed_range_type(v->type))
error_loc("'%s': [range] attribute applied to non-integer type\n",
v->name);
ptype = &v->type;
sizeless = FALSE;
if (arr) LIST_FOR_EACH_ENTRY_REV(dim, arr, expr_t, entry)
...
...
@@ -2339,6 +2374,7 @@ static void check_field_common(const type_t *container_type,
case TGT_IFACE_POINTER:
case TGT_BASIC:
case TGT_ENUM:
case TGT_RANGE:
/* nothing to do */
break;
}
...
...
@@ -2388,6 +2424,7 @@ static void check_remoting_args(const var_t *func)
{
case TGT_BASIC:
case TGT_ENUM:
case TGT_RANGE:
case TGT_STRUCT:
case TGT_UNION:
case TGT_CTXT_HANDLE:
...
...
tools/widl/typegen.c
View file @
2b3659f3
...
...
@@ -122,6 +122,19 @@ const char *string_of_type(unsigned char type)
}
}
static
void
*
get_aliaschain_attrp
(
const
type_t
*
type
,
enum
attr_type
attr
)
{
const
type_t
*
t
=
type
;
for
(;;)
{
if
(
is_attr
(
t
->
attrs
,
attr
))
return
get_attrp
(
t
->
attrs
,
attr
);
else
if
(
type_is_alias
(
t
))
t
=
type_alias_get_aliasee
(
t
);
else
return
0
;
}
}
unsigned
char
get_basic_fc
(
const
type_t
*
type
)
{
int
sign
=
type_basic_get_sign
(
type
);
...
...
@@ -200,8 +213,12 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att
switch
(
type_get_type
(
type
))
{
case
TYPE_BASIC
:
if
(
is_attr
(
attrs
,
ATTR_RANGE
)
||
is_aliaschain_attr
(
type
,
ATTR_RANGE
))
return
TGT_RANGE
;
return
TGT_BASIC
;
case
TYPE_ENUM
:
if
(
is_attr
(
attrs
,
ATTR_RANGE
)
||
is_aliaschain_attr
(
type
,
ATTR_RANGE
))
return
TGT_RANGE
;
return
TGT_ENUM
;
case
TYPE_POINTER
:
if
(
type_get_type
(
type_pointer_get_ref
(
type
))
==
TYPE_INTERFACE
||
...
...
@@ -337,6 +354,8 @@ unsigned char get_struct_fc(const type_t *type)
}
break
;
}
case
TGT_RANGE
:
return
RPC_FC_BOGUS_STRUCT
;
case
TGT_STRING
:
/* shouldn't get here because of TDT_IGNORE_STRINGS above. fall through */
case
TGT_INVALID
:
...
...
@@ -425,6 +444,9 @@ unsigned char get_array_fc(const type_t *type)
if
(
get_pointer_fc
(
elem_type
,
NULL
,
FALSE
)
==
RPC_FC_RP
||
pointer_size
!=
4
)
fc
=
RPC_FC_BOGUS_ARRAY
;
break
;
case
TGT_RANGE
:
fc
=
RPC_FC_BOGUS_ARRAY
;
break
;
case
TGT_BASIC
:
case
TGT_CTXT_HANDLE
:
case
TGT_CTXT_HANDLE_POINTER
:
...
...
@@ -499,6 +521,7 @@ static int type_has_pointers(const type_t *type)
case
TGT_IFACE_POINTER
:
case
TGT_BASIC
:
case
TGT_ENUM
:
case
TGT_RANGE
:
case
TGT_INVALID
:
break
;
}
...
...
@@ -552,6 +575,7 @@ static int type_has_full_pointer(const type_t *type, const attr_list_t *attrs,
case
TGT_IFACE_POINTER
:
case
TGT_BASIC
:
case
TGT_ENUM
:
case
TGT_RANGE
:
case
TGT_INVALID
:
break
;
}
...
...
@@ -2677,6 +2701,33 @@ static unsigned int write_contexthandle_tfs(FILE *file, const type_t *type,
return
start_offset
;
}
static
unsigned
int
write_range_tfs
(
FILE
*
file
,
const
attr_list_t
*
attrs
,
type_t
*
type
,
expr_list_t
*
range_list
,
unsigned
int
*
typeformat_offset
)
{
unsigned
char
fc
;
unsigned
int
start_offset
=
*
typeformat_offset
;
const
expr_t
*
range_min
=
LIST_ENTRY
(
list_head
(
range_list
),
const
expr_t
,
entry
);
const
expr_t
*
range_max
=
LIST_ENTRY
(
list_next
(
range_list
,
list_head
(
range_list
)),
const
expr_t
,
entry
);
if
(
type_get_type
(
type
)
==
TYPE_BASIC
)
fc
=
get_basic_fc
(
type
);
else
fc
=
get_enum_fc
(
type
);
/* fc must fit in lower 4-bits of 8-bit field below */
assert
(
fc
<=
0xf
);
print_file
(
file
,
0
,
"/* %u */
\n
"
,
*
typeformat_offset
);
print_file
(
file
,
2
,
"0x%x,
\t
/* FC_RANGE */
\n
"
,
RPC_FC_RANGE
);
print_file
(
file
,
2
,
"0x%x,
\t
/* %s */
\n
"
,
fc
,
string_of_type
(
fc
));
print_file
(
file
,
2
,
"NdrFcLong(0x%lx),
\t
/* %lu */
\n
"
,
range_min
->
cval
,
range_min
->
cval
);
print_file
(
file
,
2
,
"NdrFcLong(0x%lx),
\t
/* %lu */
\n
"
,
range_max
->
cval
,
range_max
->
cval
);
*
typeformat_offset
+=
10
;
return
start_offset
;
}
static
unsigned
int
write_typeformatstring_var
(
FILE
*
file
,
int
indent
,
const
var_t
*
func
,
type_t
*
type
,
const
var_t
*
var
,
int
toplevel_param
,
...
...
@@ -2724,6 +2775,13 @@ static unsigned int write_typeformatstring_var(FILE *file, int indent, const var
case
TGT_BASIC
:
/* nothing to do */
return
0
;
case
TGT_RANGE
:
{
expr_list_t
*
range_list
=
get_attrp
(
var
->
attrs
,
ATTR_RANGE
);
if
(
!
range_list
)
range_list
=
get_aliaschain_attrp
(
type
,
ATTR_RANGE
);
return
write_range_tfs
(
file
,
var
->
attrs
,
type
,
range_list
,
typeformat_offset
);
}
case
TGT_IFACE_POINTER
:
return
write_ip_tfs
(
file
,
var
->
attrs
,
type
,
typeformat_offset
);
case
TGT_POINTER
:
...
...
@@ -2828,6 +2886,14 @@ static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *ty
case
TGT_BASIC
:
/* nothing to do */
break
;
case
TGT_RANGE
:
{
expr_list_t
*
range_list
=
get_attrp
(
attrs
,
ATTR_RANGE
);
if
(
!
range_list
)
range_list
=
get_aliaschain_attrp
(
type
,
ATTR_RANGE
);
write_range_tfs
(
file
,
attrs
,
type
,
range_list
,
tfsoff
);
break
;
}
case
TGT_CTXT_HANDLE
:
case
TGT_CTXT_HANDLE_POINTER
:
case
TGT_INVALID
:
...
...
@@ -3004,6 +3070,7 @@ static unsigned int get_required_buffer_size_type(
{
case
TGT_BASIC
:
case
TGT_ENUM
:
case
TGT_RANGE
:
return
get_required_buffer_size_type
(
ref
,
name
,
NULL
,
FALSE
,
alignment
);
case
TGT_STRUCT
:
if
(
get_struct_fc
(
ref
)
==
RPC_FC_STRUCT
)
...
...
@@ -3503,6 +3570,49 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
print_file
(
file
,
indent
+
1
,
"0x%02x /* %s */);
\n
"
,
get_enum_fc
(
type
),
string_of_type
(
get_enum_fc
(
type
)));
}
break
;
case
TGT_RANGE
:
if
(
type_get_type
(
type
)
==
TYPE_ENUM
)
{
if
(
phase
==
PHASE_MARSHAL
||
phase
==
PHASE_UNMARSHAL
)
{
if
(
phase
==
PHASE_MARSHAL
)
print_file
(
file
,
indent
,
"NdrSimpleTypeMarshall(
\n
"
);
else
print_file
(
file
,
indent
,
"NdrSimpleTypeUnmarshall(
\n
"
);
print_file
(
file
,
indent
+
1
,
"&__frame->_StubMsg,
\n
"
);
print_file
(
file
,
indent
+
1
,
"(unsigned char *)&%s%s,
\n
"
,
local_var_prefix
,
var
->
name
);
print_file
(
file
,
indent
+
1
,
"0x%02x /* %s */);
\n
"
,
get_enum_fc
(
type
),
string_of_type
(
get_enum_fc
(
type
)));
}
}
else
{
if
(
phase
==
PHASE_MARSHAL
||
phase
==
PHASE_UNMARSHAL
)
print_phase_basetype
(
file
,
indent
,
local_var_prefix
,
phase
,
pass
,
var
,
var
->
name
);
}
/* Note: this goes beyond what MIDL does - it only supports arguments
* with the [range] attribute in Oicf mode */
if
(
phase
==
PHASE_UNMARSHAL
)
{
const
expr_t
*
range_min
;
const
expr_t
*
range_max
;
expr_list_t
*
range_list
=
get_attrp
(
var
->
attrs
,
ATTR_RANGE
);
if
(
!
range_list
)
range_list
=
get_aliaschain_attrp
(
type
,
ATTR_RANGE
);
range_min
=
LIST_ENTRY
(
list_head
(
range_list
),
const
expr_t
,
entry
);
range_max
=
LIST_ENTRY
(
list_next
(
range_list
,
list_head
(
range_list
)),
const
expr_t
,
entry
);
print_file
(
file
,
indent
,
"if ((%s%s < ("
,
local_var_prefix
,
var
->
name
);
write_type_decl
(
file
,
var
->
type
,
NULL
);
fprintf
(
file
,
")0x%lx) || (%s%s > ("
,
range_min
->
cval
,
local_var_prefix
,
var
->
name
);
write_type_decl
(
file
,
var
->
type
,
NULL
);
fprintf
(
file
,
")0x%lx))
\n
"
,
range_max
->
cval
);
print_file
(
file
,
indent
,
"{
\n
"
);
print_file
(
file
,
indent
+
1
,
"RpcRaiseException(RPC_S_INVALID_BOUND);
\n
"
);
print_file
(
file
,
indent
,
"}
\n
"
);
}
break
;
case
TGT_STRUCT
:
switch
(
get_struct_fc
(
type
))
{
...
...
@@ -3543,23 +3653,23 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
case
TGT_POINTER
:
{
const
type_t
*
ref
=
type_pointer_get_ref
(
type
);
if
(
pointer_type
==
RPC_FC_RP
&&
!
is_user_type
(
ref
))
switch
(
type_get_type
(
ref
))
if
(
pointer_type
==
RPC_FC_RP
)
switch
(
typegen_detect_type
(
ref
,
NULL
,
TDT_ALL_TYPES
))
{
case
T
YPE
_BASIC
:
case
T
GT
_BASIC
:
/* base types have known sizes, so don't need a sizing pass
* and don't have any memory to free and so don't need a
* freeing pass */
if
(
phase
==
PHASE_MARSHAL
||
phase
==
PHASE_UNMARSHAL
)
print_phase_basetype
(
file
,
indent
,
local_var_prefix
,
phase
,
pass
,
var
,
var
->
name
);
break
;
case
T
YPE
_ENUM
:
case
T
GT
_ENUM
:
/* base types have known sizes, so don't need a sizing pass
* and don't have any memory to free and so don't need a
* freeing pass */
if
(
phase
==
PHASE_MARSHAL
||
phase
==
PHASE_UNMARSHAL
)
print_phase_function
(
file
,
indent
,
"Pointer"
,
local_var_prefix
,
phase
,
var
,
start_offset
);
break
;
case
T
YPE
_STRUCT
:
case
T
GT
_STRUCT
:
{
const
char
*
struct_type
=
NULL
;
switch
(
get_struct_fc
(
ref
))
...
...
@@ -3605,8 +3715,7 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
}
break
;
}
case
TYPE_UNION
:
case
TYPE_ENCAPSULATED_UNION
:
case
TGT_UNION
:
{
const
char
*
union_type
=
NULL
;
if
(
phase
==
PHASE_FREE
)
...
...
@@ -3625,16 +3734,17 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
phase
,
var
,
start_offset
);
break
;
}
case
TYPE_POINTER
:
case
TYPE_ARRAY
:
case
TGT_STRING
:
case
TGT_POINTER
:
case
TGT_ARRAY
:
case
TGT_RANGE
:
case
TGT_IFACE_POINTER
:
case
TGT_USER_TYPE
:
case
TGT_CTXT_HANDLE
:
case
TGT_CTXT_HANDLE_POINTER
:
print_phase_function
(
file
,
indent
,
"Pointer"
,
local_var_prefix
,
phase
,
var
,
start_offset
);
break
;
case
TYPE_VOID
:
case
TYPE_ALIAS
:
case
TYPE_MODULE
:
case
TYPE_COCLASS
:
case
TYPE_FUNCTION
:
case
TYPE_INTERFACE
:
case
TGT_INVALID
:
assert
(
0
);
break
;
}
...
...
@@ -3858,6 +3968,7 @@ void assign_stub_out_args( FILE *file, int indent, const var_t *func, const char
case
TGT_BASIC
:
case
TGT_ENUM
:
case
TGT_POINTER
:
case
TGT_RANGE
:
print_file
(
file
,
indent
,
"%s_W%u = 0;
\n
"
,
local_var_prefix
,
i
);
break
;
case
TGT_STRUCT
:
...
...
tools/widl/typegen.h
View file @
2b3659f3
...
...
@@ -56,6 +56,7 @@ enum typegen_type
TGT_ENUM
,
TGT_STRUCT
,
TGT_UNION
,
TGT_RANGE
,
};
typedef
int
(
*
type_pred_t
)(
const
type_t
*
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment