X-Git-Url: https://www.kengrimes.com/gitweb/?p=henge%2Fapc.git;a=blobdiff_plain;f=src%2Fir.c;h=857f73fb017bb3509fcafe40386cd20392677e5b;hp=3577d48e00ae705eed3a3631429236cd8752ab37;hb=HEAD;hpb=e4ad1c1a9499babb6804823e60377a14b6a0b583 diff --git a/src/ir.c b/src/ir.c index 3577d48..857f73f 100644 --- a/src/ir.c +++ b/src/ir.c @@ -17,12 +17,11 @@ #include //u32_cpy #include //ulc_fprintf /* Local */ +#define eprintf_callback(...) exit(EXIT_FAILURE) #include "print.h" #include "apc.h" #include "ir.h" #include "pagenode.h" -#undef do_error -#define do_error(...) exit(-1) #define XXH_PRIVATE_API #include "../xxHash/xxhash.h" /* Public */ @@ -33,6 +32,11 @@ int ir_linker(void); int ir_condenser(void); /* Set data mem */ enum dtype { FSDAT, MSDAT, ADAT, LDAT, FBDAT }; +struct ir_facinglist_t; +struct ir_facinglist_t +{ struct ir_facinglist_t* nextsib; + apc_facing facing; +}; struct ir_namelist_t; struct ir_namelist_t { struct ir_namelist_t* nextsib; @@ -55,7 +59,9 @@ struct ir_setdata_header_t }; struct ir_framedata_t { struct ir_setdata_header_t header; - struct ir_frameinfo_t frameinfo; + apc_facing facing; + int w, h; + struct ir_facinglist_t* mirrorlist,* nextmirror; }; struct ir_framebox_t { struct ir_setdata_header_t header; @@ -65,9 +71,9 @@ struct ir_framebox_t struct ir_simplex_t { struct ir_setdata_header_t header; }; struct ir_link_t { struct ir_setdata_header_t header; - struct ir_classld_t* classld; struct ir_setld_t* setld; struct ir_set_t* trg_set; + uint8_t* dlink; enum ltype type; }; union ir_setdata_t @@ -97,7 +103,7 @@ struct ir_set_t static inline struct ir_framebox_t* ir_set_add_framebox(struct ir_set_t*,uint8_t*); static inline -union ir_setdata_t* ir_framedata (enum dtype,const uint8_t*,apc_facing,int,int); +union ir_setdata_t* ir_framedata (enum dtype,const uint8_t*,facinglist,int,int); static inline void ir_linkdata_resolve_set(union ir_setdata_t*); static inline @@ -399,17 +405,17 @@ void ir_set_assign_data switch (setdata->header.type) { case FSDAT: framebox = ir_set_add_framebox(set, setdata->header.data_name); - if (framebox->framesheets[setdata->framesheet.frameinfo.facing].header.data_name != NULL) + if (framebox->framesheets[setdata->framesheet.facing].header.data_name != NULL) wprintf("Duplicate framesheet [%i] %s\n", - setdata->framesheet.frameinfo.facing, setdata->header.data_name); - framebox->framesheets[setdata->framesheet.frameinfo.facing] = setdata->framesheet; + setdata->framesheet.facing, setdata->header.data_name); + framebox->framesheets[setdata->framesheet.facing] = setdata->framesheet; break; case MSDAT: framebox = ir_set_add_framebox(set, setdata->header.data_name); - if (framebox->mapsheets[setdata->mapsheet.frameinfo.facing].header.data_name != NULL) + if (framebox->mapsheets[setdata->mapsheet.facing].header.data_name != NULL) wprintf("Duplicate mapsheet [%i] %s\n", - setdata->mapsheet.frameinfo.facing, setdata->header.data_name); - framebox->mapsheets[setdata->mapsheet.frameinfo.facing] = setdata->mapsheet; + setdata->mapsheet.facing, setdata->header.data_name); + framebox->mapsheets[setdata->mapsheet.facing] = setdata->mapsheet; break; case ADAT: if (set->audio == NULL) @@ -487,28 +493,28 @@ void ir_data_assign_path } union ir_setdata_t* ir_framesheet -( const uint8_t* name, - apc_facing d, - int width, - int height +( const uint8_t* name, + struct ir_facinglist_t* facinglist, + int width, + int height ) -{ return ir_framedata(FSDAT, name, d, width, height); } +{ return ir_framedata(FSDAT, name, facinglist, width, height); } union ir_setdata_t* ir_mapsheet -( const uint8_t* name, - apc_facing d, - int width, - int height +( const uint8_t* name, + struct ir_facinglist_t* facinglist, + int width, + int height ) -{ return ir_framedata(MSDAT, name, d, width, height); } +{ return ir_framedata(MSDAT, name, facinglist, width, height); } static inline union ir_setdata_t* ir_framedata -( enum dtype type, - const uint8_t* name, - apc_facing d, - int width, - int height +( enum dtype type, + const uint8_t* name, + struct ir_facinglist_t* facinglist, + int width, + int height ) { struct ir_framedata_t* framedata = struct_alloc(ir_framedata_t); struct_clear(framedata); @@ -516,9 +522,17 @@ union ir_setdata_t* ir_framedata eprintf("Null name in set allocation\n"); framedata->header.type = type; framedata->header.data_name = name_alloc(name); - framedata->frameinfo.facing = d; - framedata->frameinfo.w = width; - framedata->frameinfo.h = height; + if (facinglist != NULL) + { framedata->facing = facinglist->facing; + framedata->mirrorlist = facinglist->nextsib; + } + else + { framedata->facing = SFACE; + framedata->mirrorlist = NULL; + } + framedata->nextmirror = framedata->mirrorlist; + framedata->w = width; + framedata->h = height; return (union ir_setdata_t*) framedata; } @@ -597,8 +611,7 @@ union ir_setdata_t* ir_link link = struct_alloc(ir_link_t); struct_clear(link); link->header.type = LDAT; - link->type = link_type; - link->classld = setld->classld; + link->type = link_type; link->setld = setld; if (link_type != OLINK && name != NULL) link->header.data_name = name_alloc(name); @@ -620,10 +633,10 @@ union ir_setdata_t* ir_set_link ( struct ir_set_t* set ) { return (union ir_setdata_t*) set->links; } -#define assert_link(linkdata) do { \ +#define assert_link(linkdata) if (DEBUG) { \ if (linkdata->header.type != LDAT) \ eprintf("Data %s is not a link\n", linkdata->header.data_name); \ - } while (0) + } /* Return the link type */ enum ltype ir_linkdata_type @@ -663,7 +676,7 @@ void ir_linkdata_resolve_set setld = linkdata->link.setld; if (linkdata->link.setld == NULL) eprintf("Link data is invalid\n"); - classld = linkdata->link.classld; + classld = setld->classld; if (classld != NULL) { namelist_iter = classld->namelist; if (classld->root_class == NULL) @@ -687,7 +700,9 @@ void ir_linkdata_resolve_set namelist_iter->name, namelist_iter_last->name); else - eprintf("No such class \"%s\"\n", namelist_iter->name); + { wprintf("No such class \"%s\"\n", namelist_iter->name); + return; + } } set = class_iter->root_set; } @@ -723,6 +738,85 @@ void ir_linkdata_resolve_set linkdata->link.trg_set = set; } +/* Assign a linkdatas trg_set */ +void ir_linkdata_assign_set +( union ir_setdata_t* link, struct ir_set_t* set ) +{ assert_link(link); + link->link.trg_set = set; +} + +/* Assign a linkdatas type */ +void ir_linkdata_assign_type +( union ir_setdata_t* link, enum ltype type ) +{ assert_link(link); + link->link.type = type; +} + +/* Get, or generate, the fully qualified name of the link's target set */ +uint8_t* +ir_linkdata_dlink_name +( union ir_setdata_t* link ) +{ struct ir_namelist_t* namelist_iter; + struct ir_setld_t* setld; + struct ir_classld_t* classld; + uint8_t* bytep; + size_t bytes; + char setpass; + uint8_t delimiter; + static const uint8_t dlink_prefix[] = { '/', '.', '.', '/' }; +# define dlink_prefix_len 4 + assert_link(link); + if (link->link.dlink != NULL) + return link->link.dlink; + bytes = 0; + setld = link->link.setld; + if (setld == NULL) + eprintf("No setld in dlink\n"); + classld = setld->classld; + if (classld == NULL) + eprintf("No classld in dlink\n"); + if (classld->root_class != NULL) + eprintf("Cannot dlink local class \"%s\"\n", classld->root_class->name); + namelist_iter = classld->namelist; + setpass = 0; + count_bytes_in_namelist: + while (namelist_iter != NULL) + { bytep = namelist_iter->name; + while (*bytep++); + bytes += (bytep - namelist_iter->name); + namelist_iter = namelist_iter->nextsib; + } + if (setpass == 0) + { setpass = 1; + namelist_iter = setld->namelist; + goto count_bytes_in_namelist; + } + bytes += dlink_prefix_len; + link->link.dlink = stack_alloc(&namepages, bytes); + for (bytes = 0; bytes < dlink_prefix_len; bytes++) + link->link.dlink[bytes] = dlink_prefix[bytes]; + namelist_iter = classld->namelist; + setpass = 0; + delimiter = APC_CLASS_DELIMITER; + copy_bytes_in_namelist: + while (namelist_iter != NULL) + { bytep = namelist_iter->name; + while (*bytep) + link->link.dlink[bytes++] = *bytep++; + link->link.dlink[bytes++] = delimiter; + namelist_iter = namelist_iter->nextsib; + } + if (setpass == 0) + { setpass = 1; + namelist_iter = setld->namelist; + delimiter = APC_SET_DELIMITER; + link->link.dlink[bytes - 1] = delimiter; //overwrite last delimiter + goto copy_bytes_in_namelist; + } + link->link.dlink[bytes] = '\0'; //tailing '\0' null termination + return link->link.dlink; +} + /* Get a setdata's next sibling */ union ir_setdata_t* ir_setdata_nextsib ( union ir_setdata_t* setdata ) @@ -750,13 +844,45 @@ void ir_setdata_assign_fpos ) { setdata->header.filepos = newpos; } +/* Assign a setdatas name */ +void ir_setdata_assign_name +( union ir_setdata_t* setdata, uint8_t* name ) +{ setdata->header.data_name = name;} + +/* Create a new facinglist from an apc_facing */ +struct ir_facinglist_t* ir_facinglist +( apc_facing facing ) +{ struct ir_facinglist_t* list = struct_alloc(ir_facinglist_t); + list->facing = facing; + return list; +} + +/* Add a child to the facing list */ +struct ir_facinglist_t* ir_facinglist_push +( struct ir_facinglist_t* list, + apc_facing facing +) +{ struct ir_facinglist_t* iter = list; + if (iter != NULL) + { while (iter->nextsib != NULL) + iter = iter->nextsib; + iter->nextsib = struct_alloc(ir_facinglist_t); + iter->nextsib->facing = facing; + } + return list; +} + +#define assert_framebox(fbox) if (DEBUG) { \ + if (fbox->header.type != FBDAT) \ + eprintf("Data %s is not a framebox\n", fbox->header.data_name); \ + } + /* Return a framebox's specified framesheet */ union ir_setdata_t* ir_framebox_framesheet ( union ir_setdata_t* fbox, apc_facing facing ) -{ if (fbox->header.type != FBDAT) - eprintf("Data %s is not a framebox\n", fbox->header.data_name); +{ assert_framebox(fbox); return (union ir_setdata_t*) &fbox->framebox.framesheets[facing]; } @@ -765,19 +891,51 @@ union ir_setdata_t* ir_framebox_mapsheet ( union ir_setdata_t* fbox, apc_facing facing ) -{ if (fbox->header.type != FBDAT) - eprintf("Data %s is not a framebox\n", fbox->header.data_name); +{ assert_framebox(fbox); return (union ir_setdata_t*) &fbox->framebox.mapsheets[facing]; } +#define assert_framedata(fdat) if (DEBUG) { \ + if (fdat->header.type != MSDAT && fdat->header.type != FSDAT) \ + eprintf("Data %s is not a framedata\n", fdat->header.data_name); \ + } + +/* Return a framedata's frame info */ +int ir_framedata_width +( union ir_setdata_t* framedata ) +{ assert_framedata(framedata); + return framedata->mapsheet.w; +} + /* Return a framedata's frame info */ -struct ir_frameinfo_t* ir_framedata_frameinfo +int ir_framedata_height +( union ir_setdata_t* framedata ) +{ assert_framedata(framedata); + return framedata->mapsheet.h; +} + +/* Return the next facing in the framedata's facing list, and reset the + 'nextmirror' head to mirrorlist, so that 'ir_framedata_nextmirror' will now + refer to the second facing in the framedata */ +apc_facing ir_framedata_firstfacing ( union ir_setdata_t* framedata ) -{ if (framedata->header.type != MSDAT && framedata->header.type != FSDAT) - eprintf("Data %s is not a framedata\n", framedata->header.data_name); - return &framedata->mapsheet.frameinfo; +{ assert_framedata(framedata); + framedata->mapsheet.nextmirror = framedata->mapsheet.mirrorlist; + return framedata->mapsheet.facing; } +/* Return the next facing for this framedata, incrementing the 'nextmirror' + head. Returns FACING_MAX when there are no more facings to return. */ +apc_facing ir_framedata_nextfacing +( union ir_setdata_t* framedata ) +{ apc_facing facing; + assert_framedata(framedata); + if (framedata->mapsheet.nextmirror == NULL) + return FACING_MAX; + facing = framedata->mapsheet.nextmirror->facing; + framedata->mapsheet.nextmirror = framedata->mapsheet.nextmirror->nextsib; + return facing; +} /** Allocators **/ static