From 1b7ace9043cdeba9b5c59e464e770ca59371d85b Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Tue, 17 Apr 2012 05:39:32 -0300 Subject: [PATCH] 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. --- genex/comp.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++ genex/comp.h | 9 +++- genex/genex.c | 23 +++++++++-- 3 files changed, 139 insertions(+), 5 deletions(-) diff --git a/genex/comp.c b/genex/comp.c index 2d51944..8c8496f 100644 --- a/genex/comp.c +++ b/genex/comp.c @@ -9,9 +9,11 @@ * (at your option) any later version. */ +#define _GNU_SOURCE /* for strcasecmp */ #include #include #include +#include #include "util.h" #include "comp.h" @@ -66,6 +68,7 @@ next: node = alloc_type(struct node); node->name = name; node->lib = NULL; + node->comment = NULL; node->indent = n; node->child = node->next = NULL; 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, const char *(*find_lib)(const char *sym, const char **canon, int *units)) @@ -113,9 +222,12 @@ void set_libs(struct node *node, static void dump_level(const struct node *tree, int level) { const struct node *n; + const struct line *line; for (n = tree; n; n = n->next) { 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); } } diff --git a/genex/comp.h b/genex/comp.h index 511d2e6..d40bc69 100644 --- a/genex/comp.h +++ b/genex/comp.h @@ -12,11 +12,17 @@ #ifndef COMP_H #define COMP_H +struct line { + char *s; + struct line *next; +}; + struct node { const char *name; const char *lib; /* NULL if intermediate node */ 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) */ struct node *parent; struct node *child; @@ -28,6 +34,7 @@ extern struct node *tree; void read_tree(FILE *file); +void read_desc(FILE *file); void set_libs(struct node *node, const char *(*find_lib)(const char *sym, const char **canon, int *units)); diff --git a/genex/genex.c b/genex/genex.c index f6160d3..29cd9f5 100644 --- a/genex/genex.c +++ b/genex/genex.c @@ -22,7 +22,7 @@ static void usage(const char *name) { 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 lib search the specified component library\n" , name); @@ -34,6 +34,7 @@ int main(int argc, char **argv) { FILE *file; int c; + char **arg; while ((c = getopt(argc, argv, "L:l:")) != EOF) switch (c) { @@ -47,9 +48,13 @@ int main(int argc, char **argv) usage(*argv); } - - if (argc-optind != 1) + switch (argc-optind) { + case 1: + case 2: + break; + default: usage(*argv); + } file = fopen(argv[optind], "r"); if (!file) { @@ -57,8 +62,18 @@ int main(int argc, char **argv) exit(1); } read_tree(file); - set_libs(tree, lookup_sym); 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(); make_pdf(); return 0;