Dan Hipschman : widl: Improve pointer null checking logic.

Alexandre Julliard julliard at wine.codeweavers.com
Sat Aug 12 06:10:41 CDT 2006


Module: wine
Branch: master
Commit: 9e49a8d2f2465030b1502031a8201354fa04f11d
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=9e49a8d2f2465030b1502031a8201354fa04f11d

Author: Dan Hipschman <dsh at linux.ucla.edu>
Date:   Fri Aug 11 17:33:40 2006 -0700

widl: Improve pointer null checking logic.

---

 tools/widl/client.c    |   22 +++++++--------------
 tools/widl/proxy.c     |   50 +++++++++++++++++++++++++++++++++++++++++++++---
 tools/widl/widltypes.h |    2 ++
 3 files changed, 56 insertions(+), 18 deletions(-)

diff --git a/tools/widl/client.c b/tools/widl/client.c
index 79a4283..267bbfe 100644
--- a/tools/widl/client.c
+++ b/tools/widl/client.c
@@ -83,7 +83,6 @@ static void print_message_buffer_size(co
 static void check_pointers(const func_t *func)
 {
     var_t *var;
-    int pointer_type;
 
     if (!func->args)
         return;
@@ -92,21 +91,14 @@ static void check_pointers(const func_t 
     while (NEXT_LINK(var)) var = NEXT_LINK(var);
     while (var)
     {
-        pointer_type = get_attrv(var->attrs, ATTR_POINTERTYPE);
-        if (!pointer_type)
-            pointer_type = RPC_FC_RP;
-
-        if (pointer_type == RPC_FC_RP)
+        if (is_pointer(var) && cant_be_null(var))
         {
-            if (var->ptr_level >= 1)
-            {
-                print_client("if (!%s)\n", var->name);
-                print_client("{\n");
-                indent++;
-                print_client("RpcRaiseException(RPC_X_NULL_REF_POINTER);\n");
-                indent--;
-                print_client("}\n\n");
-            }
+            print_client("if (!%s)\n", var->name);
+            print_client("{\n");
+            indent++;
+            print_client("RpcRaiseException(RPC_X_NULL_REF_POINTER);\n");
+            indent--;
+            print_client("}\n\n");
         }
 
         var = PREV_LINK(var);
diff --git a/tools/widl/proxy.c b/tools/widl/proxy.c
index 5750159..9bba5c5 100644
--- a/tools/widl/proxy.c
+++ b/tools/widl/proxy.c
@@ -181,20 +181,64 @@ static void clear_output_vars( var_t *ar
   }
 }
 
-static int is_pointer(var_t *arg)
+int is_pointer(var_t *arg)
 {
   if (arg->ptr_level)
     return 1;
-  if (arg->type->type == RPC_FC_FP )
+
+  switch (ref_type(arg->type))
+  {
+  case RPC_FC_RP:
+  case RPC_FC_C_CSTRING:
+  case RPC_FC_C_WSTRING:
+  case RPC_FC_FP:
+  case RPC_FC_OP:
+  case RPC_FC_UP:
     return 1;
+  }
+
   return 0;
 }
 
+int cant_be_null(var_t *v)
+{
+  /* Search backwards for the most recent pointer attribute.  */
+  const attr_t *attrs = v->attrs;
+  const type_t *type = v->type;
+
+  if (! attrs && type)
+  {
+    attrs = type->attrs;
+    type = type->ref;
+  }
+
+  while (attrs)
+  {
+    int t = get_attrv(attrs, ATTR_POINTERTYPE);
+
+    if (t == RPC_FC_FP || t == RPC_FC_OP || t == RPC_FC_UP)
+      return 0;
+
+    if (t == RPC_FC_RP)
+      return 1;
+
+    if (type)
+    {
+      attrs = type->attrs;
+      type = type->ref;
+    }
+    else
+      attrs = NULL;
+  }
+
+  return 1;                             /* Default is RPC_FC_RP.  */
+}
+
 static void proxy_check_pointers( var_t *arg )
 {
   END_OF_LIST(arg);
   while (arg) {
-    if (is_pointer(arg)) {
+    if (is_pointer(arg) && cant_be_null(arg)) {
         print_proxy( "if(!%s)\n", arg->name );
         indent++;
         print_proxy( "RpcRaiseException(RPC_X_NULL_REF_POINTER);\n");
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
index 926a3e2..d39def3 100644
--- a/tools/widl/widltypes.h
+++ b/tools/widl/widltypes.h
@@ -299,5 +299,7 @@ struct _typelib_t {
 
 /* Get the actual type field for a type (chase down typedef references).  */
 unsigned char ref_type(const type_t *type);
+int is_pointer(var_t *v);
+int cant_be_null(var_t *v);
 
 #endif




More information about the wine-cvs mailing list