ir treewalk fixes
[henge/apc.git] / src / ir.c
index 706f677..e88ac36 100644 (file)
--- a/src/ir.c
+++ b/src/ir.c
@@ -102,7 +102,6 @@ struct ir_class_t
 };\r
 struct ir_set_t\r
 { struct ir_set_t*      nextchild, * nextsib;\r
-  struct ir_class_t*    class;\r
   uint32_t              ref;\r
   uint8_t*              name;\r
   struct ir_framebox_t* frameboxes;\r
@@ -111,7 +110,7 @@ struct ir_set_t
 };\r
 /* Functions */\r
 static inline\r
-struct ir_framebox_t* ir_set_add_framebox(struct ir_set_t*,const uint8_t*);\r
+struct ir_framebox_t* ir_set_add_framebox(struct ir_set_t*,uint8_t*);\r
 static inline\r
 union ir_setdata_t*   ir_framedata (enum dtype,const uint8_t*,apc_facing,int,int);\r
 static inline\r
@@ -121,26 +120,30 @@ int      classnames_identical(const uint8_t*,const uint8_t*);
 static\r
 void*    stack_alloc(size_t);\r
 #define  struct_alloc(_T) ((struct _T*) stack_alloc(sizeof(struct _T)))\r
+#define  struct_clear(_S) (memset((_S), 0, sizeof(*(_S))))\r
 static\r
 uint8_t* name_alloc(const uint8_t*);\r
 static\r
 uint8_t* classname_alloc(const uint8_t*);\r
 static inline\r
 void*    pagelist_pop(struct pagelist_t*,size_t);\r
+#define $($)#$\r
 #define  pagelist_alloc(pagelist) do {                                 \\r
-    pagelist.head->header.next = (struct pagenode_t*) calloc(pagelist.pagesize,1); \\r
+    pagelist.head->header.next = (struct pagenode_t*) malloc(pagelist.pagesize); \\r
     if (pagelist.head->header.next == NULL)                            \\r
       eprintf("Memory allocation error\n");                            \\r
+    struct_clear(pagelist.head->header.next);                          \\r
     pagelist.head = pagelist.head->header.next;                                \\r
     pagelist.head->header.head = pagelist.head->root;                  \\r
   } while (0)\r
 #define  pagelist_init(pagelist,size) do {                     \\r
     pagelist.pagesize = size;                                  \\r
-    pagelist.root = (struct pagenode_t*) calloc(size,1);       \\r
+    pagelist.root = (struct pagenode_t*) malloc(size);         \\r
     if (pagelist.root == NULL)                                 \\r
       eprintf("Memory allocation error\n");                    \\r
-    pagelist.root->header.head = pagelist.root->root;          \\r
+    struct_clear(pagelist.root);                               \\r
     pagelist.head = pagelist.root;                             \\r
+    pagelist.head->header.head = pagelist.head->root;          \\r
   } while (0)\r
 static\r
 void     pagenode_free(struct pagenode_t*);\r
