Commit d15f8cde authored by Colin Walters's avatar Colin Walters

Bug 557786 - support fixed size arrays

svn path=/trunk/; revision=814
parent c7d2a071
2008-10-25 Andreas Rottmann <a.rottmann@gmx.at>
Bug 557786 - support fixed size arrays
* girepository/ginfo.c: Add g_type_info_get_array_fixed_size.
* giscanner/scannerparser.y: Retain fixed array size.
* giscanner/ast.py: Add to note.
* giscanner/girwriter.py: Write to gir.
* girepository/girnode.c: Write it to typelib.
* tools/generate.c: Generate.
* tests/*: Add tests.
2008-10-25 Colin Walters <walters@verbum.org>
Bug 557076 - move typelibs to $libdir
......
......@@ -830,6 +830,26 @@ g_type_info_get_array_length (GITypeInfo *info)
return -1;
}
gint
g_type_info_get_array_fixed_size (GITypeInfo *info)
{
GIBaseInfo *base = (GIBaseInfo *)info;
SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset];
if (!(type->reserved == 0 && type->reserved2 == 0))
{
ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->typelib->data[base->offset];
if (blob->tag == GI_TYPE_TAG_ARRAY)
{
if (blob->has_size)
return blob->size;
}
}
return -1;
}
gboolean
g_type_info_is_zero_terminated (GITypeInfo *info)
{
......
......@@ -320,6 +320,7 @@ GITypeInfo * g_type_info_get_param_type (GITypeInfo *info,
gint n);
GIBaseInfo * g_type_info_get_interface (GITypeInfo *info);
gint g_type_info_get_array_length (GITypeInfo *info);
gint g_type_info_get_array_fixed_size(GITypeInfo *info);
gboolean g_type_info_is_zero_terminated (GITypeInfo *info);
gint g_type_info_get_n_error_domains (GITypeInfo *info);
......
......@@ -1114,6 +1114,8 @@ serialize_type (GIrModule *module,
if (node->has_length)
g_string_append_printf (str, "length=%d", node->length);
else if (node->has_size)
g_string_append_printf (str, "fixed-size=%d", node->size);
if (node->zero_terminated)
g_string_append_printf (str, "%szero-terminated=1",
......@@ -1319,8 +1321,14 @@ g_ir_node_build_typelib (GIrNode *node,
array->tag = type->tag;
array->zero_terminated = type->zero_terminated;
array->has_length = type->has_length;
array->has_size = type->has_size;
array->reserved2 = 0;
array->length = type->length;
if (array->has_length)
array->length = type->length;
else if (array->has_size)
array->size = type->size;
else
array->length = -1;
pos = *offset2 + 4;
*offset2 += 8;
......
......@@ -119,6 +119,8 @@ struct _GIrNodeType
gboolean zero_terminated;
gboolean has_length;
gint length;
gboolean has_size;
gint size;
GIrNodeType *parameter_type1;
GIrNodeType *parameter_type2;
......
......@@ -1514,6 +1514,7 @@ start_type (GMarkupParseContext *context,
{
const char *zero;
const char *len;
const char *size;
typenode = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE);
......@@ -1523,10 +1524,14 @@ start_type (GMarkupParseContext *context,
zero = find_attribute ("zero-terminated", attribute_names, attribute_values);
len = find_attribute ("length", attribute_names, attribute_values);
size = find_attribute ("fixed-size", attribute_names, attribute_values);
typenode->zero_terminated = !(zero && strcmp (zero, "1") != 0);
typenode->has_length = len != NULL;
typenode->length = typenode->has_length ? atoi (len) : -1;
typenode->has_size = size != NULL;
typenode->size = typenode->has_size ? atoi (size) : -1;
}
else
{
......
......@@ -206,9 +206,13 @@ typedef struct
guint16 zero_terminated :1;
guint16 has_length :1;
guint16 reserved2 :6;
guint16 has_size :1;
guint16 reserved2 :5;
guint16 length;
union {
guint16 length;
guint16 size;
};
SimpleTypeBlob type;
} ArrayTypeBlob;
......
......@@ -227,6 +227,7 @@ class Array(Type):
self.zeroterminated = True
self.length_param_index = -1
self.length_param_name = None
self.size = None
def __repr__(self):
return 'Array(%r of %r)' % (self.name, self.element_type, )
......
......@@ -176,6 +176,8 @@ class GIRWriter(XMLWriter):
if ntype.length_param_index >= 0:
attrs.append(('length', '%d' % (ntype.length_param_index, )))
attrs.append(('c:type', ntype.ctype))
if ntype.size is not None:
attrs.append(('fixed-size', ntype.size))
with self.tagcontext('array', attrs):
self._write_type(ntype.element_type)
return
......
......@@ -923,12 +923,12 @@ direct_declarator
| direct_declarator '[' assignment_expression ']'
{
$$ = $1;
gi_source_symbol_merge_type ($$, gi_source_array_new ());
gi_source_symbol_merge_type ($$, gi_source_array_new ($3));
}
| direct_declarator '[' ']'
{
$$ = $1;
gi_source_symbol_merge_type ($$, gi_source_array_new ());
gi_source_symbol_merge_type ($$, gi_source_array_new (NULL));
}
| direct_declarator '(' parameter_list ')'
{
......@@ -1059,22 +1059,22 @@ direct_abstract_declarator
| '[' ']'
{
$$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
gi_source_symbol_merge_type ($$, gi_source_array_new ());
gi_source_symbol_merge_type ($$, gi_source_array_new (NULL));
}
| '[' assignment_expression ']'
{
$$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
gi_source_symbol_merge_type ($$, gi_source_array_new ());
gi_source_symbol_merge_type ($$, gi_source_array_new ($2));
}
| direct_abstract_declarator '[' ']'
{
$$ = $1;
gi_source_symbol_merge_type ($$, gi_source_array_new ());
gi_source_symbol_merge_type ($$, gi_source_array_new (NULL));
}
| direct_abstract_declarator '[' assignment_expression ']'
{
$$ = $1;
gi_source_symbol_merge_type ($$, gi_source_array_new ());
gi_source_symbol_merge_type ($$, gi_source_array_new ($3));
}
| '(' ')'
{
......
......@@ -163,9 +163,11 @@ gi_source_pointer_new (GISourceType * base_type)
}
GISourceType *
gi_source_array_new (void)
gi_source_array_new (GISourceSymbol *size)
{
GISourceType *array = gi_source_type_new (CTYPE_ARRAY);
if (size != NULL && size->type == CSYMBOL_TYPE_CONST && size->const_int_set)
array->child_list = g_list_append (array->child_list, size);
return array;
}
......
......@@ -163,7 +163,6 @@ GISourceDirective * gi_source_directive_new (const gchar *name,
void gi_source_directive_free (GISourceDirective *directive);
/* Private */
GISourceType * gi_source_array_new (void);
void gi_source_scanner_add_symbol (GISourceScanner *scanner,
GISourceSymbol *symbol);
gboolean gi_source_scanner_is_typedef (GISourceScanner *scanner,
......@@ -178,7 +177,7 @@ GISourceType * gi_source_struct_new (const char *name);
GISourceType * gi_source_union_new (const char *name);
GISourceType * gi_source_enum_new (const char *name);
GISourceType * gi_source_pointer_new (GISourceType *base_type);
GISourceType * gi_source_array_new (void);
GISourceType * gi_source_array_new (GISourceSymbol *size);
GISourceType * gi_source_function_new (void);
G_END_DECLS
......
......@@ -309,7 +309,14 @@ class Transformer(object):
symbol.base_type.base_type.type == CTYPE_FUNCTION):
node = self._create_callback(symbol)
else:
ftype = self._create_type(symbol.base_type, {}, True)
opts = {}
if ctype == CTYPE_ARRAY:
opts['array'] = []
child_list = list(symbol.base_type.child_list)
if child_list:
size_opt = 'fixed-size=%d' % (child_list[0].const_int, )
opts['array'].append(size_opt)
ftype = self._create_type(symbol.base_type, opts, True)
# Fields are assumed to be read-write
# (except for Objects, see also glibtransformer.py)
node = Field(symbol.ident, ftype, symbol.ident,
......@@ -392,13 +399,16 @@ class Transformer(object):
ctype,
key_type, value_type)
elif (ctype in default_array_types) or ('array' in options):
derefed_name = ctype[:-1] # strip the *
derefed_name = ctype[:-1] if ctype[-1] == '*' else ctype
rettype = Array(ctype,
self._parse_ctype(derefed_name))
array_opts = options.get('array')
if array_opts:
(_, len_name) = array_opts[0].split('=')
rettype.length_param_name = len_name
array_opts = dict([opt.split('=')
for opt in options.get('array', [])])
if 'length' in array_opts:
rettype.length_param_name = array_opts['length']
if 'fixed-size' in array_opts:
rettype.size = array_opts['fixed-size']
rettype.zeroterminated = False
else:
derefed_name = self._parse_ctype(ctype)
rettype = Type(derefed_name, ctype)
......
......@@ -41,6 +41,11 @@
<field name="bitfield2" writable="1" bits="2">
<type name="uint" c:type="guint"/>
</field>
<field name="data" writable="1">
<array zero-terminated="0" c:type="guint8" fixed-size="16">
<type name="uint8"/>
</array>
</field>
</record>
<union name="Union" c:type="UtilityUnion">
<field name="pointer" writable="1">
......
......@@ -36,6 +36,11 @@
<field name="bitfield2" writable="1" offset="0">
<type name="uint"/>
</field>
<field name="data" writable="1" offset="0">
<array fixed-size="16">
<type name="uint8"/>
</array>
</field>
</record>
<union name="Union">
<field name="pointer" writable="1" offset="0">
......
......@@ -44,6 +44,7 @@ typedef struct
int field;
guint bitfield1 : 3;
guint bitfield2 : 2;
guint8 data[16];
} UtilityStruct;
typedef union
......
......@@ -217,16 +217,19 @@ write_type_info (const gchar *namespace,
}
else if (tag == GI_TYPE_TAG_ARRAY)
{
gint length;
gint length, size;
xml_start_element (file, "array");
type = g_type_info_get_param_type (info, 0);
length = g_type_info_get_array_length (info);
if (length >= 0)
xml_printf (file, " length=\"%d\"", length);
xml_printf (file, " length=\"%d\"", length);
size = g_type_info_get_array_fixed_size (info);
if (size >= 0)
xml_printf (file, " fixed-size=\"%d\"", size);
if (g_type_info_is_zero_terminated (info))
xml_printf (file, " zero-terminated=\"1\"");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment