From e62c717db1dd57c2f537ae0b8ae6fb8b489f24be Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Wed, 11 Jul 2012 22:27:22 -0300 Subject: [PATCH] gencat/: abstract library data structure and its management (WIP) --- gencat/Makefile | 2 +- gencat/comp.c | 101 ++++-------------------------------------- gencat/comp.h | 24 ---------- gencat/gencat.c | 6 +-- gencat/libs.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++ gencat/libs.h | 49 +++++++++++++++++++++ gencat/pdf.c | 1 + gencat/tree.c | 3 +- gencat/tree.h | 3 -- 9 files changed, 178 insertions(+), 125 deletions(-) delete mode 100644 gencat/comp.h create mode 100644 gencat/libs.c create mode 100644 gencat/libs.h diff --git a/gencat/Makefile b/gencat/Makefile index 51b19a1..d4efcc0 100644 --- a/gencat/Makefile +++ b/gencat/Makefile @@ -11,7 +11,7 @@ PREFIX ?= /usr/local -OBJS = gencat.o tree.o comp.o pdf.o +OBJS = gencat.o tree.o libs.o comp.o pdf.o SHELL = /bin/bash CFLAGS = -Wall -g diff --git a/gencat/comp.c b/gencat/comp.c index 9c66d2b..8b65ad3 100644 --- a/gencat/comp.c +++ b/gencat/comp.c @@ -9,47 +9,13 @@ * (at your option) any later version. */ -#define _GNU_SOURCE /* for strcasecmp */ #include #include #include #include -#include -#include #include "util.h" -#include "comp.h" - - -struct entry { - struct name *names; - int units; - struct entry *next; -}; - -static struct lib { - const char *path; - struct entry *comps; - struct lib *next; -} *libs = NULL; - - -const char *lookup_sym(const char *name, const struct name **names, int *units) -{ - const struct lib *lib; - const struct entry *e; - - for (lib = libs; lib; lib = lib->next) - for (e = lib->comps; e; e = e->next) - if (!strcasecmp(e->names->s, name)) { - if (names) - *names = e->names; - if (units) - *units = e->units; - return lib->path; - } - return NULL; -} +#include "libs.h" static const char *field(const char *s, int n) @@ -64,25 +30,9 @@ static const char *field(const char *s, int n) } -static void add_name(struct entry *e, char *s) -{ - char *nl; - struct name **p; - - nl = strchr(s, '\n'); - if (nl) - *nl = 0; - for (p = &e->names; *p; p = &(*p)->next); - *p = alloc_type(struct name); - (*p)->s = stralloc(s); - (*p)->next = NULL; -} - - -void add_lib(const char *path) +static void add_comp_lib(struct lib *lib, const char *path) { FILE *file; - struct lib *lib; struct entry *e = NULL; char buf[1024]; /* @@@ */ char *name, *spc; @@ -94,12 +44,6 @@ void add_lib(const char *path) exit(1); } - lib = alloc_type(struct lib); - lib->path = stralloc(path); - lib->comps = NULL; - lib->next = libs; - libs = lib; - while (fgets(buf, sizeof(buf), file)) { if (!strncmp(buf, "ALIAS ", 6) && e) add_name(e, buf+6); @@ -120,49 +64,20 @@ void add_lib(const char *path) exit(1); } *spc = 0; - e = alloc_type(struct entry); - e->names = NULL; - add_name(e, name); - e->units = atoi(s); + e = new_entry(lib, atoi(s)); if (!e->units) { fprintf(stderr, "invalid number of units in %s\n", path); exit(1); } - e->next = lib->comps; - lib->comps = e; + add_name(e, name); } fclose(file); } -void add_libdir(const char *path) -{ - DIR *dir; - const struct dirent *de; - size_t len; - char *tmp; - - dir = opendir(path); - if (!dir) { - perror(path); - exit(1); - } - while (1) { - de = readdir(dir); - if (!de) - break; - len = strlen(de->d_name); - if (len < 4) - continue; - if (strcmp(de->d_name+len-4, ".lib")) - continue; - if (asprintf(&tmp, "%s/%s", path, de->d_name) < 0) { - perror("asprintf"); - exit(1); - } - add_lib(tmp); - } - closedir(dir); -} +struct lib comp_lib = { + .ext = ".lib", + .add_lib = add_comp_lib, +}; diff --git a/gencat/comp.h b/gencat/comp.h deleted file mode 100644 index 8305873..0000000 --- a/gencat/comp.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * comp.h - Component libraries - * - * 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. - */ - -#ifndef COMP_H -#define COMP_H - -struct name { - const char *s; - struct name *next; -}; - -const char *lookup_sym(const char *name, const struct name **names, int *units); -void add_lib(const char *path); -void add_libdir(const char *path); - -#endif /* !COMP_H */ diff --git a/gencat/gencat.c b/gencat/gencat.c index 3d6bd73..bf6cbe5 100644 --- a/gencat/gencat.c +++ b/gencat/gencat.c @@ -16,7 +16,7 @@ #include #include "tree.h" -#include "comp.h" +#include "libs.h" #include "pdf.h" #include "gencat.h" @@ -57,10 +57,10 @@ int main(int argc, char **argv) opt_dump_comp = 1; break; case 'L': - add_libdir(optarg); + add_libdir(&comp_lib, optarg); break; case 'l': - add_lib(optarg); + add_lib(&comp_lib, optarg); break; case 'P': postscript = 1; diff --git a/gencat/libs.c b/gencat/libs.c new file mode 100644 index 0000000..2350e13 --- /dev/null +++ b/gencat/libs.c @@ -0,0 +1,114 @@ +/* + * libc.h - Component or module libraries + * + * 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. + */ + +#define _GNU_SOURCE /* for strcasecmp */ +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "libs.h" + + +const char *lookup_sym(const struct lib *lib, const char *name, + const struct name **names, int *units) +{ + const struct file *file; + const struct entry *e; + + for (file = lib->files; file; file = file->next) + for (e = file->entries; e; e = e->next) + if (!strcasecmp(e->names->s, name)) { + if (names) + *names = e->names; + if (units) + *units = e->units; + return file->path; + } + return NULL; +} + + +void add_name(struct entry *e, char *s) +{ + char *nl; + struct name **p; + + nl = strchr(s, '\n'); + if (nl) + *nl = 0; + for (p = &e->names; *p; p = &(*p)->next); + *p = alloc_type(struct name); + (*p)->s = stralloc(s); + (*p)->next = NULL; +} + + +struct entry *new_entry(struct lib *lib, int units) +{ + struct entry *e; + + e = alloc_type(struct entry); + e->names = NULL; + e->units = units; + e->next = lib->files->entries; + lib->files->entries = e; + return e; +} + + +void add_lib(struct lib *lib, const char *path) +{ + struct file *file; + + file = alloc_type(struct file); + file->path = stralloc(path); + file->entries = NULL; + file->next = lib->files; + lib->files = file; + + lib->add_lib(lib, path); +} + + +void add_libdir(struct lib *lib, const char *path) +{ + DIR *dir; + const struct dirent *de; + size_t len; + char *tmp; + + assert(strlen(lib->ext) == 4); + dir = opendir(path); + if (!dir) { + perror(path); + exit(1); + } + while (1) { + de = readdir(dir); + if (!de) + break; + len = strlen(de->d_name); + if (len < 4) + continue; + if (strcmp(de->d_name+len-4, lib->ext)) + continue; + if (asprintf(&tmp, "%s/%s", path, de->d_name) < 0) { + perror("asprintf"); + exit(1); + } + add_lib(lib, tmp); + } + closedir(dir); +} diff --git a/gencat/libs.h b/gencat/libs.h new file mode 100644 index 0000000..37dd263 --- /dev/null +++ b/gencat/libs.h @@ -0,0 +1,49 @@ +/* + * libs.h - Component or module libraries + * + * 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. + */ + +#ifndef LIBS_H +#define LIBS_H + +struct name { + const char *s; + struct name *next; +}; + +struct entry { + struct name *names; + int units; + struct entry *next; +}; + +struct file { + const char *path; + struct entry *entries; + struct file *next; +}; + +struct lib { + const char *ext; /* file extension, ".lib" or ".mod" */ + void (*add_lib)(struct lib *lib, const char *path); + struct file *files; +}; + + +extern struct lib comp_lib; + + +const char *lookup_sym(const struct lib *lib, const char *name, + const struct name **names, int *units); +void add_name(struct entry *e, char *s); +struct entry *new_entry(struct lib *lib, int units); +void add_lib(struct lib *lib, const char *path); +void add_libdir(struct lib *lib, const char *path); + +#endif /* !LIBS_H */ diff --git a/gencat/pdf.c b/gencat/pdf.c index 5949189..3362052 100644 --- a/gencat/pdf.c +++ b/gencat/pdf.c @@ -18,6 +18,7 @@ #include "util.h" #include "gencat.h" #include "tree.h" +#include "libs.h" #include "pdf.h" diff --git a/gencat/tree.c b/gencat/tree.c index e74c21b..cd24d59 100644 --- a/gencat/tree.c +++ b/gencat/tree.c @@ -16,6 +16,7 @@ #include #include "util.h" +#include "libs.h" #include "tree.h" @@ -207,7 +208,7 @@ void set_libs(struct node *node) { while (node) { if (!node->child) { - node->lib = lookup_sym(node->name, + node->lib = lookup_sym(&comp_lib, node->name, &node->names, &node->units); if (!node->lib) { fprintf(stderr, "symbol %s not found\n", diff --git a/gencat/tree.h b/gencat/tree.h index 1eb5146..6463a97 100644 --- a/gencat/tree.h +++ b/gencat/tree.h @@ -12,9 +12,6 @@ #ifndef TREE_H #define TREE_H -#include "comp.h" - - struct line { char *s; struct line *next;