X-Git-Url: https://www.kengrimes.com/gitweb/?p=henge%2Fapc.git;a=blobdiff_plain;f=src%2Fir.c;h=4ef2e5a9fa328be6fd935f8624dfc922a36239a3;hp=e88ac364c2243a7bbbaf8ef870749f5b6cabee5a;hb=32084db924eb07c8a5e44748aaf12883189b37d2;hpb=5f13e2b92707358f5a9a297afdfcbb7851fdc736 diff --git a/src/ir.c b/src/ir.c index e88ac36..4ef2e5a 100644 --- a/src/ir.c +++ b/src/ir.c @@ -10,6 +10,7 @@ #include //va_args #include //uint64_t #include //memset, str* +#include /* Unicode */ #include //u8_* functions #include //uint8_t as a char @@ -19,6 +20,7 @@ #include "print.h" #include "apc.h" #include "ir.h" +#include "pagenode.h" #undef do_error #define do_error(...) exit(-1) #define XXH_PRIVATE_API @@ -29,25 +31,6 @@ void ir_quit(void); void ir_test(void); int ir_linker(void); int ir_condenser(void); -/* 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 SYS_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; @@ -61,16 +44,15 @@ struct ir_classld_t }; struct ir_setld_t { struct ir_classld_t* classld; - long long ref; + uint32_t ref; struct ir_namelist_t* namelist, * namelist_head; }; struct ir_setdata_header_t { enum dtype type; uint8_t* src_filename, * data_name; union ir_setdata_t* nextsib; + long filepos; }; -struct ir_frameinfo_t -{ int facing, w, h; }; struct ir_framedata_t { struct ir_setdata_header_t header; struct ir_frameinfo_t frameinfo; @@ -99,6 +81,7 @@ struct ir_class_t { struct ir_class_t* nextchild, * nextsib; struct ir_set_t* root_set; uint8_t* name; + long filepos; }; struct ir_set_t { struct ir_set_t* nextchild, * nextsib; @@ -107,6 +90,7 @@ struct ir_set_t struct ir_framebox_t* frameboxes; struct ir_simplex_t* audio; struct ir_link_t* links; + long filepos; }; /* Functions */ static inline @@ -118,37 +102,12 @@ int bytes_identical(const uint8_t*,const uint8_t*); static inline int classnames_identical(const uint8_t*,const uint8_t*); static -void* stack_alloc(size_t); -#define struct_alloc(_T) ((struct _T*) stack_alloc(sizeof(struct _T))) -#define struct_clear(_S) (memset((_S), 0, sizeof(*(_S)))) -static uint8_t* name_alloc(const uint8_t*); static uint8_t* classname_alloc(const uint8_t*); -static inline -void* pagelist_pop(struct pagelist_t*,size_t); -#define $($)#$ -#define pagelist_alloc(pagelist) do { \ - pagelist.head->header.next = (struct pagenode_t*) malloc(pagelist.pagesize); \ - if (pagelist.head->header.next == NULL) \ - eprintf("Memory allocation error\n"); \ - struct_clear(pagelist.head->header.next); \ - pagelist.head = pagelist.head->header.next; \ - pagelist.head->header.head = pagelist.head->root; \ - } while (0) -#define pagelist_init(pagelist,size) do { \ - pagelist.pagesize = size; \ - pagelist.root = (struct pagenode_t*) malloc(size); \ - if (pagelist.root == NULL) \ - eprintf("Memory allocation error\n"); \ - struct_clear(pagelist.root); \ - pagelist.head = pagelist.root; \ - pagelist.head->header.head = pagelist.head->root; \ - } while (0) -static -void pagenode_free(struct pagenode_t*); +#define struct_clear(_S) (memset((_S), 0, sizeof(*(_S)))) #define REFHASH(ref) (XXH32(&ref, sizeof(uint32_t), 0xCEED) & 0xCFF) - +#define struct_alloc(_T) ((struct _T*) stack_alloc(&datapages, sizeof(struct _T))) extern //apc.c long sys_pagesize; static @@ -162,6 +121,7 @@ int ir_init { pagelist_init(datapages, (size_t)SYS_PAGESIZE); pagelist_init(namepages, (size_t)NAME_PAGESIZE); pagelist_init(refhashpages, (size_t)SYS_PAGESIZE); + return 0; } @@ -171,15 +131,7 @@ void ir_quit { pagenode_free(datapages.root); pagenode_free(namepages.root); pagenode_free(refhashpages.root); -} -/* Recursively clean pagenode linked list, freeing last first */ -static -void pagenode_free -( struct pagenode_t* pagenode ) -{ if (pagenode->header.next != NULL) - pagenode_free(pagenode->header.next); - free(pagenode); } /* Link */ @@ -270,6 +222,11 @@ struct ir_set_t* ir_class_addset return iter->nextsib; } +/* Get the root set of the class */ +struct ir_set_t* ir_class_rootset +( struct ir_class_t* class ) +{ return class->root_set; } + struct ir_set_t* ir_set_from_ref ( uint32_t ref ) { uint16_t hash; @@ -378,6 +335,55 @@ int classnames_identical return (ca == cb); } +/* Return the name of the set */ +uint8_t* ir_set_name +( struct ir_set_t* set) +{ return set->name; } + +/* Return the next sib of the class */ +struct ir_class_t* ir_class_nextsib +( struct ir_class_t* class ) +{ return class->nextsib; } + +/* Return the next sib of the class */ +struct ir_class_t* ir_class_nextchild +( struct ir_class_t* class ) +{ return class->nextchild; } + +/* Get the file position of the class */ +long ir_class_fpos +( struct ir_class_t* class ) +{ return class->filepos; } + +/* Set the file position of the class */ +void ir_class_assign_fpos +( struct ir_class_t* class, + long newpos +) +{ class->filepos = newpos; } + +/* Get the next sibling of the provided set */ +struct ir_set_t* ir_set_nextsib +( struct ir_set_t* set ) +{ return set->nextsib; } + +/* Get the next child of the provided set */ +struct ir_set_t* ir_set_nextchild +( struct ir_set_t* set ) +{ return set->nextchild; } + +/* Get the file position of the class */ +long ir_set_fpos +( struct ir_set_t* set ) +{ return set->filepos; } + +/* Set the file position of the class */ +void ir_set_assign_fpos +( struct ir_set_t* set, + long newpos +) +{ set->filepos = newpos; } + /* Assign Setdata to Set */ void ir_set_assign_data ( struct ir_set_t* set, @@ -594,35 +600,171 @@ union ir_setdata_t* ir_link return (union ir_setdata_t*) link; } -static inline -void* pagelist_pop -( struct pagelist_t* pagelist, - size_t size -) -{ size_t headsize = PL_HEADSIZE((*pagelist)); - if (!headsize) - { free(pagelist->head); - pagelist->head = pagelist->root; - while (pagelist->head->header.next != NULL) - pagelist->head = pagelist->head->header.next; +/* Return a set's root framebox */ +union ir_setdata_t* ir_set_framebox +( struct ir_set_t* set ) +{ return (union ir_setdata_t*) set->frameboxes; } + +/* Return a set's root audio data */ +union ir_setdata_t* ir_set_audio +( struct ir_set_t* set ) +{ return (union ir_setdata_t*) set->audio; } + +/* Return a set's root link data */ +union ir_setdata_t* ir_set_link +( struct ir_set_t* set ) +{ return (union ir_setdata_t*) set->links; } + +/* Return the link type */ +enum ltype ir_linkdata_type +( union ir_setdata_t* linkdata ) +{ if (linkdata->header.type != LDAT) + eprintf("Data %s is not a link\n", linkdata->header.data_name); + return linkdata->link.type; +} + +/* Return the link type */ +uint32_t ir_linkdata_ref +( union ir_setdata_t* linkdata ) +{ if (linkdata->header.type != LDAT) + eprintf("Data %s is not a link\n", linkdata->header.data_name); + return linkdata->link.setld->ref; +} + +/* Resolve and return the link's target set + Fails on error, cannot return NULL +*/ +struct ir_set_t* ir_linkdata_set +( union ir_setdata_t* linkdata ) +{ struct ir_class_t* class_iter; + struct ir_namelist_t* namelist_iter,* namelist_iter_last; + struct ir_setld_t* setld; + struct ir_classld_t* classld; + struct ir_set_t* set; + set = NULL; + class_iter = NULL; + if (linkdata->header.type != LDAT) + eprintf("Data %s is not a link\n", linkdata->header.data_name); + setld = linkdata->link.setld; + if (linkdata->link.setld == NULL) + eprintf("Link data is invalid\n"); + classld = linkdata->link.classld; + if (classld != NULL) + { namelist_iter = classld->namelist; + if (classld->root_class == NULL) + eprintf("No root class for classld\n"); + class_iter = classld->root_class->nextchild; + namelist_iter_last = NULL; + while (class_iter != NULL) + { if (classnames_identical(class_iter->name, namelist_iter->name)) + { if (namelist_iter == classld->namelist_head) + break; + class_iter = class_iter->nextchild; + namelist_iter_last = namelist_iter; + namelist_iter = namelist_iter->nextsib; + } + else + class_iter = class_iter->nextsib; + } + if (class_iter == NULL) + { if (namelist_iter_last) + eprintf("No such subclass \"%s\" of class \"%s\"\n", + namelist_iter->name, + namelist_iter_last->name); + else + eprintf("No such class \"%s\"\n", namelist_iter->name); + } + set = class_iter->root_set; } - if (headsize < size) - eprintf("Attempted to pop unaligned value from pagelist\n"); - pagelist->head->header.head -= size; - return pagelist->head->header.head; + else + set = ir_set_from_ref(setld->ref); + if (set == NULL) + eprintf("Initial set resolution failed\n"); + namelist_iter = setld->namelist; + namelist_iter_last = NULL; + if (setld->namelist != NULL) + { while (set != NULL) + { if (bytes_identical(set->name, namelist_iter->name)) + { if (namelist_iter == setld->namelist_head) + break; + set = set->nextchild; + namelist_iter_last = namelist_iter; + namelist_iter = namelist_iter->nextsib; + } + else + set = set->nextsib; + } + if (set == NULL) + { if (namelist_iter_last) + eprintf("No such subset \"%s\" of set \"%s\"\n", + namelist_iter->name, + namelist_iter_last->name); + else + eprintf("No such set \"%s\" in class \"%s\"\n", + namelist_iter->name, + class_iter->name); + } + } + return set; } -static -void* stack_alloc -( size_t bytes ) -{ void* p; - if (PL_HEADMEM(datapages) < bytes) - pagelist_alloc(datapages); - p = datapages.head->header.head; - datapages.head->header.head += bytes; - return p; +/* Get a setdata's next sibling */ +union ir_setdata_t* ir_setdata_nextsib +( union ir_setdata_t* setdata ) +{ return setdata->header.nextsib; } + +/* Get a setdata's name */ +uint8_t* ir_setdata_name +( union ir_setdata_t* setdata ) +{ return setdata->header.data_name; } + +/* Get a setdata's filename */ +uint8_t* ir_setdata_filename +( union ir_setdata_t* setdata ) +{ return setdata->header.src_filename; } + +/* Get a setdata's file position */ +long ir_setdata_fpos +( union ir_setdata_t* setdata ) +{ return setdata->header.filepos; } + +/* Set a setdata's file position */ +void ir_setdata_assign_fpos +( union ir_setdata_t* setdata, + long newpos +) +{ setdata->header.filepos = newpos; } + +/* 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); + return (union ir_setdata_t*) &fbox->framebox.framesheets[facing]; } +/* Return a framebox's specified mapsheet */ +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); + return (union ir_setdata_t*) &fbox->framebox.mapsheets[facing]; +} + +/* Return a framedata's frame info */ +struct ir_frameinfo_t* ir_framedata_frameinfo +( 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; +} + + +/** Allocators **/ static uint8_t* name_alloc ( const uint8_t* name_src ) @@ -632,7 +774,7 @@ uint8_t* name_alloc copy: name = (uint8_t*)namepages.head->header.head; iter = name_src; - for (head_mem = PL_HEADMEM(namepages); *iter && *iter != '_' && head_mem; head_mem--) + for (head_mem = PL_HEADMEM(namepages); *iter && *iter != '_' && *iter != '.' && head_mem; head_mem--) *(namepages.head->header.head)++ = *iter++; if (head_mem < 1) //not enough room { pagelist_alloc(namepages); @@ -661,56 +803,61 @@ uint8_t* classname_alloc return name; } -static void crawl_class(struct ir_class_t*,int); +static void crawl_class(struct ir_class_t*); static void crawl_set(struct ir_set_t*,int); + +extern +int binout_init(ir_class); void ir_test(void) { uprintf("IR From Directory: %s\n",getcwd(NULL,255)); - crawl_class(&root_class,0); + crawl_class(&root_class); + if (root_class.root_set != NULL) + crawl_set(root_class.root_set, 0); + uprintf("starting binaryout \n"); + binout_init(&root_class); } -#define pspace(num) for (i = 0; i < (num); i++) putchar(' ') + static void crawl_class -( struct ir_class_t* class, - int depth -) +( struct ir_class_t* class ) { struct ir_class_t* iter; - /*if(chdir((char*)class->name)) - eprintf("CHDIR %U\n",class->name); - else - wprintf("chdir %U\n",class->name);*/ - if (class->nextchild != NULL) - { iter = class->nextchild; - do { - crawl_class(iter,depth + 1); - /*if (chdir("..")) - eprintf("CHDIR ..\n");*/ - } while ((iter = iter->nextsib) != NULL); + for (iter = class->nextchild; iter != NULL; iter = iter->nextsib) + { wprintf("Crawling class %U/\n", iter->name); + if(chdir((char*)iter->name)) + eprintf("CHDIR %U from %s\n",iter->name,getcwd(NULL,255)); + crawl_class(iter); + if (iter->root_set != NULL) + crawl_set(iter->root_set, 0); + uprintf("%U\\\n",iter->name); + if (chdir("..")) + eprintf("CHDIR ..\n"); + wprintf("Finished crawling class %U/\n", iter->name); } - wprintf("%U/\n", class->name); - if (class->root_set != NULL) - crawl_set(class->root_set,0); - uprintf("\n%U\\\n",class->name); } +#define push_setp(setp) (*(struct ir_set_t**)stack_alloc(&datapages, sizeof(struct ir_set_t*)) = setp) +#define pop_setp() (*(struct ir_set_t**)pagelist_pop(&datapages, sizeof(struct ir_set_t*))) static void crawl_set ( struct ir_set_t* set, int depth ) { struct ir_set_t* iter; - int i = depth * 10; - pspace(i); - i = 0; - for(iter = set->nextchild; iter != NULL; iter = iter->nextchild) - { uprintf("[%8U]", iter->name); - } - for(iter = set->nextchild; iter != NULL; iter = iter->nextchild) - { if (iter->nextsib != NULL) - crawl_set(iter->nextsib, i); + int i; + i = depth * 12; + while (i--) + putchar('.'); + i = depth; + + for(iter = set; iter != NULL; iter = iter->nextchild) + { uprintf("[%10U]", iter->name); + push_setp(iter); i++; } - for(iter = set->nextchild; iter != NULL; iter = iter->nextchild) - crawl_set(iter, depth + 1); + putchar('\n'); + while (--i >= depth) + if (((iter = pop_setp())->nextsib) != NULL) + crawl_set(iter->nextsib,i); }