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_classld_t
* classld
;
68 struct ir_setld_t
* setld
;
69 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 link
->classld
= setld
->classld
;
603 if (link_type
!= OLINK
&& name
!= NULL
)
604 link
->header
.data_name
= name_alloc(name
);
605 return (union ir_setdata_t
*) link
;
608 /* Return a set's root framebox */
609 union ir_setdata_t
* ir_set_framebox
610 ( struct ir_set_t
* set
)
611 { return (union ir_setdata_t
*) set
->frameboxes
; }
613 /* Return a set's root audio data */
614 union ir_setdata_t
* ir_set_audio
615 ( struct ir_set_t
* set
)
616 { return (union ir_setdata_t
*) set
->audio
; }
618 /* Return a set's root link data */
619 union ir_setdata_t
* ir_set_link
620 ( struct ir_set_t
* set
)
621 { return (union ir_setdata_t
*) set
->links
; }
623 #define assert_link(linkdata) if (DEBUG) { \
624 if (linkdata->header.type != LDAT) \
625 eprintf("Data %s is not a link\n", linkdata->header.data_name); \
628 /* Return the link type */
629 enum ltype ir_linkdata_type
630 ( union ir_setdata_t
* linkdata
)
631 { assert_link(linkdata
);
632 return linkdata
->link
.type
;
635 /* Return the link type */
636 uint32_t ir_linkdata_ref
637 ( union ir_setdata_t
* linkdata
)
638 { assert_link(linkdata
);
639 return linkdata
->link
.setld
->ref
;
642 /* Return the current target set, resolving it first if not present */
643 struct ir_set_t
* ir_linkdata_set
644 ( union ir_setdata_t
* linkdata
)
645 { assert_link(linkdata
);
646 if (linkdata
->link
.trg_set
== NULL
)
647 ir_linkdata_resolve_set(linkdata
);
648 return linkdata
->link
.trg_set
;
651 /* Resolve and assign the link's target set */
653 void ir_linkdata_resolve_set
654 ( union ir_setdata_t
* linkdata
)
655 { struct ir_class_t
* class_iter
;
656 struct ir_namelist_t
* namelist_iter
,* namelist_iter_last
;
657 struct ir_setld_t
* setld
;
658 struct ir_classld_t
* classld
;
659 struct ir_set_t
* set
;
662 assert_link(linkdata
);
663 setld
= linkdata
->link
.setld
;
664 if (linkdata
->link
.setld
== NULL
)
665 eprintf("Link data is invalid\n");
666 classld
= linkdata
->link
.classld
;
668 { namelist_iter
= classld
->namelist
;
669 if (classld
->root_class
== NULL
)
670 eprintf("No root class for classld\n");
671 class_iter
= classld
->root_class
->nextchild
;
672 namelist_iter_last
= NULL
;
673 while (class_iter
!= NULL
)
674 { if (classnames_identical(class_iter
->name
, namelist_iter
->name
))
675 { if (namelist_iter
== classld
->namelist_head
)
677 class_iter
= class_iter
->nextchild
;
678 namelist_iter_last
= namelist_iter
;
679 namelist_iter
= namelist_iter
->nextsib
;
682 class_iter
= class_iter
->nextsib
;
684 if (class_iter
== NULL
)
685 { if (namelist_iter_last
)
686 eprintf("No such subclass \"%s\" of class \"%s\"\n",
688 namelist_iter_last
->name
);
690 eprintf("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 a setdata's next sibling */
741 union ir_setdata_t
* ir_setdata_nextsib
742 ( union ir_setdata_t
* setdata
)
743 { return setdata
->header
.nextsib
; }
745 /* Get a setdata's name */
746 uint8_t* ir_setdata_name
747 ( union ir_setdata_t
* setdata
)
748 { return setdata
->header
.data_name
; }
750 /* Get a setdata's filename */
751 uint8_t* ir_setdata_filename
752 ( union ir_setdata_t
* setdata
)
753 { return setdata
->header
.src_filename
; }
755 /* Get a setdata's file position */
757 ( union ir_setdata_t
* setdata
)
758 { return setdata
->header
.filepos
; }
760 /* Set a setdata's file position */
761 void ir_setdata_assign_fpos
762 ( union ir_setdata_t
* setdata
,
765 { setdata
->header
.filepos
= newpos
; }
767 /* Assign a setdatas name */
768 void ir_setdata_assign_name
769 ( union ir_setdata_t
* setdata
, uint8_t* name
)
770 { setdata
->header
.data_name
= name
;}
772 /* Return a framebox's specified framesheet */
773 union ir_setdata_t
* ir_framebox_framesheet
774 ( union ir_setdata_t
* fbox
,
777 { if (fbox
->header
.type
!= FBDAT
)
778 eprintf("Data %s is not a framebox\n", fbox
->header
.data_name
);
779 return (union ir_setdata_t
*) &fbox
->framebox
.framesheets
[facing
];
782 /* Return a framebox's specified mapsheet */
783 union ir_setdata_t
* ir_framebox_mapsheet
784 ( union ir_setdata_t
* fbox
,
787 { if (fbox
->header
.type
!= FBDAT
)
788 eprintf("Data %s is not a framebox\n", fbox
->header
.data_name
);
789 return (union ir_setdata_t
*) &fbox
->framebox
.mapsheets
[facing
];
792 /* Return a framedata's frame info */
793 struct ir_frameinfo_t
* ir_framedata_frameinfo
794 ( union ir_setdata_t
* framedata
)
795 { if (framedata
->header
.type
!= MSDAT
&& framedata
->header
.type
!= FSDAT
)
796 eprintf("Data %s is not a framedata\n", framedata
->header
.data_name
);
797 return &framedata
->mapsheet
.frameinfo
;
804 ( const uint8_t* name_src
)
805 { const uint8_t* iter
;
809 name
= (uint8_t*)namepages
.head
->header
.head
;
811 for (head_mem
= PL_HEADMEM(namepages
); *iter
&& *iter
!= '_' && *iter
!= '.' && head_mem
; head_mem
--)
812 *(namepages
.head
->header
.head
)++ = *iter
++;
813 if (head_mem
< 1) //not enough room
814 { pagelist_alloc(namepages
);
817 *(namepages
.head
->header
.head
)++ = '\0';
822 uint8_t* classname_alloc
823 ( const uint8_t* name_src
)
824 { const uint8_t* iter
;
828 name
= (uint8_t*)namepages
.head
->header
.head
;
830 for (head_mem
= PL_HEADMEM(namepages
); *iter
&& head_mem
; head_mem
--)
831 *(namepages
.head
->header
.head
)++ = *iter
++;
832 if (head_mem
< 1) //not enough room
833 { pagelist_alloc(namepages
);
836 *(namepages
.head
->header
.head
)++ = '\0';
840 static void crawl_class(struct ir_class_t
*);
841 static void crawl_set(struct ir_set_t
*,int);
844 int binout_init(ir_class
);
846 { uprintf("IR From Directory: %s\n",getcwd(NULL
,255));
847 crawl_class(&root_class
);
848 if (root_class
.root_set
!= NULL
)
849 crawl_set(root_class
.root_set
, 0);
850 uprintf("starting binaryout \n");
851 binout_init(&root_class
);
857 ( struct ir_class_t
* class )
858 { struct ir_class_t
* iter
;
859 for (iter
= class->nextchild
; iter
!= NULL
; iter
= iter
->nextsib
)
860 { wprintf("Crawling class %U/\n", iter
->name
);
861 if(chdir((char*)iter
->name
))
862 eprintf("CHDIR %U from %s\n",iter
->name
,getcwd(NULL
,255));
864 if (iter
->root_set
!= NULL
)
865 crawl_set(iter
->root_set
, 0);
866 uprintf("%U\\\n",iter
->name
);
868 eprintf("CHDIR ..\n");
869 wprintf("Finished crawling class %U/\n", iter
->name
);
873 #define push_setp(setp) (*(struct ir_set_t**)stack_alloc(&datapages, sizeof(struct ir_set_t*)) = setp)
874 #define pop_setp() (*(struct ir_set_t**)pagelist_pop(&datapages, sizeof(struct ir_set_t*)))
877 ( struct ir_set_t
* set
,
880 { struct ir_set_t
* iter
;
887 for(iter
= set
; iter
!= NULL
; iter
= iter
->nextchild
)
888 { uprintf("[%10U]", iter
->name
);
895 if (((iter
= pop_setp())->nextsib
) != NULL
)
896 crawl_set(iter
->nextsib
,i
);