X-Git-Url: https://www.kengrimes.com/gitweb/?p=henge%2Fapc.git;a=blobdiff_plain;f=src%2Fir.c;h=a175ef3fdfd93e7c47b02f332a4ac3f4e2cfef67;hp=76c221d2d376d164489635b47fec0920c976cd8c;hb=7dae7dc73dfbabdc895a78738f550f56561da644;hpb=1effafc476cde8a9996d2a520dd3afc3666f45af diff --git a/src/ir.c b/src/ir.c index 76c221d..a175ef3 100644 --- a/src/ir.c +++ b/src/ir.c @@ -14,30 +14,53 @@ #include //u8_* functions #include //uint8_t as a char #include //u32_cpy +#include //ulc_fprintf /* Local */ +#include "print.h" #include "apc.h" #include "ir.h" +#undef do_error +#define do_error(...) exit(-1) /* Public */ int ir_init(void); void ir_quit(void); int ir_linker(void); int ir_condenser(void); -/* Private */ -extern //apc.c -long sys_pagesize; -static - -static inline -struct ir_framebox_t* ir_set_add_framebox(struct ir_set_t*, uint8_t*); -static inline -void ir_quit_r(struct pagenode_t*); -static inline -int bytes_identical(uint8_t*,uint8_t*); - -/* Enumerated types */ -enum dtype { FSDAT, MSDAT, ADAT, LDAT, FBDAT }; -enum ltype { OLINK, MLINK, VLINK, ALINK }; +/* Memory allocation structures */ +struct pagenode_t; +struct pagenode_header_t { + struct pagenode_t* next; + char* head; +}; +struct pagenode_t { + struct pagenode_header_t header; + char root[]; +}; +struct pagelist_t { + struct pagenode_t* root, * head; + size_t pagesize; +}; +#define DATA_PAGESIZE (sys_pagesize) +#define NAME_PAGESIZE (APC_NAME_MAX * 1024) +#define PL_HEADERSIZE (sizeof(struct pagenode_header_t)) +#define PL_HEADSIZE(_PL) (_PL.head->header.head - _PL.head->root) +#define PL_HEADMEM(_PL) (_PL.pagesize - PL_HEADERSIZE - PL_HEADSIZE(_PL)) /* Set data mem */ +enum dtype { FSDAT, MSDAT, ADAT, LDAT, FBDAT }; +struct ir_namelist_t; +struct ir_namelist_t +{ struct ir_namelist_t* nextsib; + uint8_t* name; +}; +struct ir_classld_t +{ struct ir_class_t* root_class; + struct ir_namelist_t* namelist, * namelist_head; +}; +struct ir_setld_t +{ struct ir_classld_t* classld; + long long ref; + struct ir_namelist_t* namelist, * namelist_head; +}; struct ir_setdata_header_t { enum dtype type; uint8_t* src_filename, * data_name; @@ -47,21 +70,20 @@ struct ir_frameinfo_t { int facing, w, h; }; struct ir_framedata_t { struct ir_setdata_header_t header; - struct ir_frameinfo_t frameinfo; -}** framedatas; + struct ir_frameinfo_t frameinfo; +}; struct ir_framebox_t { struct ir_setdata_header_t header; struct ir_framedata_t framesheets[FACING_MAX]; struct ir_framedata_t mapsheets[FACING_MAX]; -}** frameboxes; -struct ir_simplex_t -{ struct ir_setdat_header_t header; -}** simplexes; +}; +struct ir_simplex_t { struct ir_setdata_header_t header; }; struct ir_link_t -{ struct ir_setdat_header_t header; - struct ir_set_t* src, * trg; - enum ltype type; -}** links; +{ struct ir_setdata_header_t header; + struct ir_classld_t* classld; + struct ir_setld_t* setld; + enum ltype type; +}; union ir_setdata_t { struct ir_setdata_header_t header; struct ir_framebox_t framebox; @@ -74,67 +96,81 @@ struct ir_class_t { struct ir_class_t* nextchild, * nextsib; struct ir_set_t* root_set; uint8_t* name; -}** classes; +}; struct ir_set_t -{ struct ir_set_t* nextchild, * nextsib; - struct ir_class_t* class; - long long ref; - uint8_t* name; - struct framebox_t* frameboxes; - struct simplex_t* audio; - struct link_t* links; -}** sets; -/* Function-Like Macros */ -#define do_warn() do { \ - } while (0) -#define wprint(str) do { \ - fprintf(stderr, str); \ - do_warn(); \ - } while (0) - #define wprintf(fmt,...) do { \ - fprintf(stderr, fmt, __VA_ARGS__); \ - do_warn(); \ - } while (0) -#define do_error() do { \ - exit(-1); \ - } while (0) -#define eprint(str) do { \ - fprintf(stderr, str); \ - do_error(); \ - } while (0) -#define eprintf(fmt,...) do { \ - fprintf(stderr, fmt, __VA_ARGS__); \ - do_error(); \ - } while (0) -#define struct_alloc(_T) ((struct _T*) stack_alloc(sizeof(struct _T))) - - +{ struct ir_set_t* nextchild, * nextsib; + struct ir_class_t* class; + long long ref; + uint8_t* name; + struct ir_framebox_t* frameboxes; + struct ir_simplex_t* audio; + struct ir_link_t* links; +}; +/* Functions */ +static inline +struct ir_framebox_t* ir_set_add_framebox(struct ir_set_t*,const uint8_t*); +static inline +union ir_setdata_t* ir_framedata (enum dtype,const uint8_t*,apc_facing,int,int); +static inline +int init_pagelist(struct pagelist_t*,size_t); +static +void ir_free_pagenodes(struct pagenode_t*); +static inline +int bytes_identical(const uint8_t*,const uint8_t*); +static inline +int classnames_identical(const uint8_t*,const uint8_t*); static -struct ir_class_t root_class = { .name = "." }; +void* stack_alloc(size_t); +#define struct_alloc(_T) ((struct _T*) stack_alloc(sizeof(struct _T))) +static +uint8_t* name_alloc(const uint8_t*); +static +uint8_t* classname_alloc(const uint8_t*); +extern //apc.c +long sys_pagesize; +static +struct pagelist_t datapages, namepages; +static +struct ir_class_t root_class = { .name = (uint8_t*)"." }; /* Init */ int ir_init ( void ) -{ pagenode_root = calloc(struct pagenode_t*) calloc(PN_ALLOCSIZE); - if (pagenode_root == NULL) +{ if (init_pagelist(&datapages, (size_t)DATA_PAGESIZE)) + eprintf("Memory allocation error\n"); + if (init_pagelist(&namepages, (size_t)NAME_PAGESIZE)) + eprintf("Memory allocation error\n"); + return 0; +} + +static inline +int init_pagelist +( struct pagelist_t* pl, + size_t size +) +{ pl->pagesize = size; + pl->root = (struct pagenode_t*) calloc(size,1); + if (pl->root == NULL) return -1; - pagenode_root->head = pagenode_root->root; - pagenode_head = pagenode_root; + pl->root->header.head = pl->root->root; + pl->head = pl->root; return 0; -} +} /* Quit/Cleanup Recursively clean pagenode linked list */ void ir_quit ( void ) -{ ir_quit_r(pagenode_root); } +{ ir_free_pagenodes(datapages.root); + ir_free_pagenodes(namepages.root); +} -static inline -void ir_quit_r +static +void ir_free_pagenodes ( struct pagenode_t* pagenode ) -{ if (pagenode->next != NULL) - ir_quit_r(pagenode->next); +{ if (pagenode->header.next != NULL) + ir_free_pagenodes(pagenode->header.next); free(pagenode); } @@ -150,6 +186,11 @@ int ir_condenser ( void ) { return 0; } +/* Return the class's name string */ +uint8_t* ir_class_name +( struct ir_class_t* class ) +{ return class->name; } + /* Return a pointer to the root class */ struct ir_class_t* ir_class_root ( void ) @@ -161,20 +202,28 @@ struct ir_class_t* ir_class_root */ struct ir_class_t* ir_class_addchild ( struct ir_class_t* class, - uint8_t* name + const uint8_t* name ) { struct ir_class_t* iter; if (class->nextchild == NULL) - return class->nextchild = struct_alloc(ir_class_t); + goto alloc; iter = class->nextchild; + if (iter->name == NULL) + eprintf("Null name pointer in class %p\n", iter); + if (name == NULL) + eprintf("Null child added to class %s\n", iter->name); check: - if (bytes_identical(iter->name, name)) + if (classnames_identical(iter->name, name)) return iter; if (iter->nextsib != NULL) { iter = iter->nextsib; goto check; } - return iter->nextsib = struct_alloc(ir_class_t); + alloc: + iter = struct_alloc(ir_class_t); + iter->nextsib = class->nextchild; + iter->name = classname_alloc(name); + return class->nextchild = iter; } /* Add a set to a class @@ -183,12 +232,16 @@ struct ir_class_t* ir_class_addchild */ struct ir_set_t* ir_class_addset ( struct ir_class_t* class, - uint8_t* name + const uint8_t* name ) { struct ir_set_t* iter; if (class->root_set == NULL) - return class->root_set = struct_alloc(ir_set_t); + goto alloc; iter = class->root_set; + if (iter->name == NULL) + eprintf("Null name pointer in class %p\n", iter); + if (name == NULL) + eprintf("Null set added to class %U\n", iter->name); check: if (bytes_identical(iter->name, name)) return iter; @@ -196,7 +249,11 @@ struct ir_set_t* ir_class_addset { iter = iter->nextsib; goto check; } - return iter->nextsib = struct_alloc(ir_set_t); + alloc: + iter = struct_alloc(ir_set_t); + iter->nextsib = class->root_set; + iter->name = name_alloc(name); + return class->root_set = iter; } /* Add a set to a set @@ -205,12 +262,16 @@ struct ir_set_t* ir_class_addset */ struct ir_set_t* ir_set_addchild ( struct ir_set_t* set, - uint8_t* name + const uint8_t* name ) { struct ir_set_t* iter; if (set->nextchild == NULL) - return set->nextchild = struct_alloc(ir_set_t); + goto alloc; iter = set->nextchild; + if (iter->name == NULL) + eprintf("Null name pointer in set %p\n", iter); + if (name == NULL) + eprintf("Null child added to set %s\n", iter->name); check: if (bytes_identical(iter->name, name)) return iter; @@ -218,7 +279,11 @@ struct ir_set_t* ir_set_addchild { iter = iter->nextsib; goto check; } - return iter->nextsib = struct_alloc(ir_set_t); + alloc: + iter = struct_alloc(ir_set_t); + iter->nextsib = set->nextchild; + iter->name = name_alloc(name); + return set->nextchild = iter; } /* Add a framebox to a set @@ -228,20 +293,24 @@ struct ir_set_t* ir_set_addchild static inline struct ir_framebox_t* ir_set_add_framebox ( struct ir_set_t* set, - uint8_t* name + const uint8_t* name ) { struct ir_framebox_t* iter; if (set->frameboxes == NULL) - return set->frameboxes = struct_alloc(ir_framebox_t); + goto alloc; iter = set->frameboxes; check: - if (bytes_identical(iter->header.name, name)) + if (bytes_identical(iter->header.data_name, name)) return iter; if (iter->header.nextsib != NULL) - { iter = iter->header.nextsib; + { iter = (struct ir_framebox_t*) iter->header.nextsib; goto check; } - return iter->header.nextsib = struct_alloc(ir_framebox_t); + alloc: + iter = struct_alloc(ir_framebox_t); + iter->header.nextsib = (union ir_setdata_t*) set->frameboxes; + iter->header.data_name = name_alloc(name); + return set->frameboxes = iter; } /* Match two null-terminated bytestrings @@ -249,13 +318,28 @@ struct ir_framebox_t* ir_set_add_framebox */ static inline int bytes_identical -( uint8_t* stra, - uint8_t* strb +( const uint8_t* stra, + const uint8_t* strb ) -{ while (*stra && *strb) - if (*stra++ != *strb++) - return 0; - return *stra == *strb; +{ int ca, cb; + do { + ca = *stra++; + cb = *strb++; + } while (ca && ca != '_' && ca == cb); + return (ca == cb); +} + +static inline +int classnames_identical +( const uint8_t* stra, + const uint8_t* strb +) +{ int ca, cb; + do { + ca = *stra++; + cb = *strb++; + } while (ca && ca == cb); + return (ca == cb); } /* Assign Setdata to Set @@ -267,47 +351,42 @@ void ir_set_assign_data ) { struct ir_framebox_t* framebox; struct ir_simplex_t* simplex; - struct ir_link_t* link; switch (setdata->header.type) { case FSDAT: - framebox = ir_set_add_framebox(set, setdata->header.name); - if (framebox->framesheets[setdata->framesheet.frameinfo.facing] != NULL) + framebox = ir_set_add_framebox(set, setdata->header.data_name); + if (framebox->framesheets[setdata->framesheet.frameinfo.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; break; case MSDAT: - framebox = ir_set_add_framebox(set, setdata->header.name); - if (framebox->mapsheets[setdata->mapsheet.frameinfo.facing] != NULL) + framebox = ir_set_add_framebox(set, setdata->header.data_name); + if (framebox->mapsheets[setdata->mapsheet.frameinfo.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; break; case ADAT: if (set->audio == NULL) - { set->audio = &setdata->audio; + { set->audio = (struct ir_simplex_t*) setdata; return; } simplex = set->audio; - while (simplex->header.nextsib != NULL;) + while (simplex->header.nextsib != NULL) if (bytes_identical(simplex->header.data_name, setdata->header.data_name)) { wprintf("Duplicate audio %s\n", setdata->header.data_name); *simplex = setdata->audio; + //setdata is now a pointer to redundant, unused memory. return; } else - simplex = simplex->header.nextsib; - simplex->header.nextsib = &setdata->audio; + simplex = (struct ir_simplex_t*) simplex->header.nextsib; + setdata->audio.header.nextsib = (union ir_setdata_t*) set->audio; + set->audio = (struct ir_simplex_t*) setdata; break; case LDAT: - if (set->links == NULL) - { set->links = &setdata->link; - return; - } - link = set->links; - while (link->header.nextsib != NULL) - link = link->header.nextsib; - link->header.nextsib = &setdata->link; + setdata->link.header.nextsib = (union ir_setdata_t*) set->links; + set->links = (struct ir_link_t*) setdata; break; default: fprintf(stderr, "Unknown setdata type %x\n", setdata->header.type); @@ -316,92 +395,197 @@ void ir_set_assign_data } void ir_set_assign_ref -( ir_set_t* set, - long long ref +( struct ir_set_t* set, + long long ref ) { if (set->ref != 0) - wprintf("Ref override: 0x%x -> 0x%x for set %s\n", - set->ref, ref, set->name); + wprintf("Ref override: 0x%lx -> 0x%lx for set %s\n", + (long unsigned) set->ref, (long unsigned) ref, set->name); set->ref = ref; //TODO: reflist_add(set); } void ir_data_assign_path ( union ir_setdata_t* setdata, - uint8_t* path + const uint8_t* path ) -{ if (set->header.src_filename) - wprintf("Path override: %s -> %s for set %s\n", - set->header.src_filename, path, set->name); - set->header.src_filename = path; - //TODO: internal strdup, not assign (= path;) +{ if (path == NULL) + eprintf("Null path in data %s\n", setdata->header.data_name); + if (setdata->header.src_filename != NULL) + wprintf("Path override: %s -> %s for setdata %s\n", + setdata->header.src_filename, path, setdata->header.data_name); + setdata->header.src_filename = name_alloc(path); } - -//TODO: Macro ir_framsheet and mapsheet? union ir_setdata_t* ir_framesheet -( uint8_t* name, - apc_facing d, - int width, - int height +( const uint8_t* name, + apc_facing d, + int width, + int height ) -{ struct ir_framedata_t* framesheet = struct_alloc(ir_framedata_t); - framesheet->header->type = FSDAT; - framesheet->header.data_name = name; - framesheet->frameinfo.facing = d; - framesheet->frameinfo.w = width; - framesheet->frameinfo.h = height; - return (union ir_setdata_t*) framesheet; -} +{ return ir_framedata(FSDAT, name, d, width, height); } union ir_setdata_t* ir_mapsheet -( uint8_t* name, - apc_facing d, - int width, - int height, +( const uint8_t* name, + apc_facing d, + int width, + int height +) +{ return ir_framedata(MSDAT, name, d, width, height); } + +static inline +union ir_setdata_t* ir_framedata +( enum dtype type, + const uint8_t* name, + apc_facing d, + int width, + int height ) -{ struct ir_framedata_t* mapsheet = struct_alloc(ir_framedata_t); - mapsheet->header.type = MSDAT; - mapsheet->header.data_name = name; - mapsheet->frameinfo.facing = d; - mapsheet->frameinfo.w = width; - mapsheet->frameinfo.h = height; - return (union ir_setdata_t*) mapsheet; +{ struct ir_framedata_t* framedata = struct_alloc(ir_framedata_t); + if (name == NULL) + 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; + return (union ir_setdata_t*) framedata; } union ir_setdata_t* ir_audio -( uint8_t* name ) +( const uint8_t* name ) { struct ir_simplex_t* audio = struct_alloc(ir_simplex_t); + if (name == NULL) + eprintf("Null audio\n"); audio->header.type = ADAT; - audio->header.data_name = name; + audio->header.data_name = name_alloc(name); return (union ir_setdata_t*) audio; } -#define PN_ALLOCSIZE (sys_pagesize) -#define PN_HEADERSIZE() (sizeof(struct pagenode_t*) + sizeof(void*)) -#define PN_MEMSIZE() (PN_ALLOCSIZE - PN_HEADERSIZE()) -#define PN_HEADSIZE() (pagenode_head->head - pagenode_head->root) -#define PN_HEADSPACE() (PN_MEMSIZE() - PN_HEADSIZE()) -struct pagenode_t { - struct pagenode_t* next; - char* head; - char root[]; -}* pagenode_root, * pagenode_head; +/* Create classld that points to a class */ +struct ir_classld_t* ir_classld_from_class +( struct ir_class_t* class ) +{ struct ir_classld_t* classld; + if (class == NULL) + eprintf("Null class in classld\n"); + classld = struct_alloc(ir_classld_t); + classld->root_class = class; + return classld; +} + +struct ir_setld_t* ir_setld_from_ref +( long long ref ) +{ struct ir_setld_t* setld; + setld = struct_alloc(ir_setld_t); + setld->ref = ref; + return setld; +} + +struct ir_setld_t* ir_setld_from_classld +( struct ir_classld_t* classld, + const uint8_t* name +) +{ struct ir_setld_t* setld; + setld = struct_alloc(ir_setld_t); + setld->namelist = struct_alloc(ir_namelist_t); + setld->namelist_head = setld->namelist; + setld->namelist_head->name = name_alloc(name); + setld->classld = classld; + return setld; +} + +struct ir_setld_t* ir_setld_addchild +( struct ir_setld_t* setld, + const uint8_t* name +) +{ if (setld->namelist == NULL) + { setld->namelist = struct_alloc(ir_namelist_t); + setld->namelist_head = setld->namelist; + } + else + { setld->namelist_head->nextsib = struct_alloc(ir_namelist_t); + setld->namelist_head = setld->namelist_head->nextsib; + } + setld->namelist_head->name = name_alloc(name); + return setld; +} + +union ir_setdata_t* ir_link +( enum ltype link_type, + struct ir_setld_t* setld, + const uint8_t* name +) +{ struct ir_link_t* link; + link = struct_alloc(ir_link_t); + link->header.type = LDAT; + link->type = link_type; + link->classld = setld->classld; + link->setld = setld; + if (link_type != OLINK && name != NULL) + link->header.data_name = name_alloc(name); + return (union ir_setdata_t*) link; +} static -void* stack_alloc(size_t bytes) -{ if (!bytes) - { wprint("Attempting to allocate 0 bytes in stack_alloc"); - return pagenode_head->head; +void* stack_alloc +( size_t bytes ) +{ if (!bytes) //valid behavior to attain current head + return datapages.head->header.head; + if (PL_HEADMEM(datapages) < bytes) + { datapages.head->header.next = (struct pagenode_t*) calloc(datapages.pagesize,1); + if (datapages.head->header.next == NULL) + eprintf("Memory allocation error \n"); + datapages.head = datapages.head->header.next; + datapages.head->header.head = datapages.head->root; } - if (PN_HEADSPACE() < bytes) - { pagenode_head->next = (struct pagenode_t*) calloc(PN_ALLOCSIZE); - pagenode_head = pagenode_head->next; - pagenode_head->head = pagenode_head->root; + datapages.head->header.head += bytes; + return (void*) datapages.head->header.head - bytes; +} + +static +uint8_t* name_alloc +( const uint8_t* name_src ) +{ const uint8_t* iter; + uint8_t* name; + int head_mem; + copy: + name = (uint8_t*)namepages.head->header.head; + iter = name_src; + for (head_mem = PL_HEADMEM(namepages); *iter && *iter != '_' && head_mem; head_mem--) + *(namepages.head->header.head)++ = *iter++; + if (head_mem == 0) //not enough room + { namepages.head->header.next = (struct pagenode_t*) calloc(namepages.pagesize,1); + if (namepages.head->header.next == NULL) + eprintf("Memory allocation error\n"); + namepages.head = namepages.head->header.next; + namepages.head->header.head = namepages.head->root; + goto copy; } - pagenode_head->head += bytes; - return (void*) pagenode_head->head - bytes; + *(namepages.head->header.head)++ = '\0'; + return name; } +static +uint8_t* classname_alloc +( const uint8_t* name_src ) +{ const uint8_t* iter; + uint8_t* name; + int head_mem; + copy: + name = (uint8_t*)namepages.head->header.head; + iter = name_src; + for (head_mem = PL_HEADMEM(namepages); *iter && head_mem; head_mem--) + *(namepages.head->header.head)++ = *iter++; + if (head_mem == 0) //not enough room + { namepages.head->header.next = (struct pagenode_t*) calloc(namepages.pagesize,1); + if (namepages.head->header.next == NULL) + eprintf("Memory allocation error\n"); + namepages.head = namepages.head->header.next; + namepages.head->header.head = namepages.head->root; + goto copy; + } + *(namepages.head->header.head)++ = '\0'; + return name; +}