2012-02-03 19:42:56 +01:00
|
|
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
|
|
|
* GObject introspection: Typelib creation
|
2008-08-09 14:46:48 +02:00
|
|
|
*
|
|
|
|
* Copyright (C) 2005 Matthias Clasen
|
2009-02-20 03:48:51 +01:00
|
|
|
* Copyright (C) 2008,2009 Red Hat, Inc.
|
2008-08-09 14:46:48 +02:00
|
|
|
*
|
2023-10-25 18:10:10 +02:00
|
|
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
|
|
*
|
2008-08-09 14:46:48 +02:00
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the
|
|
|
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
|
* Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
2023-11-08 01:06:01 +01:00
|
|
|
#include "config.h"
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2023-11-08 01:09:04 +01:00
|
|
|
#include "girnode-private.h"
|
2024-02-08 13:35:23 +01:00
|
|
|
#include "girepository-private.h"
|
2010-05-31 22:44:46 +02:00
|
|
|
#include "gitypelib-internal.h"
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2023-11-08 01:06:01 +01:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
2012-07-24 10:09:38 +02:00
|
|
|
#ifdef _MSC_VER
|
|
|
|
#define strtoll _strtoi64
|
|
|
|
#define strtoull _strtoui64
|
|
|
|
#endif
|
|
|
|
|
2008-08-09 14:46:48 +02:00
|
|
|
static gulong string_count = 0;
|
|
|
|
static gulong unique_string_count = 0;
|
|
|
|
static gulong string_size = 0;
|
|
|
|
static gulong unique_string_size = 0;
|
|
|
|
static gulong types_count = 0;
|
|
|
|
static gulong unique_types_count = 0;
|
|
|
|
|
|
|
|
void
|
2023-11-08 16:23:31 +01:00
|
|
|
gi_ir_node_init_stats (void)
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
|
|
|
string_count = 0;
|
|
|
|
unique_string_count = 0;
|
|
|
|
string_size = 0;
|
|
|
|
unique_string_size = 0;
|
|
|
|
types_count = 0;
|
|
|
|
unique_types_count = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2023-11-08 16:23:31 +01:00
|
|
|
gi_ir_node_dump_stats (void)
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
|
|
|
g_message ("%lu strings (%lu before sharing), %lu bytes (%lu before sharing)",
|
2024-01-16 17:30:37 +01:00
|
|
|
unique_string_count, string_count, unique_string_size, string_size);
|
2008-08-09 14:46:48 +02:00
|
|
|
g_message ("%lu types (%lu before sharing)", unique_types_count, types_count);
|
|
|
|
}
|
|
|
|
|
2009-10-21 13:28:12 +02:00
|
|
|
#define DO_ALIGNED_COPY(dest_addr, value, type) \
|
|
|
|
do { \
|
2024-01-16 17:30:37 +01:00
|
|
|
type tmp_var; \
|
|
|
|
tmp_var = value; \
|
|
|
|
memcpy(dest_addr, &tmp_var, sizeof(type)); \
|
2009-10-21 13:28:12 +02:00
|
|
|
} while(0)
|
|
|
|
|
2008-08-09 14:46:48 +02:00
|
|
|
#define ALIGN_VALUE(this, boundary) \
|
|
|
|
(( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))
|
|
|
|
|
|
|
|
|
2024-01-15 20:20:47 +01:00
|
|
|
const char *
|
2023-11-08 16:23:31 +01:00
|
|
|
gi_ir_node_type_to_string (GIIrNodeTypeId type)
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
|
|
|
switch (type)
|
|
|
|
{
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_FUNCTION:
|
2008-08-09 14:46:48 +02:00
|
|
|
return "function";
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_CALLBACK:
|
2008-08-09 14:46:48 +02:00
|
|
|
return "callback";
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_PARAM:
|
2008-08-09 14:46:48 +02:00
|
|
|
return "param";
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_TYPE:
|
2008-08-09 14:46:48 +02:00
|
|
|
return "type";
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_OBJECT:
|
2008-08-09 14:46:48 +02:00
|
|
|
return "object";
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_INTERFACE:
|
2008-08-09 14:46:48 +02:00
|
|
|
return "interface";
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_SIGNAL:
|
2008-08-09 14:46:48 +02:00
|
|
|
return "signal";
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_PROPERTY:
|
2008-08-09 14:46:48 +02:00
|
|
|
return "property";
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_VFUNC:
|
2008-08-09 14:46:48 +02:00
|
|
|
return "vfunc";
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_FIELD:
|
2008-08-09 14:46:48 +02:00
|
|
|
return "field";
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_ENUM:
|
2008-08-09 14:46:48 +02:00
|
|
|
return "enum";
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_FLAGS:
|
2008-08-09 14:46:48 +02:00
|
|
|
return "flags";
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_BOXED:
|
2008-08-09 14:46:48 +02:00
|
|
|
return "boxed";
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_STRUCT:
|
2008-08-09 14:46:48 +02:00
|
|
|
return "struct";
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_VALUE:
|
2008-08-09 14:46:48 +02:00
|
|
|
return "value";
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_CONSTANT:
|
2008-08-09 14:46:48 +02:00
|
|
|
return "constant";
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_XREF:
|
2008-08-09 14:46:48 +02:00
|
|
|
return "xref";
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_UNION:
|
2008-08-09 14:46:48 +02:00
|
|
|
return "union";
|
|
|
|
default:
|
|
|
|
return "unknown";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
GIIrNode *
|
2023-11-08 16:23:31 +01:00
|
|
|
gi_ir_node_new (GIIrNodeTypeId type,
|
|
|
|
GIIrModule *module)
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2023-11-08 15:17:52 +01:00
|
|
|
GIIrNode *node = NULL;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
|
|
|
switch (type)
|
|
|
|
{
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_FUNCTION:
|
|
|
|
case GI_IR_NODE_CALLBACK:
|
|
|
|
node = g_malloc0 (sizeof (GIIrNodeFunction));
|
2008-08-09 14:46:48 +02:00
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_PARAM:
|
|
|
|
node = g_malloc0 (sizeof (GIIrNodeParam));
|
2008-08-09 14:46:48 +02:00
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_TYPE:
|
|
|
|
node = g_malloc0 (sizeof (GIIrNodeType));
|
2008-08-09 14:46:48 +02:00
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_OBJECT:
|
|
|
|
case GI_IR_NODE_INTERFACE:
|
|
|
|
node = g_malloc0 (sizeof (GIIrNodeInterface));
|
2008-08-09 14:46:48 +02:00
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_SIGNAL:
|
|
|
|
node = g_malloc0 (sizeof (GIIrNodeSignal));
|
2008-08-09 14:46:48 +02:00
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_PROPERTY:
|
|
|
|
node = g_malloc0 (sizeof (GIIrNodeProperty));
|
2008-08-09 14:46:48 +02:00
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_VFUNC:
|
|
|
|
node = g_malloc0 (sizeof (GIIrNodeFunction));
|
2008-08-09 14:46:48 +02:00
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_FIELD:
|
|
|
|
node = g_malloc0 (sizeof (GIIrNodeField));
|
2008-08-09 14:46:48 +02:00
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_ENUM:
|
|
|
|
case GI_IR_NODE_FLAGS:
|
|
|
|
node = g_malloc0 (sizeof (GIIrNodeEnum));
|
2008-08-09 14:46:48 +02:00
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_BOXED:
|
|
|
|
node = g_malloc0 (sizeof (GIIrNodeBoxed));
|
2008-08-09 14:46:48 +02:00
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_STRUCT:
|
|
|
|
node = g_malloc0 (sizeof (GIIrNodeStruct));
|
2008-08-09 14:46:48 +02:00
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_VALUE:
|
|
|
|
node = g_malloc0 (sizeof (GIIrNodeValue));
|
2008-08-09 14:46:48 +02:00
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_CONSTANT:
|
|
|
|
node = g_malloc0 (sizeof (GIIrNodeConstant));
|
2008-08-09 14:46:48 +02:00
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_XREF:
|
|
|
|
node = g_malloc0 (sizeof (GIIrNodeXRef));
|
2008-08-09 14:46:48 +02:00
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_UNION:
|
|
|
|
node = g_malloc0 (sizeof (GIIrNodeUnion));
|
2008-08-09 14:46:48 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2023-12-20 23:41:10 +01:00
|
|
|
g_error ("Unhandled node type %d", type);
|
2008-08-09 14:46:48 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
node->type = type;
|
2010-07-26 22:26:46 +02:00
|
|
|
node->module = module;
|
2009-02-20 03:48:51 +01:00
|
|
|
node->offset = 0;
|
|
|
|
node->attributes = g_hash_table_new_full (g_str_hash, g_str_equal,
|
|
|
|
g_free, g_free);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
|
|
|
return node;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2023-11-08 16:23:31 +01:00
|
|
|
gi_ir_node_free (GIIrNode *node)
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
|
|
|
GList *l;
|
|
|
|
|
|
|
|
if (node == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
switch (node->type)
|
|
|
|
{
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_FUNCTION:
|
|
|
|
case GI_IR_NODE_CALLBACK:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeFunction *function = (GIIrNodeFunction *)node;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
g_free (node->name);
|
|
|
|
g_free (function->symbol);
|
2021-06-16 20:17:27 +02:00
|
|
|
g_free (function->property);
|
2024-01-16 17:30:37 +01:00
|
|
|
gi_ir_node_free ((GIIrNode *)function->result);
|
|
|
|
for (l = function->parameters; l; l = l->next)
|
|
|
|
gi_ir_node_free ((GIIrNode *)l->data);
|
|
|
|
g_list_free (function->parameters);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_TYPE:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeType *type = (GIIrNodeType *)node;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
g_free (node->name);
|
|
|
|
gi_ir_node_free ((GIIrNode *)type->parameter_type1);
|
|
|
|
gi_ir_node_free ((GIIrNode *)type->parameter_type2);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
g_free (type->giinterface);
|
|
|
|
g_strfreev (type->errors);
|
2024-01-25 23:55:48 +01:00
|
|
|
g_free (type->unparsed);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_PARAM:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeParam *param = (GIIrNodeParam *)node;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
g_free (node->name);
|
|
|
|
gi_ir_node_free ((GIIrNode *)param->type);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_PROPERTY:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeProperty *property = (GIIrNodeProperty *)node;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
g_free (node->name);
|
Add introspection data for property accessors
A GObject property can be accessed generically through the GObject API,
e.g. g_object_set_property() and g_object_get_property(). Properties
typically also have public accessor functions, which are (according to
our own best practices) called through the generic API.
The introspection data is currently missing the relation between a
property and its public accessor functions. With this information, a
language binding could, for instance, avoid exposing the C API entirely,
thus minimizing the chances of collisions between property names and
accessor functions; alternatively, a binding could call the C API
directly instead of going through the generic GObject API, thus avoiding
the boxing and unboxing from a native type to a GIArgument and finally
into a GValue, and vice versa.
In the GIR, we add two new attributes to the `property` element:
- setter="SYMBOL"
- getter="SYMBOL"
where "symbol" is the C function identifier of the setter and getter
functions, respectively. The `setter` attribute is only applied to
writable, non-construct-only properties; the `getter` attribute is only
applied to readable properties.
We maintain the ABI compatibility of the typelib data by using 20 bits
of the 25 reserved bits inside the PropertyBlob structure. The data is
exposed through two new GIPropertyInfo methods:
- g_property_info_get_setter()
- g_property_info_get_getter()
which return the GIFunctionInfo for the setter and getter functions,
respectively.
2021-06-17 14:07:35 +02:00
|
|
|
g_free (property->setter);
|
|
|
|
g_free (property->getter);
|
2024-01-16 17:30:37 +01:00
|
|
|
gi_ir_node_free ((GIIrNode *)property->type);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_SIGNAL:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeSignal *signal = (GIIrNodeSignal *)node;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
g_free (node->name);
|
|
|
|
for (l = signal->parameters; l; l = l->next)
|
|
|
|
gi_ir_node_free ((GIIrNode *)l->data);
|
|
|
|
g_list_free (signal->parameters);
|
|
|
|
gi_ir_node_free ((GIIrNode *)signal->result);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_VFUNC:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeVFunc *vfunc = (GIIrNodeVFunc *)node;
|
|
|
|
|
|
|
|
g_free (node->name);
|
|
|
|
g_free (vfunc->invoker);
|
|
|
|
for (l = vfunc->parameters; l; l = l->next)
|
|
|
|
gi_ir_node_free ((GIIrNode *)l->data);
|
|
|
|
g_list_free (vfunc->parameters);
|
|
|
|
gi_ir_node_free ((GIIrNode *)vfunc->result);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_FIELD:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeField *field = (GIIrNodeField *)node;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
g_free (node->name);
|
|
|
|
gi_ir_node_free ((GIIrNode *)field->type);
|
|
|
|
gi_ir_node_free ((GIIrNode *)field->callback);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_OBJECT:
|
|
|
|
case GI_IR_NODE_INTERFACE:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeInterface *iface = (GIIrNodeInterface *)node;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
g_free (node->name);
|
|
|
|
g_free (iface->gtype_name);
|
|
|
|
g_free (iface->gtype_init);
|
|
|
|
g_free (iface->ref_func);
|
|
|
|
g_free (iface->unref_func);
|
|
|
|
g_free (iface->set_value_func);
|
|
|
|
g_free (iface->get_value_func);
|
2009-02-06 19:37:13 +01:00
|
|
|
|
2009-02-20 23:34:20 +01:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
g_free (iface->glib_type_struct);
|
|
|
|
g_free (iface->parent);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
for (l = iface->interfaces; l; l = l->next)
|
|
|
|
g_free ((GIIrNode *)l->data);
|
|
|
|
g_list_free (iface->interfaces);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-25 23:55:48 +01:00
|
|
|
g_list_free_full (iface->prerequisites, g_free);
|
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
for (l = iface->members; l; l = l->next)
|
|
|
|
gi_ir_node_free ((GIIrNode *)l->data);
|
|
|
|
g_list_free (iface->members);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
break;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_VALUE:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
g_free (node->name);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_ENUM:
|
|
|
|
case GI_IR_NODE_FLAGS:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeEnum *enum_ = (GIIrNodeEnum *)node;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
g_free (node->name);
|
|
|
|
g_free (enum_->gtype_name);
|
|
|
|
g_free (enum_->gtype_init);
|
|
|
|
g_free (enum_->error_domain);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
for (l = enum_->values; l; l = l->next)
|
|
|
|
gi_ir_node_free ((GIIrNode *)l->data);
|
|
|
|
g_list_free (enum_->values);
|
2011-08-13 17:28:30 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
for (l = enum_->methods; l; l = l->next)
|
|
|
|
gi_ir_node_free ((GIIrNode *)l->data);
|
|
|
|
g_list_free (enum_->methods);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_BOXED:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeBoxed *boxed = (GIIrNodeBoxed *)node;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
g_free (node->name);
|
|
|
|
g_free (boxed->gtype_name);
|
|
|
|
g_free (boxed->gtype_init);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
for (l = boxed->members; l; l = l->next)
|
|
|
|
gi_ir_node_free ((GIIrNode *)l->data);
|
|
|
|
g_list_free (boxed->members);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_STRUCT:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeStruct *struct_ = (GIIrNodeStruct *)node;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
g_free (node->name);
|
|
|
|
g_free (struct_->gtype_name);
|
|
|
|
g_free (struct_->gtype_init);
|
2022-10-29 19:09:23 +02:00
|
|
|
g_free (struct_->copy_func);
|
|
|
|
g_free (struct_->free_func);
|
2008-09-06 22:33:51 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
for (l = struct_->members; l; l = l->next)
|
|
|
|
gi_ir_node_free ((GIIrNode *)l->data);
|
|
|
|
g_list_free (struct_->members);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_CONSTANT:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeConstant *constant = (GIIrNodeConstant *)node;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
g_free (node->name);
|
|
|
|
g_free (constant->value);
|
|
|
|
gi_ir_node_free ((GIIrNode *)constant->type);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_XREF:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeXRef *xref = (GIIrNodeXRef *)node;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
g_free (node->name);
|
|
|
|
g_free (xref->namespace);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_UNION:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeUnion *union_ = (GIIrNodeUnion *)node;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
g_free (node->name);
|
|
|
|
g_free (union_->gtype_name);
|
|
|
|
g_free (union_->gtype_init);
|
2022-10-29 19:09:23 +02:00
|
|
|
g_free (union_->copy_func);
|
|
|
|
g_free (union_->free_func);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
gi_ir_node_free ((GIIrNode *)union_->discriminator_type);
|
2024-05-10 17:46:52 +02:00
|
|
|
g_clear_list (&union_->members, (GDestroyNotify) gi_ir_node_free);
|
|
|
|
g_clear_list (&union_->discriminators, (GDestroyNotify) gi_ir_node_free);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2023-12-20 23:41:10 +01:00
|
|
|
g_error ("Unhandled node type %d", node->type);
|
2008-08-09 14:46:48 +02:00
|
|
|
break;
|
2010-03-24 19:00:06 +01:00
|
|
|
}
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2009-02-20 03:48:51 +01:00
|
|
|
g_hash_table_destroy (node->attributes);
|
|
|
|
|
2008-08-09 14:46:48 +02:00
|
|
|
g_free (node);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* returns the fixed size of the blob */
|
2024-01-15 22:20:02 +01:00
|
|
|
uint32_t
|
2023-11-08 16:23:31 +01:00
|
|
|
gi_ir_node_get_size (GIIrNode *node)
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
|
|
|
GList *l;
|
2024-01-16 02:22:24 +01:00
|
|
|
size_t size, n;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
|
|
|
switch (node->type)
|
|
|
|
{
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_CALLBACK:
|
2009-02-12 05:53:05 +01:00
|
|
|
size = sizeof (CallbackBlob);
|
2008-08-09 14:46:48 +02:00
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_FUNCTION:
|
2008-11-25 23:29:20 +01:00
|
|
|
size = sizeof (FunctionBlob);
|
2008-08-09 14:46:48 +02:00
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_PARAM:
|
|
|
|
/* See the comment in the GI_IR_NODE_PARAM/ArgBlob writing below */
|
2009-02-12 05:53:05 +01:00
|
|
|
size = sizeof (ArgBlob) - sizeof (SimpleTypeBlob);
|
2008-08-09 14:46:48 +02:00
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_TYPE:
|
2009-02-12 05:53:05 +01:00
|
|
|
size = sizeof (SimpleTypeBlob);
|
2008-08-09 14:46:48 +02:00
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_OBJECT:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeInterface *iface = (GIIrNodeInterface *)node;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
n = g_list_length (iface->interfaces);
|
|
|
|
size = sizeof (ObjectBlob) + 2 * (n + (n % 2));
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
for (l = iface->members; l; l = l->next)
|
|
|
|
size += gi_ir_node_get_size ((GIIrNode *)l->data);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_INTERFACE:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeInterface *iface = (GIIrNodeInterface *)node;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
n = g_list_length (iface->prerequisites);
|
|
|
|
size = sizeof (InterfaceBlob) + 2 * (n + (n % 2));
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
for (l = iface->members; l; l = l->next)
|
|
|
|
size += gi_ir_node_get_size ((GIIrNode *)l->data);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_ENUM:
|
|
|
|
case GI_IR_NODE_FLAGS:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeEnum *enum_ = (GIIrNodeEnum *)node;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
size = sizeof (EnumBlob);
|
|
|
|
for (l = enum_->values; l; l = l->next)
|
|
|
|
size += gi_ir_node_get_size ((GIIrNode *)l->data);
|
|
|
|
for (l = enum_->methods; l; l = l->next)
|
|
|
|
size += gi_ir_node_get_size ((GIIrNode *)l->data);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_VALUE:
|
2009-02-12 05:53:05 +01:00
|
|
|
size = sizeof (ValueBlob);
|
2008-08-09 14:46:48 +02:00
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_STRUCT:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeStruct *struct_ = (GIIrNodeStruct *)node;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
size = sizeof (StructBlob);
|
|
|
|
for (l = struct_->members; l; l = l->next)
|
|
|
|
size += gi_ir_node_get_size ((GIIrNode *)l->data);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_BOXED:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeBoxed *boxed = (GIIrNodeBoxed *)node;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
size = sizeof (StructBlob);
|
|
|
|
for (l = boxed->members; l; l = l->next)
|
|
|
|
size += gi_ir_node_get_size ((GIIrNode *)l->data);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_PROPERTY:
|
2009-02-12 05:53:05 +01:00
|
|
|
size = sizeof (PropertyBlob);
|
2008-08-09 14:46:48 +02:00
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_SIGNAL:
|
2009-02-12 05:53:05 +01:00
|
|
|
size = sizeof (SignalBlob);
|
2008-08-09 14:46:48 +02:00
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_VFUNC:
|
2009-02-12 05:53:05 +01:00
|
|
|
size = sizeof (VFuncBlob);
|
2008-08-09 14:46:48 +02:00
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_FIELD:
|
2009-11-09 19:17:23 +01:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeField *field = (GIIrNodeField *)node;
|
2009-11-09 19:17:23 +01:00
|
|
|
|
|
|
|
size = sizeof (FieldBlob);
|
|
|
|
if (field->callback)
|
2023-11-08 16:23:31 +01:00
|
|
|
size += gi_ir_node_get_size ((GIIrNode *)field->callback);
|
2009-11-09 19:17:23 +01:00
|
|
|
}
|
2008-08-09 14:46:48 +02:00
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_CONSTANT:
|
2009-02-12 05:53:05 +01:00
|
|
|
size = sizeof (ConstantBlob);
|
2008-08-09 14:46:48 +02:00
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_XREF:
|
2008-08-09 14:46:48 +02:00
|
|
|
size = 0;
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_UNION:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeUnion *union_ = (GIIrNodeUnion *)node;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
size = sizeof (UnionBlob);
|
|
|
|
for (l = union_->members; l; l = l->next)
|
|
|
|
size += gi_ir_node_get_size ((GIIrNode *)l->data);
|
|
|
|
for (l = union_->discriminators; l; l = l->next)
|
|
|
|
size += gi_ir_node_get_size ((GIIrNode *)l->data);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2010-03-24 19:00:06 +01:00
|
|
|
default:
|
2023-12-20 23:41:10 +01:00
|
|
|
g_error ("Unhandled node type '%s'", gi_ir_node_type_to_string (node->type));
|
2008-08-09 14:46:48 +02:00
|
|
|
size = 0;
|
|
|
|
}
|
|
|
|
|
2024-01-16 02:22:24 +01:00
|
|
|
g_debug ("node %p type '%s' size %zu", node,
|
2024-01-16 17:30:37 +01:00
|
|
|
gi_ir_node_type_to_string (node->type), size);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 02:22:24 +01:00
|
|
|
g_assert (size <= G_MAXUINT32);
|
|
|
|
|
2024-04-25 01:41:34 +02:00
|
|
|
return (guint32) size;
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
|
2009-02-20 03:48:51 +01:00
|
|
|
static void
|
|
|
|
add_attribute_size (gpointer key, gpointer value, gpointer data)
|
|
|
|
{
|
2024-01-15 20:20:47 +01:00
|
|
|
const char *key_str = key;
|
|
|
|
const char *value_str = value;
|
2024-01-16 02:22:24 +01:00
|
|
|
size_t *size_p = data;
|
2009-02-20 03:48:51 +01:00
|
|
|
|
|
|
|
*size_p += sizeof (AttributeBlob);
|
|
|
|
*size_p += ALIGN_VALUE (strlen (key_str) + 1, 4);
|
|
|
|
*size_p += ALIGN_VALUE (strlen (value_str) + 1, 4);
|
|
|
|
}
|
|
|
|
|
2010-06-15 16:50:42 +02:00
|
|
|
/* returns the full size of the blob including variable-size parts (including attributes) */
|
2024-01-15 22:20:02 +01:00
|
|
|
static uint32_t
|
2023-11-08 16:23:31 +01:00
|
|
|
gi_ir_node_get_full_size_internal (GIIrNode *parent,
|
|
|
|
GIIrNode *node)
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
|
|
|
GList *l;
|
2024-01-16 02:22:24 +01:00
|
|
|
size_t size, n;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-04-12 16:52:31 +02:00
|
|
|
g_assert (node != NULL);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
|
|
|
g_debug ("node %p type '%s'", node,
|
2024-01-16 17:30:37 +01:00
|
|
|
gi_ir_node_type_to_string (node->type));
|
2008-08-09 14:46:48 +02:00
|
|
|
|
|
|
|
switch (node->type)
|
|
|
|
{
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_CALLBACK:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeFunction *function = (GIIrNodeFunction *)node;
|
|
|
|
size = sizeof (CallbackBlob);
|
|
|
|
size += ALIGN_VALUE (strlen (node->name) + 1, 4);
|
|
|
|
for (l = function->parameters; l; l = l->next)
|
|
|
|
{
|
|
|
|
size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)l->data);
|
|
|
|
}
|
|
|
|
size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)function->result);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_FUNCTION:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeFunction *function = (GIIrNodeFunction *)node;
|
|
|
|
size = sizeof (FunctionBlob);
|
|
|
|
size += ALIGN_VALUE (strlen (node->name) + 1, 4);
|
|
|
|
size += ALIGN_VALUE (strlen (function->symbol) + 1, 4);
|
|
|
|
for (l = function->parameters; l; l = l->next)
|
|
|
|
size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)l->data);
|
|
|
|
size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)function->result);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_PARAM:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeParam *param = (GIIrNodeParam *)node;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
/* See the comment in the GI_IR_NODE_PARAM/ArgBlob writing below */
|
|
|
|
size = sizeof (ArgBlob) - sizeof (SimpleTypeBlob);
|
|
|
|
if (node->name)
|
|
|
|
size += ALIGN_VALUE (strlen (node->name) + 1, 4);
|
|
|
|
size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)param->type);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_TYPE:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeType *type = (GIIrNodeType *)node;
|
2009-02-12 05:53:05 +01:00
|
|
|
size = sizeof (SimpleTypeBlob);
|
2022-02-13 15:35:53 +01:00
|
|
|
if (!GI_TYPE_TAG_IS_BASIC (type->tag))
|
2024-01-16 17:30:37 +01:00
|
|
|
{
|
|
|
|
g_debug ("node %p type tag '%s'", node,
|
|
|
|
gi_type_tag_to_string (type->tag));
|
|
|
|
|
|
|
|
switch (type->tag)
|
|
|
|
{
|
|
|
|
case GI_TYPE_TAG_ARRAY:
|
|
|
|
size = sizeof (ArrayTypeBlob);
|
|
|
|
if (type->parameter_type1)
|
|
|
|
size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)type->parameter_type1);
|
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_INTERFACE:
|
|
|
|
size += sizeof (InterfaceTypeBlob);
|
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_GLIST:
|
|
|
|
case GI_TYPE_TAG_GSLIST:
|
|
|
|
size += sizeof (ParamTypeBlob);
|
|
|
|
if (type->parameter_type1)
|
|
|
|
size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)type->parameter_type1);
|
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_GHASH:
|
|
|
|
size += sizeof (ParamTypeBlob) * 2;
|
|
|
|
if (type->parameter_type1)
|
|
|
|
size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)type->parameter_type1);
|
|
|
|
if (type->parameter_type2)
|
|
|
|
size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)type->parameter_type2);
|
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_ERROR:
|
|
|
|
size += sizeof (ErrorTypeBlob);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
g_error ("Unknown type tag %d", type->tag);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_OBJECT:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeInterface *iface = (GIIrNodeInterface *)node;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
n = g_list_length (iface->interfaces);
|
|
|
|
size = sizeof(ObjectBlob);
|
|
|
|
if (iface->parent)
|
|
|
|
size += ALIGN_VALUE (strlen (iface->parent) + 1, 4);
|
2009-02-20 23:34:20 +01:00
|
|
|
if (iface->glib_type_struct)
|
|
|
|
size += ALIGN_VALUE (strlen (iface->glib_type_struct) + 1, 4);
|
2024-01-16 17:30:37 +01:00
|
|
|
size += ALIGN_VALUE (strlen (node->name) + 1, 4);
|
|
|
|
size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4);
|
|
|
|
if (iface->gtype_init)
|
|
|
|
size += ALIGN_VALUE (strlen (iface->gtype_init) + 1, 4);
|
|
|
|
if (iface->ref_func)
|
|
|
|
size += ALIGN_VALUE (strlen (iface->ref_func) + 1, 4);
|
|
|
|
if (iface->unref_func)
|
|
|
|
size += ALIGN_VALUE (strlen (iface->unref_func) + 1, 4);
|
|
|
|
if (iface->set_value_func)
|
|
|
|
size += ALIGN_VALUE (strlen (iface->set_value_func) + 1, 4);
|
|
|
|
if (iface->get_value_func)
|
|
|
|
size += ALIGN_VALUE (strlen (iface->get_value_func) + 1, 4);
|
|
|
|
size += 2 * (n + (n % 2));
|
|
|
|
|
|
|
|
for (l = iface->members; l; l = l->next)
|
|
|
|
size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)l->data);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_INTERFACE:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeInterface *iface = (GIIrNodeInterface *)node;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
n = g_list_length (iface->prerequisites);
|
|
|
|
size = sizeof (InterfaceBlob);
|
|
|
|
size += ALIGN_VALUE (strlen (node->name) + 1, 4);
|
|
|
|
size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4);
|
|
|
|
size += ALIGN_VALUE (strlen (iface->gtype_init) + 1, 4);
|
|
|
|
size += 2 * (n + (n % 2));
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
for (l = iface->members; l; l = l->next)
|
|
|
|
size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)l->data);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_ENUM:
|
|
|
|
case GI_IR_NODE_FLAGS:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeEnum *enum_ = (GIIrNodeEnum *)node;
|
|
|
|
|
|
|
|
size = sizeof (EnumBlob);
|
|
|
|
size += ALIGN_VALUE (strlen (node->name) + 1, 4);
|
|
|
|
if (enum_->gtype_name)
|
|
|
|
{
|
|
|
|
size += ALIGN_VALUE (strlen (enum_->gtype_name) + 1, 4);
|
|
|
|
size += ALIGN_VALUE (strlen (enum_->gtype_init) + 1, 4);
|
|
|
|
}
|
|
|
|
if (enum_->error_domain)
|
|
|
|
size += ALIGN_VALUE (strlen (enum_->error_domain) + 1, 4);
|
|
|
|
|
|
|
|
for (l = enum_->values; l; l = l->next)
|
|
|
|
size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)l->data);
|
|
|
|
for (l = enum_->methods; l; l = l->next)
|
|
|
|
size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)l->data);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_VALUE:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
size = sizeof (ValueBlob);
|
|
|
|
size += ALIGN_VALUE (strlen (node->name) + 1, 4);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_STRUCT:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeStruct *struct_ = (GIIrNodeStruct *)node;
|
|
|
|
|
|
|
|
size = sizeof (StructBlob);
|
|
|
|
size += ALIGN_VALUE (strlen (node->name) + 1, 4);
|
|
|
|
if (struct_->gtype_name)
|
|
|
|
size += ALIGN_VALUE (strlen (struct_->gtype_name) + 1, 4);
|
|
|
|
if (struct_->gtype_init)
|
|
|
|
size += ALIGN_VALUE (strlen (struct_->gtype_init) + 1, 4);
|
|
|
|
if (struct_->copy_func)
|
|
|
|
size += ALIGN_VALUE (strlen (struct_->copy_func) + 1, 4);
|
|
|
|
if (struct_->free_func)
|
|
|
|
size += ALIGN_VALUE (strlen (struct_->free_func) + 1, 4);
|
|
|
|
for (l = struct_->members; l; l = l->next)
|
|
|
|
size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)l->data);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_BOXED:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeBoxed *boxed = (GIIrNodeBoxed *)node;
|
|
|
|
|
|
|
|
size = sizeof (StructBlob);
|
|
|
|
size += ALIGN_VALUE (strlen (node->name) + 1, 4);
|
|
|
|
if (boxed->gtype_name)
|
|
|
|
{
|
|
|
|
size += ALIGN_VALUE (strlen (boxed->gtype_name) + 1, 4);
|
|
|
|
size += ALIGN_VALUE (strlen (boxed->gtype_init) + 1, 4);
|
|
|
|
}
|
|
|
|
for (l = boxed->members; l; l = l->next)
|
|
|
|
size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)l->data);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_PROPERTY:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeProperty *prop = (GIIrNodeProperty *)node;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
size = sizeof (PropertyBlob);
|
|
|
|
size += ALIGN_VALUE (strlen (node->name) + 1, 4);
|
|
|
|
size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)prop->type);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_SIGNAL:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeSignal *signal = (GIIrNodeSignal *)node;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
size = sizeof (SignalBlob);
|
|
|
|
size += ALIGN_VALUE (strlen (node->name) + 1, 4);
|
|
|
|
for (l = signal->parameters; l; l = l->next)
|
|
|
|
size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)l->data);
|
|
|
|
size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)signal->result);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_VFUNC:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeVFunc *vfunc = (GIIrNodeVFunc *)node;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
size = sizeof (VFuncBlob);
|
|
|
|
size += ALIGN_VALUE (strlen (node->name) + 1, 4);
|
|
|
|
for (l = vfunc->parameters; l; l = l->next)
|
|
|
|
size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)l->data);
|
|
|
|
size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)vfunc->result);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_FIELD:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeField *field = (GIIrNodeField *)node;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
size = sizeof (FieldBlob);
|
|
|
|
size += ALIGN_VALUE (strlen (node->name) + 1, 4);
|
|
|
|
if (field->callback)
|
2023-11-08 16:23:31 +01:00
|
|
|
size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)field->callback);
|
2024-01-16 17:30:37 +01:00
|
|
|
else
|
2023-11-08 16:23:31 +01:00
|
|
|
size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)field->type);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_CONSTANT:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeConstant *constant = (GIIrNodeConstant *)node;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
size = sizeof (ConstantBlob);
|
|
|
|
size += ALIGN_VALUE (strlen (node->name) + 1, 4);
|
|
|
|
/* FIXME non-string values */
|
|
|
|
size += ALIGN_VALUE (strlen (constant->value) + 1, 4);
|
|
|
|
size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)constant->type);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_XREF:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeXRef *xref = (GIIrNodeXRef *)node;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
size = 0;
|
|
|
|
size += ALIGN_VALUE (strlen (node->name) + 1, 4);
|
|
|
|
size += ALIGN_VALUE (strlen (xref->namespace) + 1, 4);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_UNION:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeUnion *union_ = (GIIrNodeUnion *)node;
|
|
|
|
|
|
|
|
size = sizeof (UnionBlob);
|
|
|
|
size += ALIGN_VALUE (strlen (node->name) + 1, 4);
|
|
|
|
if (union_->gtype_name)
|
|
|
|
size += ALIGN_VALUE (strlen (union_->gtype_name) + 1, 4);
|
|
|
|
if (union_->gtype_init)
|
|
|
|
size += ALIGN_VALUE (strlen (union_->gtype_init) + 1, 4);
|
|
|
|
if (union_->copy_func)
|
|
|
|
size += ALIGN_VALUE (strlen (union_->copy_func) + 1, 4);
|
|
|
|
if (union_->free_func)
|
|
|
|
size += ALIGN_VALUE (strlen (union_->free_func) + 1, 4);
|
|
|
|
for (l = union_->members; l; l = l->next)
|
|
|
|
size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)l->data);
|
|
|
|
for (l = union_->discriminators; l; l = l->next)
|
|
|
|
size += gi_ir_node_get_full_size_internal (node, (GIIrNode *)l->data);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2010-03-24 19:00:06 +01:00
|
|
|
default:
|
2023-12-20 23:41:10 +01:00
|
|
|
g_error ("Unknown type tag %d", node->type);
|
2008-08-09 14:46:48 +02:00
|
|
|
size = 0;
|
|
|
|
}
|
|
|
|
|
2024-01-16 02:22:24 +01:00
|
|
|
g_debug ("node %s%s%s%p type '%s' full size %zu",
|
2024-01-16 17:30:37 +01:00
|
|
|
node->name ? "'" : "",
|
|
|
|
node->name ? node->name : "",
|
|
|
|
node->name ? "' " : "",
|
|
|
|
node, gi_ir_node_type_to_string (node->type), size);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2010-06-15 16:50:42 +02:00
|
|
|
g_hash_table_foreach (node->attributes, add_attribute_size, &size);
|
|
|
|
|
2024-01-16 02:22:24 +01:00
|
|
|
g_assert (size <= G_MAXUINT32);
|
|
|
|
|
2008-08-09 14:46:48 +02:00
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
2024-01-15 22:20:02 +01:00
|
|
|
uint32_t
|
2023-11-08 16:23:31 +01:00
|
|
|
gi_ir_node_get_full_size (GIIrNode *node)
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2023-11-08 16:23:31 +01:00
|
|
|
return gi_ir_node_get_full_size_internal (NULL, node);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2023-11-08 16:23:31 +01:00
|
|
|
gi_ir_node_cmp (GIIrNode *node,
|
|
|
|
GIIrNode *other)
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
|
|
|
if (node->type < other->type)
|
|
|
|
return -1;
|
|
|
|
else if (node->type > other->type)
|
|
|
|
return 1;
|
|
|
|
else
|
|
|
|
return strcmp (node->name, other->name);
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
2023-11-08 16:23:31 +01:00
|
|
|
gi_ir_node_can_have_member (GIIrNode *node)
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
|
|
|
switch (node->type)
|
|
|
|
{
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_OBJECT:
|
|
|
|
case GI_IR_NODE_INTERFACE:
|
|
|
|
case GI_IR_NODE_BOXED:
|
|
|
|
case GI_IR_NODE_STRUCT:
|
|
|
|
case GI_IR_NODE_UNION:
|
2008-08-09 14:46:48 +02:00
|
|
|
return TRUE;
|
Bug 556543 – reduce compiler warnings
2008-10-16 Tommi Komulainen <tommi.komulainen@iki.fi>
Bug 556543 – reduce compiler warnings
* girepository/ginfo.c:
* girepository/girepository.c (register_internal,
count_interfaces, find_interface, find_namespace_version,
parse_version, g_irepository_require):
* girepository/girmodule.c (g_ir_module_build_typelib):
* girepository/girnode.c (init_stats, dump_stats,
_g_irnode_init_stats, _g_irnode_dump_stats,
g_ir_node_can_have_member):
* girepository/girparser.c (firstpass_end_element_handler,
locate_gir, parse_basic, parse_type_internal, resolve_aliases,
start_alias, start_type, end_type_top, parse_include, cleanup,
post_filter):
* girepository/gtypelib.c (validate_function_blob, validate_enum_blob):
* giscanner/giscannermodule.c (directive_get_options,
type_get_child_list):
* giscanner/scannerlexer.l (parse_gtkdoc):
* giscanner/scannerparser.y (ctype_free):
* giscanner/sourcescanner.c:
* giscanner/sourcescanner.h (gi_source_scanner_parse_macros):
* tests/types/gitesttypes.c:
* tools/compiler.c (main):
* tools/generate.c (write_repository): Remove unused variables
and code, add missing includes, declarations and case
statements.
svn path=/trunk/; revision=730
2008-10-16 19:07:05 +02:00
|
|
|
/* list others individually rather than with default: so that compiler
|
|
|
|
* warns if new node types are added without adding them to the switch
|
|
|
|
*/
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_INVALID:
|
|
|
|
case GI_IR_NODE_FUNCTION:
|
|
|
|
case GI_IR_NODE_CALLBACK:
|
|
|
|
case GI_IR_NODE_ENUM:
|
|
|
|
case GI_IR_NODE_FLAGS:
|
|
|
|
case GI_IR_NODE_CONSTANT:
|
|
|
|
case GI_IR_NODE_INVALID_0:
|
|
|
|
case GI_IR_NODE_PARAM:
|
|
|
|
case GI_IR_NODE_TYPE:
|
|
|
|
case GI_IR_NODE_PROPERTY:
|
|
|
|
case GI_IR_NODE_SIGNAL:
|
|
|
|
case GI_IR_NODE_VALUE:
|
|
|
|
case GI_IR_NODE_VFUNC:
|
|
|
|
case GI_IR_NODE_FIELD:
|
|
|
|
case GI_IR_NODE_XREF:
|
Bug 556543 – reduce compiler warnings
2008-10-16 Tommi Komulainen <tommi.komulainen@iki.fi>
Bug 556543 – reduce compiler warnings
* girepository/ginfo.c:
* girepository/girepository.c (register_internal,
count_interfaces, find_interface, find_namespace_version,
parse_version, g_irepository_require):
* girepository/girmodule.c (g_ir_module_build_typelib):
* girepository/girnode.c (init_stats, dump_stats,
_g_irnode_init_stats, _g_irnode_dump_stats,
g_ir_node_can_have_member):
* girepository/girparser.c (firstpass_end_element_handler,
locate_gir, parse_basic, parse_type_internal, resolve_aliases,
start_alias, start_type, end_type_top, parse_include, cleanup,
post_filter):
* girepository/gtypelib.c (validate_function_blob, validate_enum_blob):
* giscanner/giscannermodule.c (directive_get_options,
type_get_child_list):
* giscanner/scannerlexer.l (parse_gtkdoc):
* giscanner/scannerparser.y (ctype_free):
* giscanner/sourcescanner.c:
* giscanner/sourcescanner.h (gi_source_scanner_parse_macros):
* tests/types/gitesttypes.c:
* tools/compiler.c (main):
* tools/generate.c (write_repository): Remove unused variables
and code, add missing includes, declarations and case
statements.
svn path=/trunk/; revision=730
2008-10-16 19:07:05 +02:00
|
|
|
return FALSE;
|
2018-07-29 17:13:16 +02:00
|
|
|
default:
|
|
|
|
g_assert_not_reached ();
|
2008-08-09 14:46:48 +02:00
|
|
|
};
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2023-11-08 16:23:31 +01:00
|
|
|
gi_ir_node_add_member (GIIrNode *node,
|
|
|
|
GIIrNodeFunction *member)
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
|
|
|
g_return_if_fail (node != NULL);
|
|
|
|
g_return_if_fail (member != NULL);
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2008-08-09 14:46:48 +02:00
|
|
|
switch (node->type)
|
|
|
|
{
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_OBJECT:
|
|
|
|
case GI_IR_NODE_INTERFACE:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeInterface *iface = (GIIrNodeInterface *)node;
|
|
|
|
iface->members =
|
|
|
|
g_list_insert_sorted (iface->members, member,
|
|
|
|
(GCompareFunc) gi_ir_node_cmp);
|
|
|
|
break;
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_BOXED:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeBoxed *boxed = (GIIrNodeBoxed *)node;
|
|
|
|
boxed->members =
|
|
|
|
g_list_insert_sorted (boxed->members, member,
|
|
|
|
(GCompareFunc) gi_ir_node_cmp);
|
|
|
|
break;
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_STRUCT:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeStruct *struct_ = (GIIrNodeStruct *)node;
|
|
|
|
struct_->members =
|
|
|
|
g_list_insert_sorted (struct_->members, member,
|
|
|
|
(GCompareFunc) gi_ir_node_cmp);
|
|
|
|
break;
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_UNION:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeUnion *union_ = (GIIrNodeUnion *)node;
|
|
|
|
union_->members =
|
|
|
|
g_list_insert_sorted (union_->members, member,
|
|
|
|
(GCompareFunc) gi_ir_node_cmp);
|
|
|
|
break;
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
default:
|
2023-12-20 23:41:10 +01:00
|
|
|
g_error ("Cannot add a member to unknown type tag type %d",
|
2024-01-16 17:30:37 +01:00
|
|
|
node->type);
|
2008-08-09 14:46:48 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-15 20:20:47 +01:00
|
|
|
const char *
|
2023-11-08 16:23:31 +01:00
|
|
|
gi_ir_node_param_direction_string (GIIrNodeParam * node)
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
|
|
|
if (node->out)
|
|
|
|
{
|
|
|
|
if (node->in)
|
2024-01-16 17:30:37 +01:00
|
|
|
return "in-out";
|
2008-08-09 14:46:48 +02:00
|
|
|
else
|
2024-01-16 17:30:37 +01:00
|
|
|
return "out";
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
return "in";
|
|
|
|
}
|
|
|
|
|
2024-01-15 22:20:02 +01:00
|
|
|
static int64_t
|
2024-01-15 20:20:47 +01:00
|
|
|
parse_int_value (const char *str)
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2017-09-24 15:32:26 +02:00
|
|
|
return g_ascii_strtoll (str, NULL, 0);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
|
2024-01-15 22:20:02 +01:00
|
|
|
static uint64_t
|
2024-01-15 20:20:47 +01:00
|
|
|
parse_uint_value (const char *str)
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2017-09-24 15:32:26 +02:00
|
|
|
return g_ascii_strtoull (str, NULL, 0);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
|
2024-01-15 22:20:02 +01:00
|
|
|
static double
|
2024-01-15 20:20:47 +01:00
|
|
|
parse_float_value (const char *str)
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2017-09-24 15:32:26 +02:00
|
|
|
return g_ascii_strtod (str, NULL);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
2024-01-15 20:20:47 +01:00
|
|
|
parse_boolean_value (const char *str)
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2013-11-29 01:12:40 +01:00
|
|
|
if (g_ascii_strcasecmp (str, "TRUE") == 0)
|
2008-08-09 14:46:48 +02:00
|
|
|
return TRUE;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2013-11-29 01:12:40 +01:00
|
|
|
if (g_ascii_strcasecmp (str, "FALSE") == 0)
|
2008-08-09 14:46:48 +02:00
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
return parse_int_value (str) ? TRUE : FALSE;
|
|
|
|
}
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
static GIIrNode *
|
|
|
|
find_entry_node (GIIrTypelibBuild *build,
|
2024-01-15 20:20:47 +01:00
|
|
|
const char *name,
|
2024-01-15 22:20:02 +01:00
|
|
|
uint16_t *idx)
|
2008-08-09 14:46:48 +02:00
|
|
|
|
|
|
|
{
|
2023-11-08 15:17:52 +01:00
|
|
|
GIIrModule *module = build->module;
|
2008-08-09 14:46:48 +02:00
|
|
|
GList *l;
|
2024-01-16 01:57:09 +01:00
|
|
|
size_t i;
|
2024-01-15 22:47:52 +01:00
|
|
|
unsigned int n_names;
|
2024-01-15 20:20:47 +01:00
|
|
|
char **names;
|
2023-11-08 15:17:52 +01:00
|
|
|
GIIrNode *result = NULL;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2008-08-18 10:52:47 +02:00
|
|
|
g_assert (name != NULL);
|
|
|
|
g_assert (strlen (name) > 0);
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2008-08-09 14:46:48 +02:00
|
|
|
names = g_strsplit (name, ".", 0);
|
|
|
|
n_names = g_strv_length (names);
|
|
|
|
if (n_names > 2)
|
|
|
|
g_error ("Too many name parts");
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2008-08-09 14:46:48 +02:00
|
|
|
for (l = module->entries, i = 1; l; l = l->next, i++)
|
|
|
|
{
|
2023-11-08 15:17:52 +01:00
|
|
|
GIIrNode *node = (GIIrNode *)l->data;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2008-08-09 14:46:48 +02:00
|
|
|
if (n_names > 1)
|
2024-01-16 17:30:37 +01:00
|
|
|
{
|
|
|
|
if (node->type != GI_IR_NODE_XREF)
|
|
|
|
continue;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
if (((GIIrNodeXRef *)node)->namespace == NULL ||
|
|
|
|
strcmp (((GIIrNodeXRef *)node)->namespace, names[0]) != 0)
|
|
|
|
continue;
|
|
|
|
}
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2008-08-09 14:46:48 +02:00
|
|
|
if (strcmp (node->name, names[n_names - 1]) == 0)
|
2024-01-16 17:30:37 +01:00
|
|
|
{
|
|
|
|
if (idx)
|
|
|
|
*idx = i;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
result = node;
|
|
|
|
goto out;
|
|
|
|
}
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (n_names > 1)
|
|
|
|
{
|
2023-11-08 16:23:31 +01:00
|
|
|
GIIrNode *node = gi_ir_node_new (GI_IR_NODE_XREF, module);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
((GIIrNodeXRef *)node)->namespace = g_strdup (names[0]);
|
2008-08-09 14:46:48 +02:00
|
|
|
node->name = g_strdup (names[1]);
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2008-08-09 14:46:48 +02:00
|
|
|
module->entries = g_list_append (module->entries, node);
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2008-08-09 14:46:48 +02:00
|
|
|
if (idx)
|
2024-01-16 17:30:37 +01:00
|
|
|
*idx = g_list_length (module->entries);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
|
|
|
result = node;
|
|
|
|
|
2008-08-23 23:30:06 +02:00
|
|
|
g_debug ("Creating XREF: %s %s", names[0], names[1]);
|
|
|
|
|
2008-08-09 14:46:48 +02:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2010-07-26 22:26:46 +02:00
|
|
|
|
2024-01-16 01:47:01 +01:00
|
|
|
gi_ir_module_fatal (build, 0, "type reference '%s' not found", name);
|
2008-08-09 14:46:48 +02:00
|
|
|
out:
|
|
|
|
|
|
|
|
g_strfreev (names);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2024-01-15 22:20:02 +01:00
|
|
|
static uint16_t
|
2023-11-08 15:17:52 +01:00
|
|
|
find_entry (GIIrTypelibBuild *build,
|
2024-01-15 20:20:47 +01:00
|
|
|
const char *name)
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-15 22:20:02 +01:00
|
|
|
uint16_t idx = 0;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2010-07-26 22:26:46 +02:00
|
|
|
find_entry_node (build, name, &idx);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
|
|
|
return idx;
|
|
|
|
}
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
static GIIrModule *
|
|
|
|
find_namespace (GIIrModule *module,
|
|
|
|
const char *name)
|
2008-11-11 01:48:17 +01:00
|
|
|
{
|
2023-11-08 15:17:52 +01:00
|
|
|
GIIrModule *target;
|
2008-11-11 01:48:17 +01:00
|
|
|
GList *l;
|
2010-07-26 22:26:46 +02:00
|
|
|
|
|
|
|
if (strcmp (module->name, name) == 0)
|
|
|
|
return module;
|
2008-11-11 01:48:17 +01:00
|
|
|
|
2010-07-26 22:26:46 +02:00
|
|
|
for (l = module->include_modules; l; l = l->next)
|
2008-11-11 01:48:17 +01:00
|
|
|
{
|
2023-11-08 15:17:52 +01:00
|
|
|
GIIrModule *submodule = l->data;
|
2008-11-11 01:48:17 +01:00
|
|
|
|
2010-07-26 22:26:46 +02:00
|
|
|
if (strcmp (submodule->name, name) == 0)
|
|
|
|
return submodule;
|
2008-11-11 01:48:17 +01:00
|
|
|
|
2010-07-26 22:26:46 +02:00
|
|
|
target = find_namespace (submodule, name);
|
|
|
|
if (target)
|
|
|
|
return target;
|
|
|
|
}
|
2008-11-11 01:48:17 +01:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
GIIrNode *
|
2023-11-08 16:23:31 +01:00
|
|
|
gi_ir_find_node (GIIrTypelibBuild *build,
|
|
|
|
GIIrModule *src_module,
|
|
|
|
const char *name)
|
2008-11-11 01:48:17 +01:00
|
|
|
{
|
2010-07-26 22:26:46 +02:00
|
|
|
GList *l;
|
2023-11-08 15:17:52 +01:00
|
|
|
GIIrNode *return_node = NULL;
|
2008-11-11 01:48:17 +01:00
|
|
|
char **names = g_strsplit (name, ".", 0);
|
2024-01-15 22:47:52 +01:00
|
|
|
unsigned n_names = g_strv_length (names);
|
2010-07-26 22:26:46 +02:00
|
|
|
const char *target_name;
|
2023-11-08 15:17:52 +01:00
|
|
|
GIIrModule *target_module;
|
2008-11-11 01:48:17 +01:00
|
|
|
|
|
|
|
if (n_names == 1)
|
|
|
|
{
|
2010-07-26 22:26:46 +02:00
|
|
|
target_module = src_module;
|
|
|
|
target_name = name;
|
2008-11-11 01:48:17 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-07-26 22:26:46 +02:00
|
|
|
target_module = find_namespace (build->module, names[0]);
|
|
|
|
target_name = names[1];
|
|
|
|
}
|
2008-11-11 01:48:17 +01:00
|
|
|
|
2013-11-06 12:37:50 +01:00
|
|
|
/* find_namespace() may return NULL. */
|
|
|
|
if (target_module == NULL)
|
|
|
|
goto done;
|
|
|
|
|
2010-07-26 22:26:46 +02:00
|
|
|
for (l = target_module->entries; l; l = l->next)
|
|
|
|
{
|
2023-11-08 15:17:52 +01:00
|
|
|
GIIrNode *node = (GIIrNode *)l->data;
|
2008-11-11 01:48:17 +01:00
|
|
|
|
2010-07-26 22:26:46 +02:00
|
|
|
if (strcmp (node->name, target_name) == 0)
|
2024-01-16 17:30:37 +01:00
|
|
|
{
|
|
|
|
return_node = node;
|
|
|
|
break;
|
|
|
|
}
|
2008-11-11 01:48:17 +01:00
|
|
|
}
|
|
|
|
|
2013-11-06 12:37:50 +01:00
|
|
|
done:
|
2008-11-11 01:48:17 +01:00
|
|
|
g_strfreev (names);
|
|
|
|
|
2010-07-26 22:26:46 +02:00
|
|
|
return return_node;
|
2008-11-11 01:48:17 +01:00
|
|
|
}
|
|
|
|
|
2009-02-28 01:02:48 +01:00
|
|
|
static int
|
2023-11-08 15:17:52 +01:00
|
|
|
get_index_of_member_type (GIIrNodeInterface *node,
|
|
|
|
GIIrNodeTypeId type,
|
|
|
|
const char *name)
|
2009-02-28 01:02:48 +01:00
|
|
|
{
|
2024-01-15 22:20:02 +01:00
|
|
|
int index = -1;
|
2009-02-28 01:02:48 +01:00
|
|
|
GList *l;
|
|
|
|
|
|
|
|
for (l = node->members; l; l = l->next)
|
|
|
|
{
|
2023-11-08 15:17:52 +01:00
|
|
|
GIIrNode *member_node = l->data;
|
2009-02-28 01:02:48 +01:00
|
|
|
|
2018-07-29 15:56:35 +02:00
|
|
|
if (member_node->type != type)
|
2009-02-28 01:02:48 +01:00
|
|
|
continue;
|
|
|
|
|
|
|
|
index++;
|
|
|
|
|
2018-07-29 15:56:35 +02:00
|
|
|
if (strcmp (member_node->name, name) == 0)
|
2009-02-28 01:02:48 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return index;
|
|
|
|
}
|
|
|
|
|
2008-08-09 14:46:48 +02:00
|
|
|
static void
|
2023-11-08 15:17:52 +01:00
|
|
|
serialize_type (GIIrTypelibBuild *build,
|
|
|
|
GIIrNodeType *node,
|
|
|
|
GString *str)
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 01:57:09 +01:00
|
|
|
size_t i;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2022-02-13 15:35:53 +01:00
|
|
|
if (GI_TYPE_TAG_IS_BASIC (node->tag))
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2023-11-08 15:17:52 +01:00
|
|
|
g_string_append_printf (str, "%s%s", gi_type_tag_to_string (node->tag),
|
2024-01-16 17:30:37 +01:00
|
|
|
node->is_pointer ? "*" : "");
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
2008-08-23 00:15:28 +02:00
|
|
|
else if (node->tag == GI_TYPE_TAG_ARRAY)
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2011-02-18 18:14:25 +01:00
|
|
|
if (node->array_type == GI_ARRAY_TYPE_C)
|
2024-01-16 17:30:37 +01:00
|
|
|
{
|
|
|
|
serialize_type (build, node->parameter_type1, str);
|
|
|
|
g_string_append (str, "[");
|
|
|
|
|
|
|
|
if (node->has_length)
|
|
|
|
g_string_append_printf (str, "length=%d", node->length);
|
|
|
|
else if (node->has_size)
|
2024-01-26 10:15:43 +01:00
|
|
|
g_string_append_printf (str, "fixed-size=%" G_GSIZE_FORMAT, node->size);
|
2024-01-16 17:30:37 +01:00
|
|
|
|
|
|
|
if (node->zero_terminated)
|
|
|
|
g_string_append_printf (str, "%szero-terminated=1",
|
|
|
|
node->has_length ? "," : "");
|
|
|
|
|
|
|
|
g_string_append (str, "]");
|
|
|
|
if (node->is_pointer)
|
|
|
|
g_string_append (str, "*");
|
|
|
|
}
|
2011-02-18 18:14:25 +01:00
|
|
|
else if (node->array_type == GI_ARRAY_TYPE_BYTE_ARRAY)
|
2024-01-16 17:30:37 +01:00
|
|
|
{
|
|
|
|
/* We on purpose skip serializing parameter_type1, which should
|
|
|
|
always be void*
|
|
|
|
*/
|
|
|
|
g_string_append (str, "GByteArray");
|
|
|
|
}
|
2011-02-18 18:14:25 +01:00
|
|
|
else
|
2024-01-16 17:30:37 +01:00
|
|
|
{
|
|
|
|
if (node->array_type == GI_ARRAY_TYPE_ARRAY)
|
|
|
|
g_string_append (str, "GArray");
|
|
|
|
else
|
|
|
|
g_string_append (str, "GPtrArray");
|
|
|
|
if (node->parameter_type1)
|
|
|
|
{
|
|
|
|
g_string_append (str, "<");
|
|
|
|
serialize_type (build, node->parameter_type1, str);
|
|
|
|
g_string_append (str, ">");
|
|
|
|
}
|
|
|
|
}
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
2008-08-23 00:15:28 +02:00
|
|
|
else if (node->tag == GI_TYPE_TAG_INTERFACE)
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2023-11-08 15:17:52 +01:00
|
|
|
GIIrNode *iface;
|
2024-01-15 20:20:47 +01:00
|
|
|
char *name;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2012-07-24 10:09:38 +02:00
|
|
|
iface = find_entry_node (build, node->giinterface, NULL);
|
2008-08-09 14:46:48 +02:00
|
|
|
if (iface)
|
2008-11-13 23:56:15 +01:00
|
|
|
{
|
2023-11-08 15:17:52 +01:00
|
|
|
if (iface->type == GI_IR_NODE_XREF)
|
|
|
|
g_string_append_printf (str, "%s.", ((GIIrNodeXRef *)iface)->namespace);
|
2008-11-13 23:56:15 +01:00
|
|
|
name = iface->name;
|
|
|
|
}
|
2008-08-09 14:46:48 +02:00
|
|
|
else
|
2024-01-16 17:30:37 +01:00
|
|
|
{
|
|
|
|
g_warning ("Interface for type reference %s not found", node->giinterface);
|
|
|
|
name = node->giinterface;
|
|
|
|
}
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2008-11-16 22:20:26 +01:00
|
|
|
g_string_append_printf (str, "%s%s", name,
|
2024-01-16 17:30:37 +01:00
|
|
|
node->is_pointer ? "*" : "");
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
2008-08-23 00:15:28 +02:00
|
|
|
else if (node->tag == GI_TYPE_TAG_GLIST)
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
|
|
|
g_string_append (str, "GList");
|
|
|
|
if (node->parameter_type1)
|
2024-01-16 17:30:37 +01:00
|
|
|
{
|
|
|
|
g_string_append (str, "<");
|
|
|
|
serialize_type (build, node->parameter_type1, str);
|
|
|
|
g_string_append (str, ">");
|
|
|
|
}
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
2008-08-23 00:15:28 +02:00
|
|
|
else if (node->tag == GI_TYPE_TAG_GSLIST)
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
|
|
|
g_string_append (str, "GSList");
|
|
|
|
if (node->parameter_type1)
|
2024-01-16 17:30:37 +01:00
|
|
|
{
|
|
|
|
g_string_append (str, "<");
|
|
|
|
serialize_type (build, node->parameter_type1, str);
|
|
|
|
g_string_append (str, ">");
|
|
|
|
}
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
2008-08-23 00:15:28 +02:00
|
|
|
else if (node->tag == GI_TYPE_TAG_GHASH)
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2011-02-18 18:14:25 +01:00
|
|
|
g_string_append (str, "GHashTable");
|
2008-08-09 14:46:48 +02:00
|
|
|
if (node->parameter_type1)
|
2024-01-16 17:30:37 +01:00
|
|
|
{
|
|
|
|
g_string_append (str, "<");
|
|
|
|
serialize_type (build, node->parameter_type1, str);
|
|
|
|
g_string_append (str, ",");
|
|
|
|
serialize_type (build, node->parameter_type2, str);
|
|
|
|
g_string_append (str, ">");
|
|
|
|
}
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
2008-08-23 00:15:28 +02:00
|
|
|
else if (node->tag == GI_TYPE_TAG_ERROR)
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
|
|
|
g_string_append (str, "GError");
|
|
|
|
if (node->errors)
|
2024-01-16 17:30:37 +01:00
|
|
|
{
|
|
|
|
g_string_append (str, "<");
|
|
|
|
for (i = 0; node->errors[i]; i++)
|
|
|
|
{
|
|
|
|
if (i > 0)
|
|
|
|
g_string_append (str, ",");
|
|
|
|
g_string_append (str, node->errors[i]);
|
|
|
|
}
|
|
|
|
g_string_append (str, ">");
|
|
|
|
}
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-10-16 00:28:41 +02:00
|
|
|
static void
|
2023-11-08 16:23:31 +01:00
|
|
|
gi_ir_node_build_members (GList **members,
|
|
|
|
GIIrNodeTypeId type,
|
2024-01-15 22:20:02 +01:00
|
|
|
uint16_t *count,
|
2023-11-08 16:23:31 +01:00
|
|
|
GIIrNode *parent,
|
|
|
|
GIIrTypelibBuild *build,
|
2024-01-15 22:20:02 +01:00
|
|
|
uint32_t *offset,
|
|
|
|
uint32_t *offset2,
|
|
|
|
uint16_t *count2)
|
2008-10-16 00:28:41 +02:00
|
|
|
{
|
|
|
|
GList *l = *members;
|
|
|
|
|
|
|
|
while (l)
|
|
|
|
{
|
2023-11-08 15:17:52 +01:00
|
|
|
GIIrNode *member = (GIIrNode *)l->data;
|
2008-10-16 00:28:41 +02:00
|
|
|
GList *next = l->next;
|
|
|
|
|
|
|
|
if (member->type == type)
|
2024-01-16 17:30:37 +01:00
|
|
|
{
|
|
|
|
(*count)++;
|
|
|
|
gi_ir_node_build_typelib (member, parent, build, offset, offset2, count2);
|
|
|
|
*members = g_list_delete_link (*members, l);
|
|
|
|
}
|
2008-10-16 00:28:41 +02:00
|
|
|
l = next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-10-16 00:28:53 +02:00
|
|
|
static void
|
2023-11-08 16:23:31 +01:00
|
|
|
gi_ir_node_check_unhandled_members (GList **members,
|
|
|
|
GIIrNodeTypeId container_type)
|
2008-10-16 00:28:53 +02:00
|
|
|
{
|
2008-10-24 13:33:33 +02:00
|
|
|
#if 0
|
2008-10-16 00:28:53 +02:00
|
|
|
if (*members)
|
|
|
|
{
|
|
|
|
GList *l;
|
|
|
|
|
|
|
|
for (l = *members; l; l = l->next)
|
2024-01-16 17:30:37 +01:00
|
|
|
{
|
|
|
|
GIIrNode *member = (GIIrNode *)l->data;
|
|
|
|
g_printerr ("Unhandled '%s' member '%s' type '%s'\n",
|
|
|
|
gi_ir_node_type_to_string (container_type),
|
|
|
|
member->name,
|
|
|
|
gi_ir_node_type_to_string (member->type));
|
|
|
|
}
|
2008-10-16 00:28:53 +02:00
|
|
|
|
|
|
|
g_list_free (*members);
|
|
|
|
*members = NULL;
|
|
|
|
|
|
|
|
g_error ("Unhandled members. Aborting.");
|
|
|
|
}
|
2008-10-24 13:33:33 +02:00
|
|
|
#else
|
|
|
|
g_list_free (*members);
|
|
|
|
*members = NULL;
|
|
|
|
#endif
|
2008-10-16 00:28:53 +02:00
|
|
|
}
|
|
|
|
|
2008-08-09 14:46:48 +02:00
|
|
|
void
|
2023-11-08 16:23:31 +01:00
|
|
|
gi_ir_node_build_typelib (GIIrNode *node,
|
|
|
|
GIIrNode *parent,
|
|
|
|
GIIrTypelibBuild *build,
|
2024-01-15 22:20:02 +01:00
|
|
|
uint32_t *offset,
|
|
|
|
uint32_t *offset2,
|
|
|
|
uint16_t *count2)
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2010-07-26 22:26:46 +02:00
|
|
|
gboolean appended_stack;
|
2009-02-20 17:05:53 +01:00
|
|
|
GHashTable *strings = build->strings;
|
|
|
|
GHashTable *types = build->types;
|
2024-01-16 00:10:43 +01:00
|
|
|
uint8_t *data = build->data;
|
2008-08-09 14:46:48 +02:00
|
|
|
GList *l;
|
2024-01-15 22:20:02 +01:00
|
|
|
uint32_t old_offset = *offset;
|
|
|
|
uint32_t old_offset2 = *offset2;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
|
|
|
g_assert (node != NULL);
|
|
|
|
|
2008-08-28 18:55:37 +02:00
|
|
|
g_debug ("build_typelib: %s%s(%s)",
|
2024-01-16 17:30:37 +01:00
|
|
|
node->name ? node->name : "",
|
|
|
|
node->name ? " " : "",
|
|
|
|
gi_ir_node_type_to_string (node->type));
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2010-07-26 22:26:46 +02:00
|
|
|
if (build->stack)
|
2023-11-08 15:17:52 +01:00
|
|
|
appended_stack = node != (GIIrNode*)build->stack->data;
|
2010-07-26 22:26:46 +02:00
|
|
|
else
|
|
|
|
appended_stack = TRUE;
|
|
|
|
if (appended_stack)
|
|
|
|
build->stack = g_list_prepend (build->stack, node);
|
|
|
|
|
2023-11-08 16:23:31 +01:00
|
|
|
gi_ir_node_compute_offsets (build, node);
|
2008-11-11 06:10:36 +01:00
|
|
|
|
2009-02-20 03:48:51 +01:00
|
|
|
/* We should only be building each node once. If we do a typelib expansion, we also
|
|
|
|
* reset the offset in girmodule.c.
|
|
|
|
*/
|
|
|
|
g_assert (node->offset == 0);
|
|
|
|
node->offset = *offset;
|
2010-06-15 16:50:42 +02:00
|
|
|
build->nodes_with_attributes = g_list_prepend (build->nodes_with_attributes, node);
|
2009-02-20 03:48:51 +01:00
|
|
|
|
|
|
|
build->n_attributes += g_hash_table_size (node->attributes);
|
|
|
|
|
2008-08-09 14:46:48 +02:00
|
|
|
switch (node->type)
|
|
|
|
{
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_TYPE:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeType *type = (GIIrNodeType *)node;
|
|
|
|
SimpleTypeBlob *blob = (SimpleTypeBlob *)&data[*offset];
|
|
|
|
|
|
|
|
*offset += sizeof (SimpleTypeBlob);
|
|
|
|
|
|
|
|
if (GI_TYPE_TAG_IS_BASIC (type->tag))
|
|
|
|
{
|
|
|
|
blob->flags.reserved = 0;
|
|
|
|
blob->flags.reserved2 = 0;
|
|
|
|
blob->flags.pointer = type->is_pointer;
|
|
|
|
blob->flags.reserved3 = 0;
|
|
|
|
blob->flags.tag = type->tag;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GString *str;
|
|
|
|
gpointer value;
|
|
|
|
|
|
|
|
str = g_string_new (0);
|
|
|
|
serialize_type (build, type, str);
|
|
|
|
|
|
|
|
types_count += 1;
|
2024-05-10 17:36:23 +02:00
|
|
|
value = g_hash_table_lookup (types, str->str);
|
2024-01-16 17:30:37 +01:00
|
|
|
if (value)
|
|
|
|
{
|
|
|
|
blob->offset = GPOINTER_TO_UINT (value);
|
2024-05-10 17:36:23 +02:00
|
|
|
g_string_free (g_steal_pointer (&str), TRUE);
|
2024-01-16 17:30:37 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
unique_types_count += 1;
|
2024-05-10 17:36:23 +02:00
|
|
|
g_hash_table_insert (types, g_string_free_and_steal (g_steal_pointer (&str)),
|
2024-05-10 17:28:17 +02:00
|
|
|
GUINT_TO_POINTER(*offset2));
|
2024-01-16 17:30:37 +01:00
|
|
|
|
|
|
|
blob->offset = *offset2;
|
|
|
|
switch (type->tag)
|
|
|
|
{
|
|
|
|
case GI_TYPE_TAG_ARRAY:
|
|
|
|
{
|
|
|
|
ArrayTypeBlob *array = (ArrayTypeBlob *)&data[*offset2];
|
2024-01-15 22:20:02 +01:00
|
|
|
uint32_t pos;
|
2024-01-16 17:30:37 +01:00
|
|
|
|
|
|
|
array->pointer = type->is_pointer;
|
|
|
|
array->reserved = 0;
|
|
|
|
array->tag = type->tag;
|
|
|
|
array->zero_terminated = type->zero_terminated;
|
|
|
|
array->has_length = type->has_length;
|
2008-10-25 17:20:54 +02:00
|
|
|
array->has_size = type->has_size;
|
2010-05-04 16:57:51 +02:00
|
|
|
array->array_type = type->array_type;
|
2024-01-16 17:30:37 +01:00
|
|
|
array->reserved2 = 0;
|
2008-10-25 17:20:54 +02:00
|
|
|
if (array->has_length)
|
2009-06-24 23:52:05 +02:00
|
|
|
array->dimensions.length = type->length;
|
2008-10-25 17:20:54 +02:00
|
|
|
else if (array->has_size)
|
2009-06-24 23:52:05 +02:00
|
|
|
array->dimensions.size = type->size;
|
2008-10-25 17:20:54 +02:00
|
|
|
else
|
2009-06-24 23:52:05 +02:00
|
|
|
array->dimensions.length = -1;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
pos = *offset2 + G_STRUCT_OFFSET (ArrayTypeBlob, type);
|
|
|
|
*offset2 += sizeof (ArrayTypeBlob);
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
gi_ir_node_build_typelib ((GIIrNode *)type->parameter_type1,
|
2023-11-08 16:23:31 +01:00
|
|
|
node, build, &pos, offset2, NULL);
|
2024-01-16 17:30:37 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GI_TYPE_TAG_INTERFACE:
|
|
|
|
{
|
|
|
|
InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&data[*offset2];
|
|
|
|
*offset2 += sizeof (InterfaceTypeBlob);
|
|
|
|
|
|
|
|
iface->pointer = type->is_pointer;
|
|
|
|
iface->reserved = 0;
|
|
|
|
iface->tag = type->tag;
|
|
|
|
iface->reserved2 = 0;
|
|
|
|
iface->interface = find_entry (build, type->giinterface);
|
|
|
|
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GI_TYPE_TAG_GLIST:
|
|
|
|
case GI_TYPE_TAG_GSLIST:
|
|
|
|
{
|
|
|
|
ParamTypeBlob *param = (ParamTypeBlob *)&data[*offset2];
|
2024-01-15 22:20:02 +01:00
|
|
|
uint32_t pos;
|
2024-01-16 17:30:37 +01:00
|
|
|
|
|
|
|
param->pointer = 1;
|
|
|
|
param->reserved = 0;
|
|
|
|
param->tag = type->tag;
|
|
|
|
param->reserved2 = 0;
|
|
|
|
param->n_types = 1;
|
|
|
|
|
|
|
|
pos = *offset2 + G_STRUCT_OFFSET (ParamTypeBlob, type);
|
|
|
|
*offset2 += sizeof (ParamTypeBlob) + sizeof (SimpleTypeBlob);
|
|
|
|
|
|
|
|
gi_ir_node_build_typelib ((GIIrNode *)type->parameter_type1,
|
2023-11-08 16:23:31 +01:00
|
|
|
node, build, &pos, offset2, NULL);
|
2024-01-16 17:30:37 +01:00
|
|
|
}
|
|
|
|
break;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
case GI_TYPE_TAG_GHASH:
|
|
|
|
{
|
|
|
|
ParamTypeBlob *param = (ParamTypeBlob *)&data[*offset2];
|
2024-01-15 22:20:02 +01:00
|
|
|
uint32_t pos;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
param->pointer = 1;
|
|
|
|
param->reserved = 0;
|
|
|
|
param->tag = type->tag;
|
|
|
|
param->reserved2 = 0;
|
|
|
|
param->n_types = 2;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
pos = *offset2 + G_STRUCT_OFFSET (ParamTypeBlob, type);
|
|
|
|
*offset2 += sizeof (ParamTypeBlob) + sizeof (SimpleTypeBlob)*2;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
gi_ir_node_build_typelib ((GIIrNode *)type->parameter_type1,
|
2023-11-08 16:23:31 +01:00
|
|
|
node, build, &pos, offset2, NULL);
|
2024-01-16 17:30:37 +01:00
|
|
|
gi_ir_node_build_typelib ((GIIrNode *)type->parameter_type2,
|
2023-11-08 16:23:31 +01:00
|
|
|
node, build, &pos, offset2, NULL);
|
2024-01-16 17:30:37 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GI_TYPE_TAG_ERROR:
|
|
|
|
{
|
|
|
|
ErrorTypeBlob *error_blob = (ErrorTypeBlob *)&data[*offset2];
|
|
|
|
|
|
|
|
error_blob->pointer = 1;
|
|
|
|
error_blob->reserved = 0;
|
|
|
|
error_blob->tag = type->tag;
|
|
|
|
error_blob->reserved2 = 0;
|
|
|
|
error_blob->n_domains = 0;
|
|
|
|
|
|
|
|
*offset2 += sizeof (ErrorTypeBlob);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
g_error ("Unknown type tag %d", type->tag);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_FIELD:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeField *field = (GIIrNodeField *)node;
|
|
|
|
FieldBlob *blob;
|
|
|
|
|
|
|
|
blob = (FieldBlob *)&data[*offset];
|
|
|
|
|
|
|
|
blob->name = gi_ir_write_string (node->name, strings, data, offset2);
|
|
|
|
blob->readable = field->readable;
|
|
|
|
blob->writable = field->writable;
|
|
|
|
blob->reserved = 0;
|
|
|
|
blob->bits = 0;
|
2024-01-26 10:20:07 +01:00
|
|
|
if (field->offset_state == GI_IR_OFFSETS_COMPUTED)
|
2024-01-16 17:30:37 +01:00
|
|
|
blob->struct_offset = field->offset;
|
|
|
|
else
|
|
|
|
blob->struct_offset = 0xFFFF; /* mark as unknown */
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2009-11-09 19:17:23 +01:00
|
|
|
if (field->callback)
|
|
|
|
{
|
|
|
|
blob->has_embedded_type = TRUE;
|
|
|
|
blob->type.offset = GI_INFO_TYPE_CALLBACK;
|
2024-01-16 17:30:37 +01:00
|
|
|
*offset += sizeof (FieldBlob);
|
2023-11-08 16:23:31 +01:00
|
|
|
gi_ir_node_build_typelib ((GIIrNode *)field->callback,
|
|
|
|
node, build, offset, offset2, NULL);
|
2014-02-28 02:10:19 +01:00
|
|
|
/* Fields with callbacks are bigger than normal, update count2
|
|
|
|
* as an extra hint which represents the number of fields which are
|
|
|
|
* callbacks. This allows us to gain constant time performance in the
|
|
|
|
* repository for skipping over the fields section.
|
|
|
|
*/
|
|
|
|
if (count2)
|
|
|
|
(*count2)++;
|
2009-11-09 19:17:23 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
blob->has_embedded_type = FALSE;
|
|
|
|
/* We handle the size member specially below, so subtract it */
|
2024-01-16 17:30:37 +01:00
|
|
|
*offset += sizeof (FieldBlob) - sizeof (SimpleTypeBlob);
|
2023-11-08 16:23:31 +01:00
|
|
|
gi_ir_node_build_typelib ((GIIrNode *)field->type,
|
|
|
|
node, build, offset, offset2, NULL);
|
2009-11-09 19:17:23 +01:00
|
|
|
}
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_PROPERTY:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeProperty *prop = (GIIrNodeProperty *)node;
|
|
|
|
PropertyBlob *blob = (PropertyBlob *)&data[*offset];
|
2009-02-12 05:53:05 +01:00
|
|
|
/* We handle the size member specially below, so subtract it */
|
2024-01-16 17:30:37 +01:00
|
|
|
*offset += sizeof (PropertyBlob) - sizeof (SimpleTypeBlob);
|
|
|
|
|
|
|
|
blob->name = gi_ir_write_string (node->name, strings, data, offset2);
|
|
|
|
blob->deprecated = prop->deprecated;
|
|
|
|
blob->readable = prop->readable;
|
|
|
|
blob->writable = prop->writable;
|
|
|
|
blob->construct = prop->construct;
|
|
|
|
blob->construct_only = prop->construct_only;
|
|
|
|
blob->transfer_ownership = prop->transfer;
|
|
|
|
blob->transfer_container_ownership = prop->shallow_transfer;
|
|
|
|
blob->reserved = 0;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
Add introspection data for property accessors
A GObject property can be accessed generically through the GObject API,
e.g. g_object_set_property() and g_object_get_property(). Properties
typically also have public accessor functions, which are (according to
our own best practices) called through the generic API.
The introspection data is currently missing the relation between a
property and its public accessor functions. With this information, a
language binding could, for instance, avoid exposing the C API entirely,
thus minimizing the chances of collisions between property names and
accessor functions; alternatively, a binding could call the C API
directly instead of going through the generic GObject API, thus avoiding
the boxing and unboxing from a native type to a GIArgument and finally
into a GValue, and vice versa.
In the GIR, we add two new attributes to the `property` element:
- setter="SYMBOL"
- getter="SYMBOL"
where "symbol" is the C function identifier of the setter and getter
functions, respectively. The `setter` attribute is only applied to
writable, non-construct-only properties; the `getter` attribute is only
applied to readable properties.
We maintain the ABI compatibility of the typelib data by using 20 bits
of the 25 reserved bits inside the PropertyBlob structure. The data is
exposed through two new GIPropertyInfo methods:
- g_property_info_get_setter()
- g_property_info_get_getter()
which return the GIFunctionInfo for the setter and getter functions,
respectively.
2021-06-17 14:07:35 +02:00
|
|
|
if (prop->setter != NULL)
|
|
|
|
{
|
2023-11-08 15:17:52 +01:00
|
|
|
int index = get_index_of_member_type ((GIIrNodeInterface*)parent,
|
|
|
|
GI_IR_NODE_FUNCTION,
|
Add introspection data for property accessors
A GObject property can be accessed generically through the GObject API,
e.g. g_object_set_property() and g_object_get_property(). Properties
typically also have public accessor functions, which are (according to
our own best practices) called through the generic API.
The introspection data is currently missing the relation between a
property and its public accessor functions. With this information, a
language binding could, for instance, avoid exposing the C API entirely,
thus minimizing the chances of collisions between property names and
accessor functions; alternatively, a binding could call the C API
directly instead of going through the generic GObject API, thus avoiding
the boxing and unboxing from a native type to a GIArgument and finally
into a GValue, and vice versa.
In the GIR, we add two new attributes to the `property` element:
- setter="SYMBOL"
- getter="SYMBOL"
where "symbol" is the C function identifier of the setter and getter
functions, respectively. The `setter` attribute is only applied to
writable, non-construct-only properties; the `getter` attribute is only
applied to readable properties.
We maintain the ABI compatibility of the typelib data by using 20 bits
of the 25 reserved bits inside the PropertyBlob structure. The data is
exposed through two new GIPropertyInfo methods:
- g_property_info_get_setter()
- g_property_info_get_getter()
which return the GIFunctionInfo for the setter and getter functions,
respectively.
2021-06-17 14:07:35 +02:00
|
|
|
prop->setter);
|
|
|
|
if (index == -1)
|
|
|
|
{
|
2021-07-27 15:46:15 +02:00
|
|
|
g_error ("Unknown setter %s for property %s:%s", prop->setter, parent->name, node->name);
|
Add introspection data for property accessors
A GObject property can be accessed generically through the GObject API,
e.g. g_object_set_property() and g_object_get_property(). Properties
typically also have public accessor functions, which are (according to
our own best practices) called through the generic API.
The introspection data is currently missing the relation between a
property and its public accessor functions. With this information, a
language binding could, for instance, avoid exposing the C API entirely,
thus minimizing the chances of collisions between property names and
accessor functions; alternatively, a binding could call the C API
directly instead of going through the generic GObject API, thus avoiding
the boxing and unboxing from a native type to a GIArgument and finally
into a GValue, and vice versa.
In the GIR, we add two new attributes to the `property` element:
- setter="SYMBOL"
- getter="SYMBOL"
where "symbol" is the C function identifier of the setter and getter
functions, respectively. The `setter` attribute is only applied to
writable, non-construct-only properties; the `getter` attribute is only
applied to readable properties.
We maintain the ABI compatibility of the typelib data by using 20 bits
of the 25 reserved bits inside the PropertyBlob structure. The data is
exposed through two new GIPropertyInfo methods:
- g_property_info_get_setter()
- g_property_info_get_getter()
which return the GIFunctionInfo for the setter and getter functions,
respectively.
2021-06-17 14:07:35 +02:00
|
|
|
}
|
|
|
|
|
2024-01-15 22:47:52 +01:00
|
|
|
blob->setter = (uint16_t) index;
|
Add introspection data for property accessors
A GObject property can be accessed generically through the GObject API,
e.g. g_object_set_property() and g_object_get_property(). Properties
typically also have public accessor functions, which are (according to
our own best practices) called through the generic API.
The introspection data is currently missing the relation between a
property and its public accessor functions. With this information, a
language binding could, for instance, avoid exposing the C API entirely,
thus minimizing the chances of collisions between property names and
accessor functions; alternatively, a binding could call the C API
directly instead of going through the generic GObject API, thus avoiding
the boxing and unboxing from a native type to a GIArgument and finally
into a GValue, and vice versa.
In the GIR, we add two new attributes to the `property` element:
- setter="SYMBOL"
- getter="SYMBOL"
where "symbol" is the C function identifier of the setter and getter
functions, respectively. The `setter` attribute is only applied to
writable, non-construct-only properties; the `getter` attribute is only
applied to readable properties.
We maintain the ABI compatibility of the typelib data by using 20 bits
of the 25 reserved bits inside the PropertyBlob structure. The data is
exposed through two new GIPropertyInfo methods:
- g_property_info_get_setter()
- g_property_info_get_getter()
which return the GIFunctionInfo for the setter and getter functions,
respectively.
2021-06-17 14:07:35 +02:00
|
|
|
}
|
|
|
|
else
|
2021-06-29 00:22:35 +02:00
|
|
|
blob->setter = ACCESSOR_SENTINEL;
|
Add introspection data for property accessors
A GObject property can be accessed generically through the GObject API,
e.g. g_object_set_property() and g_object_get_property(). Properties
typically also have public accessor functions, which are (according to
our own best practices) called through the generic API.
The introspection data is currently missing the relation between a
property and its public accessor functions. With this information, a
language binding could, for instance, avoid exposing the C API entirely,
thus minimizing the chances of collisions between property names and
accessor functions; alternatively, a binding could call the C API
directly instead of going through the generic GObject API, thus avoiding
the boxing and unboxing from a native type to a GIArgument and finally
into a GValue, and vice versa.
In the GIR, we add two new attributes to the `property` element:
- setter="SYMBOL"
- getter="SYMBOL"
where "symbol" is the C function identifier of the setter and getter
functions, respectively. The `setter` attribute is only applied to
writable, non-construct-only properties; the `getter` attribute is only
applied to readable properties.
We maintain the ABI compatibility of the typelib data by using 20 bits
of the 25 reserved bits inside the PropertyBlob structure. The data is
exposed through two new GIPropertyInfo methods:
- g_property_info_get_setter()
- g_property_info_get_getter()
which return the GIFunctionInfo for the setter and getter functions,
respectively.
2021-06-17 14:07:35 +02:00
|
|
|
|
|
|
|
if (prop->getter != NULL)
|
|
|
|
{
|
2023-11-08 15:17:52 +01:00
|
|
|
int index = get_index_of_member_type ((GIIrNodeInterface*)parent,
|
|
|
|
GI_IR_NODE_FUNCTION,
|
Add introspection data for property accessors
A GObject property can be accessed generically through the GObject API,
e.g. g_object_set_property() and g_object_get_property(). Properties
typically also have public accessor functions, which are (according to
our own best practices) called through the generic API.
The introspection data is currently missing the relation between a
property and its public accessor functions. With this information, a
language binding could, for instance, avoid exposing the C API entirely,
thus minimizing the chances of collisions between property names and
accessor functions; alternatively, a binding could call the C API
directly instead of going through the generic GObject API, thus avoiding
the boxing and unboxing from a native type to a GIArgument and finally
into a GValue, and vice versa.
In the GIR, we add two new attributes to the `property` element:
- setter="SYMBOL"
- getter="SYMBOL"
where "symbol" is the C function identifier of the setter and getter
functions, respectively. The `setter` attribute is only applied to
writable, non-construct-only properties; the `getter` attribute is only
applied to readable properties.
We maintain the ABI compatibility of the typelib data by using 20 bits
of the 25 reserved bits inside the PropertyBlob structure. The data is
exposed through two new GIPropertyInfo methods:
- g_property_info_get_setter()
- g_property_info_get_getter()
which return the GIFunctionInfo for the setter and getter functions,
respectively.
2021-06-17 14:07:35 +02:00
|
|
|
prop->getter);
|
|
|
|
if (index == -1)
|
|
|
|
{
|
2021-07-27 15:46:15 +02:00
|
|
|
g_error ("Unknown getter %s for property %s:%s", prop->getter, parent->name, node->name);
|
Add introspection data for property accessors
A GObject property can be accessed generically through the GObject API,
e.g. g_object_set_property() and g_object_get_property(). Properties
typically also have public accessor functions, which are (according to
our own best practices) called through the generic API.
The introspection data is currently missing the relation between a
property and its public accessor functions. With this information, a
language binding could, for instance, avoid exposing the C API entirely,
thus minimizing the chances of collisions between property names and
accessor functions; alternatively, a binding could call the C API
directly instead of going through the generic GObject API, thus avoiding
the boxing and unboxing from a native type to a GIArgument and finally
into a GValue, and vice versa.
In the GIR, we add two new attributes to the `property` element:
- setter="SYMBOL"
- getter="SYMBOL"
where "symbol" is the C function identifier of the setter and getter
functions, respectively. The `setter` attribute is only applied to
writable, non-construct-only properties; the `getter` attribute is only
applied to readable properties.
We maintain the ABI compatibility of the typelib data by using 20 bits
of the 25 reserved bits inside the PropertyBlob structure. The data is
exposed through two new GIPropertyInfo methods:
- g_property_info_get_setter()
- g_property_info_get_getter()
which return the GIFunctionInfo for the setter and getter functions,
respectively.
2021-06-17 14:07:35 +02:00
|
|
|
}
|
|
|
|
|
2024-01-15 22:47:52 +01:00
|
|
|
blob->getter = (uint16_t) index;
|
Add introspection data for property accessors
A GObject property can be accessed generically through the GObject API,
e.g. g_object_set_property() and g_object_get_property(). Properties
typically also have public accessor functions, which are (according to
our own best practices) called through the generic API.
The introspection data is currently missing the relation between a
property and its public accessor functions. With this information, a
language binding could, for instance, avoid exposing the C API entirely,
thus minimizing the chances of collisions between property names and
accessor functions; alternatively, a binding could call the C API
directly instead of going through the generic GObject API, thus avoiding
the boxing and unboxing from a native type to a GIArgument and finally
into a GValue, and vice versa.
In the GIR, we add two new attributes to the `property` element:
- setter="SYMBOL"
- getter="SYMBOL"
where "symbol" is the C function identifier of the setter and getter
functions, respectively. The `setter` attribute is only applied to
writable, non-construct-only properties; the `getter` attribute is only
applied to readable properties.
We maintain the ABI compatibility of the typelib data by using 20 bits
of the 25 reserved bits inside the PropertyBlob structure. The data is
exposed through two new GIPropertyInfo methods:
- g_property_info_get_setter()
- g_property_info_get_getter()
which return the GIFunctionInfo for the setter and getter functions,
respectively.
2021-06-17 14:07:35 +02:00
|
|
|
}
|
|
|
|
else
|
2021-06-29 00:22:35 +02:00
|
|
|
blob->getter = ACCESSOR_SENTINEL;
|
Add introspection data for property accessors
A GObject property can be accessed generically through the GObject API,
e.g. g_object_set_property() and g_object_get_property(). Properties
typically also have public accessor functions, which are (according to
our own best practices) called through the generic API.
The introspection data is currently missing the relation between a
property and its public accessor functions. With this information, a
language binding could, for instance, avoid exposing the C API entirely,
thus minimizing the chances of collisions between property names and
accessor functions; alternatively, a binding could call the C API
directly instead of going through the generic GObject API, thus avoiding
the boxing and unboxing from a native type to a GIArgument and finally
into a GValue, and vice versa.
In the GIR, we add two new attributes to the `property` element:
- setter="SYMBOL"
- getter="SYMBOL"
where "symbol" is the C function identifier of the setter and getter
functions, respectively. The `setter` attribute is only applied to
writable, non-construct-only properties; the `getter` attribute is only
applied to readable properties.
We maintain the ABI compatibility of the typelib data by using 20 bits
of the 25 reserved bits inside the PropertyBlob structure. The data is
exposed through two new GIPropertyInfo methods:
- g_property_info_get_setter()
- g_property_info_get_getter()
which return the GIFunctionInfo for the setter and getter functions,
respectively.
2021-06-17 14:07:35 +02:00
|
|
|
|
2023-11-08 16:23:31 +01:00
|
|
|
gi_ir_node_build_typelib ((GIIrNode *)prop->type,
|
|
|
|
node, build, offset, offset2, NULL);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_FUNCTION:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
FunctionBlob *blob = (FunctionBlob *)&data[*offset];
|
|
|
|
SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
|
|
|
|
GIIrNodeFunction *function = (GIIrNodeFunction *)node;
|
2024-01-15 22:20:02 +01:00
|
|
|
uint32_t signature;
|
2024-01-15 22:47:52 +01:00
|
|
|
unsigned int n;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
signature = *offset2;
|
|
|
|
n = g_list_length (function->parameters);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
*offset += sizeof (FunctionBlob);
|
|
|
|
*offset2 += sizeof (SignatureBlob) + n * sizeof (ArgBlob);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
blob->blob_type = BLOB_TYPE_FUNCTION;
|
|
|
|
blob->deprecated = function->deprecated;
|
2008-11-25 23:29:20 +01:00
|
|
|
blob->is_static = !function->is_method;
|
2024-01-16 17:30:37 +01:00
|
|
|
blob->setter = FALSE;
|
|
|
|
blob->getter = FALSE;
|
|
|
|
blob->constructor = function->is_constructor;
|
|
|
|
blob->wraps_vfunc = function->wraps_vfunc;
|
|
|
|
blob->throws = function->throws; /* Deprecated. Also stored in SignatureBlob. */
|
|
|
|
blob->index = 0;
|
|
|
|
blob->name = gi_ir_write_string (node->name, strings, data, offset2);
|
|
|
|
blob->symbol = gi_ir_write_string (function->symbol, strings, data, offset2);
|
|
|
|
blob->signature = signature;
|
2008-08-23 18:46:58 +02:00
|
|
|
|
2021-06-16 20:17:27 +02:00
|
|
|
if (function->is_setter || function->is_getter)
|
|
|
|
{
|
2023-11-08 15:17:52 +01:00
|
|
|
int index = get_index_of_member_type ((GIIrNodeInterface*)parent,
|
|
|
|
GI_IR_NODE_PROPERTY,
|
2021-06-16 20:17:27 +02:00
|
|
|
function->property);
|
|
|
|
if (index == -1)
|
|
|
|
{
|
2021-07-27 15:46:15 +02:00
|
|
|
g_error ("Unknown property %s:%s for accessor %s", parent->name, function->property, function->symbol);
|
2021-06-16 20:17:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
blob->setter = function->is_setter;
|
|
|
|
blob->getter = function->is_getter;
|
2024-01-15 22:47:52 +01:00
|
|
|
blob->index = (uint16_t) index;
|
2021-06-16 20:17:27 +02:00
|
|
|
}
|
|
|
|
|
2010-06-15 17:01:37 +02:00
|
|
|
/* function->result is special since it doesn't appear in the serialized format but
|
|
|
|
* we do want the attributes for it to appear
|
|
|
|
*/
|
|
|
|
build->nodes_with_attributes = g_list_prepend (build->nodes_with_attributes, function->result);
|
2023-11-08 15:17:52 +01:00
|
|
|
build->n_attributes += g_hash_table_size (((GIIrNode *) function->result)->attributes);
|
|
|
|
g_assert (((GIIrNode *) function->result)->offset == 0);
|
|
|
|
((GIIrNode *) function->result)->offset = signature;
|
2010-06-15 17:01:37 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
g_debug ("building function '%s'", function->symbol);
|
2008-08-23 18:46:58 +02:00
|
|
|
|
2023-11-08 16:23:31 +01:00
|
|
|
gi_ir_node_build_typelib ((GIIrNode *)function->result->type,
|
|
|
|
node, build, &signature, offset2, NULL);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
blob2->may_return_null = function->result->nullable;
|
|
|
|
blob2->caller_owns_return_value = function->result->transfer;
|
|
|
|
blob2->caller_owns_return_container = function->result->shallow_transfer;
|
|
|
|
blob2->skip_return = function->result->skip;
|
2014-05-06 18:53:21 +02:00
|
|
|
blob2->instance_transfer_ownership = function->instance_transfer_full;
|
2024-01-16 17:30:37 +01:00
|
|
|
blob2->reserved = 0;
|
|
|
|
blob2->n_arguments = n;
|
|
|
|
blob2->throws = function->throws;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
signature += 4;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
for (l = function->parameters; l; l = l->next)
|
|
|
|
{
|
|
|
|
GIIrNode *param = (GIIrNode *)l->data;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
gi_ir_node_build_typelib (param, node, build, &signature, offset2, NULL);
|
|
|
|
}
|
2008-08-23 18:46:58 +02:00
|
|
|
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_CALLBACK:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
CallbackBlob *blob = (CallbackBlob *)&data[*offset];
|
|
|
|
SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
|
|
|
|
GIIrNodeFunction *function = (GIIrNodeFunction *)node;
|
2024-01-15 22:20:02 +01:00
|
|
|
uint32_t signature;
|
|
|
|
unsigned int n;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
signature = *offset2;
|
|
|
|
n = g_list_length (function->parameters);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
*offset += sizeof (CallbackBlob);
|
|
|
|
*offset2 += sizeof (SignatureBlob) + n * sizeof (ArgBlob);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
blob->blob_type = BLOB_TYPE_CALLBACK;
|
|
|
|
blob->deprecated = function->deprecated;
|
|
|
|
blob->reserved = 0;
|
|
|
|
blob->name = gi_ir_write_string (node->name, strings, data, offset2);
|
|
|
|
blob->signature = signature;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2023-11-08 16:23:31 +01:00
|
|
|
gi_ir_node_build_typelib ((GIIrNode *)function->result->type,
|
|
|
|
node, build, &signature, offset2, NULL);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
blob2->may_return_null = function->result->nullable;
|
|
|
|
blob2->caller_owns_return_value = function->result->transfer;
|
|
|
|
blob2->caller_owns_return_container = function->result->shallow_transfer;
|
|
|
|
blob2->reserved = 0;
|
|
|
|
blob2->n_arguments = n;
|
|
|
|
blob2->throws = function->throws;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
signature += 4;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
for (l = function->parameters; l; l = l->next)
|
|
|
|
{
|
|
|
|
GIIrNode *param = (GIIrNode *)l->data;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
gi_ir_node_build_typelib (param, node, build, &signature, offset2, NULL);
|
|
|
|
}
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_SIGNAL:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
SignalBlob *blob = (SignalBlob *)&data[*offset];
|
|
|
|
SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
|
|
|
|
GIIrNodeSignal *signal = (GIIrNodeSignal *)node;
|
2024-01-15 22:20:02 +01:00
|
|
|
uint32_t signature;
|
|
|
|
unsigned int n;
|
2024-01-16 17:30:37 +01:00
|
|
|
|
|
|
|
signature = *offset2;
|
|
|
|
n = g_list_length (signal->parameters);
|
|
|
|
|
|
|
|
*offset += sizeof (SignalBlob);
|
|
|
|
*offset2 += sizeof (SignatureBlob) + n * sizeof (ArgBlob);
|
|
|
|
|
|
|
|
blob->deprecated = signal->deprecated;
|
|
|
|
blob->run_first = signal->run_first;
|
|
|
|
blob->run_last = signal->run_last;
|
|
|
|
blob->run_cleanup = signal->run_cleanup;
|
|
|
|
blob->no_recurse = signal->no_recurse;
|
|
|
|
blob->detailed = signal->detailed;
|
|
|
|
blob->action = signal->action;
|
|
|
|
blob->no_hooks = signal->no_hooks;
|
|
|
|
blob->has_class_closure = 0; /* FIXME */
|
|
|
|
blob->true_stops_emit = 0; /* FIXME */
|
|
|
|
blob->reserved = 0;
|
|
|
|
blob->class_closure = 0; /* FIXME */
|
|
|
|
blob->name = gi_ir_write_string (node->name, strings, data, offset2);
|
|
|
|
blob->signature = signature;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2010-06-15 17:01:37 +02:00
|
|
|
/* signal->result is special since it doesn't appear in the serialized format but
|
|
|
|
* we do want the attributes for it to appear
|
|
|
|
*/
|
|
|
|
build->nodes_with_attributes = g_list_prepend (build->nodes_with_attributes, signal->result);
|
2023-11-08 15:17:52 +01:00
|
|
|
build->n_attributes += g_hash_table_size (((GIIrNode *) signal->result)->attributes);
|
|
|
|
g_assert (((GIIrNode *) signal->result)->offset == 0);
|
|
|
|
((GIIrNode *) signal->result)->offset = signature;
|
2010-06-15 17:01:37 +02:00
|
|
|
|
2023-11-08 16:23:31 +01:00
|
|
|
gi_ir_node_build_typelib ((GIIrNode *)signal->result->type,
|
|
|
|
node, build, &signature, offset2, NULL);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
blob2->may_return_null = signal->result->nullable;
|
|
|
|
blob2->caller_owns_return_value = signal->result->transfer;
|
|
|
|
blob2->caller_owns_return_container = signal->result->shallow_transfer;
|
2014-05-06 18:53:21 +02:00
|
|
|
blob2->instance_transfer_ownership = signal->instance_transfer_full;
|
2024-01-16 17:30:37 +01:00
|
|
|
blob2->reserved = 0;
|
|
|
|
blob2->n_arguments = n;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
signature += 4;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
for (l = signal->parameters; l; l = l->next)
|
|
|
|
{
|
|
|
|
GIIrNode *param = (GIIrNode *)l->data;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
gi_ir_node_build_typelib (param, node, build, &signature, offset2, NULL);
|
|
|
|
}
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_VFUNC:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
VFuncBlob *blob = (VFuncBlob *)&data[*offset];
|
|
|
|
SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
|
|
|
|
GIIrNodeVFunc *vfunc = (GIIrNodeVFunc *)node;
|
2024-01-15 22:20:02 +01:00
|
|
|
uint32_t signature;
|
|
|
|
unsigned int n;
|
2024-01-16 17:30:37 +01:00
|
|
|
|
|
|
|
signature = *offset2;
|
|
|
|
n = g_list_length (vfunc->parameters);
|
|
|
|
|
|
|
|
*offset += sizeof (VFuncBlob);
|
|
|
|
*offset2 += sizeof (SignatureBlob) + n * sizeof (ArgBlob);
|
|
|
|
|
|
|
|
blob->name = gi_ir_write_string (node->name, strings, data, offset2);
|
|
|
|
blob->must_chain_up = 0; /* FIXME */
|
|
|
|
blob->must_be_implemented = 0; /* FIXME */
|
|
|
|
blob->must_not_be_implemented = 0; /* FIXME */
|
|
|
|
blob->class_closure = 0; /* FIXME */
|
|
|
|
blob->throws = vfunc->throws; /* Deprecated. Also stored in SignatureBlob. */
|
|
|
|
blob->reserved = 0;
|
|
|
|
|
|
|
|
if (vfunc->invoker)
|
|
|
|
{
|
|
|
|
int index = get_index_of_member_type ((GIIrNodeInterface*)parent, GI_IR_NODE_FUNCTION, vfunc->invoker);
|
|
|
|
if (index == -1)
|
|
|
|
{
|
|
|
|
g_error ("Unknown member function %s for vfunc %s", vfunc->invoker, node->name);
|
|
|
|
}
|
2024-01-15 22:47:52 +01:00
|
|
|
blob->invoker = (uint16_t) index;
|
2024-01-16 17:30:37 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
blob->invoker = 0x3ff; /* max of 10 bits */
|
2009-02-28 01:02:48 +01:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
blob->struct_offset = vfunc->offset;
|
|
|
|
blob->reserved2 = 0;
|
|
|
|
blob->signature = signature;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2023-11-08 16:23:31 +01:00
|
|
|
gi_ir_node_build_typelib ((GIIrNode *)vfunc->result->type,
|
|
|
|
node, build, &signature, offset2, NULL);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
blob2->may_return_null = vfunc->result->nullable;
|
|
|
|
blob2->caller_owns_return_value = vfunc->result->transfer;
|
|
|
|
blob2->caller_owns_return_container = vfunc->result->shallow_transfer;
|
2014-05-06 18:53:21 +02:00
|
|
|
blob2->instance_transfer_ownership = vfunc->instance_transfer_full;
|
2024-01-16 17:30:37 +01:00
|
|
|
blob2->reserved = 0;
|
|
|
|
blob2->n_arguments = n;
|
|
|
|
blob2->throws = vfunc->throws;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
signature += 4;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
for (l = vfunc->parameters; l; l = l->next)
|
|
|
|
{
|
|
|
|
GIIrNode *param = (GIIrNode *)l->data;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
gi_ir_node_build_typelib (param, node, build, &signature, offset2, NULL);
|
|
|
|
}
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_PARAM:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
ArgBlob *blob = (ArgBlob *)&data[*offset];
|
|
|
|
GIIrNodeParam *param = (GIIrNodeParam *)node;
|
|
|
|
|
|
|
|
/* The offset for this one is smaller than the struct because
|
|
|
|
* we recursively build the simple type inline here below.
|
|
|
|
*/
|
|
|
|
*offset += sizeof (ArgBlob) - sizeof (SimpleTypeBlob);
|
|
|
|
|
|
|
|
blob->name = gi_ir_write_string (node->name, strings, data, offset2);
|
|
|
|
blob->in = param->in;
|
|
|
|
blob->out = param->out;
|
|
|
|
blob->caller_allocates = param->caller_allocates;
|
|
|
|
blob->nullable = param->nullable;
|
|
|
|
blob->skip = param->skip;
|
|
|
|
blob->optional = param->optional;
|
|
|
|
blob->transfer_ownership = param->transfer;
|
|
|
|
blob->transfer_container_ownership = param->shallow_transfer;
|
|
|
|
blob->return_value = param->retval;
|
Bug 556489 – callback annotations
2008-01-03 Andreas Rottmann <a.rottmann@gmx.at>
Bug 556489 – callback annotations
* giscanner/transformer.py
* tools/generate.c (write_callable_info): Write out the new scope,
closure and destroy attributes.
* giscanner/transformer.py (Transformer._type_is_callback): New
method, checking if a given type is a callback.
(Transformer._augment_callback_params): New method; adds
information (closure, destroy) to callback parameters.
(Transformer._handle_closure, Transformer._handle_destroy): New methods,
auxiliary to _augment_callback_params.
(Transformer._create_function): Call _augment_callback_params().
(Transformer._create_parameter): Handle scope option.
(Transformer._create_typedef_callback): New method, creates a
callback, and registers it in the typedef namespace
(Transformer._create_typedef): Use _create_typedef_callback()
instead of the plain _create_callback().
* giscanner/ast.py (Parameter): Added callback-related fields.
* giscanner/girwriter.py: Write out new Parameter fields.
* girepository/girnode.h (GIrNodeParam): Added fields scope,
closure and destroy.
* girepository/gtypelib.h (ArgBlob): Ditto.
* girepository/girparser.c (start_parameter): Handle new fields.
* girepository/girmodule.c (g_ir_module_build_typelib): Adjust
arg_blob_size, bump major version due to this change.
* girepository/girnode.c (g_ir_node_get_full_size_internal)
(g_ir_node_build_typelib)
* girepository/gtypelib.c (g_typelib_check_sanity): ArgBlob size
adjustments.
(g_ir_node_build_typelib): Fill in new ArgBlob flags from param.
* girepository/girepository.h (GIScope): New enumeration, listing
the different possible scopes for callbacks.
* girepository/ginfo.c (g_arg_info_get_scope)
(g_arg_info_get_closure, g_arg_info_get_destroy): Accessors for
callback-related argument indices (callback scope, closure for a
callback, destroy notification for a callback).
* tests/scanner/: Added testcases for new features.
svn path=/trunk/; revision=998
2009-01-03 14:44:42 +01:00
|
|
|
blob->scope = param->scope;
|
2024-01-16 17:30:37 +01:00
|
|
|
blob->reserved = 0;
|
Bug 556489 – callback annotations
2008-01-03 Andreas Rottmann <a.rottmann@gmx.at>
Bug 556489 – callback annotations
* giscanner/transformer.py
* tools/generate.c (write_callable_info): Write out the new scope,
closure and destroy attributes.
* giscanner/transformer.py (Transformer._type_is_callback): New
method, checking if a given type is a callback.
(Transformer._augment_callback_params): New method; adds
information (closure, destroy) to callback parameters.
(Transformer._handle_closure, Transformer._handle_destroy): New methods,
auxiliary to _augment_callback_params.
(Transformer._create_function): Call _augment_callback_params().
(Transformer._create_parameter): Handle scope option.
(Transformer._create_typedef_callback): New method, creates a
callback, and registers it in the typedef namespace
(Transformer._create_typedef): Use _create_typedef_callback()
instead of the plain _create_callback().
* giscanner/ast.py (Parameter): Added callback-related fields.
* giscanner/girwriter.py: Write out new Parameter fields.
* girepository/girnode.h (GIrNodeParam): Added fields scope,
closure and destroy.
* girepository/gtypelib.h (ArgBlob): Ditto.
* girepository/girparser.c (start_parameter): Handle new fields.
* girepository/girmodule.c (g_ir_module_build_typelib): Adjust
arg_blob_size, bump major version due to this change.
* girepository/girnode.c (g_ir_node_get_full_size_internal)
(g_ir_node_build_typelib)
* girepository/gtypelib.c (g_typelib_check_sanity): ArgBlob size
adjustments.
(g_ir_node_build_typelib): Fill in new ArgBlob flags from param.
* girepository/girepository.h (GIScope): New enumeration, listing
the different possible scopes for callbacks.
* girepository/ginfo.c (g_arg_info_get_scope)
(g_arg_info_get_closure, g_arg_info_get_destroy): Accessors for
callback-related argument indices (callback scope, closure for a
callback, destroy notification for a callback).
* tests/scanner/: Added testcases for new features.
svn path=/trunk/; revision=998
2009-01-03 14:44:42 +01:00
|
|
|
blob->closure = param->closure;
|
|
|
|
blob->destroy = param->destroy;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2023-11-08 16:23:31 +01:00
|
|
|
gi_ir_node_build_typelib ((GIIrNode *)param->type, node, build, offset, offset2, NULL);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_STRUCT:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
StructBlob *blob = (StructBlob *)&data[*offset];
|
|
|
|
GIIrNodeStruct *struct_ = (GIIrNodeStruct *)node;
|
|
|
|
GList *members;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
blob->blob_type = BLOB_TYPE_STRUCT;
|
2010-03-26 03:12:12 +01:00
|
|
|
blob->foreign = struct_->foreign;
|
2024-01-16 17:30:37 +01:00
|
|
|
blob->deprecated = struct_->deprecated;
|
|
|
|
blob->is_gtype_struct = struct_->is_gtype_struct;
|
|
|
|
blob->reserved = 0;
|
|
|
|
blob->name = gi_ir_write_string (node->name, strings, data, offset2);
|
|
|
|
blob->alignment = struct_->alignment;
|
|
|
|
blob->size = struct_->size;
|
|
|
|
|
|
|
|
if (struct_->gtype_name)
|
|
|
|
{
|
|
|
|
blob->unregistered = FALSE;
|
|
|
|
blob->gtype_name = gi_ir_write_string (struct_->gtype_name, strings, data, offset2);
|
|
|
|
blob->gtype_init = gi_ir_write_string (struct_->gtype_init, strings, data, offset2);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
blob->unregistered = TRUE;
|
|
|
|
blob->gtype_name = 0;
|
|
|
|
blob->gtype_init = 0;
|
|
|
|
}
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2022-10-29 19:09:23 +02:00
|
|
|
if (struct_->copy_func)
|
2023-11-08 16:23:31 +01:00
|
|
|
blob->copy_func = gi_ir_write_string (struct_->copy_func, strings, data, offset2);
|
2022-10-29 19:09:23 +02:00
|
|
|
if (struct_->free_func)
|
2023-11-08 16:23:31 +01:00
|
|
|
blob->free_func = gi_ir_write_string (struct_->free_func, strings, data, offset2);
|
2022-10-29 19:09:23 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
blob->n_fields = 0;
|
|
|
|
blob->n_methods = 0;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
*offset += sizeof (StructBlob);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
members = g_list_copy (struct_->members);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
gi_ir_node_build_members (&members, GI_IR_NODE_FIELD, &blob->n_fields,
|
2023-11-08 16:23:31 +01:00
|
|
|
node, build, offset, offset2, NULL);
|
2008-10-16 00:28:41 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
gi_ir_node_build_members (&members, GI_IR_NODE_FUNCTION, &blob->n_methods,
|
2023-11-08 16:23:31 +01:00
|
|
|
node, build, offset, offset2, NULL);
|
2008-10-16 00:28:41 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
gi_ir_node_check_unhandled_members (&members, node->type);
|
2008-10-16 00:28:53 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
g_assert (members == NULL);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_BOXED:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
StructBlob *blob = (StructBlob *)&data[*offset];
|
|
|
|
GIIrNodeBoxed *boxed = (GIIrNodeBoxed *)node;
|
|
|
|
GList *members;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
blob->blob_type = BLOB_TYPE_BOXED;
|
|
|
|
blob->deprecated = boxed->deprecated;
|
|
|
|
blob->unregistered = FALSE;
|
|
|
|
blob->reserved = 0;
|
|
|
|
blob->name = gi_ir_write_string (node->name, strings, data, offset2);
|
|
|
|
blob->gtype_name = gi_ir_write_string (boxed->gtype_name, strings, data, offset2);
|
|
|
|
blob->gtype_init = gi_ir_write_string (boxed->gtype_init, strings, data, offset2);
|
|
|
|
blob->alignment = boxed->alignment;
|
|
|
|
blob->size = boxed->size;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
blob->n_fields = 0;
|
|
|
|
blob->n_methods = 0;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
*offset += sizeof (StructBlob);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
members = g_list_copy (boxed->members);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
gi_ir_node_build_members (&members, GI_IR_NODE_FIELD, &blob->n_fields,
|
2023-11-08 16:23:31 +01:00
|
|
|
node, build, offset, offset2, NULL);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
gi_ir_node_build_members (&members, GI_IR_NODE_FUNCTION, &blob->n_methods,
|
2023-11-08 16:23:31 +01:00
|
|
|
node, build, offset, offset2, NULL);
|
2008-10-16 00:28:41 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
gi_ir_node_check_unhandled_members (&members, node->type);
|
2008-10-16 00:28:53 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
g_assert (members == NULL);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_UNION:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
UnionBlob *blob = (UnionBlob *)&data[*offset];
|
|
|
|
GIIrNodeUnion *union_ = (GIIrNodeUnion *)node;
|
|
|
|
GList *members;
|
|
|
|
|
|
|
|
blob->blob_type = BLOB_TYPE_UNION;
|
|
|
|
blob->deprecated = union_->deprecated;
|
|
|
|
blob->reserved = 0;
|
|
|
|
blob->name = gi_ir_write_string (node->name, strings, data, offset2);
|
|
|
|
blob->alignment = union_->alignment;
|
|
|
|
blob->size = union_->size;
|
|
|
|
if (union_->gtype_name)
|
|
|
|
{
|
|
|
|
blob->unregistered = FALSE;
|
|
|
|
blob->gtype_name = gi_ir_write_string (union_->gtype_name, strings, data, offset2);
|
|
|
|
blob->gtype_init = gi_ir_write_string (union_->gtype_init, strings, data, offset2);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
blob->unregistered = TRUE;
|
|
|
|
blob->gtype_name = 0;
|
|
|
|
blob->gtype_init = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
blob->n_fields = 0;
|
|
|
|
blob->n_functions = 0;
|
|
|
|
|
|
|
|
blob->discriminator_offset = union_->discriminator_offset;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2022-10-29 19:09:23 +02:00
|
|
|
if (union_->copy_func)
|
2023-11-08 16:23:31 +01:00
|
|
|
blob->copy_func = gi_ir_write_string (union_->copy_func, strings, data, offset2);
|
2022-10-29 19:09:23 +02:00
|
|
|
if (union_->free_func)
|
2023-11-08 16:23:31 +01:00
|
|
|
blob->free_func = gi_ir_write_string (union_->free_func, strings, data, offset2);
|
2022-10-29 19:09:23 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
/* We don't support Union discriminators right now. */
|
|
|
|
/*
|
|
|
|
if (union_->discriminator_type)
|
|
|
|
{
|
|
|
|
*offset += 28;
|
|
|
|
blob->discriminated = TRUE;
|
|
|
|
gi_ir_node_build_typelib ((GIIrNode *)union_->discriminator_type,
|
2023-11-08 16:23:31 +01:00
|
|
|
build, offset, offset2, NULL);
|
2024-01-16 17:30:37 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-02-19 15:56:20 +01:00
|
|
|
*/
|
2024-01-16 17:30:37 +01:00
|
|
|
*offset += sizeof (UnionBlob);
|
|
|
|
blob->discriminated = FALSE;
|
|
|
|
blob->discriminator_type.offset = 0;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
members = g_list_copy (union_->members);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
gi_ir_node_build_members (&members, GI_IR_NODE_FIELD, &blob->n_fields,
|
2023-11-08 16:23:31 +01:00
|
|
|
node, build, offset, offset2, NULL);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
gi_ir_node_build_members (&members, GI_IR_NODE_FUNCTION, &blob->n_functions,
|
2023-11-08 16:23:31 +01:00
|
|
|
node, build, offset, offset2, NULL);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
gi_ir_node_check_unhandled_members (&members, node->type);
|
2008-10-16 00:28:53 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
g_assert (members == NULL);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
if (union_->discriminator_type)
|
|
|
|
{
|
|
|
|
for (l = union_->discriminators; l; l = l->next)
|
|
|
|
{
|
|
|
|
GIIrNode *member = (GIIrNode *)l->data;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
gi_ir_node_build_typelib (member, node, build, offset, offset2, NULL);
|
|
|
|
}
|
|
|
|
}
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_ENUM:
|
|
|
|
case GI_IR_NODE_FLAGS:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
EnumBlob *blob = (EnumBlob *)&data[*offset];
|
|
|
|
GIIrNodeEnum *enum_ = (GIIrNodeEnum *)node;
|
|
|
|
|
|
|
|
*offset += sizeof (EnumBlob);
|
|
|
|
|
|
|
|
if (node->type == GI_IR_NODE_ENUM)
|
|
|
|
blob->blob_type = BLOB_TYPE_ENUM;
|
|
|
|
else
|
|
|
|
blob->blob_type = BLOB_TYPE_FLAGS;
|
|
|
|
|
|
|
|
blob->deprecated = enum_->deprecated;
|
|
|
|
blob->reserved = 0;
|
|
|
|
blob->storage_type = enum_->storage_type;
|
|
|
|
blob->name = gi_ir_write_string (node->name, strings, data, offset2);
|
|
|
|
if (enum_->gtype_name)
|
|
|
|
{
|
|
|
|
blob->unregistered = FALSE;
|
|
|
|
blob->gtype_name = gi_ir_write_string (enum_->gtype_name, strings, data, offset2);
|
|
|
|
blob->gtype_init = gi_ir_write_string (enum_->gtype_init, strings, data, offset2);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
blob->unregistered = TRUE;
|
|
|
|
blob->gtype_name = 0;
|
|
|
|
blob->gtype_init = 0;
|
|
|
|
}
|
|
|
|
if (enum_->error_domain)
|
|
|
|
blob->error_domain = gi_ir_write_string (enum_->error_domain, strings, data, offset2);
|
|
|
|
else
|
|
|
|
blob->error_domain = 0;
|
|
|
|
|
|
|
|
blob->n_values = 0;
|
|
|
|
blob->n_methods = 0;
|
|
|
|
|
|
|
|
for (l = enum_->values; l; l = l->next)
|
|
|
|
{
|
|
|
|
GIIrNode *value = (GIIrNode *)l->data;
|
|
|
|
|
|
|
|
blob->n_values++;
|
|
|
|
gi_ir_node_build_typelib (value, node, build, offset, offset2, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (l = enum_->methods; l; l = l->next)
|
|
|
|
{
|
|
|
|
GIIrNode *method = (GIIrNode *)l->data;
|
|
|
|
|
|
|
|
blob->n_methods++;
|
|
|
|
gi_ir_node_build_typelib (method, node, build, offset, offset2, NULL);
|
|
|
|
}
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_OBJECT:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
ObjectBlob *blob = (ObjectBlob *)&data[*offset];
|
|
|
|
GIIrNodeInterface *object = (GIIrNodeInterface *)node;
|
|
|
|
GList *members;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
blob->blob_type = BLOB_TYPE_OBJECT;
|
|
|
|
blob->abstract = object->abstract;
|
2010-06-12 23:08:56 +02:00
|
|
|
blob->fundamental = object->fundamental;
|
2021-02-09 12:38:27 +01:00
|
|
|
blob->final_ = object->final_;
|
2024-01-16 17:30:37 +01:00
|
|
|
blob->deprecated = object->deprecated;
|
|
|
|
blob->reserved = 0;
|
|
|
|
blob->name = gi_ir_write_string (node->name, strings, data, offset2);
|
|
|
|
blob->gtype_name = gi_ir_write_string (object->gtype_name, strings, data, offset2);
|
|
|
|
blob->gtype_init = gi_ir_write_string (object->gtype_init, strings, data, offset2);
|
2010-06-12 23:08:56 +02:00
|
|
|
if (object->ref_func)
|
2023-11-08 16:23:31 +01:00
|
|
|
blob->ref_func = gi_ir_write_string (object->ref_func, strings, data, offset2);
|
2010-06-12 23:08:56 +02:00
|
|
|
if (object->unref_func)
|
2023-11-08 16:23:31 +01:00
|
|
|
blob->unref_func = gi_ir_write_string (object->unref_func, strings, data, offset2);
|
2010-06-12 23:08:56 +02:00
|
|
|
if (object->set_value_func)
|
2023-11-08 16:23:31 +01:00
|
|
|
blob->set_value_func = gi_ir_write_string (object->set_value_func, strings, data, offset2);
|
2010-06-12 23:08:56 +02:00
|
|
|
if (object->get_value_func)
|
2023-11-08 16:23:31 +01:00
|
|
|
blob->get_value_func = gi_ir_write_string (object->get_value_func, strings, data, offset2);
|
2024-01-16 17:30:37 +01:00
|
|
|
if (object->parent)
|
|
|
|
blob->parent = find_entry (build, object->parent);
|
|
|
|
else
|
|
|
|
blob->parent = 0;
|
|
|
|
if (object->glib_type_struct)
|
|
|
|
blob->gtype_struct = find_entry (build, object->glib_type_struct);
|
|
|
|
else
|
|
|
|
blob->gtype_struct = 0;
|
|
|
|
|
|
|
|
blob->n_interfaces = 0;
|
|
|
|
blob->n_fields = 0;
|
|
|
|
blob->n_properties = 0;
|
|
|
|
blob->n_methods = 0;
|
|
|
|
blob->n_signals = 0;
|
|
|
|
blob->n_vfuncs = 0;
|
|
|
|
blob->n_constants = 0;
|
|
|
|
blob->n_field_callbacks = 0;
|
|
|
|
|
|
|
|
*offset += sizeof(ObjectBlob);
|
|
|
|
for (l = object->interfaces; l; l = l->next)
|
|
|
|
{
|
|
|
|
blob->n_interfaces++;
|
2024-01-15 22:20:02 +01:00
|
|
|
*(uint16_t *)&data[*offset] = find_entry (build, (char *)l->data);
|
2024-01-16 17:30:37 +01:00
|
|
|
*offset += 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
members = g_list_copy (object->members);
|
|
|
|
|
|
|
|
*offset = ALIGN_VALUE (*offset, 4);
|
|
|
|
gi_ir_node_build_members (&members, GI_IR_NODE_FIELD, &blob->n_fields,
|
2023-11-08 16:23:31 +01:00
|
|
|
node, build, offset, offset2, &blob->n_field_callbacks);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
*offset = ALIGN_VALUE (*offset, 4);
|
|
|
|
gi_ir_node_build_members (&members, GI_IR_NODE_PROPERTY, &blob->n_properties,
|
2023-11-08 16:23:31 +01:00
|
|
|
node, build, offset, offset2, NULL);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
*offset = ALIGN_VALUE (*offset, 4);
|
|
|
|
gi_ir_node_build_members (&members, GI_IR_NODE_FUNCTION, &blob->n_methods,
|
2023-11-08 16:23:31 +01:00
|
|
|
node, build, offset, offset2, NULL);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
*offset = ALIGN_VALUE (*offset, 4);
|
|
|
|
gi_ir_node_build_members (&members, GI_IR_NODE_SIGNAL, &blob->n_signals,
|
2023-11-08 16:23:31 +01:00
|
|
|
node, build, offset, offset2, NULL);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
*offset = ALIGN_VALUE (*offset, 4);
|
|
|
|
gi_ir_node_build_members (&members, GI_IR_NODE_VFUNC, &blob->n_vfuncs,
|
2023-11-08 16:23:31 +01:00
|
|
|
node, build, offset, offset2, NULL);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
*offset = ALIGN_VALUE (*offset, 4);
|
|
|
|
gi_ir_node_build_members (&members, GI_IR_NODE_CONSTANT, &blob->n_constants,
|
2023-11-08 16:23:31 +01:00
|
|
|
node, build, offset, offset2, NULL);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
gi_ir_node_check_unhandled_members (&members, node->type);
|
2008-10-16 00:28:53 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
g_assert (members == NULL);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_INTERFACE:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
InterfaceBlob *blob = (InterfaceBlob *)&data[*offset];
|
|
|
|
GIIrNodeInterface *iface = (GIIrNodeInterface *)node;
|
|
|
|
GList *members;
|
|
|
|
|
|
|
|
blob->blob_type = BLOB_TYPE_INTERFACE;
|
|
|
|
blob->deprecated = iface->deprecated;
|
|
|
|
blob->reserved = 0;
|
|
|
|
blob->name = gi_ir_write_string (node->name, strings, data, offset2);
|
|
|
|
blob->gtype_name = gi_ir_write_string (iface->gtype_name, strings, data, offset2);
|
|
|
|
blob->gtype_init = gi_ir_write_string (iface->gtype_init, strings, data, offset2);
|
|
|
|
if (iface->glib_type_struct)
|
|
|
|
blob->gtype_struct = find_entry (build, iface->glib_type_struct);
|
|
|
|
else
|
|
|
|
blob->gtype_struct = 0;
|
|
|
|
blob->n_prerequisites = 0;
|
|
|
|
blob->n_properties = 0;
|
|
|
|
blob->n_methods = 0;
|
|
|
|
blob->n_signals = 0;
|
|
|
|
blob->n_vfuncs = 0;
|
|
|
|
blob->n_constants = 0;
|
|
|
|
|
|
|
|
*offset += sizeof (InterfaceBlob);
|
|
|
|
for (l = iface->prerequisites; l; l = l->next)
|
|
|
|
{
|
|
|
|
blob->n_prerequisites++;
|
2024-01-15 22:20:02 +01:00
|
|
|
*(uint16_t *)&data[*offset] = find_entry (build, (char *)l->data);
|
2024-01-16 17:30:37 +01:00
|
|
|
*offset += 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
members = g_list_copy (iface->members);
|
|
|
|
|
|
|
|
*offset = ALIGN_VALUE (*offset, 4);
|
|
|
|
gi_ir_node_build_members (&members, GI_IR_NODE_PROPERTY, &blob->n_properties,
|
2023-11-08 16:23:31 +01:00
|
|
|
node, build, offset, offset2, NULL);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
*offset = ALIGN_VALUE (*offset, 4);
|
|
|
|
gi_ir_node_build_members (&members, GI_IR_NODE_FUNCTION, &blob->n_methods,
|
2023-11-08 16:23:31 +01:00
|
|
|
node, build, offset, offset2, NULL);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
*offset = ALIGN_VALUE (*offset, 4);
|
|
|
|
gi_ir_node_build_members (&members, GI_IR_NODE_SIGNAL, &blob->n_signals,
|
2023-11-08 16:23:31 +01:00
|
|
|
node, build, offset, offset2, NULL);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
*offset = ALIGN_VALUE (*offset, 4);
|
|
|
|
gi_ir_node_build_members (&members, GI_IR_NODE_VFUNC, &blob->n_vfuncs,
|
2023-11-08 16:23:31 +01:00
|
|
|
node, build, offset, offset2, NULL);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
*offset = ALIGN_VALUE (*offset, 4);
|
|
|
|
gi_ir_node_build_members (&members, GI_IR_NODE_CONSTANT, &blob->n_constants,
|
2023-11-08 16:23:31 +01:00
|
|
|
node, build, offset, offset2, NULL);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
gi_ir_node_check_unhandled_members (&members, node->type);
|
2008-10-16 00:28:53 +02:00
|
|
|
|
2024-01-16 17:30:37 +01:00
|
|
|
g_assert (members == NULL);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_VALUE:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeValue *value = (GIIrNodeValue *)node;
|
|
|
|
ValueBlob *blob = (ValueBlob *)&data[*offset];
|
|
|
|
*offset += sizeof (ValueBlob);
|
|
|
|
|
|
|
|
blob->deprecated = value->deprecated;
|
|
|
|
blob->reserved = 0;
|
|
|
|
blob->unsigned_value = value->value >= 0 ? 1 : 0;
|
|
|
|
blob->name = gi_ir_write_string (node->name, strings, data, offset2);
|
2024-01-15 22:20:02 +01:00
|
|
|
blob->value = (int32_t) value->value;
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-11-08 15:17:52 +01:00
|
|
|
case GI_IR_NODE_CONSTANT:
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-16 17:30:37 +01:00
|
|
|
GIIrNodeConstant *constant = (GIIrNodeConstant *)node;
|
|
|
|
ConstantBlob *blob = (ConstantBlob *)&data[*offset];
|
2024-01-15 22:20:02 +01:00
|
|
|
uint32_t pos;
|
2024-01-16 17:30:37 +01:00
|
|
|
|
|
|
|
pos = *offset + G_STRUCT_OFFSET (ConstantBlob, type);
|
|
|
|
*offset += sizeof (ConstantBlob);
|
|
|
|
|
|
|
|
blob->blob_type = BLOB_TYPE_CONSTANT;
|
|
|
|
blob->deprecated = constant->deprecated;
|
|
|
|
blob->reserved = 0;
|
|
|
|
blob->name = gi_ir_write_string (node->name, strings, data, offset2);
|
|
|
|
|
|
|
|
blob->offset = *offset2;
|
|
|
|
switch (constant->type->tag)
|
|
|
|
{
|
|
|
|
case GI_TYPE_TAG_BOOLEAN:
|
|
|
|
blob->size = 4;
|
|
|
|
*(gboolean*)&data[blob->offset] = parse_boolean_value (constant->value);
|
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_INT8:
|
|
|
|
blob->size = 1;
|
2024-01-15 22:20:02 +01:00
|
|
|
*(int8_t *)&data[blob->offset] = (int8_t) parse_int_value (constant->value);
|
2024-01-16 17:30:37 +01:00
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_UINT8:
|
|
|
|
blob->size = 1;
|
2024-01-15 22:20:02 +01:00
|
|
|
*(uint8_t *)&data[blob->offset] = (uint8_t) parse_uint_value (constant->value);
|
2024-01-16 17:30:37 +01:00
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_INT16:
|
|
|
|
blob->size = 2;
|
2024-01-15 22:20:02 +01:00
|
|
|
*(int16_t *)&data[blob->offset] = (int16_t) parse_int_value (constant->value);
|
2024-01-16 17:30:37 +01:00
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_UINT16:
|
|
|
|
blob->size = 2;
|
2024-01-15 22:20:02 +01:00
|
|
|
*(uint16_t *)&data[blob->offset] = (uint16_t) parse_uint_value (constant->value);
|
2024-01-16 17:30:37 +01:00
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_INT32:
|
|
|
|
blob->size = 4;
|
2024-01-15 22:20:02 +01:00
|
|
|
*(int32_t *)&data[blob->offset] = (int32_t) parse_int_value (constant->value);
|
2024-01-16 17:30:37 +01:00
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_UINT32:
|
|
|
|
blob->size = 4;
|
2024-01-15 22:20:02 +01:00
|
|
|
*(uint32_t*)&data[blob->offset] = (uint32_t) parse_uint_value (constant->value);
|
2024-01-16 17:30:37 +01:00
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_INT64:
|
|
|
|
blob->size = 8;
|
2024-01-15 22:20:02 +01:00
|
|
|
DO_ALIGNED_COPY (&data[blob->offset], parse_int_value (constant->value), int64_t);
|
2024-01-16 17:30:37 +01:00
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_UINT64:
|
|
|
|
blob->size = 8;
|
2024-01-15 22:20:02 +01:00
|
|
|
DO_ALIGNED_COPY (&data[blob->offset], parse_uint_value (constant->value), uint64_t);
|
2024-01-16 17:30:37 +01:00
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_FLOAT:
|
2024-01-15 22:20:02 +01:00
|
|
|
blob->size = sizeof (float);
|
|
|
|
DO_ALIGNED_COPY (&data[blob->offset], parse_float_value (constant->value), float);
|
2024-01-16 17:30:37 +01:00
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_DOUBLE:
|
2024-01-15 22:20:02 +01:00
|
|
|
blob->size = sizeof (double);
|
|
|
|
DO_ALIGNED_COPY (&data[blob->offset], parse_float_value (constant->value), double);
|
2024-01-16 17:30:37 +01:00
|
|
|
break;
|
|
|
|
case GI_TYPE_TAG_UTF8:
|
|
|
|
case GI_TYPE_TAG_FILENAME:
|
|
|
|
blob->size = strlen (constant->value) + 1;
|
|
|
|
memcpy (&data[blob->offset], constant->value, blob->size);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
*offset2 += ALIGN_VALUE (blob->size, 4);
|
|
|
|
|
|
|
|
gi_ir_node_build_typelib ((GIIrNode *)constant->type, node, build, &pos, offset2, NULL);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
g_assert_not_reached ();
|
|
|
|
}
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2008-08-28 18:55:37 +02:00
|
|
|
g_debug ("node %s%s%s%p type '%s', offset %d -> %d, offset2 %d -> %d",
|
2024-01-16 17:30:37 +01:00
|
|
|
node->name ? "'" : "",
|
|
|
|
node->name ? node->name : "",
|
|
|
|
node->name ? "' " : "",
|
|
|
|
node, gi_ir_node_type_to_string (node->type),
|
|
|
|
old_offset, *offset, old_offset2, *offset2);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
2023-11-08 16:23:31 +01:00
|
|
|
if (*offset2 - old_offset2 + *offset - old_offset > gi_ir_node_get_full_size (node))
|
2009-02-20 03:48:51 +01:00
|
|
|
g_error ("exceeding space reservation; offset: %d (prev %d) offset2: %d (prev %d) nodesize: %d",
|
2023-11-08 16:23:31 +01:00
|
|
|
*offset, old_offset, *offset2, old_offset2, gi_ir_node_get_full_size (node));
|
2010-07-26 22:26:46 +02:00
|
|
|
|
|
|
|
if (appended_stack)
|
|
|
|
build->stack = g_list_delete_link (build->stack, build->stack);
|
2008-08-09 14:46:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* if str is already in the pool, return previous location, otherwise write str
|
2010-03-24 19:00:06 +01:00
|
|
|
* to the typelib at offset, put it in the pool and update offset. If the
|
2008-08-09 14:55:32 +02:00
|
|
|
* typelib is not large enough to hold the string, reallocate it.
|
2008-08-09 14:46:48 +02:00
|
|
|
*/
|
2024-01-15 22:20:02 +01:00
|
|
|
uint32_t
|
2024-01-15 20:20:47 +01:00
|
|
|
gi_ir_write_string (const char *str,
|
2023-11-08 16:23:31 +01:00
|
|
|
GHashTable *strings,
|
2024-01-16 00:10:43 +01:00
|
|
|
uint8_t *data,
|
2024-01-15 22:20:02 +01:00
|
|
|
uint32_t *offset)
|
2008-08-09 14:46:48 +02:00
|
|
|
{
|
2024-01-15 22:20:02 +01:00
|
|
|
uint32_t start;
|
2024-01-15 20:16:00 +01:00
|
|
|
void *value;
|
2008-08-09 14:46:48 +02:00
|
|
|
|
|
|
|
string_count += 1;
|
|
|
|
string_size += strlen (str);
|
|
|
|
|
|
|
|
value = g_hash_table_lookup (strings, str);
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2008-08-09 14:46:48 +02:00
|
|
|
if (value)
|
2008-08-21 18:15:55 +02:00
|
|
|
return GPOINTER_TO_UINT (value);
|
2008-08-09 14:46:48 +02:00
|
|
|
|
|
|
|
unique_string_count += 1;
|
|
|
|
unique_string_size += strlen (str);
|
|
|
|
|
2024-01-15 20:16:00 +01:00
|
|
|
g_hash_table_insert (strings, (void *)str, GUINT_TO_POINTER (*offset));
|
2008-08-09 14:46:48 +02:00
|
|
|
|
|
|
|
start = *offset;
|
|
|
|
*offset = ALIGN_VALUE (start + strlen (str) + 1, 4);
|
|
|
|
|
2024-01-15 20:20:47 +01:00
|
|
|
strcpy ((char *)&data[start], str);
|
2010-03-24 19:00:06 +01:00
|
|
|
|
2008-08-09 14:46:48 +02:00
|
|
|
return start;
|
|
|
|
}
|
|
|
|
|