1
0
mirror of git://projects.qi-hardware.com/eda-tools.git synced 2024-12-23 14:39:53 +02:00

genex: added reading of files containing supplemental descriptions

Each entry has this structure:

component: text
  more text

  more text on a new line
next component: ...

If a component has multiple entries, a line break is placed between
them. Component names are case-insensitive.
This commit is contained in:
Werner Almesberger 2012-04-17 05:39:32 -03:00
parent b6b4c9946b
commit 1b7ace9043
3 changed files with 139 additions and 5 deletions

View File

@ -9,9 +9,11 @@
* (at your option) any later version. * (at your option) any later version.
*/ */
#define _GNU_SOURCE /* for strcasecmp */
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <ctype.h>
#include "util.h" #include "util.h"
#include "comp.h" #include "comp.h"
@ -66,6 +68,7 @@ next:
node = alloc_type(struct node); node = alloc_type(struct node);
node->name = name; node->name = name;
node->lib = NULL; node->lib = NULL;
node->comment = NULL;
node->indent = n; node->indent = n;
node->child = node->next = NULL; node->child = node->next = NULL;
if (n > depth) { if (n > depth) {
@ -90,6 +93,112 @@ next:
} }
static struct node *find_comp(struct node *node, const char *name)
{
struct node *found;
while (node) {
if (!strcasecmp(node->name, name))
return node;
found = find_comp(node->child, name);
if (found)
return found;
node = node->next;
}
return NULL;
}
static struct line *new_line(char *s)
{
struct line *line;
line = alloc_type(struct line);
line->s = stralloc(s);
line->next = NULL;
return line;
}
static void append_line(struct line *line, char *s)
{
int len1, len2;
len1 = strlen(line->s);
len2 = strlen(s);
line->s = realloc(line->s, len1+len2+1+1); /* separating space */
if (!line->s) {
perror("realloc");
exit(1);
}
line->s[len1] = ' ';
memcpy(line->s+len1+1, s, len2);
line->s[len1+len2+1] = 0;
}
void read_desc(FILE *file)
{
struct line **anchor = NULL;
char buf[1100]; /* more than enough */
struct node *node;
char *p, *end;
int lineno = 0;
while (fgets(buf, sizeof(buf), file)) {
lineno++;
p = strchr(buf, '\n');
if (p)
*p = 0;
p = buf;
if (*buf && !isspace(*buf)) {
/* tag is ^.*?:\s */
while (1) {
p = strchr(p, ':');
if (!p) {
fprintf(stderr, "no tag in line %d\n",
lineno);
exit(1);
}
if (!p[1] || isspace(p[1]))
break;
p++;
}
*p++ = 0;
node = find_comp(tree, buf);
if (!node) {
fprintf(stderr,
"component \"%s\" not found in line %d\n",
buf, lineno);
exit(1);
}
for (anchor = &node->comment; *anchor;
anchor = &(*anchor)->next);
}
/* remove leading whitespace */
while (*p && isspace(*p))
p++;
if (!*p) {
if (*anchor)
anchor = &(*anchor)->next;
continue;
}
/* remove training whitespace */
end = strrchr(p, 0);
while (isspace(end[-1]))
end--;
*end = 0;
if (*anchor)
append_line(*anchor, p);
else
*anchor = new_line(p);
}
}
void set_libs(struct node *node, void set_libs(struct node *node,
const char *(*find_lib)(const char *sym, const char **canon, const char *(*find_lib)(const char *sym, const char **canon,
int *units)) int *units))
@ -113,9 +222,12 @@ void set_libs(struct node *node,
static void dump_level(const struct node *tree, int level) static void dump_level(const struct node *tree, int level)
{ {
const struct node *n; const struct node *n;
const struct line *line;
for (n = tree; n; n = n->next) { for (n = tree; n; n = n->next) {
printf("%*s%s\n", 4*level, "", n->name); printf("%*s%s\n", 4*level, "", n->name);
for (line = n->comment; line; line = line->next)
printf("%*s\"%s\"\n", 4*level+2, "", line->s);
dump_level(n->child, level+1); dump_level(n->child, level+1);
} }
} }

View File

@ -12,11 +12,17 @@
#ifndef COMP_H #ifndef COMP_H
#define COMP_H #define COMP_H
struct line {
char *s;
struct line *next;
};
struct node { struct node {
const char *name; const char *name;
const char *lib; /* NULL if intermediate node */ const char *lib; /* NULL if intermediate node */
const char *canon; /* canonical name of component */ const char *canon; /* canonical name of component */
int units; /* number of units */ int units; /* number of units; undefined if intermediate */
struct line *comment; /* NULL if intermediate node */
int indent; /* level of indentation (characters) */ int indent; /* level of indentation (characters) */
struct node *parent; struct node *parent;
struct node *child; struct node *child;
@ -28,6 +34,7 @@ extern struct node *tree;
void read_tree(FILE *file); void read_tree(FILE *file);
void read_desc(FILE *file);
void set_libs(struct node *node, void set_libs(struct node *node,
const char *(*find_lib)(const char *sym, const char **canon, const char *(*find_lib)(const char *sym, const char **canon,
int *units)); int *units));

View File

@ -22,7 +22,7 @@
static void usage(const char *name) static void usage(const char *name)
{ {
fprintf(stderr, fprintf(stderr,
"usage: %s [-L libdir ...] [-l lib ...] hierarchy\n\n" "usage: %s [-L libdir ...] [-l lib ...] hierarchy [descriptions ...]\n\n"
" -L libdir search all libraries in the specified directory\n" " -L libdir search all libraries in the specified directory\n"
" -l lib search the specified component library\n" " -l lib search the specified component library\n"
, name); , name);
@ -34,6 +34,7 @@ int main(int argc, char **argv)
{ {
FILE *file; FILE *file;
int c; int c;
char **arg;
while ((c = getopt(argc, argv, "L:l:")) != EOF) while ((c = getopt(argc, argv, "L:l:")) != EOF)
switch (c) { switch (c) {
@ -47,9 +48,13 @@ int main(int argc, char **argv)
usage(*argv); usage(*argv);
} }
switch (argc-optind) {
if (argc-optind != 1) case 1:
case 2:
break;
default:
usage(*argv); usage(*argv);
}
file = fopen(argv[optind], "r"); file = fopen(argv[optind], "r");
if (!file) { if (!file) {
@ -57,8 +62,18 @@ int main(int argc, char **argv)
exit(1); exit(1);
} }
read_tree(file); read_tree(file);
set_libs(tree, lookup_sym);
fclose(file); fclose(file);
set_libs(tree, lookup_sym);
for (arg = argv+optind+1; *arg; arg++) {
file = fopen(*arg, "r");
if (!file) {
perror(*arg);
exit(1);
}
read_desc(file);
fclose(file);
}
// dump_tree(); // dump_tree();
make_pdf(); make_pdf();
return 0; return 0;