# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: a.rottmann@gmx.at-20081011220718-2lw8wzdk5rxu7a3y
# target_branch: http://bzr-playground.gnome.org/gobject-\
#   introspection/trunk
# testament_sha1: 1a93d7bdf42d4e4f444866b11d6067563b477831
# timestamp: 2008-10-12 00:07:40 +0200
# base_revision_id: svn-v3-trunk0:f5b5f685-ed25-0410-8673-\
#   93f92c561f07:trunk:668
# 
# Begin patch
=== modified file 'ChangeLog'
--- ChangeLog	2008-10-11 20:32:19 +0000
+++ ChangeLog	2008-10-11 22:07:18 +0000
@@ -1,3 +1,8 @@
+2008-10-12  Andreas Rottmann  <a.rottmann@gmx.at>
+
+	* tests/scanner/Makefile.am (%.typelib): Set PYTHONPATH
+	appropriatly when invoking the scanner.
+
 2008-10-11  Lucas Rocha  <lucasr@gnome.org>
 
 	Bug 552370: add one more test for unsigned as a type, not as
@@ -9,6 +14,56 @@
 
 2008-10-11  Andreas Rottmann  <a.rottmann@gmx.at>
 
+	* tests/scanner/utility.h (UtilityTaggedValue): Make the union
+	member anonymous.
+	(UtilityByte): New union typedef with an unnamed struct in it.
+
+	* giscanner/transformer.py (Transformer._create_struct): Create
+	unnamed structs for symbols with a None ident.
+	(Transformer._create_union): Likewise.
+
+	* giscanner/girwriter.py (GIRWriter._write_record): Allow name
+	being None.
+	(GIRWriter._write_union): Likewise.
+
+	* girepository/girparser.c (start_struct): Allow a NULL name for
+	non-toplevel structs.
+	(start_union): Likewise.
+
+	* tests/scanner/utility.h (UtilityTaggedValue): New struct
+	typedef, which has a nested union member.
+	* tests/scanner/utility-expected.gir: Adapted.
+
+	* giscanner/transformer.py (Transformer._create_member): Create
+	struct/union members if appropriate.
+	(Transformer._create_struct, Transformer._create_union): Allow for
+	structs/unions without a C type.
+
+	* giscanner/glibtransformer.py (GLibTransformer._resolve_field):
+	We don't need to resolve non-typef'd
+	(GLibTransformer._resolve_field): Add cases for non-typedef'd
+	struct/union "fields".
+
+	* giscanner/girwriter.py (GIRWriter._write_record): Allow for
+	records without a C type.
+	(GIRWriter._write_field): structs and unions may appear in places
+	where fields do.
+
+	* girepository/girparser.c (ParseContext): Removed member
+	current_node, added node_stack instead.
+	(CURRENT_NODE): New macro, returns the current node (top of
+	node_stack).
+	(VALID_UNION_STATE, VALID_STRUCT_STATE): New predicate macros,
+	return true if the state passed is a valid point for a union and
+	struct node, respectively.
+	(pop_node, push_node): New functions; pop or push a node from
+	node_stack.
+	(state_switch_end_struct_or_union): New function, switches the
+	state at the end of a struct/union.
+	Rest of the file adapted to tehse changes.
+
+2008-10-09  Andreas Rottmann  <a.rottmann@gmx.at>
+
 	Bug 555712: Struct and union issues
 
 	* giscanner/scannerparser.y (struct_declarator): Use information

=== modified file 'girepository/girparser.c'
--- girepository/girparser.c	2008-10-02 13:07:42 +0000
+++ girepository/girparser.c	2008-10-11 20:49:39 +0000
@@ -77,7 +77,7 @@
 
   const char *namespace;
   GIrModule *current_module;
-  GIrNode *current_node;
+  GSList *node_stack;
   GIrNode *current_typed;
   gboolean is_varargs;
   GList *type_stack;
@@ -85,6 +85,12 @@
   int type_depth;
 };
 
+#define VALID_UNION_STATE(state) ((state) == STATE_NAMESPACE || \
+                                  (state) == STATE_UNION || \
+                                  (state) == STATE_STRUCT)
+#define VALID_STRUCT_STATE(state) VALID_UNION_STATE(state)
+#define CURRENT_NODE(ctx) ((GIrNode *)((ctx)->node_stack->data))
+
 static gboolean
 start_alias (GMarkupParseContext *context,
 	     const gchar         *element_name,
@@ -223,6 +229,27 @@
   ctx->state = newstate;
 }
 
+static GIrNode *
+pop_node (ParseContext *ctx)
+{
+  g_assert (ctx->node_stack != 0);
+  
+  GSList *top = ctx->node_stack;
+  GIrNode *node = top->data;
+  
+  g_debug ("popping node %d %s", node->type, node->name);
+  ctx->node_stack = top->next;
+  g_slist_free_1 (top);
+  return node;
+}
+
+static void
+push_node (ParseContext *ctx, GIrNode *node)
+{
+  g_debug ("pushing node %d %s", node->type, node->name);
+  ctx->node_stack = g_slist_prepend (ctx->node_stack, node);
+}
+
 static GIrNodeType * parse_type_internal (const gchar *str, gchar **next, gboolean in_glib,
 					  gboolean in_gobject);
 
@@ -516,7 +543,7 @@
   else
     boxed->deprecated = FALSE;
 	  
-  ctx->current_node = (GIrNode *)boxed;
+  push_node (ctx, (GIrNode *)boxed);
   ctx->current_module->entries = 
     g_list_append (ctx->current_module->entries, boxed);
   
@@ -608,20 +635,20 @@
 	((GIrNode *)function)->type = G_IR_NODE_CALLBACK;
     }
 	  
-  if (ctx->current_node == NULL)
+  if (ctx->node_stack == NULL)
     {
       ctx->current_module->entries = 
 	g_list_append (ctx->current_module->entries, function);	      
     }
   else
-    switch (ctx->current_node->type)
+    switch (CURRENT_NODE (ctx)->type)
       {
       case G_IR_NODE_INTERFACE:
       case G_IR_NODE_OBJECT:
 	{
 	  GIrNodeInterface *iface;
 	  
-	  iface = (GIrNodeInterface *)ctx->current_node;
+	  iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
 	  iface->members = g_list_append (iface->members, function);
 	}
 	break;
@@ -629,7 +656,7 @@
 	{
 	  GIrNodeBoxed *boxed;
 	  
-	  boxed = (GIrNodeBoxed *)ctx->current_node;
+	  boxed = (GIrNodeBoxed *)CURRENT_NODE (ctx);
 	  boxed->members = g_list_append (boxed->members, function);
 	}
 	break;
@@ -637,14 +664,14 @@
 	{
 	  GIrNodeStruct *struct_;
 	  
-	  struct_ = (GIrNodeStruct *)ctx->current_node;
+	  struct_ = (GIrNodeStruct *)CURRENT_NODE (ctx);
 	  struct_->members = g_list_append (struct_->members, function);		}
 	break;
       case G_IR_NODE_UNION:
 	{
 	  GIrNodeUnion *union_;
 	  
-	  union_ = (GIrNodeUnion *)ctx->current_node;
+	  union_ = (GIrNodeUnion *)CURRENT_NODE (ctx);
 	  union_->members = g_list_append (union_->members, function);
 	}
 	break;
@@ -652,7 +679,7 @@
 	g_assert_not_reached ();
       }
   
-  ctx->current_node = (GIrNode *)function;
+  push_node (ctx, (GIrNode *)function);
   state_switch (ctx, STATE_FUNCTION);
   
   return TRUE;
@@ -761,14 +788,14 @@
 	  
   ((GIrNode *)param)->name = g_strdup (name);
 	  
