Sync to wine-1.1.1 (Patch 2 of 10):
[reactos.git] / reactos / tools / widl / typegen.c
index f89f13f..70036a4 100644 (file)
@@ -1437,6 +1437,14 @@ static int write_varying_array_pointer_descriptions(
             if (offset_in_memory && offset_in_buffer)
             {
                 size_t padding;
+
+                if (is_array(v->type) && v->type->length_is)
+                {
+                    *offset_in_buffer = ROUND_SIZE(*offset_in_buffer, 4);
+                    /* skip over variance and offset in buffer */
+                    *offset_in_buffer += 8;
+                }
+
                 align = 0;
                 type_memsize(v->type, &align);
                 padding = ROUNDING(*offset_in_memory, align);
@@ -1470,19 +1478,13 @@ static void write_pointer_description(FILE *file, type_t *type,
 {
     size_t offset_in_buffer;
     size_t offset_in_memory;
-    size_t conformance = 0;
-
-    if (type->type == RPC_FC_CVSTRUCT)
-        conformance = 8;
-    else if (type->type == RPC_FC_CSTRUCT || type->type == RPC_FC_CPSTRUCT)
-        conformance = 4;
 
     /* pass 1: search for single instance of a pointer (i.e. don't descend
      * into arrays) */
     if (!is_array(type))
     {
         offset_in_memory = 0;
-        offset_in_buffer = conformance;
+        offset_in_buffer = 0;
         write_no_repeat_pointer_descriptions(
             file, type,
             &offset_in_memory, &offset_in_buffer, typestring_offset);
@@ -1490,7 +1492,7 @@ static void write_pointer_description(FILE *file, type_t *type,
 
     /* pass 2: search for pointers in fixed arrays */
     offset_in_memory = 0;
-    offset_in_buffer = conformance;
+    offset_in_buffer = 0;
     write_fixed_array_pointer_descriptions(
         file, NULL, type,
         &offset_in_memory, &offset_in_buffer, typestring_offset);
@@ -1512,7 +1514,7 @@ static void write_pointer_description(FILE *file, type_t *type,
 
     /* pass 4: search for pointers in varying arrays */
     offset_in_memory = 0;
-    offset_in_buffer = conformance;
+    offset_in_buffer = 0;
     write_varying_array_pointer_descriptions(
             file, NULL, type,
             &offset_in_memory, &offset_in_buffer, typestring_offset);
@@ -2032,6 +2034,34 @@ static size_t write_union_tfs(FILE *file, type_t *type, unsigned int *tfsoff)
             error("union switch type must be an integer, char, or enum\n");
         }
     }
+    else if (is_attr(type->attrs, ATTR_SWITCHTYPE))
+    {
+        static const expr_t dummy_expr;  /* FIXME */
+        const type_t *st = get_attrp(type->attrs, ATTR_SWITCHTYPE);
+
+        switch (st->type)
+        {
+        case RPC_FC_CHAR:
+        case RPC_FC_SMALL:
+        case RPC_FC_USMALL:
+        case RPC_FC_SHORT:
+        case RPC_FC_USHORT:
+        case RPC_FC_LONG:
+        case RPC_FC_ULONG:
+        case RPC_FC_ENUM16:
+        case RPC_FC_ENUM32:
+            print_file(file, 2, "0x%x,\t/* %s */\n", type->type, string_of_type(type->type));
+            print_file(file, 2, "0x%x,\t/* Switch type= %s */\n",
+                       st->type, string_of_type(st->type));
+            *tfsoff += 2;
+            break;
+        default:
+            error("union switch type must be an integer, char, or enum\n");
+        }
+
+        *tfsoff += write_conf_or_var_desc(file, NULL, *tfsoff, st, &dummy_expr );
+    }
+
     print_file(file, 2, "NdrFcShort(0x%x),\t/* %d */\n", size, size);
     print_file(file, 2, "NdrFcShort(0x%x),\t/* %d */\n", nbranch, nbranch);
     *tfsoff += 4;
@@ -3091,7 +3121,7 @@ size_t get_size_procformatstring(const statement_list_t *stmts, type_pred_t pred
             size += get_size_procformatstring(stmt->u.lib->stmts, pred) - 1;
             continue;
         }
-        else if (stmt->type != STMT_TYPE && stmt->u.type->type != RPC_FC_IP)
+        else if (stmt->type != STMT_TYPE || stmt->u.type->type != RPC_FC_IP)
             continue;
 
         iface = stmt->u.type;