/* * comp.c - Component hierarchy * * Copyright 2012 by Werner Almesberger * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #include #include #include #include "util.h" #include "comp.h" struct node *tree = NULL; void read_tree(FILE *file) { char buf[1100]; /* more than enough */ struct node *last = NULL, *node; int depth = -1; const char *s, *p, *e; char *name; int n; next: while (fgets(buf, sizeof(buf), file)) { n = 0; s = buf; while (1) { switch (*s++) { case ' ': n++; continue; case '\t': n = (n+8) & ~7; continue; case 0: case '#': goto next; default: break; } break; } for (p = e = s--; *p && *p != '#' && *p != '\n'; p++) if (*p != ' ' && *p != '\t') e = p; if (!last && n) { fprintf(stderr, "first entry must not be intended\n"); exit(1); } name = malloc(e-s+2); if (!name) { perror("malloc"); exit(1); } memcpy(name, s, e-s+1); name[e-s+1] = 0; node = alloc_type(struct node); node->name = name; node->lib = NULL; node->indent = n; node->child = node->next = NULL; if (n > depth) { if (last) last->child = node; else tree = node; node->parent = last; } else { while (last && last->indent != n) last = last->parent; if (!last && n) { fprintf(stderr, "indentation error\n"); exit(1); } last->next = node; node->parent = last->parent; } last = node; depth = n; } } void set_libs(struct node *node, const char *(*find_lib)(const char *sym, const char **canon, int *units)) { while (node) { if (!node->child) { node->lib = find_lib(node->name, &node->canon, &node->units); if (!node->lib) { fprintf(stderr, "symbol %s not found\n", node->name); exit(1); } } set_libs(node->child, find_lib); node = node->next; } } static void dump_level(const struct node *tree, int level) { const struct node *n; for (n = tree; n; n = n->next) { printf("%*s%s\n", 4*level, "", n->name); dump_level(n->child, level+1); } } void dump_tree(void) { dump_level(tree, 0); }