2 \brief IR Memory Implementation
3 \details Intermediary memory management
6 ----------------------------------------------------------------------------*/
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*
15 #include <unistd.h> //u8_* functions
16 #include <unitypes.h> //uint8_t as a char
17 #include <unistr.h> //u32_cpy
18 #include <unistdio.h> //ulc_fprintf
20 #define eprintf_callback(...) exit(EXIT_FAILURE)
25 #define XXH_PRIVATE_API
26 #include "../xxHash/xxhash.h"
32 int ir_condenser(void);
34 enum dtype
{ FSDAT
, MSDAT
, ADAT
, LDAT
, FBDAT
};
37 { struct ir_namelist_t
* nextsib
;
41 { struct ir_class_t
* root_class
;
42 struct ir_namelist_t
* namelist
, * namelist_head
;
45 { struct ir_classld_t
* classld
;
47 struct ir_namelist_t
* namelist
, * namelist_head
;
49 struct ir_setdata_header_t
51 uint8_t* src_filename
, * data_name
;
52 union ir_setdata_t
* nextsib
;
56 { struct ir_setdata_header_t header
;
57 struct ir_frameinfo_t frameinfo
;
60 { struct ir_setdata_header_t header
;
61 struct ir_framedata_t framesheets
[FACING_MAX
];
62 struct ir_framedata_t mapsheets
[FACING_MAX
];
64 struct ir_simplex_t
{ struct ir_setdata_header_t header
; };
66 { struct ir_setdata_header_t header
;
67 struct ir_setld_t
* setld
;
68 struct ir_set_t
* trg_set
;
73 { struct ir_setdata_header_t header
;
74 struct ir_framebox_t framebox
;
75 struct ir_framedata_t framesheet
;
76 struct ir_framedata_t mapsheet
;
77 struct ir_simplex_t audio
;
78 struct ir_link_t link
;
81 { struct ir_class_t
* nextchild
, * nextsib
;
82 struct ir_set_t
* root_set
;
87 { struct ir_set_t
* nextchild
, * nextsib
;
90 struct ir_framebox_t
* frameboxes
;
91 struct ir_simplex_t
* audio
;
92 struct ir_link_t
* links
;
97 struct ir_framebox_t
* ir_set_add_framebox(struct ir_set_t
*,uint8_t*);
99 union ir_setdata_t
* ir_framedata (enum dtype
,const uint8_t*,apc_facing
,int,int);
101 void ir_linkdata_resolve_set(union ir_setdata_t
*);
103 int bytes_identical(const uint8_t*,const uint8_t*);
105 int classnames_identical(const uint8_t*,const uint8_t*);
107 uint8_t* name_alloc(const uint8_t*);
109 uint8_t* classname_alloc(const uint8_t*);
110 #define struct_clear(_S) (memset((_S), 0, sizeof(*(_S))))
111 #define REFHASH(ref) (XXH32(&ref, sizeof(uint32_t), 0xCEED) & 0xCFF)
112 #define struct_alloc(_T) ((struct _T*) stack_alloc(&datapages, sizeof(struct _T)))
116 char* apc_package_name
;
118 struct pagelist_t datapages
, namepages
, refhashpages
;
120 struct ir_class_t root_class
;
125 { pagelist_init(datapages
, (size_t)SYS_PAGESIZE
);
126 pagelist_init(namepages
, (size_t)NAME_PAGESIZE
);
127 pagelist_init(refhashpages
, (size_t)SYS_PAGESIZE
);
128 root_class
.name
= (uint8_t*) apc_package_name
;
135 { pagenode_free(datapages
.root
);
136 pagenode_free(namepages
.root
);
137 pagenode_free(refhashpages
.root
);
153 /* Return the class's name string */
154 uint8_t* ir_class_name
155 ( struct ir_class_t
* class )
156 { return class->name
; }
158 /* Return a pointer to the root class */
159 struct ir_class_t
* ir_class_root
161 { return &root_class
; }
163 /* Add a subclass to a class
164 Attempts to create a new subclass in the provided class, returning
165 the class if it already exists
167 struct ir_class_t
* ir_class_addchild
168 ( struct ir_class_t
* class,
171 { struct ir_class_t
* iter
;
172 if (class->nextchild
== NULL
)
173 { class->nextchild
= struct_alloc(ir_class_t
);
174 struct_clear(class->nextchild
);
175 class->nextchild
->name
= classname_alloc(name
);
176 return class->nextchild
;
178 iter
= class->nextchild
;
179 if (iter
->name
== NULL
)
180 eprintf("Null name pointer in class %p\n", iter
);
182 eprintf("Null child added to class %s\n", iter
->name
);
184 if (classnames_identical(iter
->name
, name
))
186 if (iter
->nextsib
!= NULL
)
187 { iter
= iter
->nextsib
;
190 iter
->nextsib
= struct_alloc(ir_class_t
);
191 struct_clear(iter
->nextsib
);
192 iter
->nextsib
->name
= classname_alloc(name
);
193 return iter
->nextsib
;
196 /* Add a set to a class
197 Attempts to create a new root set in the specified class, returning
198 the set if it already exists
200 struct ir_set_t
* ir_class_addset
201 ( struct ir_class_t
* class,
204 { struct ir_set_t
* iter
;
205 if (class->root_set
== NULL
)
206 { class->root_set
= struct_alloc(ir_set_t
);
207 struct_clear(class->root_set
);
208 class->root_set
->name
= name_alloc(name
);
209 return class->root_set
;
211 iter
= class->root_set
;
212 if (iter
->name
== NULL
)
213 eprintf("Null name pointer in class %p\n", iter
);
215 eprintf("Null set added to class %U\n", iter
->name
);
217 if (bytes_identical(iter
->name
, name
))
219 if (iter
->nextsib
!= NULL
)
220 { iter
= iter
->nextsib
;
223 iter
->nextsib
= struct_alloc(ir_set_t
);
224 struct_clear(iter
->nextsib
);
225 iter
->nextsib
->name
= name_alloc(name
);
226 return iter
->nextsib
;
229 /* Get the root set of the class */
230 struct ir_set_t
* ir_class_rootset
231 ( struct ir_class_t
* class )
232 { return class->root_set
; }
234 struct ir_set_t
* ir_set_from_ref
237 struct ir_set_t
** iters
;
238 struct pagenode_t
* iterp
;
239 iterp
= refhashpages
.root
;
242 iters
= ((struct ir_set_t
**) iterp
->root
) + hash
;
243 while (*iters
!= NULL
&& (*iters
)->ref
!= ref
&& (iterp
= iterp
->header
.next
) != NULL
);
248 /* Add a set to a set
249 Attempts to create a new subset of the specified set, returning the
250 child if it already exists
252 struct ir_set_t
* ir_set_addchild
253 ( struct ir_set_t
* set
,
256 { struct ir_set_t
* iter
;
257 if (set
->nextchild
== NULL
)
258 { set
->nextchild
= struct_alloc(ir_set_t
);
259 struct_clear(set
->nextchild
);
260 set
->nextchild
->name
= name_alloc(name
);
261 return set
->nextchild
;
263 iter
= set
->nextchild
;
265 eprintf("Null child added to set %s\n", iter
->name
);
266 if (iter
->name
== NULL
)
267 eprintf("Null name pointer in set %p\n", iter
);
269 if (bytes_identical(iter
->name
, name
))
271 if (iter
->nextsib
!= NULL
)
272 { iter
= iter
->nextsib
;
275 iter
->nextsib
= struct_alloc(ir_set_t
);
276 struct_clear(iter
->nextsib
);
277 iter
->nextsib
->name
= name_alloc(name
);
278 return iter
->nextsib
;
281 /* Add a framebox to a set
282 Attempts to create a new framebox of the specified set, returning
283 the framebox if it already exists
284 Name is not allocated, but assigned, unlike other "XXX_add" functions where
285 name is duplicated into IR's internal array.
288 struct ir_framebox_t
* ir_set_add_framebox
289 ( struct ir_set_t
* set
,
292 { struct ir_framebox_t
* iter
;
293 if (set
->frameboxes
== NULL
)
294 { set
->frameboxes
= struct_alloc(ir_framebox_t
);
295 struct_clear(set
->frameboxes
);
296 set
->frameboxes
->header
.data_name
= name
;
297 return set
->frameboxes
;
299 iter
= set
->frameboxes
;
301 if (bytes_identical(iter
->header
.data_name
, name
))
303 if (iter
->header
.nextsib
!= NULL
)
304 { iter
= (struct ir_framebox_t
*) iter
->header
.nextsib
;
307 iter
->header
.nextsib
= (union ir_setdata_t
*) struct_alloc(ir_framebox_t
);
308 struct_clear(iter
->header
.nextsib
);
309 iter
->header
.nextsib
->header
.data_name
= name
;
310 return (struct ir_framebox_t
*) (iter
->header
.nextsib
);
313 /* Match two null-terminated bytestrings
314 Return 1 if the two bytestrings are identical, else 0
318 ( const uint8_t* stra
,
325 } while (ca
&& ca
!= '_' && ca
== cb
);
330 int classnames_identical
331 ( const uint8_t* stra
,
338 } while (ca
&& ca
== cb
);
342 /* Return the name of the set */
344 ( struct ir_set_t
* set
)
345 { return set
->name
; }
347 /* Return the next sib of the class */
348 struct ir_class_t
* ir_class_nextsib
349 ( struct ir_class_t
* class )
350 { return class->nextsib
; }
352 /* Return the next sib of the class */
353 struct ir_class_t
* ir_class_nextchild
354 ( struct ir_class_t
* class )
355 { return class->nextchild
; }
357 /* Get the file position of the class */
359 ( struct ir_class_t
* class )
360 { return class->filepos
; }
362 /* Set the file position of the class */
363 void ir_class_assign_fpos
364 ( struct ir_class_t
* class,
367 { class->filepos
= newpos
; }
369 /* Get the next sibling of the provided set */
370 struct ir_set_t
* ir_set_nextsib
371 ( struct ir_set_t
* set
)
372 { return set
->nextsib
; }
374 /* Get the next child of the provided set */
375 struct ir_set_t
* ir_set_nextchild
376 ( struct ir_set_t
* set
)
377 { return set
->nextchild
; }
379 /* Get the file position of the class */
381 ( struct ir_set_t
* set
)
382 { return set
->filepos
; }
384 /* Set the file position of the class */
385 void ir_set_assign_fpos
386 ( struct ir_set_t
* set
,
389 { set
->filepos
= newpos
; }
391 /* Assign Setdata to Set */
392 void ir_set_assign_data
393 ( struct ir_set_t
* set
,
394 union ir_setdata_t
* setdata
396 { struct ir_framebox_t
* framebox
;
397 struct ir_simplex_t
* simplex
;
398 switch (setdata
->header
.type
)
400 framebox
= ir_set_add_framebox(set
, setdata
->header
.data_name
);
401 if (framebox
->framesheets
[setdata
->framesheet
.frameinfo
.facing
].header
.data_name
!= NULL
)
402 wprintf("Duplicate framesheet [%i] %s\n",
403 setdata
->framesheet
.frameinfo
.facing
, setdata
->header
.data_name
);
404 framebox
->framesheets
[setdata
->framesheet
.frameinfo
.facing
] = setdata
->framesheet
;
407 framebox
= ir_set_add_framebox(set
, setdata
->header
.data_name
);
408 if (framebox
->mapsheets
[setdata
->mapsheet
.frameinfo
.facing
].header
.data_name
!= NULL
)
409 wprintf("Duplicate mapsheet [%i] %s\n",
410 setdata
->mapsheet
.frameinfo
.facing
, setdata
->header
.data_name
);
411 framebox
->mapsheets
[setdata
->mapsheet
.frameinfo
.facing
] = setdata
->mapsheet
;
414 if (set
->audio
== NULL
)
415 { set
->audio
= (struct ir_simplex_t
*) setdata
;
418 simplex
= set
->audio
;
419 while (simplex
->header
.nextsib
!= NULL
)
420 if (bytes_identical(simplex
->header
.data_name
, setdata
->header
.data_name
))
421 { wprintf("Duplicate audio %s\n", setdata
->header
.data_name
);
422 *simplex
= setdata
->audio
;
423 //setdata is now a pointer to redundant, unused memory.
427 simplex
= (struct ir_simplex_t
*) simplex
->header
.nextsib
;
428 setdata
->audio
.header
.nextsib
= (union ir_setdata_t
*) set
->audio
;
429 set
->audio
= (struct ir_simplex_t
*) setdata
;
432 setdata
->link
.header
.nextsib
= (union ir_setdata_t
*) set
->links
;
433 set
->links
= (struct ir_link_t
*) setdata
;
436 fprintf(stderr
, "Unknown setdata type %x\n", setdata
->header
.type
);
441 void ir_set_assign_ref
442 ( struct ir_set_t
* set
,
445 { uint16_t hash
, oldhash
;
446 struct ir_set_t
** iters
;
447 struct pagenode_t
* iterp
;
452 iterp
= refhashpages
.root
;
454 iters
= ((struct ir_set_t
**) iterp
->root
) + hash
;
455 if (*iters
== NULL
|| *iters
== set
)
458 { if (iterp
->header
.next
== NULL
)
459 pagelist_alloc(refhashpages
);
460 iterp
= iterp
->header
.next
;
464 { wprintf("Ref override: 0x%x -> 0x%x for set %s\n", oldref
, ref
, set
->name
);
469 hash
= REFHASH(oldref
);
476 void ir_data_assign_path
477 ( union ir_setdata_t
* setdata
,
481 eprintf("Null path in data %s\n", setdata
->header
.data_name
);
482 if (setdata
->header
.src_filename
!= NULL
)
483 wprintf("Path override: %s -> %s for setdata %s\n",
484 setdata
->header
.src_filename
, path
, setdata
->header
.data_name
);
485 setdata
->header
.src_filename
= name_alloc(path
);
488 union ir_setdata_t
* ir_framesheet
489 ( const uint8_t* name
,
494 { return ir_framedata(FSDAT
, name
, d
, width
, height
); }
496 union ir_setdata_t
* ir_mapsheet
497 ( const uint8_t* name
,
502 { return ir_framedata(MSDAT
, name
, d
, width
, height
); }
505 union ir_setdata_t
* ir_framedata
512 { struct ir_framedata_t
* framedata
= struct_alloc(ir_framedata_t
);
513 struct_clear(framedata
);
515 eprintf("Null name in set allocation\n");
516 framedata
->header
.type
= type
;
517 framedata
->header
.data_name
= name_alloc(name
);
518 framedata
->frameinfo
.facing
= d
;
519 framedata
->frameinfo
.w
= width
;
520 framedata
->frameinfo
.h
= height
;
521 return (union ir_setdata_t
*) framedata
;
524 union ir_setdata_t
* ir_audio
525 ( const uint8_t* name
)
526 { struct ir_simplex_t
* audio
= struct_alloc(ir_simplex_t
);
529 eprintf("Null audio\n");
530 audio
->header
.type
= ADAT
;
531 audio
->header
.data_name
= name_alloc(name
);
532 return (union ir_setdata_t
*) audio
;
536 /* Create classld that points to a class */
537 struct ir_classld_t
* ir_classld_from_class
538 ( struct ir_class_t
* class )
539 { struct ir_classld_t
* classld
;
541 eprintf("Null class in classld\n");
542 classld
= struct_alloc(ir_classld_t
);
543 struct_clear(classld
);
544 classld
->root_class
= class;
548 struct ir_setld_t
* ir_setld_from_ref
550 { struct ir_setld_t
* setld
;
551 setld
= struct_alloc(ir_setld_t
);
557 struct ir_setld_t
* ir_setld_from_classld
558 ( struct ir_classld_t
* classld
,
561 { struct ir_setld_t
* setld
;
562 setld
= struct_alloc(ir_setld_t
);
564 setld
->namelist
= struct_alloc(ir_namelist_t
);
565 struct_clear(setld
->namelist
);
566 setld
->namelist_head
= setld
->namelist
;
567 setld
->namelist_head
->name
= name_alloc(name
);
568 setld
->classld
= classld
;
572 struct ir_setld_t
* ir_setld_addchild
573 ( struct ir_setld_t
* setld
,
576 { if (setld
->namelist
== NULL
)
577 { setld
->namelist
= struct_alloc(ir_namelist_t
);
578 struct_clear(setld
->namelist
);
579 setld
->namelist_head
= setld
->namelist
;
582 { setld
->namelist_head
->nextsib
= struct_alloc(ir_namelist_t
);
583 struct_clear(setld
->namelist_head
->nextsib
);
584 setld
->namelist_head
= setld
->namelist_head
->nextsib
;
586 setld
->namelist_head
->name
= name_alloc(name
);
590 union ir_setdata_t
* ir_link
591 ( enum ltype link_type
,
592 struct ir_setld_t
* setld
,
595 { struct ir_link_t
* link
;
596 link
= struct_alloc(ir_link_t
);
598 link
->header
.type
= LDAT
;
599 link
->type
= link_type
;
601 if (link_type
!= OLINK
&& name
!= NULL
)
602 link
->header
.data_name
= name_alloc(name
);
603 return (union ir_setdata_t
*) link
;
606 /* Return a set's root framebox */
607 union ir_setdata_t
* ir_set_framebox
608 ( struct ir_set_t
* set
)
609 { return (union ir_setdata_t
*) set
->frameboxes
; }
611 /* Return a set's root audio data */
612 union ir_setdata_t
* ir_set_audio
613 ( struct ir_set_t
* set
)
614 { return (union ir_setdata_t
*) set
->audio
; }
616 /* Return a set's root link data */
617 union ir_setdata_t
* ir_set_link
618 ( struct ir_set_t
* set
)
619 { return (union ir_setdata_t
*) set
->links
; }
621 #define assert_link(linkdata) if (DEBUG) { \
622 if (linkdata->header.type != LDAT) \
623 eprintf("Data %s is not a link\n", linkdata->header.data_name); \
626 /* Return the link type */
627 enum ltype ir_linkdata_type
628 ( union ir_setdata_t
* linkdata
)
629 { assert_link(linkdata
);
630 return linkdata
->link
.type
;
633 /* Return the link type */
634 uint32_t ir_linkdata_ref
635 ( union ir_setdata_t
* linkdata
)
636 { assert_link(linkdata
);
637 return linkdata
->link
.setld
->ref
;
640 /* Return the current target set, resolving it first if not present */
641 struct ir_set_t
* ir_linkdata_set
642 ( union ir_setdata_t
* linkdata
)
643 { assert_link(linkdata
);
644 if (linkdata
->link
.trg_set
== NULL
)
645 ir_linkdata_resolve_set(linkdata
);
646 return linkdata
->link
.trg_set
;
649 /* Resolve and assign the link's target set */
651 void ir_linkdata_resolve_set
652 ( union ir_setdata_t
* linkdata
)
653 { struct ir_class_t
* class_iter
;
654 struct ir_namelist_t
* namelist_iter
,* namelist_iter_last
;
655 struct ir_setld_t
* setld
;
656 struct ir_classld_t
* classld
;
657 struct ir_set_t
* set
;
660 assert_link(linkdata
);
661 setld
= linkdata
->link
.setld
;
662 if (linkdata
->link
.setld
== NULL
)
663 eprintf("Link data is invalid\n");
664 classld
= setld
->classld
;
666 { namelist_iter
= classld
->namelist
;
667 if (classld
->root_class
== NULL
)
668 eprintf("No root class for classld\n");
669 class_iter
= classld
->root_class
->nextchild
;
670 namelist_iter_last
= NULL
;
671 while (class_iter
!= NULL
)
672 { if (classnames_identical(class_iter
->name
, namelist_iter
->name
))
673 { if (namelist_iter
== classld
->namelist_head
)
675 class_iter
= class_iter
->nextchild
;
676 namelist_iter_last
= namelist_iter
;
677 namelist_iter
= namelist_iter
->nextsib
;
680 class_iter
= class_iter
->nextsib
;
682 if (class_iter
== NULL
)
683 { if (namelist_iter_last
)
684 eprintf("No such subclass \"%s\" of class \"%s\"\n",
686 namelist_iter_last
->name
);
688 { wprintf("No such class \"%s\"\n", namelist_iter
->name
);
692 set
= class_iter
->root_set
;
695 set
= ir_set_from_ref(setld
->ref
);
697 eprintf("Initial set resolution failed\n");
698 namelist_iter
= setld
->namelist
;
699 namelist_iter_last
= NULL
;
700 if (setld
->namelist
!= NULL
)
701 { while (set
!= NULL
)
702 { if (bytes_identical(set
->name
, namelist_iter
->name
))
703 { if (namelist_iter
== setld
->namelist_head
)
705 set
= set
->nextchild
;
706 namelist_iter_last
= namelist_iter
;
707 namelist_iter
= namelist_iter
->nextsib
;
713 { if (namelist_iter_last
)
714 eprintf("No such subset \"%s\" of set \"%s\"\n",
716 namelist_iter_last
->name
);
718 eprintf("No such set \"%s\" in class \"%s\"\n",
723 linkdata
->link
.trg_set
= set
;
726 /* Assign a linkdatas trg_set */
727 void ir_linkdata_assign_set
728 ( union ir_setdata_t
* link
, struct ir_set_t
* set
)
730 link
->link
.trg_set
= set
;
733 /* Assign a linkdatas type */
734 void ir_linkdata_assign_type
735 ( union ir_setdata_t
* link
, enum ltype type
)
737 link
->link
.type
= type
;
740 /* Get, or generate, the fully qualified name of the link's target set */
742 ir_linkdata_dlink_name
743 ( union ir_setdata_t
* link
)
744 { struct ir_namelist_t
* namelist_iter
;
745 struct ir_setld_t
* setld
;
746 struct ir_classld_t
* classld
;
751 static const uint8_t dlink_prefix
[] = { '/', '.', '.', '/' };
752 # define dlink_prefix_len 4
754 if (link
->link
.dlink
!= NULL
)
755 return link
->link
.dlink
;
757 setld
= link
->link
.setld
;
759 eprintf("No setld in dlink\n");
760 classld
= setld
->classld
;
762 eprintf("No classld in dlink\n");
763 if (classld
->root_class
!= NULL
)
764 eprintf("Cannot dlink local class \"%s\"\n", classld
->root_class
->name
);
765 namelist_iter
= classld
->namelist
;
767 count_bytes_in_namelist
:
768 while (namelist_iter
!= NULL
)
769 { bytep
= namelist_iter
->name
;
771 bytes
+= (bytep
- namelist_iter
->name
);
772 namelist_iter
= namelist_iter
->nextsib
;
776 namelist_iter
= setld
->namelist
;
777 goto count_bytes_in_namelist
;
779 bytes
+= dlink_prefix_len
;
780 link
->link
.dlink
= stack_alloc(&namepages
, bytes
);
781 for (bytes
= 0; bytes
< dlink_prefix_len
; bytes
++)
782 link
->link
.dlink
[bytes
] = dlink_prefix
[bytes
];
783 namelist_iter
= classld
->namelist
;
785 delimiter
= APC_CLASS_DELIMITER
;
786 copy_bytes_in_namelist
:
787 while (namelist_iter
!= NULL
)
788 { bytep
= namelist_iter
->name
;
790 link
->link
.dlink
[bytes
++] = *bytep
++;
791 link
->link
.dlink
[bytes
++] = delimiter
;
792 namelist_iter
= namelist_iter
->nextsib
;
796 namelist_iter
= setld
->namelist
;
797 delimiter
= APC_SET_DELIMITER
;
798 link
->link
.dlink
[bytes
- 1] = delimiter
; //overwrite last delimiter
799 goto copy_bytes_in_namelist
;
801 link
->link
.dlink
[bytes
] = '\0'; //tailing '\0' null termination
802 return link
->link
.dlink
;
805 /* Get a setdata's next sibling */
806 union ir_setdata_t
* ir_setdata_nextsib
807 ( union ir_setdata_t
* setdata
)
808 { return setdata
->header
.nextsib
; }
810 /* Get a setdata's name */
811 uint8_t* ir_setdata_name
812 ( union ir_setdata_t
* setdata
)
813 { return setdata
->header
.data_name
; }
815 /* Get a setdata's filename */
816 uint8_t* ir_setdata_filename
817 ( union ir_setdata_t
* setdata
)
818 { return setdata
->header
.src_filename
; }
820 /* Get a setdata's file position */
822 ( union ir_setdata_t
* setdata
)
823 { return setdata
->header
.filepos
; }
825 /* Set a setdata's file position */
826 void ir_setdata_assign_fpos
827 ( union ir_setdata_t
* setdata
,
830 { setdata
->header
.filepos
= newpos
; }
832 /* Assign a setdatas name */
833 void ir_setdata_assign_name
834 ( union ir_setdata_t
* setdata
, uint8_t* name
)
835 { setdata
->header
.data_name
= name
;}
837 /* Return a framebox's specified framesheet */
838 union ir_setdata_t
* ir_framebox_framesheet
839 ( union ir_setdata_t
* fbox
,
842 { if (fbox
->header
.type
!= FBDAT
)
843 eprintf("Data %s is not a framebox\n", fbox
->header
.data_name
);
844 return (union ir_setdata_t
*) &fbox
->framebox
.framesheets
[facing
];
847 /* Return a framebox's specified mapsheet */
848 union ir_setdata_t
* ir_framebox_mapsheet
849 ( union ir_setdata_t
* fbox
,
852 { if (fbox
->header
.type
!= FBDAT
)
853 eprintf("Data %s is not a framebox\n", fbox
->header
.data_name
);
854 return (union ir_setdata_t
*) &fbox
->framebox
.mapsheets
[facing
];
857 /* Return a framedata's frame info */
858 struct ir_frameinfo_t
* ir_framedata_frameinfo
859 ( union ir_setdata_t
* framedata
)
860 { if (framedata
->header
.type
!= MSDAT
&& framedata
->header
.type
!= FSDAT
)
861 eprintf("Data %s is not a framedata\n", framedata
->header
.data_name
);
862 return &framedata
->mapsheet
.frameinfo
;
869 ( const uint8_t* name_src
)
870 { const uint8_t* iter
;
874 name
= (uint8_t*)namepages
.head
->header
.head
;
876 for (head_mem
= PL_HEADMEM(namepages
); *iter
&& *iter
!= '_' && *iter
!= '.' && head_mem
; head_mem
--)
877 *(namepages
.head
->header
.head
)++ = *iter
++;
878 if (head_mem
< 1) //not enough room
879 { pagelist_alloc(namepages
);
882 *(namepages
.head
->header
.head
)++ = '\0';
887 uint8_t* classname_alloc
888 ( const uint8_t* name_src
)
889 { const uint8_t* iter
;
893 name
= (uint8_t*)namepages
.head
->header
.head
;
895 for (head_mem
= PL_HEADMEM(namepages
); *iter
&& head_mem
; head_mem
--)
896 *(namepages
.head
->header
.head
)++ = *iter
++;
897 if (head_mem
< 1) //not enough room
898 { pagelist_alloc(namepages
);
901 *(namepages
.head
->header
.head
)++ = '\0';
905 static void crawl_class(struct ir_class_t
*);
906 static void crawl_set(struct ir_set_t
*,int);
909 int binout_init(ir_class
);
911 { uprintf("IR From Directory: %s\n",getcwd(NULL
,255));
912 crawl_class(&root_class
);
913 if (root_class
.root_set
!= NULL
)
914 crawl_set(root_class
.root_set
, 0);
915 uprintf("starting binaryout \n");
916 binout_init(&root_class
);
922 ( struct ir_class_t
* class )
923 { struct ir_class_t
* iter
;
924 for (iter
= class->nextchild
; iter
!= NULL
; iter
= iter
->nextsib
)
925 { wprintf("Crawling class %U/\n", iter
->name
);
926 if(chdir((char*)iter
->name
))
927 eprintf("CHDIR %U from %s\n",iter
->name
,getcwd(NULL
,255));
929 if (iter
->root_set
!= NULL
)
930 crawl_set(iter
->root_set
, 0);
931 uprintf("%U\\\n",iter
->name
);
933 eprintf("CHDIR ..\n");
934 wprintf("Finished crawling class %U/\n", iter
->name
);
938 #define push_setp(setp) (*(struct ir_set_t**)stack_alloc(&datapages, sizeof(struct ir_set_t*)) = setp)
939 #define pop_setp() (*(struct ir_set_t**)pagelist_pop(&datapages, sizeof(struct ir_set_t*)))
942 ( struct ir_set_t
* set
,
945 { struct ir_set_t
* iter
;
952 for(iter
= set
; iter
!= NULL
; iter
= iter
->nextchild
)
953 { uprintf("[%10U]", iter
->name
);
960 if (((iter
= pop_setp())->nextsib
) != NULL
)
961 crawl_set(iter
->nextsib
,i
);