[vkgen] Add support for labeled array elements

This treats dictionary items as arrays ordered by key creation (ie, the
order of the key/value pairs in the dictionary is preserved). The label
is written to the specified field when parsing the struct. Both actual
arrays and single element "arrays" are supported.
This commit is contained in:
Bill Currie 2023-02-10 19:36:53 +09:00
parent 061f90ab83
commit 3498d8b2ae
9 changed files with 200 additions and 4 deletions

View file

@ -12,6 +12,8 @@ vkgen_dat_src= \
libs/video/renderer/vulkan/vkgen/vkfielddata.r \
libs/video/renderer/vulkan/vkgen/vkfielddef.r \
libs/video/renderer/vulkan/vkgen/vkfieldignore.r \
libs/video/renderer/vulkan/vkgen/vkfieldlabeledarray.r \
libs/video/renderer/vulkan/vkgen/vkfieldlabeledsingle.r \
libs/video/renderer/vulkan/vkgen/vkfieldreadonly.r \
libs/video/renderer/vulkan/vkgen/vkfieldsingle.r \
libs/video/renderer/vulkan/vkgen/vkfieldstring.r \
@ -57,6 +59,8 @@ EXTRA_DIST += \
libs/video/renderer/vulkan/vkgen/vkfielddata.h \
libs/video/renderer/vulkan/vkgen/vkfielddef.h \
libs/video/renderer/vulkan/vkgen/vkfieldignore.h \
libs/video/renderer/vulkan/vkgen/vkfieldlabeledarray.h \
libs/video/renderer/vulkan/vkgen/vkfieldlabeledsingle.h \
libs/video/renderer/vulkan/vkgen/vkfieldreadonly.h \
libs/video/renderer/vulkan/vkgen/vkfieldsingle.h \
libs/video/renderer/vulkan/vkgen/vkfieldstring.h \

View file

@ -7,6 +7,8 @@
#include "vkfielddata.h"
#include "vkfielddef.h"
#include "vkfieldignore.h"
#include "vkfieldlabeledarray.h"
#include "vkfieldlabeledsingle.h"
#include "vkfieldreadonly.h"
#include "vkfieldsingle.h"
#include "vkfieldstring.h"
@ -44,6 +46,10 @@
return [[[SingleField alloc] init:item struct:strct field:fname] autorelease];
case "array":
return [[[ArrayField alloc] init:item struct:strct field:fname] autorelease];
case "labeledarray":
return [[[LabeledArrayField alloc] init:item struct:strct field:fname] autorelease];
case "labeledsingle":
return [[[LabeledSingleField alloc] init:item struct:strct field:fname] autorelease];
case "readonly":
return [[[ReadOnlyField alloc] init:item struct:strct field:fname] autorelease];
case "ignore":

View file

@ -0,0 +1,11 @@
#ifndef __renderer_vulkan_vkgen_vkfieldlabeledarray_h
#define __renderer_vulkan_vkgen_vkfieldlabeledarray_h
#include "vkfieldarray.h"
@interface LabeledArrayField: ArrayField
{
}
@end
#endif//__renderer_vulkan_vkgen_vkfieldlabeledarray_h

View file

@ -0,0 +1,37 @@
#include <PropertyList.h>
#include "vkfieldlabeledarray.h"
#include "vkfieldtype.h"
#include "vkgen.h"
#include "vkstruct.h"
#include "vktype.h"
@implementation LabeledArrayField
-init:(PLItem *) item struct:(Struct *)strct field:(string)fname
{
self = [super init:item struct:strct field:fname];
if (!self) {
return self;
}
PLItem *desc = [item getObjectForKey:"type"];
string label_field = [[desc getObjectAtIndex:2] string];
Type *t = [[Type lookup:[type type]] resolveType];
if ([t isKindOfClass:[Struct class]]) {
Struct *s = (Struct *) t;
[s setLabelField:label_field];
}
return self;
}
-writeField
{
fprintf (output_file, "\t{\"%s\", 0, %s, parse_%s, &parse_%s_%s_data},\n",
field_name, "QFDictionary", "labeledarray", struct_name,
field_name);
return self;
}
@end

View file

@ -0,0 +1,11 @@
#ifndef __renderer_vulkan_vkgen_vkfieldlabeledsingle_h
#define __renderer_vulkan_vkgen_vkfieldlabeledsingle_h
#include "vkfieldsingle.h"
@interface LabeledSingleField: SingleField
{
}
@end
#endif//__renderer_vulkan_vkgen_vkfieldlabeledsingle_h

View file

@ -0,0 +1,37 @@
#include <PropertyList.h>
#include "vkfieldlabeledsingle.h"
#include "vkfieldtype.h"
#include "vkgen.h"
#include "vkstruct.h"
#include "vktype.h"
@implementation LabeledSingleField
-init:(PLItem *) item struct:(Struct *)strct field:(string)fname
{
self = [super init:item struct:strct field:fname];
if (!self) {
return self;
}
PLItem *desc = [item getObjectForKey:"type"];
string label_field = [[desc getObjectAtIndex:2] string];
Type *t = [[Type lookup:[type type]] resolveType];
if ([t isKindOfClass:[Struct class]]) {
Struct *s = (Struct *) t;
[s setLabelField:label_field];
}
return self;
}
-writeField
{
fprintf (output_file, "\t{\"%s\", 0, %s, parse_%s, &parse_%s_%s_data},\n",
field_name, "QFDictionary", "labeledsingle", struct_name,
field_name);
return self;
}
@end