-  switch (ctx->current_node->type)
+  switch (CURRENT_NODE (ctx)->type)
     {
     case G_IR_NODE_FUNCTION:
     case G_IR_NODE_CALLBACK:
       {
 	GIrNodeFunction *func;
 
-	func = (GIrNodeFunction *)ctx->current_node;
+	func = (GIrNodeFunction *)CURRENT_NODE (ctx);
 	func->parameters = g_list_append (func->parameters, param);
       }
       break;
@@ -776,7 +803,7 @@
       {
 	GIrNodeSignal *signal;
 
-	signal = (GIrNodeSignal *)ctx->current_node;
+	signal = (GIrNodeSignal *)CURRENT_NODE (ctx);
 	signal->parameters = g_list_append (signal->parameters, param);
       }
       break;
@@ -784,7 +811,7 @@
       {
 	GIrNodeVFunc *vfunc;
 		
-	vfunc = (GIrNodeVFunc *)ctx->current_node;
+	vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx);
 	vfunc->parameters = g_list_append (vfunc->parameters, param);
       }
       break;
@@ -862,13 +889,13 @@
   else
     field->offset = 0;
   
-  switch (ctx->current_node->type)
+  switch (CURRENT_NODE (ctx)->type)
     {
     case G_IR_NODE_OBJECT:
       {
 	GIrNodeInterface *iface;
 	
-	iface = (GIrNodeInterface *)ctx->current_node;
+	iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
 	iface->members = g_list_append (iface->members, field);
 	state_switch (ctx, STATE_CLASS_FIELD);
       }
@@ -877,7 +904,7 @@
       {
 	GIrNodeInterface *iface;
 	
-	iface = (GIrNodeInterface *)ctx->current_node;
+	iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
 	iface->members = g_list_append (iface->members, field);
 	state_switch (ctx, STATE_INTERFACE_FIELD);
       }
@@ -886,7 +913,7 @@
       {
 	GIrNodeBoxed *boxed;
 	
-	boxed = (GIrNodeBoxed *)ctx->current_node;
+	boxed = (GIrNodeBoxed *)CURRENT_NODE (ctx);
 		boxed->members = g_list_append (boxed->members, field);
 		state_switch (ctx, STATE_BOXED_FIELD);
       }
@@ -895,7 +922,7 @@
       {
 	GIrNodeStruct *struct_;
 	
-	struct_ = (GIrNodeStruct *)ctx->current_node;
+	struct_ = (GIrNodeStruct *)CURRENT_NODE (ctx);
 	struct_->members = g_list_append (struct_->members, field);
 	state_switch (ctx, STATE_STRUCT_FIELD);
       }
@@ -904,7 +931,7 @@
       {
 	GIrNodeUnion *union_;
 	
-	union_ = (GIrNodeUnion *)ctx->current_node;
+	union_ = (GIrNodeUnion *)CURRENT_NODE (ctx);
 	union_->members = g_list_append (union_->members, field);
 	if (branch)
 	  {
@@ -1020,7 +1047,7 @@
 	  else
 	    enum_->deprecated = FALSE;
 
-	  ctx->current_node = (GIrNode *) enum_;
+	  push_node (ctx, (GIrNode *) enum_);
 	  ctx->current_module->entries = 
 	    g_list_append (ctx->current_module->entries, enum_);	      
 	  
@@ -1086,7 +1113,7 @@
 	  else
 	    property->construct_only = FALSE;
 
-	  iface = (GIrNodeInterface *)ctx->current_node;
+	  iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
 	  iface->members = g_list_append (iface->members, property);
 
 	  if (ctx->state == STATE_CLASS)
@@ -1162,7 +1189,7 @@
 	  else
 	    value_->deprecated = FALSE;
 
-	  enum_ = (GIrNodeEnum *)ctx->current_node;
+	  enum_ = (GIrNodeEnum *)CURRENT_NODE (ctx);
 	  enum_->values = g_list_append (enum_->values, value_);
 	}
       
@@ -1214,7 +1241,7 @@
 
 	  if (ctx->state == STATE_NAMESPACE)
 	    {
-	      ctx->current_node = (GIrNode *) constant;
+	      push_node (ctx, (GIrNode *) constant);
 	      ctx->current_module->entries = 
 		g_list_append (ctx->current_module->entries, constant);
 	    }
@@ -1222,7 +1249,7 @@
 	    {
 	      GIrNodeInterface *iface;
 
-	      iface = (GIrNodeInterface *)ctx->current_node;
+	      iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
 	      iface->members = g_list_append (iface->members, constant);
 	    }
 
@@ -1290,7 +1317,7 @@
 	  else
 	    domain->deprecated = FALSE;
 
-	  ctx->current_node = (GIrNode *) domain;
+	  push_node (ctx, (GIrNode *) domain);
 	  ctx->current_module->entries = 
 	    g_list_append (ctx->current_module->entries, domain);
 
@@ -1342,7 +1369,7 @@
 	  else
 	    iface->deprecated = FALSE;
 	  
-	  ctx->current_node = (GIrNode *) iface;
+	  push_node (ctx, (GIrNode *) iface);
 	  ctx->current_module->entries = 
 	    g_list_append (ctx->current_module->entries, iface);	      
 	  
@@ -1398,7 +1425,7 @@
 	  else
 	    iface->deprecated = FALSE;
 	  
-	  ctx->current_node = (GIrNode *) iface;
+	  push_node (ctx, (GIrNode *) iface);
 	  ctx->current_module->entries = 
 	    g_list_append (ctx->current_module->entries, iface);	      
 	  
@@ -1454,18 +1481,18 @@
       ctx->type_depth = 1;
       if (is_varargs)
 	{
-	  switch (ctx->current_node->type)
+	  switch (CURRENT_NODE (ctx)->type)
 	    {
 	    case G_IR_NODE_FUNCTION:
 	    case G_IR_NODE_CALLBACK:
 	      {
-		GIrNodeFunction *func = (GIrNodeFunction *)ctx->current_node;
+		GIrNodeFunction *func = (GIrNodeFunction *)CURRENT_NODE (ctx);
 		func->is_varargs = TRUE;
 	      }
 	      break;
 	    case G_IR_NODE_VFUNC:
 	      {
-		GIrNodeVFunc *vfunc = (GIrNodeVFunc *)ctx->current_node;
+		GIrNodeVFunc *vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx);
 		vfunc->is_varargs = TRUE;
 	      }
 	      break;
@@ -1585,7 +1612,7 @@
       }
       break;
     default:
-      g_printerr("current node is %d\n", ctx->current_node->type);
+      g_printerr("current node is %d\n", CURRENT_NODE (ctx)->type);
       g_assert_not_reached ();
     }
   g_list_free (ctx->type_parameters);
@@ -1668,24 +1695,24 @@
 
       state_switch (ctx, STATE_FUNCTION_RETURN);
 
-      switch (ctx->current_node->type)
+      switch (CURRENT_NODE (ctx)->type)
 	{
 	case G_IR_NODE_FUNCTION:
 	case G_IR_NODE_CALLBACK:
 	  {
-	    GIrNodeFunction *func = (GIrNodeFunction *)ctx->current_node;
+	    GIrNodeFunction *func = (GIrNodeFunction *)CURRENT_NODE (ctx);
 	    func->result = param;
 	  }
 	  break;
 	case G_IR_NODE_SIGNAL:
 	  {
-	    GIrNodeSignal *signal = (GIrNodeSignal *)ctx->current_node;
+	    GIrNodeSignal *signal = (GIrNodeSignal *)CURRENT_NODE (ctx);
 	    signal->result = param;
 	  }
 	  break;
 	case G_IR_NODE_VFUNC:
 	  {
-	    GIrNodeVFunc *vfunc = (GIrNodeVFunc *)ctx->current_node;
+	    GIrNodeVFunc *vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx);
 	    vfunc->result = param;
 	  }
 	  break;
@@ -1723,7 +1750,7 @@
       return FALSE;
     }
       
-  iface = (GIrNodeInterface *)ctx->current_node;
+  iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
   iface->interfaces = g_list_append (iface->interfaces, g_strdup (name));
 
   return TRUE;