@@ -211,7 +214,11 @@ struct ir_class_t* ir_class_addchild
 )\r
 { struct ir_class_t* iter;\r
   if (class->nextchild == NULL)\r
-    goto alloc;\r
+    { class->nextchild = struct_alloc(ir_class_t);\r
+      struct_clear(class->nextchild);\r
+      class->nextchild->name = classname_alloc(name);\r
+      return class->nextchild;\r
+    }\r
   iter = class->nextchild;\r
   if (iter->name == NULL)\r
     eprintf("Null name pointer in class %p\n", iter);\r
@@ -224,11 +231,10 @@ struct ir_class_t* ir_class_addchild
     { iter = iter->nextsib;\r
       goto check;\r
     }\r
- alloc:\r
-  iter = struct_alloc(ir_class_t);\r
-  iter->nextsib = class->nextchild;\r
-  iter->name = classname_alloc(name);\r
-  return class->nextchild = iter;\r
+  iter->nextsib = struct_alloc(ir_class_t);\r
+  struct_clear(iter->nextsib);\r
+  iter->nextsib->name = classname_alloc(name);\r
+  return iter->nextsib;\r
 }\r
 \r
 /* Add a set to a class\r
@@ -241,7 +247,11 @@ struct ir_set_t* ir_class_addset
 )\r
 { struct ir_set_t* iter;\r
   if (class->root_set == NULL)\r
-    goto alloc;\r
+    { class->root_set = struct_alloc(ir_set_t);\r
+      struct_clear(class->root_set);\r
+      class->root_set->name = name_alloc(name);\r
+      return class->root_set;\r
+    }\r
   iter = class->root_set;\r
   if (iter->name == NULL)\r
     eprintf("Null name pointer in class %p\n", iter);\r
@@ -254,11 +264,10 @@ struct ir_set_t* ir_class_addset
     { iter = iter->nextsib;\r
       goto check;\r
     }\r
- alloc:\r
-  iter = struct_alloc(ir_set_t);\r
-  iter->nextsib = class->root_set;\r
-  iter->name = name_alloc(name);\r
-  return class->root_set = iter;\r
+  iter->nextsib = struct_alloc(ir_set_t);\r
+  struct_clear(iter->nextsib);\r
+  iter->nextsib->name = name_alloc(name);\r
+  return iter->nextsib;\r
 }\r
 \r
 struct ir_set_t* ir_set_from_ref\r
@@ -285,12 +294,16 @@ struct ir_set_t* ir_set_addchild
 )\r
 { struct ir_set_t* iter;\r
   if (set->nextchild == NULL)\r
-    goto alloc;\r
+    { set->nextchild = struct_alloc(ir_set_t);\r
+      struct_clear(set->nextchild);\r
+      set->nextchild->name = name_alloc(name);\r
+      return set->nextchild;\r
+    }\r
   iter = set->nextchild;\r
-  if (iter->name == NULL)\r
-    eprintf("Null name pointer in set %p\n", iter);\r
   if (name == NULL)\r
     eprintf("Null child added to set %s\n", iter->name);\r
+  if (iter->name == NULL)\r
+    eprintf("Null name pointer in set %p\n", iter);\r
  check:\r
   if (bytes_identical(iter->name, name))\r
     return iter;\r
@@ -298,25 +311,30 @@ struct ir_set_t* ir_set_addchild
     { iter = iter->nextsib;\r
       goto check;\r
     }\r
- alloc:\r
-  iter = struct_alloc(ir_set_t);\r
-  iter->nextsib = set->nextchild;\r
-  iter->name = name_alloc(name);\r
-  return set->nextchild = iter;\r
+  iter->nextsib = struct_alloc(ir_set_t);\r
+  struct_clear(iter->nextsib);\r
+  iter->nextsib->name = name_alloc(name);\r
+  return iter->nextsib;\r
 }\r
 \r
 /* Add a framebox to a set\r
    Attempts to create a new framebox of the specified set, returning\r
    the framebox if it already exists\r
+   Name is not allocated, but assigned, unlike other "XXX_add" functions where\r
+   name is duplicated into IR's internal array.\r
 */\r
 static inline\r
 struct ir_framebox_t* ir_set_add_framebox\r
 ( struct ir_set_t* set,\r
-  const uint8_t*   name\r
+  uint8_t*         name\r
 )\r
 { struct ir_framebox_t* iter;\r
   if (set->frameboxes == NULL)\r
-    goto alloc;\r
+    { set->frameboxes = struct_alloc(ir_framebox_t);\r
+      struct_clear(set->frameboxes);\r
+      set->frameboxes->header.data_name = name;\r
+      return set->frameboxes;\r
+    }\r
   iter = set->frameboxes;\r
  check:\r
   if (bytes_identical(iter->header.data_name, name))\r
@@ -325,11 +343,10 @@ struct ir_framebox_t* ir_set_add_framebox
     { iter = (struct ir_framebox_t*) iter->header.nextsib;\r
       goto check;\r
     }\r
- alloc:\r
-  iter = struct_alloc(ir_framebox_t);\r
-  iter->header.nextsib = (union ir_setdata_t*) set->frameboxes;\r
-  iter->header.data_name = name_alloc(name);\r
-  return set->frameboxes = iter;\r
+  iter->header.nextsib = (union ir_setdata_t*) struct_alloc(ir_framebox_t);\r
+  struct_clear(iter->header.nextsib);\r
+  iter->header.nextsib->header.data_name = name;\r
+  return (struct ir_framebox_t*) (iter->header.nextsib);\r
 }\r
 \r
 /* Match two null-terminated bytestrings\r
@@ -483,6 +500,7 @@ union ir_setdata_t* ir_framedata
   int            height\r
 )\r
 { struct ir_framedata_t* framedata = struct_alloc(ir_framedata_t);\r
+  struct_clear(framedata);\r
   if (name == NULL)\r
     eprintf("Null name in set allocation\n");\r
   framedata->header.type = type;\r
@@ -496,6 +514,7 @@ union ir_setdata_t* ir_framedata
 union ir_setdata_t* ir_audio\r
 ( const uint8_t* name )\r
 { struct ir_simplex_t* audio = struct_alloc(ir_simplex_t);\r
+  struct_clear(audio);\r
   if (name == NULL)\r
     eprintf("Null audio\n");\r
   audio->header.type = ADAT;\r
@@ -511,6 +530,7 @@ struct ir_classld_t* ir_classld_from_class
   if (class == NULL)\r
     eprintf("Null class in classld\n");\r
   classld = struct_alloc(ir_classld_t);\r
+  struct_clear(classld);\r
   classld->root_class = class;\r
   return classld;\r
 }\r
@@ -519,6 +539,7 @@ struct ir_setld_t* ir_setld_from_ref
 ( uint32_t ref )\r
 { struct ir_setld_t* setld;\r
   setld = struct_alloc(ir_setld_t);\r
+  struct_clear(setld);\r
   setld->ref = ref;\r
   return setld;\r
 }\r
@@ -529,7 +550,9 @@ struct ir_setld_t* ir_setld_from_classld
 )\r
 { struct ir_setld_t* setld;\r
   setld = struct_alloc(ir_setld_t);\r
+  struct_clear(setld);\r
   setld->namelist = struct_alloc(ir_namelist_t);\r
+  struct_clear(setld->namelist);\r
   setld->namelist_head = setld->namelist;\r
   setld->namelist_head->name = name_alloc(name);\r
   setld->classld = classld;\r
@@ -542,10 +565,12 @@ struct ir_setld_t* ir_setld_addchild
 )\r
 { if (setld->namelist == NULL)\r
     { setld->namelist = struct_alloc(ir_namelist_t);\r
+      struct_clear(setld->namelist);\r
       setld->namelist_head = setld->namelist;\r
     }\r
   else\r
     { setld->namelist_head->nextsib = struct_alloc(ir_namelist_t);\r
+      struct_clear(setld->namelist_head->nextsib);\r
       setld->namelist_head = setld->namelist_head->nextsib;\r
     }\r
   setld->namelist_head->name = name_alloc(name);\r
@@ -559,6 +584,7 @@ union ir_setdata_t* ir_link
 )\r
 { struct ir_link_t* link;\r
   link = struct_alloc(ir_link_t);\r
+  struct_clear(link);\r
   link->header.type = LDAT;\r
   link->type = link_type; \r
   link->classld = setld->classld;\r
@@ -589,10 +615,12 @@ void* pagelist_pop
 static\r
 void* stack_alloc\r
 ( size_t bytes )\r
-{ if (PL_HEADMEM(datapages) < bytes) \r
+{ void* p;\r
+  if (PL_HEADMEM(datapages) < bytes) \r
     pagelist_alloc(datapages);\r
+  p = datapages.head->header.head;\r
   datapages.head->header.head += bytes;\r
-  return (void*) datapages.head->header.head - bytes;\r
+  return p;\r
 }\r
 \r
 static\r
@@ -606,7 +634,7 @@ uint8_t* name_alloc
   iter = name_src;\r
   for (head_mem = PL_HEADMEM(namepages); *iter && *iter != '_' && head_mem; head_mem--)\r
     *(namepages.head->header.head)++ = *iter++;\r
-  if (head_mem == 0) //not enough room\r
+  if (head_mem < 1) //not enough room\r
     { pagelist_alloc(namepages);\r
       goto copy;\r
     }\r
@@ -625,7 +653,7 @@ uint8_t* classname_alloc
   iter = name_src;\r
   for (head_mem = PL_HEADMEM(namepages); *iter && head_mem; head_mem--)\r
     *(namepages.head->header.head)++ = *iter++;\r
-  if (head_mem == 0) //not enough room\r
+  if (head_mem < 1) //not enough room\r
     { pagelist_alloc(namepages);\r
       goto copy;\r
     }\r
@@ -633,43 +661,56 @@ uint8_t* classname_alloc
   return name;\r
 }\r
 \r
-#define pdepth() do { for (i = 0; i < depth * 2; i++) putchar(' '); } while (0)\r
+static void crawl_class(struct ir_class_t*,int);\r
+static void crawl_set(struct ir_set_t*,int);\r
 void     ir_test(void)\r
-{ struct ir_class_t* class, * classbuf;\r
-  struct ir_set_t* set, * set_child;\r
-  int depth, i, olddepth;\r
-  depth = olddepth = 0;\r
-  classbuf = NULL;\r
-  for(class = ir_class_root(); class != NULL; class = class->nextchild)\r
-    {handle_class:\r
-      pdepth();\r
-      uprintf("%U\n",class->name);\r
-      old_depth = depth;\r
-      set = class->root_set;\r
-    handle_set:\r
-      while(set != NULL)\r
-       { pdepth();uprintf("|");\r
-         pdepth();\r
-         uprintf("-[%U]",set->name);\r
-         set_child = set->nextchild;\r
-         while (set_child != NULL)\r
-           { depth++;\r
-             uprintf("--[%U]",set_child->name);\r
-             set_child = set_child->nextchild;\r
-           }\r
-         uprintf("\n");\r
-         set = set->nextsib;\r
-       }\r
-      if (class->nextsib != NULL)\r
-       { if (classbuf == NULL)\r
-           classbuf = class;\r
-         class = class->nextsib;\r
-         goto handle_class;\r
-       }\r
-      if (classbuf != NULL)\r
-       class = classbuf;\r
-      classbuf = NULL;\r
-      uprintf("\n");\r
-      depth = olddepth + 1;\r
+{ uprintf("IR From Directory: %s\n",getcwd(NULL,255));\r
+  crawl_class(&root_class,0);\r
+}\r
+\r
+#define pspace(num) for (i = 0; i < (num); i++) putchar(' ')\r
+static\r
+void crawl_class\r
+( struct ir_class_t* class,\r
+  int depth\r
+)\r
+{ struct ir_class_t* iter;\r
+  /*if(chdir((char*)class->name))\r
+    eprintf("CHDIR %U\n",class->name);\r
+  else\r
+  wprintf("chdir %U\n",class->name);*/\r
+  if (class->nextchild != NULL)\r
+    { iter = class->nextchild;\r
+      do {\r
+       crawl_class(iter,depth + 1);\r
+       /*if (chdir(".."))\r
+         eprintf("CHDIR ..\n");*/\r
+      } while ((iter = iter->nextsib) != NULL);\r
+    }\r
+  wprintf("%U/\n", class->name);\r
+  if (class->root_set != NULL)\r
+    crawl_set(class->root_set,0);\r
+  uprintf("\n%U\\\n",class->name);\r
+}\r
+\r
+static\r
+void crawl_set\r
+( struct ir_set_t* set,\r
+  int depth\r
+)\r
+{ struct ir_set_t* iter;\r
+  int i = depth * 10;\r
+  pspace(i);\r
+  i = 0;\r
+  for(iter = set->nextchild; iter != NULL; iter = iter->nextchild)\r
+    { uprintf("[%8U]", iter->name);\r
+    }\r
+  for(iter = set->nextchild; iter != NULL; iter = iter->nextchild)\r
+    { if (iter->nextsib != NULL)\r
+        crawl_set(iter->nextsib, i);\r
+      i++;\r
     }\r
+  for(iter = set->nextchild; iter != NULL; iter = iter->nextchild)\r
+    crawl_set(iter, depth + 1);\r
+  putchar('\n');\r
 }\r