X-Git-Url: https://www.kengrimes.com/gitweb/?p=henge%2Fapc.git;a=blobdiff_plain;f=src%2Fir.c;h=4ef2e5a9fa328be6fd935f8624dfc922a36239a3;hp=432581393f98eba20912c39ed53d791b334420f2;hb=32084db924eb07c8a5e44748aaf12883189b37d2;hpb=55eb5697b20b577ecb4a3c6355c1ee4695f016cd diff --git a/src/ir.c b/src/ir.c index 4325813..4ef2e5a 100644 --- a/src/ir.c +++ b/src/ir.c @@ -4,915 +4,860 @@ \author Jordan Lavatai \date Aug 2016 ----------------------------------------------------------------------------*/ -#include -#include -#include //uint8_t as a char -#include //u32_cpy +/* Standard */ +#include //exit, malloc +#include //print +#include //va_args #include //uint64_t -#include //memset -#include //u8_* functions +#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" - - -extern -int -name_u8_cpy(struct name*, struct name*); - -extern -int -name_u8_cmp(struct name*, struct name*); - -extern -int -name_u8_set(struct name*, ucs4_t); - -int -ir_init(void); -struct cdat* -alloc_cdat(void); -struct odat* -alloc_odat(void); -void -alloc_vdat(void); -struct link* -alloc_link(void); -struct ref* -alloc_ref(void); -struct set* -alloc_set(void); -struct cdat* -curr_cdat(void); -struct odat* -curr_odat(void); -struct vdat* -curr_vdat(void); -struct map* -curr_map(void); -struct set* -curr_cdat_set(void); -struct set* -curr_set(void); -struct ref* -curr_ref(void); -struct model* -curr_model(void); - -/* ir.c */ -void -inc_posts(void); -void -push_cdat(struct name*); -void -pop_cdat(void); -void -insert_refid(int); -void -insert_link_name(struct name*); -void -insert_link_namelist(struct name*); -void -insert_ss_name(struct name*); -void -insert_ss_namelist(struct name*); -void -insert_mlink(struct name*, int); -void -insert_vlink(struct name*, int); -void -insert_ref(struct odat*, int); -void -alloc_vdat(void); -void -insert_vdat(void); -void -insert_map(struct name*, int, int, int, int, uint8_t*); -void -insert_framesheet(struct name*, int, int, int, int, uint8_t*); - - - -//type safety handled by macro expansion (do not call these directly from code, make dependent macros for access to these) -#define CHUNKS_LEN(STACK) ((STACK).csp - (STACK).chunks) -#define CURRENT_CHUNK(STACK) ((STACK).chunks[CHUNKS_LEN(STACK) - 1]) -#define CHUNKS_FULL(STACK) ( (STACK).csp >= \ - (STACK).chunks + MAX_CHUNKS * (STACK).chunk_size) -#define CURRENT_DSP(STACK,TYPE) ((TYPE*) ((STACK).dsp[CHUNKS_LEN(STACK) - 1])) -#define DATA_FULL(STACK,TYPE) ((void*) CURRENT_DSP(STACK,TYPE) >= \ - (CURRENT_CHUNK(STACK) + (STACK).chunk_size)) -#define CSP_PUSH(STACK) (*(++(STACK).csp) = malloc((STACK).chunk_size)) -#define CURRENT_DATP(STACK,TYPE) (((TYPE**)(STACK).dsp)[CHUNKS_LEN(STACK) - 1]) -#define PREVIOUS_DATP(STACK,TYPE) (((TYPE**)(STACK).dsp)[CHUNKS_LEN(STACK) - 2]) -#define ALLOC_DAT(STACK,TYPE) (++CURRENT_DATP(STACK,TYPE)) -#define INIT_STACK(STACK,TYPE) \ - { int i; \ - (STACK).chunk_size = PAGES_PER_CHUNK * pagesize; \ - (STACK).max_dats = (STACK).chunk_size / sizeof (TYPE); \ - CSP_PUSH(STACK); \ - for( i = 0; i < MAX_CHUNKS; i++){ \ - (STACK).dsp[i] += pagesize; \ - } \ - } -//Stack-specific macros (called directly from code (safety enforcement) -#define INIT_ODAT() (INIT_STACK(ocs, struct odat)) -#define CURRENT_ODAT() (CURRENT_DATP(ocs,struct odat)) -#define ODAT_FULL() (DATA_FULL(ocs,struct odat)) -#define ODAT_ALLOC() (ALLOC_DAT(ocs,struct odat)) -#define OCS_FULL() (CHUNKS_FULL(ocs)) -#define INIT_VDAT() (INIT_STACK(vcs, struct vdat)) -#define CURRENT_VDAT() (CURRENT_DATP(vcs,struct vdat)) -#define VDAT_FULL() (DATA_FULL(vcs,struct vdat)) -#define VDAT_ALLOC() (ALLOC_DAT(vcs,struct vdat)) -#define VCS_FULL() (CHUNKS_FULL(vcs)) -#define INIT_CDAT() (INIT_STACK(ccs, struct cdat)) -#define CURRENT_CDAT() (CURRENT_DATP(ccs,struct cdat)) -#define CDAT_FULL() (DATA_FULL(ccs, struct cdat)) -#define CDAT_ALLOC() (ALLOC_DAT(ccs, struct cdat)) -#define CCS_FULL() (CHUNKS_FULL(ccs)) -#define INIT_SET() (INIT_STACK(scs, struct set)) -#define CURRENT_SET() (CURRENT_DATP(scs, struct set)) -#define SET_FULL() (DATA_FULL(scs, struct set)) -#define SET_ALLOC() (ALLOC_DAT(scs, struct set)) -#define SCS_FULL() (CHUNKS_FULL(scs)) -#define INIT_LINK() (INIT_STACK(lcs, struct link)) -#define CURRENT_LINK() (CURRENT_DATP(lcs,struct link)) -#define LDAT_FULL() (DATA_FULL(lcs, struct link)) -#define LDAT_ALLOC() (ALLOC_DAT(lcs, struct link)) -#define LCS_FULL() (CHUNKS_FULL(lcs)) -#define INIT_POST() (INIT_STACK(rcs, struct ref)) -#define CURRENT_POST() (CURRENT_DATP(pcs,struct ref)) -#define POST_FULL() (DATA_FULL(pcs,struct ref)) -#define POST_ALLOC() (ALLOC_DAT(pcs,struct ref)) -#define PCS_FULL() (CHUNKS_FULL(pcs)) -#define INIT_REF() (INIT_STACK(rcs, struct ref)) -#define CURRENT_REF() (CURRENT_DATP(rcs,struct ref)) -#define PREVIOUS_REF() (PREVIOUS_DATP(rcs, struct ref)) -#define REF_FULL() (DATA_FULL(rcs,struct ref)) -#define REF_ALLOC() (ALLOC_DAT(rcs,struct ref)) -#define RCS_FULL() (CHUNKS_FULL(rcs)) -//Metadata -#define CURRENT_MODEL() (CURRENT_VDAT()->model_list[CURRENT_VDAT()->num_models]) - - - - -/* Cdats: A cdat is a class data structure. Cdats serve as the central */ -/* data types of the IR. Cdats contain pointers to their subclasses so that the relationship between */ -/* classes can be determined, but the subclasses are not represented inside */ -/* of the cdat itself but rather in subsequent cdats in cdat_buf. We */ -/* can determine the number of subclasses (the last index into cdat_buf */ -/* that represents a subclass of some arbitrary cdat) each cdat has by */ -/* incrementing num_classes during parse time. */ -/* TODO: Should classes point to their parent class? */ -/* TODO: Talk more about cdat set structure */ - -struct cdat { - struct name name; - int idx; - int num_classes; - int num_sets; - struct cdat* class_list[MAX_CLASSES]; - struct set* set_list[MAX_SETS]; +#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); +/* 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 set { - int cdat_idx; - int num_sets; - struct set* set_list[MAX_SETS]; -}; - -struct ref { - struct ref* nextref; - struct ref* lastref; - struct odat* odatp; - int refid; //0xFFFFFF->digit -}; - -struct olink { - int src_refid; -}; - -struct vlink { - int src_refid; - struct name src_animname; - struct name src_namelist[MAX_DEPTH]; -}; - -struct mlink { - int src_refid; - struct name src_mapname; - struct name src_namelist[MAX_DEPTH]; - +struct ir_classld_t +{ struct ir_class_t* root_class; + struct ir_namelist_t* namelist, * namelist_head; }; - -union link_t { - struct vlink vlink; - struct mlink mlink; - struct olink olink; +struct ir_setld_t +{ struct ir_classld_t* classld; + uint32_t ref; + struct ir_namelist_t* namelist, * namelist_head; }; - - -/* Links are a mechanism for designers to indicate in the grammar that a odat, vdat, or map - is defined elsewhere and that the link should be replaced with the specified odat/vdat/map */ -struct link { - int type; //1 = olink, 2 = vlink, 3 = mlink - union link_t link_t; - int dest_refid; //if it exists - struct odat* dest_odatp; - +struct ir_setdata_header_t +{ enum dtype type; + uint8_t* src_filename, * data_name; + union ir_setdata_t* nextsib; + long filepos; }; - -struct map { - struct name name; - int height; - int width; - uint8_t filepath[FPATH_MAX]; +struct ir_framedata_t +{ struct ir_setdata_header_t header; + struct ir_frameinfo_t frameinfo; }; - -/* Odats: Odats consist of the object data necessary for - each object. Odats are sometimes referred to as archetypes - at compile-time, in order to distinguish the difference from - a runtime object and a compile-time object. - TODO: Need more info about objects at runtime, to described - the reasoning behind odat structure at compile-time*/ -struct odat { - struct name name; - int refid; - int ismap; - int vdat_idx; - struct link* linkp; - struct vdat* vdatp; - struct odat* parent_odatp; /* null if parent is a cdat */ - struct ref* refp; /* pointer to it's ref on ref_list */ - struct map map; /* only valid if odat ismap */ - +struct ir_framebox_t +{ struct ir_setdata_header_t header; + struct ir_framedata_t framesheets[FACING_MAX]; + struct ir_framedata_t mapsheets[FACING_MAX]; }; - -/* A framesheet is a grouping of animation frames in a single direction (N,W,S,E, etc.). Framesheets - also hold the framesheet dimensions and the filepath to the png of the framesheet so the file can be opened - and the png data can be extracted. */ -struct framesheet { - int width; - int height; - uint8_t filepath[FPATH_MAX]; - int num_frames; - +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; }; - -/* A model is a collection of framesheets for every - direction (N,W,S,E,NW,NE,SW,SE). Currently, users can only define - framesheets in the APC grammar, which are inserted into the current model*/ -struct model { - struct name name; - struct framesheet spritesheet[8]; //one for each +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; }; - -/* Vdat: Vdats are the video data of each object. Vdats have a list of models for every - animation that the vdats odat can do for that vdat. */ -struct vdat { - struct odat* creator; //pointer to odat that made this vdat - int num_models; - struct model model_list[MAX_MODELS]; +struct ir_class_t +{ struct ir_class_t* nextchild, * nextsib; + struct ir_set_t* root_set; + uint8_t* name; + long filepos; }; - -/* An entry on the set_stack that describes the namelist and relevant information for - the current set that is being processed in the parser. For each set name, - there is a corresponding set/odat that is created when set names are encountered. */ - -struct set_frame -{ struct name namelist[MAX_DEPTH]; - int num_names; - struct set* setp; - struct odat* odatp; -} ; - -/* Stores the last defined set at every depth */ -struct set_stack -{ struct set_frame set_frames[MAX_DEPTH]; - int curr_depth; //used to get most recently created set/odat + to check for undefined parents of namelists +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 +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; +} -//"type free" chunk stacking -struct chunk_stack -{ void* chunks[MAX_CHUNKS]; - void* *csp; //chunk stack pointer - void* dsp[MAX_CHUNKS]; //dat stack pointer (per chunk) - int chunk_size; //size of a chunk (including its forfeited page) - int max_dats; //number of dats per chunk for this stack -} ocs, vcs, ccs, rcs, lcs, pcs, scs; //odat, vdat, cdat, ref, link, post stacks - -/* The cdat_stack is a stack pointers to cdat pointers, the top of which is - the cdat that is currently being parsed. Whenever a new cdat is recognized - by the grammar (CLOPEN), a cdat is pushed onto the cdat_stack, and we refer - to this cdat through the macro CURR_CDAT. By keeping a cdat_stack, we have - access to the current cdat so that the elements and sets can populate themselves - in the cdat accordingly. */ - -struct cdat* cdat_stack[MAX_CLASSES]; -struct cdat** cdat_stackp; - - - -struct set_stack ss; -struct name set_namelist[MAX_DEPTH]; -int set_numnames = 0; - -struct name link_namelist[MAX_DEPTH]; -int link_numnames = 0; - -int num_cdats = 0; -int num_odats = 0; -int num_vdats = 0; -int num_sets = 0; -int num_refs = 0; -int ss_refid = 0x0FFFFFFF; /* system space for refids */ -int num_posts = 0; -int num_links = 0; -int num_models = 0; -long pagesize = 0; - - -/* The initalization function of the IR. */ -int -ir_init() -{ struct name name; - - - uint8_t root[4] = "root"; - - u8_stpncpy(name.name, root, 4); - - pagesize = sysconf(_SC_PAGESIZE); - - INIT_CDAT(); - *cdat_stackp = CURRENT_CDAT(); - name_u8_cpy(&(*cdat_stackp)->name, &name); - - INIT_ODAT(); - INIT_VDAT(); - VDAT_ALLOC(); //NULL vdat - VDAT_ALLOC(); //First vdat req. because alloc_vdat happens after vdat is reduced - INIT_SET(); - INIT_LINK(); - INIT_REF(); - INIT_POST(); +/* 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; - } -void -ir_quit() -{ - int i; - - for(i = 0; i < CHUNKS_LEN(ccs) ; i++) - { - free(ccs.chunks[i]); - } - for(i = 0; i < CHUNKS_LEN(ocs); i++) - { - free(ocs.chunks[i]); +/* 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, returning + the class if it already exists +*/ +struct ir_class_t* ir_class_addchild +( struct ir_class_t* class, + const uint8_t* name +) +{ 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; } - for(i = 0; i < CHUNKS_LEN(vcs) ; i++) - { - free(vcs.chunks[i]); + 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; } - for(i = 0; i < CHUNKS_LEN(rcs); i++) - { - free(rcs.chunks[i]); - } - for(i = 0; i < CHUNKS_LEN(lcs); i++) - { - free(lcs.chunks[i]); - } - for(i = 0; i < CHUNKS_LEN(pcs); i++) - { - free(pcs.chunks[i]); - } - + iter->nextsib = struct_alloc(ir_class_t); + struct_clear(iter->nextsib); + iter->nextsib->name = classname_alloc(name); + return iter->nextsib; } -struct cdat* -alloc_cdat() -{ - num_cdats++; - if(CDAT_FULL()) - { if(CCS_FULL()) - { fprintf(stderr, "You have allocated to many (%d) cdats ", num_cdats); - exit(EXIT_FAILURE); - } - else - CSP_PUSH(ccs); +/* Add a set to a class + Attempts to create a new root set in the specified class, returning + the set if it already exists +*/ +struct ir_set_t* ir_class_addset +( struct ir_class_t* class, + const uint8_t* name +) +{ 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; } - else - CDAT_ALLOC(); - - return CURRENT_CDAT(); -} - -//these should probably be inline -struct odat* -alloc_odat -() -{ - num_odats++; - if(ODAT_FULL()) - { if(!OCS_FULL()) - { fprintf(stderr, "You have allocated to many (%d) odats ", num_odats); - exit(EXIT_FAILURE); - } - else - CSP_PUSH(ocs); + 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; } - else - ODAT_ALLOC(); + iter->nextsib = struct_alloc(ir_set_t); + struct_clear(iter->nextsib); + iter->nextsib->name = name_alloc(name); + return iter->nextsib; +} - return CURRENT_ODAT(); +/* 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; } -void -alloc_vdat -() -{ num_vdats++; - if(VDAT_FULL()) - { if(!VCS_FULL()) - { fprintf(stderr, "You have allocated to many (%d) vdats ", num_vdats); - exit(EXIT_FAILURE); - } - else - CSP_PUSH(vcs); - } - else - VDAT_ALLOC(); - +/* 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; } -struct set* -alloc_set -() -{ num_sets++; - if(SET_FULL()) - { if(!SCS_FULL()) - { fprintf(stderr, "You have allocated to many (%d) sets ", num_sets); - exit(EXIT_FAILURE); - } - else - CSP_PUSH(scs); +/* 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; } - else - SET_ALLOC(); + 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); +} - return CURRENT_SET(); +/* Match two null-terminated bytestrings + Return 1 if the two bytestrings are identical, else 0 +*/ +static inline +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); +} -struct link* -alloc_link -() -{ num_links++; - if(LDAT_FULL()) - { if(!LCS_FULL()) - { fprintf(stderr, "You have allocated to many (%d) links ", num_links); - exit(EXIT_FAILURE); - } - else - CSP_PUSH(lcs); +/* 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); } - else - LDAT_ALLOC(); - - return CURRENT_LINK(); - } -struct ref* -alloc_ref -() -{ num_refs++; - if(REF_FULL()) - { if(!RCS_FULL()) - { fprintf(stderr, "You have allocated to many (%d) refs ", num_refs); - exit(EXIT_FAILURE); - } - else - CSP_PUSH(rcs); - } +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 - REF_ALLOC(); - - - if(num_refs % 16 == 0) - { CURRENT_POST() = CURRENT_REF(); - inc_posts(); + { if (iterp->header.next == NULL) + pagelist_alloc(refhashpages); + iterp = iterp->header.next; + goto check_depth; } - - return CURRENT_REF(); -} - -void -inc_posts() -{ num_posts++; - if(POST_FULL()) - { if(!PCS_FULL()) - { fprintf(stderr, "You have allocated to many (%d) refs ", num_posts); - exit(EXIT_FAILURE); - } + if (oldref != 0) + { wprintf("Ref override: 0x%x -> 0x%x for set %s\n", oldref, ref, set->name); + if (oldhash != 0) + *iters = NULL; else - CSP_PUSH(pcs); + { oldhash = hash; + hash = REFHASH(oldref); + goto check_depth; + } } - else - POST_ALLOC(); - + set->ref = ref; } -struct cdat* -curr_cdat -() -{ - return (*cdat_stackp); +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); } -struct odat* -curr_odat -() -{ - return CURRENT_ODAT(); -} - -struct vdat* -curr_vdat -() -{ - return CURRENT_VDAT(); -} -struct set* -curr_cdat_set -() -{ - return CURRENT_SET(); +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; } -struct ref* -curr_ref -() -{ - return CURRENT_REF(); +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; } -struct ref* -prev_ref -() -{ - return PREVIOUS_REF(); -} -struct model* -curr_model -() -{ - return &CURRENT_MODEL(); -} - -/* IR.C*/ -void -push_cdat -( struct name* name ) -{ - struct cdat* curr_cdatp; - - curr_cdatp = alloc_cdat(); - name_u8_cpy(&curr_cdatp->name, name); - curr_cdatp->idx = num_cdats; - /* Set the cdat as a subclass of the previous cdat */ - (*cdat_stackp)->class_list[(*cdat_stackp)->num_classes++] = curr_cdatp; - /* Push the cdat onto the cdat_stack */ - *++cdat_stackp = curr_cdatp; +/* 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; } -void -pop_cdat -() -{ - cdat_stackp--; +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; +} -void -insert_set_name -( struct name* name ) -{ - //Push name onto current namelist, set the set_namelist. - name_u8_cpy(&set_namelist[set_numnames++], name); - +/* 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; +} -/* Called at the last name of a sets namelist. Inserts the set namelist - onto the set_stack at the appropriate depth i.e. the number of names in - the namelist. If each name in the namelist at every depth matches, nothing happens. For every - name on the namelist that doesnt match what is currently on the set_stack, - a new set/odat is created at the depth that it describes. E.g. a set name - of A_B_C is a depth of 3 and is represented in the set_stack as A, A_B and A_B_C. - If a new set namelist is defined, X_Y, the new set_stack will become X, X_Y. */ - -void -insert_set_namelist -( struct name* name ) -{ int depth, nameidx, i; - - insert_set_name(name); - - - for( depth = 0; depth < set_numnames ; depth++ ) - { for (nameidx = 0; nameidx <= depth; nameidx++) - { if( name_u8_cmp(&set_namelist[nameidx], &ss.set_frames[depth].namelist[nameidx]) != 0 ) - { /* Populate the namelist of the set at the current depth */ - for(i = 0; i <= depth; i++) - name_u8_cpy(&ss.set_frames[depth].namelist[i], &set_namelist[i]); - - /* Alloc set and odat */ - ss.set_frames[depth].odatp = alloc_odat(); - ss.set_frames[depth].setp = alloc_set(); - - /* populate set/odat name and cdat_idx */ - name_u8_cpy(&ss.set_frames[depth].odatp->name, &set_namelist[depth]); - ss.set_frames[depth].setp->cdat_idx = ( *cdat_stackp)->idx; - - /* Insert allocated set and odat into their respective trees if there is a depth - (they have parents) */ - if(depth) - { ss.set_frames[depth].odatp->parent_odatp = ss.set_frames[depth-1].odatp; - if(ss.set_frames[depth-1].setp->num_sets < MAX_SETS) - ss.set_frames[depth-1].setp->set_list[ss.set_frames[depth-1].setp->num_sets++] = ss.set_frames[depth].setp; - else - { printf("you have allocated too many sets in insert_namelist()\n"); - //TODO: EXIT() - } - } - else /* no parent set, so assign to cdat set_list */ - { ss.set_frames[depth].odatp->parent_odatp = NULL; //no parent odat = NULL. - if(curr_cdat_set()->num_sets < MAX_SETS) - curr_cdat_set()->set_list[curr_cdat_set()->num_sets++] = ss.set_frames[depth].setp; - else - { printf("you have allocated too many sets in insert_namelist()\n"); - //TODO: EXIT() - } - } - - - ss.set_frames[depth].num_names = set_numnames; - ss.curr_depth = depth; - - /* Every set has a vdat, but some won't be populated because the namelist that instantiated */ - /* the set might not have a SS statement that populates the models of the vdat. This is ok */ - /* because 1) IR is supposed to be bloated so that binary out isnt 2) this functionality */ - /* preserves the assumptions that insert_framesheet() makes when it calls curr_vdat() */ - alloc_vdat(); +/* 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; } - - /* Set to 0 to reset for next set_namelist */ - set_numnames = 0; -} - - -/* We create new odats for each map variant that are children of the current odat/set - set their name as the map name, and identify them by marking them as a map. This lets - us distinguish between sibling odats that have the same name because the map of the parent - odat had the same name as another, regular odat. */ -#define CURR_SS_FRAME() (ss.set_frames[ss.curr_depth]) -#define CURR_SS_SETP() (CURR_SS_FRAME().setp) -#define CURR_SS_ODATP() (CURR_SS_FRAME().odatp) -void -insert_map -( struct name* name, int direction, int height, int width, int refid, uint8_t* filepath ) -{ int i; - struct odat* curr_map_odatp; //pointer to odat in odat_buf - struct set* curr_map_setp; //pointer to set in set_buf - struct link* linkp; - - curr_map_odatp = alloc_odat(); - curr_map_setp = alloc_set(); - /* Create a new odat, make its parent be the set. Make a set for mdat, its name should */ - /* be the name of the odat + name of model. That makes a conflict beween odats that are named */ - /* the same thing as the model of a sibling odat that was created from a map. They can have */ - /* same name if the map odat is marked. So mark the map odat. */ - - /* insert parent odat */ - curr_map_odatp->parent_odatp = CURR_SS_ODATP(); - - /* insert into set_list */ - if(CURR_SS_SETP()->num_sets < MAX_SETS) - CURR_SS_SETP()->set_list[CURR_SS_SETP()->num_sets++] = curr_map_setp; else - { printf("You have allocated to many sets, error in insert_map()\n"); - //TODO: EXIT() - } - - /* indicate that newly created odat is a map */ - curr_map_odatp->ismap = 1; - /* set odat and set name */ - name_u8_cpy(&curr_map_odatp->name, name); - - /* set cdat idx values for both set and odat */ - curr_map_setp->cdat_idx = num_cdats; - - /* Insert map information into the odats map */ - curr_map_odatp->map.height = height; - curr_map_odatp->map.width = width; - u8_stpncpy(curr_map_odatp->map.filepath, filepath, FPATH_MAX); - - - /* Generate refid if needed, put into ref_buf */ - if(!refid) - refid = ss_refid++; - - insert_ref(curr_map_odatp, refid); - - /* If current odatp on stack has a link, then we need to make our own link. just set the vdat_idx */ - if(CURR_SS_ODATP()->vdat_idx == 0) - { linkp = alloc_link(); - linkp->type = CURR_SS_ODATP()->linkp->type; - linkp->dest_odatp = CURR_SS_ODATP(); - linkp->dest_refid = refid; - linkp->link_t.mlink.src_refid = CURR_SS_ODATP()->linkp->link_t.mlink.src_refid; - - /* Copy the animation name of the vlink*/ - name_u8_cpy(&linkp->link_t.vlink.src_animname, &CURR_SS_ODATP()->linkp->link_t.vlink.src_animname); - /* Copy the namelist of the vlink*/ - for(i = 0; i < MAX_DEPTH; i++) - name_u8_cpy(&linkp->link_t.vlink.src_namelist[i], &CURR_SS_ODATP()->linkp->link_t.vlink.src_namelist[i]); + 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); + } } - else - curr_map_odatp->vdat_idx = CURR_SS_ODATP()->vdat_idx; - + return set; } - - -/* 11/22 Each vdat has a multiple models. Each model has 8 framesheets, one in each - direction, that create a spritesheet. Inserting framesheets into the correct - model is just a matter of checking whether or not the last models name matches - the current one. We can never get a framesheet that is for the same model before - AND after some other model, due to alphasorting of the files in each directory */ -void -insert_framesheet -( struct name* model_name, int direction, int height, int width, int refid, uint8_t* filepath ) -{ struct vdat* curr_vdatp; - struct model* curr_modelp; - static struct name last_model_name[32]; - - curr_vdatp = curr_vdat(); - - /* If the model name changed, that means there are no more - framesheets for that model to be processed, a guaruntee we make - b/c the filenames are alphabetically sorted */ - if(!name_u8_cmp(last_model_name, model_name)) - { if(curr_vdatp->num_models) - curr_vdatp->num_models++; - num_models++; // total number of models - } - - - if(CURR_SS_ODATP()->refid == 0) - { if(!refid) - refid = ss_refid++; - insert_ref(CURR_SS_ODATP(), refid); /* given a odatp and a refid, insert the odatp into the ref_buf. */ - } - else - printf("error: redefining a previously set refid\n"); - - curr_modelp = curr_model(); - - name_u8_cpy(&curr_modelp->name, model_name); - curr_modelp->spritesheet[direction].height = height; - curr_modelp->spritesheet[direction].width = width; - u8_stpncpy(curr_modelp->spritesheet[direction].filepath, filepath, FPATH_MAX); - name_u8_cpy(last_model_name, model_name); - +/* 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]; } - -void -insert_mlink -( struct name* src_mapname, int src_refid) -{ struct link* linkp; - int i; - - linkp = alloc_link(); - - /* set type */ - linkp->type = 3; - /* set the name of the src map for the link, if a name exists */ - if(src_mapname) - name_u8_cpy(&linkp->link_t.mlink.src_mapname, src_mapname); - /* Set the source ref id of the link */ - linkp->link_t.mlink.src_refid = src_refid; - - /* Copy the entire namelist of the link, if it exists */ - for(i = 0; i < link_numnames; i--) - { name_u8_cpy(&linkp->link_t.mlink.src_namelist[i], &link_namelist[i]); - name_u8_set(&link_namelist[i], (ucs4_t) 0); - } - link_numnames = 0; - - linkp->dest_odatp = CURR_SS_ODATP();//current odat on set_stack - +/* 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]; } - -void -insert_link_name -( struct name* name ) -{ - //Push name onto current namelist, set the set_namelist. - name_u8_cpy(&link_namelist[link_numnames++], name); - +/* 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; } -/* Nearly identical to mlink */ -void -insert_vlink -( struct name* src_animname, int src_refid ) -{ struct link* linkp; - int i; - - linkp = alloc_link(); - - /* set type */ - linkp->type = 2; - - /* set the name of the src animname for the link, if a name exists */ - if(src_animname) - name_u8_cpy(&linkp->link_t.vlink.src_animname, src_animname); - - /* Set the source ref id of the link */ - linkp->link_t.mlink.src_refid = src_refid; - - /* Copy the entire namelist of the link, if it exists */ - for(i = 0; i < link_numnames; i++) - { name_u8_cpy(&linkp->link_t.vlink.src_namelist[i], &link_namelist[i]); - name_u8_set(&link_namelist[i], (ucs4_t) 0);//set to null for next link_namelist +/** 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; } - link_numnames = 0; - - linkp->dest_odatp = CURR_SS_ODATP();//current odat on set_stack - + *(namepages.head->header.head)++ = '\0'; + return name; } - -/* TODO: Do we really need to store the prev/next pointer? iterating through the - ref_buf could be achieved by iterating until the num_refs anyway. */ -void -insert_ref -( struct odat* odatp, int refid ) -{ struct ref* curr_refp; - struct ref* prev_refp; - - curr_refp = alloc_ref(); - prev_refp = prev_ref(); - - prev_refp->nextref = curr_refp; - curr_refp->lastref = prev_refp; - - curr_refp->odatp = odatp; - curr_refp->refid = refid; - - if(refid % 16) - { POST_ALLOC(); - CURRENT_POST()->refid = refid; - CURRENT_POST()->odatp = odatp; +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); -void -insert_refid -( int refid ) -{ CURR_SS_ODATP()->refid = refid; +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); } -void -insert_vdat -() -{ struct vdat* curr_vdatp; +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++; + } - curr_vdatp = curr_vdat(); - - curr_vdatp->creator = CURR_SS_ODATP(); - CURR_SS_ODATP()->vdat_idx = num_vdats; - CURR_SS_ODATP()->vdatp = curr_vdatp; - alloc_vdat(); + putchar('\n'); + while (--i >= depth) + if (((iter = pop_setp())->nextsib) != NULL) + crawl_set(iter->nextsib,i); }