@@ -1799,10 +1826,10 @@
 	  else
 	    signal->has_class_closure = FALSE;
 
-	  iface = (GIrNodeInterface *)ctx->current_node;
+	  iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
 	  iface->members = g_list_append (iface->members, signal);
 
-	  ctx->current_node = (GIrNode *)signal;
+	  push_node (ctx, (GIrNode *)signal);
 	  state_switch (ctx, STATE_FUNCTION);
 	}
       
@@ -1877,10 +1904,10 @@
 	  else
 	    vfunc->offset = 0;
 
-	  iface = (GIrNodeInterface *)ctx->current_node;
+	  iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
 	  iface->members = g_list_append (iface->members, vfunc);
 
-	  ctx->current_node = (GIrNode *)vfunc;
+	  push_node (ctx, (GIrNode *)vfunc);
 	  state_switch (ctx, STATE_FUNCTION);
 	}
       
@@ -1898,8 +1925,8 @@
 	      ParseContext       *ctx,
 	      GError             **error)
 {
-  if (strcmp (element_name, "record") == 0 && 
-      ctx->state == STATE_NAMESPACE)
+  if (strcmp (element_name, "record") == 0
+      && VALID_STRUCT_STATE (ctx->state))
     {
       const gchar *name;
       const gchar *deprecated;
@@ -1912,7 +1939,7 @@
       gtype_name = find_attribute ("glib:type-name", attribute_names, attribute_values);
       gtype_init = find_attribute ("glib:get-type", attribute_names, attribute_values);
 
-      if (name == NULL)
+      if (name == NULL && ctx->node_stack == NULL)
 	{
 	  MISSING_ATTRIBUTE (context, error, element_name, "name");
 	  return FALSE;
@@ -1930,7 +1957,7 @@
 
       struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT);
       
-      ((GIrNode *)struct_)->name = g_strdup (name);
+      ((GIrNode *)struct_)->name = g_strdup (name ? name : "");
       if (deprecated)
 	struct_->deprecated = TRUE;
       else
@@ -1938,10 +1965,11 @@
 
       struct_->gtype_name = g_strdup (gtype_name);
       struct_->gtype_init = g_strdup (gtype_init);
-      
-      ctx->current_node = (GIrNode *)struct_;
-      ctx->current_module->entries = 
-	g_list_append (ctx->current_module->entries, struct_);
+
+      if (ctx->node_stack == NULL)
+          ctx->current_module->entries = 
+            g_list_append (ctx->current_module->entries, struct_);
+      push_node (ctx, (GIrNode *)struct_);
       
       state_switch (ctx, STATE_STRUCT);
       return TRUE;
@@ -1958,8 +1986,8 @@
 	     ParseContext       *ctx,
 	     GError             **error)
 {
-  if (strcmp (element_name, "union") == 0 && 
-      ctx->state == STATE_NAMESPACE)
+  if (strcmp (element_name, "union") == 0 &&
+      VALID_UNION_STATE(ctx->state))
     {
       const gchar *name;
       const gchar *deprecated;
@@ -1971,7 +1999,7 @@
       typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
       typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
       
-      if (name == NULL)
+      if (name == NULL && ctx->node_stack == NULL)
 	MISSING_ATTRIBUTE (context, error, element_name, "name");
       else
 	{
@@ -1979,7 +2007,7 @@
 
 	  union_ = (GIrNodeUnion *) g_ir_node_new (G_IR_NODE_UNION);
 	  
-	  ((GIrNode *)union_)->name = g_strdup (name);
+	  ((GIrNode *)union_)->name = g_strdup (name ? name : "");
 	  union_->gtype_name = g_strdup (typename);
 	  union_->gtype_init = g_strdup (typeinit);
 	  if (deprecated)
@@ -1987,9 +2015,10 @@
 	  else
 	    union_->deprecated = FALSE;
 
-	  ctx->current_node = (GIrNode *)union_;
-	  ctx->current_module->entries = 
-	    g_list_append (ctx->current_module->entries, union_);
+          if (ctx->node_stack == NULL)
+            ctx->current_module->entries = 
+              g_list_append (ctx->current_module->entries, union_);
+          push_node (ctx, (GIrNode *)union_);
 	  
 	  state_switch (ctx, STATE_UNION);
 	}
@@ -2019,9 +2048,9 @@
       else if (offset == NULL)
 	MISSING_ATTRIBUTE (context, error, element_name, "offset");
 	{
-	  ((GIrNodeUnion *)ctx->current_node)->discriminator_type 
+	  ((GIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_type 
 	    = parse_type (ctx, type);
-	  ((GIrNodeUnion *)ctx->current_node)->discriminator_offset 
+	  ((GIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_offset 
 	    = atoi (offset);
 	}
       
@@ -2165,7 +2194,7 @@
 	    {  
 	      GIrNodeInterface *iface;
 
-	      iface = (GIrNodeInterface *)ctx->current_node;
+	      iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
 	      iface ->prerequisites = g_list_append (iface->prerequisites, g_strdup (name));
 	    }
 
@@ -2421,6 +2450,39 @@
 }
 
 static gboolean
+state_switch_end_struct_or_union (GMarkupParseContext *context,
+                                  ParseContext *ctx,
+                                  const gchar *element_name,
+                                  GError **error)
+{
+  pop_node (ctx);
+  if (ctx->node_stack == NULL)
+    {
+      state_switch (ctx, STATE_NAMESPACE);
+    }
+  else 
+    {
+      if (CURRENT_NODE (ctx)->type == G_IR_NODE_STRUCT)
+        state_switch (ctx, STATE_STRUCT);
+      else if (CURRENT_NODE (ctx)->type == G_IR_NODE_UNION)
+        state_switch (ctx, STATE_UNION);
+      else
+        {
+          int line_number, char_number;
+          g_markup_parse_context_get_position (context, &line_number, &char_number);
+          g_set_error (error,
+                       G_MARKUP_ERROR,
+                       G_MARKUP_ERROR_INVALID_CONTENT,
+                       "Unexpected end tag '%s' on line %d char %d",
+                       element_name,
+                       line_number, char_number);
+          return FALSE;
+        }
+    }
+  return TRUE;
+}
+
+static gboolean
 require_end_element (GMarkupParseContext *context,
 		     ParseContext        *ctx,
 		     const char          *expected_name,
@@ -2500,28 +2562,22 @@
 
     case STATE_FUNCTION:
       {
- 	gboolean current_is_toplevel;
-	GList *last = g_list_last (ctx->current_module->entries);
-	
-	current_is_toplevel = ctx->current_node == last->data;	
-
-	if (current_is_toplevel)
+        pop_node (ctx);
+	if (ctx->node_stack == NULL)
 	  {
-	    ctx->current_node = NULL;
 	    state_switch (ctx, STATE_NAMESPACE);
 	  }
 	else 
-	  { 
-	    ctx->current_node = g_list_last (ctx->current_module->entries)->data;
-	    if (ctx->current_node->type == G_IR_NODE_INTERFACE)
+	  {
+	    if (CURRENT_NODE (ctx)->type == G_IR_NODE_INTERFACE)
 	      state_switch (ctx, STATE_INTERFACE);
-	    else if (ctx->current_node->type == G_IR_NODE_OBJECT) 
+	    else if (CURRENT_NODE (ctx)->type == G_IR_NODE_OBJECT) 
 	      state_switch (ctx, STATE_CLASS);
-	    else if (ctx->current_node->type == G_IR_NODE_BOXED)
+	    else if (CURRENT_NODE (ctx)->type == G_IR_NODE_BOXED)
 	      state_switch (ctx, STATE_BOXED);
-	    else if (ctx->current_node->type == G_IR_NODE_STRUCT)
+	    else if (CURRENT_NODE (ctx)->type == G_IR_NODE_STRUCT)
 	      state_switch (ctx, STATE_STRUCT);
-	    else if (ctx->current_node->type == G_IR_NODE_UNION)
+	    else if (CURRENT_NODE (ctx)->type == G_IR_NODE_UNION)
 	      state_switch (ctx, STATE_UNION);
 	    else
 	      {
@@ -2559,7 +2615,7 @@
     case STATE_CLASS:
       if (require_end_element (context, ctx, "class", element_name, error))
 	{
-	  ctx->current_node = NULL;
+	  pop_node (ctx);
 	  state_switch (ctx, STATE_NAMESPACE);
 	}
       break;
@@ -2567,7 +2623,7 @@
     case STATE_ERRORDOMAIN:
       if (require_end_element (context, ctx, "errordomain", element_name, error))
 	{
-	  ctx->current_node = NULL;
+	  pop_node (ctx);
 	  state_switch (ctx, STATE_NAMESPACE);
 	}
       break;
@@ -2593,7 +2649,7 @@
     case STATE_INTERFACE:
       if (require_end_element (context, ctx, "interface", element_name, error))
 	{
-	  ctx->current_node = NULL;
+	  pop_node (ctx);
 	  state_switch (ctx, STATE_NAMESPACE);
 	}
       break;
@@ -2605,7 +2661,7 @@
 					    element_name, error, "enumeration", 
 					    "bitfield", NULL))
 	{
-	  ctx->current_node = NULL;
+	  pop_node (ctx);
 	  state_switch (ctx, STATE_NAMESPACE);
 	}
       break;
@@ -2613,7 +2669,7 @@
     case STATE_BOXED:
       if (require_end_element (context, ctx, "glib:boxed", element_name, error))
 	{
-	  ctx->current_node = NULL;
+	  pop_node (ctx);
 	  state_switch (ctx, STATE_NAMESPACE);
 	}
       break;
@@ -2639,8 +2695,7 @@
     case STATE_STRUCT:
       if (require_end_element (context, ctx, "record", element_name, error))
 	{
-	  ctx->current_node = NULL;
-	  state_switch (ctx, STATE_NAMESPACE);
+	  state_switch_end_struct_or_union (context, ctx, element_name, error);
 	}
       break;
 
@@ -2656,8 +2711,7 @@
     case STATE_UNION:
       if (require_end_element (context, ctx, "union", element_name, error))
 	{
-	  ctx->current_node = NULL;
-	  state_switch (ctx, STATE_NAMESPACE);
+	  state_switch_end_struct_or_union (context, ctx, element_name, error);
 	}
       break;
     case STATE_IMPLEMENTS:
@@ -2677,7 +2731,7 @@
 	break;
       if (require_end_element (context, ctx, "constant", element_name, error))
 	{
-	  ctx->current_node = NULL;
+	  pop_node (ctx);
 	  switch (ctx->state)
 	    {
 	    case STATE_NAMESPACE_CONSTANT:

=== modified file 'giscanner/girwriter.py'
--- giscanner/girwriter.py	2008-10-11 20:16:57 +0000
+++ giscanner/girwriter.py	2008-10-11 22:07:18 +0000
@@ -281,8 +281,11 @@
             self._write_method(method)
 
     def _write_record(self, record):
-        attrs = [('name', record.name),
-                 ('c:type', record.symbol)]
+        attrs = []
+        if record.name is not None:
+            attrs.append(('name', record.name))
+        if record.symbol is not None: # the record might be anonymous
+            attrs.append(('c:type', record.symbol))
         self._append_deprecated(record, attrs)
         if isinstance(record, GLibBoxed):
             attrs.extend(self._boxed_attrs(record))
@@ -294,8 +297,11 @@
                 self._write_boxed_ctors_methods(record)
 
     def _write_union(self, union):
-        attrs = [('name', union.name),
-                 ('c:type', union.symbol)]
+        attrs = []
+        if union.name is not None:
+            attrs.append(('name', union.name))
+        if union.symbol is not None: # the union might be anonymous
+            attrs.append(('c:type', union.symbol))
         self._append_deprecated(union, attrs)
         if isinstance(union, GLibBoxed):
             attrs.extend(self._boxed_attrs(union))
@@ -313,13 +319,16 @@
 
         if isinstance(field, Callback):
             self._write_callback(field)
-            return
-
-        attrs = [('name', field.name)]
-        if field.bits:
-            attrs.append(('bits', str(field.bits)))
-        with self.tagcontext('field', attrs):
-            self._write_type(field.type)
+        elif isinstance(field, Struct):
+            self._write_record(field)
+        elif isinstance(field, Union):
+            self._write_union(field)
+        else:
+            attrs = [('name', field.name)]
+            if field.bits:
+                attrs.append(('bits', str(field.bits)))
+            with self.tagcontext('field', attrs):
+                self._write_type(field.type)
 
     def _write_signal(self, signal):
         attrs = [('name', signal.name)]

=== modified file 'giscanner/glibtransformer.py'
--- giscanner/glibtransformer.py	2008-10-03 18:30:16 +0000
+++ giscanner/glibtransformer.py	2008-10-11 19:23:40 +0000
@@ -782,8 +782,12 @@
     def _resolve_field(self, field):
         if isinstance(field, Callback):
             self._resolve_function(field)
-            return
-        field.type = self._resolve_param_type(field.type)
+        elif isinstance(field, Struct): # non-typedef'd struct
+            self._resolve_struct(field)
+        elif isinstance(field, Union): # non-typedef'd union
+            self._resolve_union(field)
+        else:
+            field.type = self._resolve_param_type(field.type)
 
     def _resolve_alias(self, alias):
         alias.target = self._resolve_type_name(alias.target, alias.target)

=== modified file 'giscanner/transformer.py'
--- giscanner/transformer.py	2008-10-11 20:16:57 +0000
+++ giscanner/transformer.py	2008-10-11 22:07:18 +0000
@@ -295,10 +295,15 @@
                 child, options.get(child.ident, []))
 
     def _create_member(self, symbol):
-        ctype = symbol.base_type.type
+        base_type = symbol.base_type
+        ctype = base_type.type
         if (ctype == CTYPE_POINTER and
-            symbol.base_type.base_type.type == CTYPE_FUNCTION):
+            base_type.base_type.type == CTYPE_FUNCTION):
             node = self._create_callback(symbol)
+        elif ctype == CTYPE_STRUCT and base_type.name is None:
+            node = self._create_struct(symbol, anonymous=True)
+        elif ctype == CTYPE_UNION and base_type.name is None:
+            node = self._create_union(symbol, anonymous=True)
         else:
             ftype = self._create_type(symbol.base_type)
             node = Field(symbol.ident, ftype, symbol.ident, symbol.const_int)
@@ -428,19 +433,24 @@
         self._create_union(symbol)
         return union
 
-    def _create_struct(self, symbol):
-        struct = self._typedefs_ns.get(symbol.ident, None)
-        if struct is None:
-            # This is a bit of a hack; really we should try
-            # to resolve through the typedefs to find the real
-            # name
-            if symbol.ident.startswith('_'):
-                name = symbol.ident[1:]
-            else:
-                name = symbol.ident
-            name = self.strip_namespace_object(name)
-            name = self.resolve_type_name(name)
-            struct = Struct(name, symbol.ident)
+    def _create_struct(self, symbol, anonymous=False):
+        if symbol.ident is None:
+            # the struct is an anonymous member of another union or a struct
+            assert anonymous
+            struct = Struct(None, None)
+        else:
+            struct = self._typedefs_ns.get(symbol.ident, None)
+            if struct is None:
+                # This is a bit of a hack; really we should try
+                # to resolve through the typedefs to find the real
+                # name
+                if symbol.ident.startswith('_'):
+                    name = symbol.ident[1:]
+                else:
+                    name = symbol.ident
+                name = self.strip_namespace_object(name)
+                name = self.resolve_type_name(name)
+                struct = Struct(name, None if anonymous else symbol.ident)
 
         for child in symbol.base_type.child_list:
             field = self._traverse_one(child)
@@ -449,19 +459,24 @@
 
         return struct
 
-    def _create_union(self, symbol):
-        union = self._typedefs_ns.get(symbol.ident, None)
-        if union is None:
-            # This is a bit of a hack; really we should try
-            # to resolve through the typedefs to find the real
-            # name
-            if symbol.ident.startswith('_'):
-                name = symbol.ident[1:]
-            else:
-                name = symbol.ident
-            name = self.strip_namespace_object(name)
-            name = self.resolve_type_name(name)
-            union = Union(name, symbol.ident)
+    def _create_union(self, symbol, anonymous=False):
+        if symbol.ident is None:
+            # the union is an anonymous member of another union or a struct
+            assert anonymous
+            union = Union(None, None)
+        else:
+            union = self._typedefs_ns.get(symbol.ident, None)
+            if union is None:
+                # This is a bit of a hack; really we should try
+                # to resolve through the typedefs to find the real
+                # name
+                if symbol.ident.startswith('_'):
+                    name = symbol.ident[1:]
+                else:
+                    name = symbol.ident
+                name = self.strip_namespace_object(name)
+                name = self.resolve_type_name(name)
+                union = Union(name, None if anonymous else symbol.ident)
 
         for child in symbol.base_type.child_list:
             field = self._traverse_one(child)

=== modified file 'tests/scanner/Makefile.am'
--- tests/scanner/Makefile.am	2008-09-14 19:33:33 +0000
+++ tests/scanner/Makefile.am	2008-10-11 22:07:18 +0000
@@ -76,7 +76,7 @@
 
 %.typelib: %.gir $(top_builddir)/tools/g-ir-compiler$(EXEEXT) Makefile
 	$(top_builddir)/tools/g-ir-compiler --includedir=. --includedir=$(top_builddir)/gir $< -o $@
-	$(SCANNER) --typelib-xml $< > $<.tmp && mv $<.tmp $<.txml
+	PYTHONPATH=$(top_builddir):$$PYTHONPATH $(CHECK_DEBUG) $(SCANNER) --typelib-xml $< > $<.tmp && mv $<.tmp $<.txml
 
 check-local: pre-check
 check-local: $(CHECKGIRS) $(TYPELIBS)

=== modified file 'tests/scanner/utility-expected.gir'
--- tests/scanner/utility-expected.gir	2008-10-11 20:16:57 +0000
+++ tests/scanner/utility-expected.gir	2008-10-11 22:07:18 +0000
@@ -49,5 +49,34 @@
         <type name="double" c:type="double"/>
       </field>
     </union>
+    <record name="TaggedValue" c:type="UtilityTaggedValue">
+      <field name="tag">
+        <type name="int" c:type="int"/>
+      </field>
+      <union>
+        <field name="v_pointer">
+          <type name="any" c:type="gpointer"/>
+        </field>
+        <field name="v_real">
+          <type name="double" c:type="double"/>
+        </field>
+        <field name="v_integer">
+          <type name="long" c:type="long"/>
+        </field>
+      </union>
+    </record>
+    <union name="Byte" c:type="UtilityByte">
+      <field name="value">
+        <type name="uint8" c:type="guint8"/>
+      </field>
+      <record>
+        <field name="first_nibble" bits="4">
+          <type name="uint8" c:type="guint8"/>
+        </field>
+        <field name="second_nibble" bits="4">
+          <type name="uint8" c:type="guint8"/>
+        </field>
+      </record>
+    </union>
   </namespace>
 </repository>

=== modified file 'tests/scanner/utility.h'
--- tests/scanner/utility.h	2008-10-11 20:16:57 +0000
+++ tests/scanner/utility.h	2008-10-11 22:07:18 +0000
@@ -49,5 +49,27 @@
   glong integer;
   double real;
 } UtilityUnion;
+
+typedef struct
+{
+  int tag;
+  union
+  {
+    gpointer v_pointer;
+    double v_real;
+    long v_integer;
+  };
+} UtilityTaggedValue;
+
+typedef union
+{
+  guint8 value;
+  struct
+  {
+    guint8 first_nibble : 4;
+    guint8 second_nibble : 4;
+  };
+} UtilityByte;
+    
   
 #endif /* __UTILITY_H__ */

# Begin bundle
IyBCYXphYXIgcmV2aXNpb24gYnVuZGxlIHY0CiMKQlpoOTFBWSZTWb2gYXMAKk3/gFV0SAF/9///
///f7r////5gLJ729seMcffd931xviqe7146652nd7mdPNq7Pu182faJe9uvbAm7dQkOxqBOsJPo
Y7aSChEnps0L5qZvt1ruZdnoegevQufe8DrdZ9e7A1uzQHRq31dooDohZbZ10B9b2Gvo0UuVtmPC
UETQTUzTU8RqaYqemp6eqehNk0jQNp6oABoAb1Q0GgSgIBARBIpp5T9IajYo0AAaABo0Bo0AANMQ
gpJk0ZQyPUAABiAGgAAAAAAEmpCCCAaTU8kzUmT0ekNTT1PEQ00ZGT1A0ZNADIyCJSU9Jk9TTNCa
aJjRk1T08pD0m1A2k0DahpoaDQNDQAKkiBNNAQJoJpqbRkxU8ajInqY0Sep5J6mwp6hoeoAelnHB
R5yKo3gS8RFkVYQGQBmr/DwlH+fBaS7CTTX7sT+D6qTaIza0iL4qNbd2Xo85H+PWbhnY4fjwk67o
0WCtBv5dlwbMB40UusbqJXdehus9fs4u8XXaeJwKuWZoSe0D0dHJEDrADkMEgAghbVXhG3Vcuy8n
gHhaHDTFgpGYooyuWERxB1goCuLtUHdhb2/dXqZCKFtl2eaKGuJ/vo1ekbgsEWDMP+ywaHCLEGj6
iCDw53mVNgsuWrW2s27bS7SNHBC5KZoIkNwo2rF6MkaBChaFRH9uQ1OLDu0iBQNfNxtrTIk/kJ6G
HwkltZQdi2mPnPuCnxFL1bxpyIVVUp9DFYZmaasfE9xrm5QwQwofSh+QVNs53dPdnVztWlnGcUmB
hecs65PL9/DyBLEIIE6gGQ3ZN/Y6tGsVge+5ZdeJbrq+e21W2TW18s6FNN2cN0gBhgLALoZMDNIB
SSTcwMM0po2IQl4YUd1UxYFBRjqV0iRkC9pHpKYrgw6VFs8AQzWwUmQYsJhl2LU5kgwy2bOyHYJS
msOWZgYcBCYHAAbkDJ3i8lS5xndRjdPWcTe5083qiYPrfTvzwqpS2syrrzV1t1TokE8mGF1/wWhC
ZkARYutiwIyIhGCgES647MlbXIKEVikUEREUYxFn/Owz6yg1PZryGz/OT++ozpu560xMfOTwLAO7
MxpZzr6c/Giuid5Dw9Jvkd4ltur4XM2E/fJMaJSUSiXnFy3waeTz80SQN+A1BrNeGRNhe1aq/Izo
Y3kmZJmXHC5V1175Wydf0xI6ryJt4S1FlJa1klACwBYKRKqAUMERYiLEQWLGKigshSShiwFILGMU
WEts+uSEl/H7f368evixaFu54t0mpLNSoKozEvCBRXw0XofVOfvC6xVr1LMhWC9CCKNYWtcPdvO6
3KjeKEmdC6EyA5EvaptoHSGyMyiYDSxEVq5O2HZgkEg4wyY00MassDRjJwRKVYQCIkyQkgTgxsi9
6CYiayi4GtNf7uUMvcyYQvZLqMpkUiGZUtVkWKPdRajAzGQ8iLrWt6i8VeSBJ2XmEEYLUNquAQwc
CgpauDA7rW1cgqCyxmWEpSjQ8QKfPRtFLEQwoGozni4rskAkEohmiZKmrury8rWp0Fnhp21ZgDel
Unda3LVyRhKTF0g2nlCUoSIKrIKhcUzsbU5jfn0np40kgaRwdJEFmBTpjCz291pMYohbsKCVJU+W
x1gcU85354sbsjZjOGmf0PVdjJmU1qSyWyF/Tq5KKZVS0jDCrYqUO34PkL3gmJ5Z6OS/NWUPuO49
pOtOM+3hykIzL+cOr0xpynf+n48pNRioYCphwc+tc2s0qcXPYli5FMfWDfCXALmLtNCKgfBvNZKH
oZ3JrVqVFgHw8yPG9SH20yIB5PufK/qdh9/jtfm8gXAT2ZaS0ONNdfkBIBcY0iOChxUs6GBDJNRf
CXNuugPWbCitUw7wfQe4OZWfFLWUj0okL18LfMf0vx9zPmm63C8u8RdZeSy1KWUpMLpZFxtjXY7L
dVC1OdjHIfb9blakj93K2obiANGb/B0ycnDX8rcDPWZjlYXn804+2NzQeIgGaKKKKKKCGgdvhkxe
g6LGIuZRx9Jy302tmTRjL14algkESpVJycHYcz2kirNsEsBANCYxi7YKnybTX3pPkowpgA2sl5Ff
cu5+IawvJ9157rLnaDC0l7wnFWSvRZZPRThzYpTOOZ61ObiDn1Mh1d/s8PV2ZnG7IRU8RCMnZlZo
QZJoPbsonpnpj2dvbVNoDkqs83l8WEpf2joLR9eU8yonojnF1wxi+FKjiqYdyCwxRRTIVzc+r3nl
elnM73btjhE8yLSR51HPNKpoKqR77m4V3PE6zX9sjHTrFEck4ObBY0WUVU2ZcxKyyPFRjXmznIZu
ToGbanKXru5a3Vlhq6BAEL7y+6/DDLServZ8vFjpk5MuJoA6wLQD6FEJD9zA7ECUNIQWSekKnpGj
458PyXPZTO5RohSVvA9QEh2wAQgXkuqef4IV8yPxCoZ/W32X/B5vIYKmE3qUe4pPH5HLE0euZBv/
9StyY42cblrz2CcGKLDVirCCJKcYqYZdYiz3kyYQCma55nGG8TBLjCkD26IhVhIsX/CM8JSgoqmH
Mq9tZF/bVTH9/736tKApZWXyOFnBV0Hqxa0jllQj6//n8x+OI/8/FY+McdFvswnNWzk1dl3iuk9n
oy7dHbRx8cfUvbJaaeS1pkvUJjGPPVndvTDpmULDkfPl0LYmit1GlD3bcvJu0qtmf67a38ES8oej
0oZ2hD6RhdIcNuOzl1OjbRgLWkLtyWKm4pOS/QBepOTEiJF25zSxSVtMi472SmBHRQESlUikYWe6
QPH5ZT7UboIXI+4TAgfjIH0VVdh2efscylLYSL1KiXbED4BukT22+mkDrAN++KwPwgrqxAvhR7Fz
mBs4bcNdF75Xrs3d/X1Uz0dLZ7Nu/r4HPbr5dDvxBiDBFKVqb08SSHyXxcZVZDDJcOMFwyX5lVzM
5yMFUUBiEWRY0dwSQKEJolfDGJLQPx5iOA4dvvOJtkvtzypUTVOpmZlOC58EQAO6gQYga5K44SJU
QkklEJIQkglYX5RLrFkRsWjmXl158vh6fJv8vjX55kPNnU6AzhJNWQtBjBJM0miGaUwsgC6OadjJ
TllQBmyC6oWbsJNdKAlOxeWBIZgFXCiPe5+K51jEgWuiIAQiCNDLIuje378EeLGa0uRCpCfUpnpV
/DdeTIoIiIRE6YP57jmTkMU54NXlnF05gAdjR8SHDGRjRYY3KFzg3JDWNvoBABrBBZBF2GASxkkZ
h7rg+H7NTitUsvBYbJ2aC9+e03OJHpb0gcM9OzYiFas29nm2dbuPXhvkJowXaoj1pJnwROjZowcW
LgydG9TM5sH4USSxQNFCx584JJIihwaSTydGhxzyZAvm6Xw0gta9AmZVL+5kkd3BQrFa4ojjYZa5
0AS1xBhiy3ESy8szjEvsERjltgItPUs0IQrC3XIoZtfKmJXqGyth6zGSF9DvN5N2q999eScCBijv
1V37pCYf6WSSLcmKywwcQVjlZKwyJilDqStHTQgyognIQwgiUPJlXLjTAmeRDfiqtgqUWkJSGAcX
gbWaxMBM1RL0RmLdGd77KtwqxV2+su/u3c+/G9Z69mIvbF8+CentC83Xe2JWGo9LZAYDcgJGNzrr
wq5z2QNLKCCnBJ047tYwIIUeooKZJIRCCRfAhRi2TFeBU3KiGkqNwXhZMngHoqc508boBYNRHIB9
8Uh+ipQqpyL5HNzYgH1tvCGU20cJgKGx4NXx8vgEGc6fZ7CqggMx9qgz3LucC5JBEbDmhwhU45bR
gs6OH3vhqiN0Z7lXcXa5rqdjkdWKnBo8hTm/sHU7WajfZTJg5eW7+G5kkDJxdGw3mQSeEA7ITHeb
6bXXorIixLHPtuXlUXsKD03fSDrNLIdU9bZnGQqFVut5fXnMpPn5tnq61rTXhveMjgOT8J6IIWa1
OTfELLkZ8xqOlNtMW0KInHPTfaDsKEmQs5ZrmDejq8RiRWiw3uNscM2za9JSVKnB4s5t2UxmKwDh
EEadkuKhsUzzvuts5LEwaMFVhFKdAgBuQhVQ5KsgVVTHvcoT3tp9CjrQWyyaGOBU2VCxA2jI03ZV
DbHsK9ypgWkJkW6pcULGmHIkwZETs5ODgvYm+eclKZKjjqiaNkyWYOqiJjQ98iRkwZubg6t6nJk6
smrc2WcyBZ4NGLU3MzdkybNnTpZ0WOC4xwSXPUEKAicZ4tyvYnpOz7FGEKG01RhrUIe19UiFLNZw
thrXSr8YBAD5T4CIk7CZRFto2GHNzwMEKiiwSObGxMHtg39i5yVE5HJPJwSazh9xcHqbFBZPQkoE
olzYsaSHUsGDBJv8Fy5c4w16U0ZlzyEOorPZy5mraQdjou1ydq3B0WlmjZgpiX1RuZu5qzawciou
jHsYYrtyl9VXObsXjdXde1KU2au3izZcxNGE69XVdl7InBdTBvZLcQXsgwcg52QKQSeCxw6rwOWO
jz1goaU3LLEDtaLvrDITUjbHsnS988LU64d1ubVRYrmFpRHSndKK1KtXZrZh+SADV4mEQRrJjwMI
IaJNzW4XBACNmsQYLHYdG5rJXa4yixYyVHSEwqG6rZrChguFNhjI9favq7FCLFzkgtB3m2pYvpG2
Y6DiIWBeSCHOgoODiWUcRO/MnJOxwZOw7KohyMehuRPWJODopgwOZOSSO8im5coIJUc1bs8GD7BE
Cq6kRybmpGsDg2dVOLRkxN7Nq6MWboxZNWZ1Z5MVqrkzWXXbmqlODR5hHVgR1BA5b5By8XFTMFmb
4klTKZp4VY4FULGELLVythWfHWtHcOmZA0IGmrfVbsVO0bc0UQoo0X6OB7i0wb2jdeMttsCtUW90
pi9G0YNHRsFxiowIpB2WyT16dEQSXOyE5UNZ8lo3GKFF57ig6YBACZwCIw5z2FSpbFV3GOFtQZsB
Y0CJBx4N8mqiJXYratjgoXb29TsbMnAzYEDVzWZrMmDFs5rMim/DJs3tG5quXeqJm3kDFZ2dfnI0
5u91UwQeEddPRw6d+tRW49iK+VUlohqQ1hfDZ3QuqNZVELanS4bUmQDeBg9Bht/ZELqv1Jd4FGZG
yE6ViuXD0FlZTorjMtt5kGMiWAgBgepl2tVj0MRn00dHR6GbFhTRwKa4ysTzgt1Cs1ipuCG5UdPc
il2xyRi4NncERmINCliWjYsMiOu4qWUQc0ULEwLZdlsTOgQAhn3OyqF52oyQuDcW86CAQAbTjFQs
RZCLtU4uciPRHbG47FGzg1bMTe7WLFxeMlMlMWy67RxcW90c24u1R4u1wZqWcHN2sw/cJ0R1d3Fx
m9v5dONgzlU61KZWvW4imLrVSAa47t53VBmkwClEvYVXOkpeMBEnsH0LwFq7ZUqWxLC2ggEJwdkH
gttfPHmHfzZOPa5Luh11IHRzcKcEaK3KXZ8crLNDoY9qpSngU3pRhlgvogarFtjgfJYsUFvexUgz
JShsWHeXNdCzUk0OlVxAxpTNW4K8/Fku3LKckJzIG87G5+wjoyaGxY7lNl25yU5M2Lsbm5ZvjtNX
Vg+ckuYJNg9PWC/B51zgQpCHhaSCikzVBasqzyPbSsSrtW3myzJNhhPsRrdOnZmXSzooIXBEy2ab
Yow8dmQr4HGpuXNzg7OSB65TZuEAQOGape5mhjG5hMnFKlSHobFnNsijD0upUoMUqKibj0HKuSxY
UuG4YOCopcyXqCAyakm5izZcKwmNWZO/j6SBm7e3juyb3go8CmTRjiovfD+7WPBFjTt4YjcgY8Dn
kg4AxAiMbCnBog5OBjQ5g9DBkKFTgapoZZOBt1HGP0UQT5AQf7CjVyopjsXjC1zG1vNBUGi9K0pC
gSRkO4YuAksnkGzi5o5JHJPLhlix5OHCnY5s9Awc2i8mKiTc3ODyknLju3cllpEzbUu3OjuZcSBX
FplV12gmq6zyEDpeZVrzZM29vau90ZOSjNk120O55Gb397DNSHR8kHEsMycGQzCE7KvXZCEmZPUs
bmTODLwK5ccsHZQ4OjcYRAcRiWzZ+IM1mbgc2rl08Gzi4mjmwcmLFz7FV1drVi5uxzdWTB1at7ck
nxFTakqyxa1CcBKKDw2khv9BR2we8Epiry1ISpEizgkLhOwYJE7JEdqEw5ojWQmV0TKBiQOxD7df
l2gbq/yoaVH5OtvBu+PpkNQyWUbK/I5b4xeLTr7effRoA+8H4E/uFQVPLfdxdutn8AB0HvMTzbbg
UV2xm5isbkAPnAxa0gfThYsRuXMgk/SfUyogCxJA9E8K5LSe4UlkKVF+Vi8pFF6il7WWJBRLDzAI
gNoXApEEV5gKCW5YkZGLGRiRiIgJclgUgyKgxhJQISfR8OwCaw1nuSeUNNjRIpTBYWQqxQCFlEqD
KWEoDzgZAWBqLBhMhpcYD6wyFSDBtH0o9R0hADYPSBsKggMQDdBUPV+s/sCnkPu9R2o3HABpjiA0
5FICSDIEjAikUiwQfr+PyFj5suyaH2f7n7NNf+hTzZyp7pkEtQElPGkpRLEvpUXd5BNyL/IFvnVD
JvuWqoKUqnj5m/D2fs+3P54EOmuM3GvW3Gkopoef+OnR6xrXkWwQ9wt12gE7YawoIc/0YhkkiJO3
y1ILC1rS5P9HKeNT/iOTuL1HWLycYWCf5djTRHzDmism087dBq9MyfJl8/1182uaaN/Ooa1ADW1u
maaIJYJSoKD4ABiHJOAil2xEBJCdxONguL5XEk/5H9/Vae1xa1Jrba0BBrhidCLvOjnGVSZ76kbv
P4NHdJilCvPFJ5+9OjhCcslDA4S9wMipiBBnX4wvOIi+krsHvR5dyPRzh//bQjboVw1iulpfja1l
rVrU++kJIeRDDKhpxTck6e4KVopP+HUqnUZE9E54jwGA7wZqrH0/V48l3X1Qs6wi8lreEpVozlRR
q6qdvTu+crYsYm0V/kErCAkIkFikEMDCcpYn0l5AmUSwIk1HvDWiAhKr4jyGUUbhV9CxpRebJDbD
TXMzYdqCIRiFKkRZnBSpP43s2KG1PCoarywyqZXwGLlBX8KT9X3aXaf1H2voSp6YpaWWWQyVASga
iUQZKASoCSpEqCUCjCCgfqkwnfO0qN5vN8OMFbNNlzOYCCH3l4fEZsER/N17NWrcc2jmuu5ODAjV
ZmxWfyiZsTo22zdTo3tynAs5uSmDqu4v5qdCpU9lODY/wc9C5oybnXWjkd+yShgU8nwyQdjeyO5x
SPU/lXaiqk8jyM9zwcnGy7q6sMurF2N384lPI8XR4lmZ2uh6g9MhPbGv7U5PXFKp8/8et395+5jU
r6DfpEDgM++WMBb8tJ50OMkI2REvEYkNc/Lh7myW187fNtFAz80BB28mHiWrvpWAYA3FL1xcVy5g
9JldceycOHZCQsFTq4uXDutDyYItJUjFaZ4Y+Ddw/iWt/Wjf6g3fp9PubPpcn0milnudWhor6FPS
9rVo9DkwNzJuWexdqpuWWf8xOKzZwaN7F72LkQNy7U5MmRTze/Fs2c3BZTkU0Wb3FvbNG51dVm5T
B7msj0eXyeWX8Dec3VxdGzg713JdudTBs7GLo1Wdij6PLALG83iHQam82zR7yoc774USofRJ1Hui
I4kPjzy1+/ePE8WP0X8snE/FH8oglJhKXHJa9Zxmkr2OYERjIaDaVVKUUUmoUUgeYqIGQ8Wzg119
K1sXpZKYYd75HBo4tXJSm5YgWMXFs2WNttHE4OK7m4q9OqrdWTByaPS8Q0Xbzc5MfiiJXkrN1dXN
owblNxk5u1m6BuQ8Cjuau7uwdzM9PJgzbO84PYLeIBga02Ll4MRwyAkgFAbcRQGF+nzNsZGq/T5X
TdVgJXylhlUL8bhEYkFiBasSQol68gMikjdPRrqaggyGyjkwB3dYD6UR4nGeT9A+gx6Q6gCPWbEi
qEUKgQqvDAmYQQdiyez4HXxa7NQzJagETQQe9VCCAWlJU+Y0LPfrvrfj+Jq1e187V62BAp7Wr3Nm
52km9wbmDZubMG5g6SIss3vcu5oSm9xU3GbVi3Dmwcm9swV3SSR0dlVUlVLx27kyTRzaun+/xfax
eDsbjo3Pg4smyZHV71OE47FTFiZtlMDVVnT64klmTFswglnscld2/+iZj5fqwXf+JUZQcbKU2b13
Y8JBgleURL3AeMEzgH6KOoLbQsUynJAte+LvhInz/4PjVV0YYLW6NaiTlCkYt68L5XKCqBQqiFBi
Y7TXXVPuTa5EA02a5wQecnIGuECPYQ0NGB+oygQOYWHAqL2h45CZ3GxHkBKGWjB3hYMb2SixuDGH
GZnmYZGa1mOC6rrLWaFy+OOi9YlopB8rV8ynnexqvxwr0fN7cc9zOJZdoxXepk1LPY8WizwXK/En
/bXGZbhfpXO7cXnDEtzMXrmrWVdWekX4OTNzUpRkcnNs5nrYubcdFNG9TVvXarpfO0F4DLCQjCEO
HNLehF2gInEhxMGKIwGREYsAPMAcoToQhrFEZUmjWKkmMFJKmN/OyedBjISzc3zqywm6CrUk0VUW
WKodXmeDvcHFqmfl9I58rIPO+b27nkdXoY49GDFT5HVvv2tpJ/hJgJ9Rj0c+unfj4zLuppjaQ2f1
IGL5Hix80WfK5SSjp4sLdrz+V0TCRRpRkpmzfKu8yl3m82zzPIp8xmOkX7/Ygf9fzfc+Dt+QHc+5
Pz4/UWoFSfCbpvaFNK+bpsbxB6w56G+GEiGGBQU1Sq2E/GY3wQNyonefiVs5XkStqVYkJeA5kLw0
AqlVBBggwFVRVZEcRM/VNKsssAtmQLJaER9/XR64KpyAH1+byqw4VdxoOkTkpQdtDm5yQzf00WVn
J6ImcngvAn+afJNfpDei1RIe0kw0DzccA8ZKCgRCVILVQRoY9ghuIqJwfWuwfF7yB8Hpkwe8+GCv
QpuZtzB72jJgyYM3nUnVkxNGaz+0e9JKgSzNm+pk3NycyBzcHsRiwXcWrw5G9vMH1Lslze1UQNmj
JvZs2Dqs1cmDB54d8jZycGrc7XBdvdXNkzXM1MWLNg4uCkRowXWYOSzmU1YPi3N7Zq5IjyfQ/P++
J8f0e4+BRlSp+mzzH7YmDO6zRB2H4ILhCjK5qICzWCFlRWnFTQB1GHQHkrMmROXqnG6hSKX+M/uk
S2c8Oz9f3VgmMGkHslpCaRy7DH/F3eyRM45ujEO5Nn7XnU8qi0osYBMEXwrC9fgJ8CSGid8ffj/t
HskTQsXKqcPYAnFyj8QzyQRnsB67TOsxlkQopiqqsJiLJerGUSqIjV/SC4tkJjkkR4c9xydP2xLn
okInf3naQkC15yTzH1HhCgVVuDxVVgV6pzqqdOUHfgYnWIczEkVCkKwDnlqU6FHUboUZErO3cwO6
Op2ju40VSTbIZBE4/CfA8jwuwxKI2iLiNwe9eKzxKCZ2RU1zbdfbzz6ynME75TZi8IHdRRXZAVGV
1iJZ8fmj4joM4evvpKopVVSo4CohZSUAlEoIFAgESChGnReNSvHEDMRk0J3yiyJMHrlzMErzPKfn
dKYeHFpE4EmKWRyhaQxGiI5OWKC/5Q/MSfeSWE0k8yPUJwSTqRlB94XIDaDOo84+Bx8ig8m+DkuE
iVGihRJAXGJLN2uIa/KsSLUnRaQULlhDTtxTOqpB5jv1unL4/qt0cmyIz4fti1hTf8PWtXJOfGRk
VJxGAvJzxkfpI+QTwyfJuZaOFr3XVziOqpjlJCOvkQx0k0ilU9hDoJrIDH6amijKTPQh/SZv7x7R
5BjJQ0Ur0Q/2OcNjlIcOb5HqDiPtRG23YSQ3saO+VQ5LRMqLKwXtDfUtQwSiqLp9qSF2TuJIkAMw
kgMhDQmsfe/If2PeYflPwjuYF2apcuUsxRDWXbPNI71cyUKrrLSmCxZLSE5LHbInzyMDAFTXWQTK
pLP+3HLKVRUbkNjygboGYIQVVEYIhFCZCQCGWUkCFXaIQmhnCD78Pz0NqR3DDaQfWocVVgzkDbQU
bT1HUbBAZMAuohaihEghSBRBkkEUh/eA3kLBJREQf8qZJeEyxkPk/u+lYa91kX0eeO4T90BESKsQ
NvSGES57iBzXlnfUDemtS8b2pDEiFkFq9FETeSIo1mAB+gCnrjprLj9ZVVGchw27nSikWBa1nfKc
lpkhTbDE6AZAnk1kmCQmhcAMqgMNCY/KpUCoYxh2EzAYYpUYMBVXiT7St2g0lifOFxL31Ui3jNe2
kH2D7B9aEw4yTH2t6I90kHdr9kFSXQu9dJZxBbtkJRPBpkXuHjrOmHwb2ROabISoA3IFV4xPFYrE
e8DvCho9+jNw/XaSv1WcPxT4yE/MScuU9Eb7KMshSVKqVCxBJCHfzL/OXKwlGVXloSR5YnbJldJ9
gTOZwkr1D9iNUTLCzEKX5OXgtPnke97oi/lyyl48rDx8vuykZd7kgqKQMbzsFWVMTyKtPyPLZrWW
8ecXQcBUiXkdSbVk7N9HRez4D+MVJP8UaPBIlSeaTTPua6oO5McY7SSHzt2XeOQ3yV9tGkUqTKIx
XnC6wWssGEkTzFIIxkn+ZFmQMVtDG6y9OEWtgmkgIJh0p9ToQE1gdnANBAXQvybXY5gbnwwsRAAt
UW14W0b8d18k0YD9gVLVnRmqmQsCBmVtAOw+XiWKsYqRiiACEK9WwkaVFIaDaONRtM0Tqv0ArYto
762Xt3YPewVU+dSv0Ve7BUnY3ST46TXh2+qeBC6TJEXRFtz6vZ+/sITzwzQeVCU/YJzibmMWcaCj
OcL3ReXTmtpBiMI6PW4a3T9D49z34sbTTc+zukJkybNl08jxq0ccZFLSu5WdwoL7JIHqbIHWxYoC
hjk+SjSR6jiNm1ZgspSiVKh7jopw83hd9xzeOeEzryltDpY+coDRaYFFPpUb8ohWmFxSSAHAzQEw
VhFrF70payzCCF4sx0RZcpGP2j1DLOQxZRdmtpbTFBZKRSsDC92BBvZsIOPhXS8Q1iYp5lCuVrbh
guqMkWKRcbqr3GqbAG6GzFBkEE4AJDxgYpaRRBzG2Uj2KlYCdy6y2+dAygeuGIYZcJJbaSEdGMLI
+byLq/LlOkhOY1ShShtLvZH5Kr6SrJ5FqMBvzChJQSifMMFIqJESQ37iSdIQLNp0VplAtJeyUtL1
FB2UhKWHbJCP4I6RPNJ55E0SI79BpAxiWCoFu0xVNHtSfihOMwWMCKD7fIXhgATuasT0bRUwq25U
ZecEp5Ucg81qo87AgZu4dlwocBYRIxqLoacYHcQr5UqWJG5vJnxuw7zclx64hvyJL2g3Su97ZVl6
CAQq/Iek+9w7V0rzLaBwwHc0ZgCohOHHwCRLaJCJRP+mL9GUmgelJMtaqqVXHZGlW9b0CelHteHj
pnACcCSbNLy8RnQBNoQwIEdFS8zg0e7OSoocwDszgcqvcUfMCQQccBDMCodAL1o/WC40r4bUEdwE
oC5+mAdclrGCoW9FxmPA8chkoVRKxZooyDJUFxdFkkobiT1yJ7PAhrIUykSNolvaZ+eJx+0jukGc
mI8sfjfb8E/0SPAaImgocf+LuSKcKEhe0DC5gA==
