/* * libs.c - 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. */ #define _GNU_SOURCE /* for strcasecmp */ #include #include #include #include #include #include #include "util.h" #include "libs.h" struct entry { const char *name; 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 char **canon, 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->name, name)) { if (canon) *canon = e->name; if (units) *units = e->units; return lib->path; } return NULL; } static const char *field(const char *s, int n) { while (n-- && *s) { while (*s && !isspace(*s)) s++; while (*s && isspace(*s)) s++; } return *s ? s : NULL; } void add_lib(const char *path) { FILE *file; struct lib *lib; struct entry *e; char buf[1024]; /* @@@ */ char *spc; const char *s; file = fopen(path, "r"); if (!file) { perror(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, "DEF ", 4)) continue; s = field(buf, 7); if (!s) { fprintf(stderr, "DEF record lacks units field in %s\n", path); exit(1); } spc = strchr(buf+4, ' '); if (!spc) { fprintf(stderr, "invalid DEF line in %s\n", path); exit(1); } *spc = 0; e = alloc_type(struct entry); e->name = stralloc(buf+4); e->units = atoi(s); if (!e->units) { fprintf(stderr, "invalid number of units in %s\n", path); exit(1); } e->next = lib->comps; lib->comps = e; } 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); }