View file

@ -11,10 +11,12 @@
@interface Struct: Type
{
string outname;
string label_field;
int write_symtab;
}
-(void) queueFieldTypes;
-(qfot_var_t *)findField:(string) fieldName;
-(void) setLabelField:(string) label_field;
-(void) writeForward;
-(void) writeTable;
-(void) writeSymtabInit;

View file

@ -12,6 +12,12 @@
@implementation Struct
-(void) dealloc
{
str_free (outname);
str_free (label_field);
}
-(string) name
{
return str_mid(type.strct.tag, 4);
@ -67,7 +73,7 @@
-(string)sTypeName
{
string s = "VK_STRUCTURE_TYPE";
string name = str_hold ([self outname]);
string name = [self outname];
int length = strlen (name);
int start, end, c;
for (start = 2; start < length; start = end) {
@ -83,6 +89,11 @@
return str_upper (s);
}
-(void) setLabelField:(string)label_field
{
self.label_field = label_field;
}
-(void) writeForward
{
PLItem *field_dict = [parse getObjectForKey:[self name]];
@ -183,6 +194,11 @@
fprintf (output_file, "\t((%s *) data)->sType", [self outname]);
fprintf (output_file, " = %s;\n", [self sTypeName]);
}
if (label_field) {
fprintf (output_file, "\t((%s *) data)->%s", [self outname],
label_field);
fprintf (output_file, " = vkstrdup (context, field->name);\n");
}
fprintf (output_file,
"\tif (PL_Type (item) == QFString\n"
"\t\t&& !(item = parse_reference (item, \"%s\", messages, context))) {\n"

View file

@ -303,6 +303,34 @@ parse_ignore (const plfield_t *field, const plitem_t *item,
return 1;
}
static int __attribute__((used))
parse_labeledsingle (const plfield_t *field, const plitem_t *item,
void *data, plitem_t *messages, void *context)
{
__auto_type single = (parse_single_t *) field->data;
void *flddata = (byte *)data + single->value_offset;
//Sys_MaskPrintf (SYS_vulkan_parse,"parse_labeledsingle: %s %zd %d %p %p\n",
// field->name, field->offset,
// field->type, field->parser, field->data);
if (!PL_CheckType (single->type, PL_Type (item))) {
PL_TypeMismatch (messages, item, field->name, single->type,
PL_Type (item));
return 0;
}
plfield_t f = { 0, 0, single->type, single->parser, 0 };
void *value = vkparse_alloc (context, single->stride);
memset (value, 0, single->stride);
if (!single->parser (&f, item, value, messages, context)) {
return 0;
}
*(void **) flddata = value;
return 1;
}
static int
parse_single (const plfield_t *field, const plitem_t *item,
void *data, plitem_t *messages, void *context)
@ -331,6 +359,43 @@ parse_single (const plfield_t *field, const plitem_t *item,
return 1;
}
static int __attribute__((used))
parse_labeledarray (const plfield_t *field, const plitem_t *item,
void *data, plitem_t *messages, void *context)
{
__auto_type array = (parse_array_t *) field->data;
__auto_type value = (void **) ((byte *)data + array->value_offset);
__auto_type size = (uint32_t *) ((byte *)data + array->size_offset);
plelement_t element = {
array->type,
array->stride,
vkparse_alloc,
array->parser,
array->data,
};
plfield_t f = { 0, 0, 0, 0, &element };
typedef struct arr_s DARRAY_TYPE(byte) arr_t;
arr_t *arr;
//Sys_MaskPrintf (SYS_vulkan_parse, "parse_array: %s %zd %d %p %p %p\n",
// field->name, field->offset, field->type, field->parser,
// field->data, data);
//Sys_MaskPrintf (SYS_vulkan_parse, " %d %zd %p %zd %zd\n", array->type,
// array->stride, array->parser, array->value_offset,
// array->size_offset);
if (!PL_ParseLabeledArray (&f, item, &arr, messages, context)) {
return 0;
}
*value = vkparse_alloc (context, array->stride * arr->size);
memcpy (*value, arr->a, array->stride * arr->size);
if ((void *) size >= data) {
*size = arr->size;
}
return 1;
}
static int
parse_array (const plfield_t *field, const plitem_t *item,
void *data, plitem_t *messages, void *context)
@ -395,6 +460,15 @@ parse_fixed_array (const plfield_t *field, const plitem_t *item,
return 1;
}
static char *
vkstrdup (parsectx_t *context, const char *str)
{
size_t len = strlen (str) + 1;
char *dup = vkparse_alloc (context, len);
memcpy (dup, str, len);
return dup;
}
static int
parse_string (const plfield_t *field, const plitem_t *item,
void *data, plitem_t *messages, void *context)
@ -410,9 +484,7 @@ parse_string (const plfield_t *field, const plitem_t *item,
//Sys_MaskPrintf (SYS_vulkan_parse, " %zd\n", string->value_offset);
//Sys_MaskPrintf (SYS_vulkan_parse, " %s\n", str);
size_t len = strlen (str) + 1;
*value = vkparse_alloc (context, len);
memcpy (*value, str, len);
*value = vkstrdup (context, str);
return 1;
}