X-Git-Url: https://www.kengrimes.com/gitweb/?p=henge%2Fapc.git;a=blobdiff_plain;f=src%2Fir.c;h=d6ad16f26b66eb02bcf1dacda2886c2b2bba286b;hp=49480ab2def18b7a91f252103dbb6d96b6df7650;hb=21f57201034a7b54ebb42703f2a8bef4b561acb4;hpb=0dc97f87cbbe47ef84501678f302404d042428b1 diff --git a/src/ir.c b/src/ir.c index 49480ab..d6ad16f 100644 --- a/src/ir.c +++ b/src/ir.c @@ -10,190 +10,777 @@ #include //va_args #include //uint64_t #include //memset, str* +#include /* Unicode */ #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" +#include "pagenode.h" +#undef do_error +#define do_error(...) exit(-1) +#define XXH_PRIVATE_API +#include "../xxHash/xxhash.h" /* Public */ int ir_init(void); +void ir_quit(void); +void ir_test(void); int ir_linker(void); int ir_condenser(void); -#if 0 -ir_class ir_class_findchild(ir_class, uint8_t*); -ir_set ir_class_rootset(ir_class); -ir_class ir_class_nextsib(ir_class); -ir_class ir_class_nextchild(ir_class); -uint8_t* ir_class_name(ir_class); -ir_set ir_class_findset(ir_class,uint8_t*); -ir_set ir_set_findchild(ir_set, uint8_t*); -ir_set ir_set_nextsib(ir_set); -ir_set ir_set_nextchild(ir_set); -ir_set ir_set_findref(long long); -uint8_t* ir_set_name(ir_set); -#endif -/* Private */ -static inline -uint8_t bytes_identical(uint8_t*,uint8_t*); - -/* Enumerated types */ -enum dtype { FSDAT, MSDAT, ADAT, LDAT }; -enum ltype { OLINK, MLINK, VLINK, ALINK }; /* Set data mem */ -struct sdat_header_t -{ enum dtype type; - uint8_t* src_file_name; - uint8_t* data_name; +enum dtype { FSDAT, MSDAT, ADAT, LDAT, FBDAT }; +struct ir_namelist_t; +struct ir_namelist_t +{ struct ir_namelist_t* nextsib; + uint8_t* name; }; -struct frameinfo_t -{ int facing, w, h; +struct ir_classld_t +{ struct ir_class_t* root_class; + struct ir_namelist_t* namelist, * namelist_head; }; -struct framedata_t -{ struct sdat_header_t header; - struct frameinfo_t frameinfo; -} **framedatas; -struct framebox_t -{ struct framedata_t framesheets[FACE_MAX]; - struct framedata_t mapsheets[FACE_MAX]; - uint8_t *data_name; -} **frameboxes; -struct simplex_t -{ struct sdat_header_t header; -} **simplexes; -struct link_t -{ struct sdat_header_t header; - struct set_t *src, *trg; - enum ltype type; -} **links; -union sdat_t -{ struct sdat_header_t header; - struct framedata_t framesheet; - struct framedata_t mapsheet; - struct simplex_t audio; - struct link_t link; +struct ir_setld_t +{ struct ir_classld_t* classld; + uint32_t ref; + struct ir_namelist_t* namelist, * namelist_head; }; -struct ir_class -{ struct class_t *parent, *nextchild, *nextsib; - struct set_t *root_set; - uint8_t *name; -} **classes; -struct ir_set -{ struct set_t *parent, *nextchild, *nextsib; - struct class_t *class; - uint8_t *name; - struct framebox_t **sprites; - struct framebox_t **maps; - 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) - +struct ir_setdata_header_t +{ enum dtype type; + uint8_t* src_filename, * data_name; + union ir_setdata_t* nextsib; + long filepos; +}; +struct ir_framedata_t +{ struct ir_setdata_header_t header; + 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]; +}; +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; + enum ltype type; +}; +union ir_setdata_t +{ struct ir_setdata_header_t header; + struct ir_framebox_t framebox; + struct ir_framedata_t framesheet; + struct ir_framedata_t mapsheet; + struct ir_simplex_t audio; + struct ir_link_t link; +}; +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; + uint32_t ref; + uint8_t* name; + struct ir_framebox_t* frameboxes; + struct ir_simplex_t* audio; + struct ir_link_t* links; + long filepos; +}; +/* Functions */ +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); +static inline +int bytes_identical(const uint8_t*,const uint8_t*); +static inline +int classnames_identical(const uint8_t*,const uint8_t*); +static +uint8_t* name_alloc(const uint8_t*); static -struct ir_class root_class = { .name = &"." }; +uint8_t* classname_alloc(const uint8_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 +struct pagelist_t datapages, namepages, refhashpages; +static +struct ir_class_t root_class = { .name = (uint8_t*)"." }; /* Init */ int ir_init ( void ) +{ pagelist_init(datapages, (size_t)SYS_PAGESIZE); + pagelist_init(namepages, (size_t)NAME_PAGESIZE); + pagelist_init(refhashpages, (size_t)SYS_PAGESIZE); + + return 0; +} + +/* Quit/Cleanup */ +void ir_quit +( void ) +{ pagenode_free(datapages.root); + pagenode_free(namepages.root); + pagenode_free(refhashpages.root); + +} + +/* Link */ +int ir_linker +( void ) +{ + return 0; +} + +/* Condense */ +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 ) { return &root_class; } /* Add a subclass to a class - Attempts to create a new subclass in the provided class, exiting with an - error if the class already exists + Attempts to create a new subclass in the provided class, returning + the class if it already exists */ -#define ERR_DUPECLASS "Subclass %s of class %s already exists!", name, *class.name struct ir_class_t* ir_class_addchild ( struct ir_class_t* class, - uint8_t* name + const uint8_t* name ) -{ struct ir_class_t* iter = *class.nextchild; - if (iter == NULL) - return *class.nextchild = class_alloc(name); - iterate: - if (bytes_identical(*iter.name, name)) - { fprintf(stderr, ERR_DUPECLASS); - exit(-1); +{ struct ir_class_t* iter; + if (class->nextchild == NULL) + { class->nextchild = struct_alloc(ir_class_t); + struct_clear(class->nextchild); + class->nextchild->name = classname_alloc(name); + return class->nextchild; } - if (*iter.nextsib != NULL) - { iter = *iter.nextsib; - goto iterate; + 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 (classnames_identical(iter->name, name)) + return iter; + if (iter->nextsib != NULL) + { iter = iter->nextsib; + goto check; } - return *iter.nextsib = class_alloc(name); - + iter->nextsib = struct_alloc(ir_class_t); + struct_clear(iter->nextsib); + iter->nextsib->name = classname_alloc(name); + return iter->nextsib; } -/* Return a pointer to the parent of the provided class */ -struct ir_class_t* ir_class_parent -( struct ir_class_t* class ) -{ return class.parent; } - /* Add a set to a class - Attempts to create a new root set in the specified class, exiting with an - error if the set already exists + Attempts to create a new root set in the specified class, returning + the set if it already exists */ -#define ERR_DUPESET "Root set %s of class %s already exists!", name, *class.name struct ir_set_t* ir_class_addset ( struct ir_class_t* class, - uint8_t* name + const uint8_t* name ) -{ struct ir_set_t* iter = *class.root_set; - if (iter == NULL) - return *class.root_set = set_alloc(name); - iterate: - if (bytes_identical(*iter.name, name)) - { fprintf(stderr, ERR_DUPSET); - exit(-1); +{ struct ir_set_t* iter; + if (class->root_set == NULL) + { class->root_set = struct_alloc(ir_set_t); + struct_clear(class->root_set); + class->root_set->name = name_alloc(name); + return class->root_set; } - if (*iter.nextsib != NULL) - { iter = *iter.nextsib; - goto iterate; + 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; + if (iter->nextsib != NULL) + { iter = iter->nextsib; + goto check; } - return *iter.nextsib = set_alloc(name); + iter->nextsib = struct_alloc(ir_set_t); + struct_clear(iter->nextsib); + iter->nextsib->name = name_alloc(name); + 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; + struct ir_set_t** iters; + struct pagenode_t* iterp; + iterp = refhashpages.root; + hash = REFHASH(ref); + do + iters = ((struct ir_set_t**) iterp->root) + hash; + while (*iters != NULL && (*iters)->ref != ref && (iterp = iterp->header.next) != NULL); + return *iters; } + +/* Add a set to a set + Attempts to create a new subset of the specified set, returning the + child if it already exists +*/ struct ir_set_t* ir_set_addchild +( struct ir_set_t* set, + const uint8_t* name +) +{ struct ir_set_t* iter; + if (set->nextchild == NULL) + { set->nextchild = struct_alloc(ir_set_t); + struct_clear(set->nextchild); + set->nextchild->name = name_alloc(name); + return set->nextchild; + } + iter = set->nextchild; + if (name == NULL) + eprintf("Null child added to set %s\n", iter->name); + if (iter->name == NULL) + eprintf("Null name pointer in set %p\n", iter); + check: + if (bytes_identical(iter->name, name)) + return iter; + if (iter->nextsib != NULL) + { iter = iter->nextsib; + goto check; + } + iter->nextsib = struct_alloc(ir_set_t); + struct_clear(iter->nextsib); + iter->nextsib->name = name_alloc(name); + return iter->nextsib; +} + +/* Add a framebox to a set + Attempts to create a new framebox of the specified set, returning + the framebox if it already exists + Name is not allocated, but assigned, unlike other "XXX_add" functions where + name is duplicated into IR's internal array. +*/ +static inline +struct ir_framebox_t* ir_set_add_framebox ( struct ir_set_t* set, uint8_t* name ) -{ } +{ struct ir_framebox_t* iter; + if (set->frameboxes == NULL) + { set->frameboxes = struct_alloc(ir_framebox_t); + struct_clear(set->frameboxes); + set->frameboxes->header.data_name = name; + return set->frameboxes; + } + iter = set->frameboxes; + check: + if (bytes_identical(iter->header.data_name, name)) + return iter; + if (iter->header.nextsib != NULL) + { iter = (struct ir_framebox_t*) iter->header.nextsib; + goto check; + } + iter->header.nextsib = (union ir_setdata_t*) struct_alloc(ir_framebox_t); + struct_clear(iter->header.nextsib); + iter->header.nextsib->header.data_name = name; + return (struct ir_framebox_t*) (iter->header.nextsib); +} /* Match two null-terminated bytestrings Return 1 if the two bytestrings are identical, else 0 */ static inline -uint8_t bytes_identical -( uint8_t* stra, - uint8_t* strb -) -{ while (*stra && *strb) - if (*stra++ != *strb++) - return 0; - return *stra == *strb; +int bytes_identical +( const uint8_t* stra, + const uint8_t* 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); +} + +/* 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, + union ir_setdata_t* setdata +) +{ struct ir_framebox_t* framebox; + struct ir_simplex_t* simplex; + 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) + 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.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 = (struct ir_simplex_t*) setdata; + return; + } + simplex = set->audio; + 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 = (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: + 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); + exit(-1); + } +} + +void ir_set_assign_ref +( struct ir_set_t* set, + uint32_t ref +) +{ uint16_t hash, oldhash; + struct ir_set_t** iters; + struct pagenode_t* iterp; + uint32_t oldref; + oldref = set->ref; + oldhash = 0; + hash = REFHASH(ref); + iterp = refhashpages.root; + check_depth: + iters = ((struct ir_set_t**) iterp->root) + hash; + if (*iters == NULL || *iters == set) + *iters = set; + else + { if (iterp->header.next == NULL) + pagelist_alloc(refhashpages); + iterp = iterp->header.next; + goto check_depth; + } + if (oldref != 0) + { wprintf("Ref override: 0x%x -> 0x%x for set %s\n", oldref, ref, set->name); + if (oldhash != 0) + *iters = NULL; + else + { oldhash = hash; + hash = REFHASH(oldref); + goto check_depth; + } + } + set->ref = ref; +} + +void ir_data_assign_path +( union ir_setdata_t* setdata, + const uint8_t* 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); +} + +union ir_setdata_t* ir_framesheet +( const uint8_t* name, + apc_facing d, + int width, + int height +) +{ return ir_framedata(FSDAT, name, d, width, height); } + +union ir_setdata_t* ir_mapsheet +( 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* framedata = struct_alloc(ir_framedata_t); + struct_clear(framedata); + 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 +( const uint8_t* name ) +{ struct ir_simplex_t* audio = struct_alloc(ir_simplex_t); + struct_clear(audio); + if (name == NULL) + eprintf("Null audio\n"); + audio->header.type = ADAT; + audio->header.data_name = name_alloc(name); + return (union ir_setdata_t*) audio; +} + + +/* 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); + struct_clear(classld); + classld->root_class = class; + return classld; +} + +struct ir_setld_t* ir_setld_from_ref +( uint32_t ref ) +{ struct ir_setld_t* setld; + setld = struct_alloc(ir_setld_t); + struct_clear(setld); + 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); + struct_clear(setld); + setld->namelist = struct_alloc(ir_namelist_t); + struct_clear(setld->namelist); + 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); + struct_clear(setld->namelist); + setld->namelist_head = setld->namelist; + } + else + { setld->namelist_head->nextsib = struct_alloc(ir_namelist_t); + struct_clear(setld->namelist_head->nextsib); + 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); + struct_clear(link); + 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; +} + +/* 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; +} + +/* 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 ) +{ 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 != '_' && *iter != '.' && head_mem; head_mem--) + *(namepages.head->header.head)++ = *iter++; + if (head_mem < 1) //not enough room + { pagelist_alloc(namepages); + goto copy; + } + *(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 < 1) //not enough room + { pagelist_alloc(namepages); + goto copy; + } + *(namepages.head->header.head)++ = '\0'; + return name; +} + +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); + if (root_class.root_set != NULL) + crawl_set(root_class.root_set, 0); + uprintf("starting binaryout \n"); + binout_init(&root_class); +} + + +static +void crawl_class +( struct ir_class_t* class ) +{ struct ir_class_t* iter; + 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); + } +} + +#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; + i = depth * 12; + while (i--) + putchar('.'); + i = depth; + + for(iter = set; iter != NULL; iter = iter->nextchild) + { uprintf("[%10U]", iter->name); + push_setp(iter); + i++; + } + + putchar('\n'); + while (--i >= depth) + if (((iter = pop_setp())->nextsib) != NULL) + crawl_set(iter->nextsib,i); }