/*!@file \brief IR Memory Implementation \details Intermediary memory management \author Jordan Lavatai \date Aug 2016 ----------------------------------------------------------------------------*/ /* Standard */ #include //exit, malloc #include //print #include //va_args #include //uint64_t #include //memset, str* /* Unicode */ #include //u8_* functions #include //uint8_t as a char #include //u32_cpy /* Local */ #include "apc.h" #include "ir.h" /* Public */ int ir_init(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; }; struct frameinfo_t { int facing, w, h; }; 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_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) static struct ir_class root_class = { .name = &"." }; /* Init */ int ir_init ( void ) { return 0; } /* 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 */ #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 ) { 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); } if (*iter.nextsib != NULL) { iter = *iter.nextsib; goto iterate; } return *iter.nextsib = class_alloc(name); } /* 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 */ #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 ) { 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); } if (*iter.nextsib != NULL) { iter = *iter.nextsib; goto iterate; } return *iter.nextsib = set_alloc(name); } struct ir_set_t* ir_set_addchild ( struct ir_set_t* set, uint8_t* name ) { } /* 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; }