wip
[henge/apc.git] / src / ir.c
1 /*!@file
2 \brief IR Memory Implementation
3 \details Intermediary memory management
4 \author Jordan Lavatai
5 \date Aug 2016
6 ----------------------------------------------------------------------------*/
7 /* Standard */
8 #include <stdlib.h> //exit, malloc
9 #include <stdio.h> //print
10 #include <stdarg.h> //va_args
11 #include <stdint.h> //uint64_t
12 #include <string.h> //memset, str*
13 /* Unicode */
14 #include <unistd.h> //u8_* functions
15 #include <unitypes.h> //uint8_t as a char
16 #include <unistr.h> //u32_cpy
17 /* Local */
18 #include "apc.h"
19 #include "ir.h"
20 /* Public */
21 int ir_init(void);
22 int ir_linker(void);
23 int ir_condenser(void);
24 #if 0
25 ir_class ir_class_findchild(ir_class, uint8_t*);
26 ir_set ir_class_rootset(ir_class);
27 ir_class ir_class_nextsib(ir_class);
28 ir_class ir_class_nextchild(ir_class);
29 uint8_t* ir_class_name(ir_class);
30 ir_set ir_class_findset(ir_class,uint8_t*);
31 ir_set ir_set_findchild(ir_set, uint8_t*);
32 ir_set ir_set_nextsib(ir_set);
33 ir_set ir_set_nextchild(ir_set);
34 ir_set ir_set_findref(long long);
35 uint8_t* ir_set_name(ir_set);
36 #endif
37 /* Private */
38 static inline
39 uint8_t bytes_identical(uint8_t*,uint8_t*);
40
41 /* Enumerated types */
42 enum dtype { FSDAT, MSDAT, ADAT, LDAT };
43 enum ltype { OLINK, MLINK, VLINK, ALINK };
44 /* Set data mem */
45 struct sdat_header_t
46 { enum dtype type;
47 uint8_t* src_file_name;
48 uint8_t* data_name;
49 };
50 struct frameinfo_t
51 { int facing, w, h;
52 };
53 struct framedata_t
54 { struct sdat_header_t header;
55 struct frameinfo_t frameinfo;
56 } **framedatas;
57 struct framebox_t
58 { struct framedata_t framesheets[FACE_MAX];
59 struct framedata_t mapsheets[FACE_MAX];
60 uint8_t *data_name;
61 } **frameboxes;
62 struct simplex_t
63 { struct sdat_header_t header;
64 } **simplexes;
65 struct link_t
66 { struct sdat_header_t header;
67 struct set_t *src, *trg;
68 enum ltype type;
69 } **links;
70 union sdat_t
71 { struct sdat_header_t header;
72 struct framedata_t framesheet;
73 struct framedata_t mapsheet;
74 struct simplex_t audio;
75 struct link_t link;
76 };
77 struct ir_class
78 { struct class_t *parent, *nextchild, *nextsib;
79 struct set_t *root_set;
80 uint8_t *name;
81 } **classes;
82 struct ir_set
83 { struct set_t *parent, *nextchild, *nextsib;
84 struct class_t *class;
85 uint8_t *name;
86 struct framebox_t **sprites;
87 struct framebox_t **maps;
88 struct simplex_t **audio;
89 struct link_t **links;
90 } **sets;
91 /* Function-Like Macros */
92 #define do_warn() do { \
93 } while (0)
94 #define wprint(str) do { \
95 fprintf(stderr, str); \
96 do_warn(); \
97 } while (0)
98 #define wprintf(fmt,...) do { \
99 fprintf(stderr, fmt, __VA_ARGS__); \
100 do_warn(); \
101 } while (0)
102 #define do_error() do { \
103 exit(-1); \
104 } while (0)
105 #define eprint(str) do { \
106 fprintf(stderr, str); \
107 do_error(); \
108 } while (0)
109 #define eprintf(fmt,...) do { \
110 fprintf(stderr, fmt, __VA_ARGS__); \
111 do_error(); \
112 } while (0)
113
114 static
115 struct ir_class root_class = { .name = &"." };
116
117 /* Init */
118 int ir_init
119 ( void )
120 { return 0; }
121
122 /* Return a pointer to the root class */
123 struct ir_class_t* ir_class_root
124 ( void )
125 { return &root_class; }
126
127 /* Add a subclass to a class
128 Attempts to create a new subclass in the provided class, exiting with an
129 error if the class already exists
130 */
131 #define ERR_DUPECLASS "Subclass %s of class %s already exists!", name, *class.name
132 struct ir_class_t* ir_class_addchild
133 ( struct ir_class_t* class,
134 uint8_t* name
135 )
136 { struct ir_class_t* iter = *class.nextchild;
137 if (iter == NULL)
138 return *class.nextchild = class_alloc(name);
139 iterate:
140 if (bytes_identical(*iter.name, name))
141 { fprintf(stderr, ERR_DUPECLASS);
142 exit(-1);
143 }
144 if (*iter.nextsib != NULL)
145 { iter = *iter.nextsib;
146 goto iterate;
147 }
148 return *iter.nextsib = class_alloc(name);
149
150 }
151
152 /* Return a pointer to the parent of the provided class */
153 struct ir_class_t* ir_class_parent
154 ( struct ir_class_t* class )
155 { return class.parent; }
156
157 /* Add a set to a class
158 Attempts to create a new root set in the specified class, exiting with an
159 error if the set already exists
160 */
161 #define ERR_DUPESET "Root set %s of class %s already exists!", name, *class.name
162 struct ir_set_t* ir_class_addset
163 ( struct ir_class_t* class,
164 uint8_t* name
165 )
166 { struct ir_set_t* iter = *class.root_set;
167 if (iter == NULL)
168 return *class.root_set = set_alloc(name);
169 iterate:
170 if (bytes_identical(*iter.name, name))
171 { fprintf(stderr, ERR_DUPSET);
172 exit(-1);
173 }
174 if (*iter.nextsib != NULL)
175 { iter = *iter.nextsib;
176 goto iterate;
177 }
178 return *iter.nextsib = set_alloc(name);
179 }
180
181 struct ir_set_t* ir_set_addchild
182 ( struct ir_set_t* set,
183 uint8_t* name
184 )
185 { }
186
187 /* Match two null-terminated bytestrings
188 Return 1 if the two bytestrings are identical, else 0
189 */
190 static inline
191 uint8_t bytes_identical
192 ( uint8_t* stra,
193 uint8_t* strb
194 )
195 { while (*stra && *strb)
196 if (*stra++ != *strb++)
197 return 0;
198 return *stra == *strb;
199 }