mirror of
git://projects.qi-hardware.com/eda-tools.git
synced 2024-11-26 16:01:31 +02:00
126 lines
2.3 KiB
C
126 lines
2.3 KiB
C
|
/*
|
||
|
* 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 <stdlib.h>
|
||
|
#include <stdio.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
#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))
|
||
|
{
|
||
|
while (node) {
|
||
|
if (!node->child) {
|
||
|
node->lib = find_lib(node->name, &node->canon);
|
||
|
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);
|
||
|
}
|