Date:2012-06-26 02:12:26 (11 years 9 months ago)
Author:Werner Almesberger
Commit:823b85f900b84765fc0fbe94cafdf385135a8880
Message:gencat/comp.*: renamed to tree.*

Files: gencat/Makefile (1 diff)
gencat/comp.c (1 diff)
gencat/comp.h (1 diff)
gencat/gencat.c (1 diff)
gencat/pdf.c (1 diff)
gencat/tree.c (1 diff)
gencat/tree.h (1 diff)

Change Details

gencat/Makefile
1111
1212PREFIX ?= /usr/local
1313
14OBJS = gencat.o comp.o libs.o pdf.o
14OBJS = gencat.o tree.o libs.o pdf.o
1515
1616SHELL = /bin/bash
1717CFLAGS = -Wall -g
gencat/comp.c
1/*
2 * comp.c - Component hierarchy
3 *
4 * Copyright 2012 by Werner Almesberger
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#define _GNU_SOURCE /* for strcasecmp */
13#include <stdlib.h>
14#include <stdio.h>
15#include <string.h>
16#include <ctype.h>
17
18#include "util.h"
19#include "comp.h"
20
21
22struct node *tree = NULL;
23
24
25void read_tree(FILE *file)
26{
27    char buf[1100]; /* more than enough */
28    struct node *last = NULL, *node;
29    int depth = -1;
30    const char *s, *p, *e;
31    char *name;
32    int n;
33
34next:
35    while (fgets(buf, sizeof(buf), file)) {
36        n = 0;
37        s = buf;
38        while (1) {
39            switch (*s++) {
40            case ' ':
41                n++;
42                continue;
43            case '\t':
44                n = (n+8) & ~7;
45                continue;
46            case 0:
47            case '#':
48                goto next;
49            default:
50                break;
51            }
52            break;
53        }
54        for (p = e = --s; *p && *p != '#' && *p != '\n'; p++)
55            if (*p != ' ' && *p != '\t')
56                e = p;
57        if (!last && n) {
58            fprintf(stderr, "first entry must not be intended\n");
59            exit(1);
60        }
61        name = malloc(e-s+2);
62        if (!name) {
63            perror("malloc");
64            exit(1);
65        }
66        memcpy(name, s, e-s+1);
67        name[e-s+1] = 0;
68        node = alloc_type(struct node);
69        node->name = name;
70        node->lib = NULL;
71        node->comment = NULL;
72        node->indent = n;
73        node->child = node->next = NULL;
74        if (n > depth) {
75            if (last)
76                last->child = node;
77            else
78                tree = node;
79            node->parent = last;
80        } else {
81            while (last && last->indent != n)
82                last = last->parent;
83            if (!last && n) {
84                fprintf(stderr, "indentation error\n");
85                exit(1);
86            }
87            last->next = node;
88            node->parent = last->parent;
89        }
90        last = node;
91        depth = n;
92    }
93}
94
95
96static struct node *find_comp(struct node *node, const char *name)
97{
98    struct node *found;
99
100    while (node) {
101        if (!strcasecmp(node->name, name))
102            return node;
103        found = find_comp(node->child, name);
104        if (found)
105            return found;
106        node = node->next;
107    }
108    return NULL;
109}
110
111
112static struct line *new_line(char *s)
113{
114    struct line *line;
115
116    line = alloc_type(struct line);
117    line->s = stralloc(s);
118    line->next = NULL;
119    return line;
120}
121
122
123static void append_line(struct line *line, char *s)
124{
125    int len1, len2;
126
127    len1 = strlen(line->s);
128    len2 = strlen(s);
129    line->s = realloc(line->s, len1+len2+1+1); /* separating space */
130    if (!line->s) {
131        perror("realloc");
132        exit(1);
133    }
134    line->s[len1] = ' ';
135    memcpy(line->s+len1+1, s, len2);
136    line->s[len1+len2+1] = 0;
137}
138
139
140void read_desc(FILE *file)
141{
142    struct line **anchor = NULL;
143    char buf[1100]; /* more than enough */
144    struct node *node;
145    char *p, *end;
146    int skip = 0, lineno = 0;
147
148    while (fgets(buf, sizeof(buf), file)) {
149        lineno++;
150        p = strchr(buf, '\n');
151        if (p)
152            *p = 0;
153        p = buf;
154        if (*buf && !isspace(*buf)) {
155            /* tag is ^.*?:\s */
156            while (1) {
157                p = strchr(p, ':');
158                if (!p) {
159                    fprintf(stderr, "no tag in line %d\n",
160                        lineno);
161                    exit(1);
162                }
163                if (!p[1] || isspace(p[1]))
164                    break;
165                p++;
166            }
167            *p++ = 0;
168            node = find_comp(tree, buf);
169            if (!node) {
170                fprintf(stderr,
171                    "component \"%s\" not found in line %d\n",
172                    buf, lineno);
173                skip = 1;
174                continue;
175            }
176            for (anchor = &node->comment; *anchor;
177                anchor = &(*anchor)->next);
178            skip = 0;
179        }
180        if (skip)
181            continue;
182
183        /* remove leading whitespace */
184        while (*p && isspace(*p))
185            p++;
186        if (!*p) {
187            if (*anchor)
188                anchor = &(*anchor)->next;
189            continue;
190        }
191
192        /* remove training whitespace */
193        end = strrchr(p, 0);
194        while (isspace(end[-1]))
195            end--;
196        *end = 0;
197
198        if (*anchor)
199            append_line(*anchor, p);
200        else
201            *anchor = new_line(p);
202    }
203}
204
205
206void set_libs(struct node *node,
207    const char *(*find_lib)(const char *sym, const struct name **names,
208    int *units))
209{
210    while (node) {
211        if (!node->child) {
212            node->lib =
213                find_lib(node->name, &node->names, &node->units);
214            if (!node->lib) {
215                fprintf(stderr, "symbol %s not found\n",
216                    node->name);
217                exit(1);
218            }
219        }
220        set_libs(node->child, find_lib);
221        node = node->next;
222    }
223}
224
225
226static void dump_tree_level(const struct node *tree, int level)
227{
228    const struct node *n;
229    const struct line *line;
230    const struct name *name;
231
232    for (n = tree; n; n = n->next) {
233        printf("%*s%s", 4*level, "", n->name);
234        if (n->lib) {
235            for (name = n->names; name; name = name->next)
236                printf("%s%s",
237                    name == n->names ? " (" : ", ", name->s);
238            printf(")");
239        }
240        printf("\n");
241        for (line = n->comment; line; line = line->next)
242            printf("%*s\"%s\"\n", 4*level+2, "", line->s);
243        dump_tree_level(n->child, level+1);
244    }
245}
246
247
248void dump_tree(void)
249{
250    dump_tree_level(tree, 0);
251}
252
253
254static void dump_comp_level(const struct node *tree)
255{
256    const struct node *n;
257
258    for (n = tree; n; n = n->next) {
259        if (n->lib)
260            printf("%s\n", n->names->s);
261        dump_comp_level(n->child);
262    }
263}
264
265
266void dump_comp(void)
267{
268    dump_comp_level(tree);
269}
gencat/comp.h
1/*
2 * comp.h - Component hierarchy
3 *
4 * Copyright 2012 by Werner Almesberger
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#ifndef COMP_H
13#define COMP_H
14
15#include "libs.h"
16
17
18struct line {
19    char *s;
20    struct line *next;
21};
22
23struct node {
24    const char *name;
25    const char *lib; /* NULL if intermediate node */
26    const struct name *names;
27                /* canonical name and aliases of component */
28    int units; /* number of units; undefined if intermediate */
29    struct line *comment; /* NULL if intermediate node */
30    int indent; /* level of indentation (characters) */
31    struct node *parent;
32    struct node *child;
33    struct node *next;
34};
35
36
37extern struct node *tree;
38
39
40void read_tree(FILE *file);
41void read_desc(FILE *file);
42void set_libs(struct node *node,
43    const char *(*find_lib)(const char *sym, const struct name **names,
44    int *units));
45void dump_tree(void);
46void dump_comp(void);
47
48#endif /* !COMP_H */
gencat/gencat.c
1515#include <unistd.h>
1616#include <string.h>
1717
18#include "comp.h"
18#include "tree.h"
1919#include "libs.h"
2020#include "pdf.h"
2121#include "gencat.h"
gencat/pdf.c
1515#include <sys/types.h>
1616
1717#include "gencat.h"
18#include "comp.h"
18#include "tree.h"
1919#include "pdf.h"
2020
2121
gencat/tree.c
1/*
2 * tree.c - Component hierarchy
3 *
4 * Copyright 2012 by Werner Almesberger
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#define _GNU_SOURCE /* for strcasecmp */
13#include <stdlib.h>
14#include <stdio.h>
15#include <string.h>
16#include <ctype.h>
17
18#include "util.h"
19#include "tree.h"
20
21
22struct node *tree = NULL;
23
24
25void read_tree(FILE *file)
26{
27    char buf[1100]; /* more than enough */
28    struct node *last = NULL, *node;
29    int depth = -1;
30    const char *s, *p, *e;
31    char *name;
32    int n;
33
34next:
35    while (fgets(buf, sizeof(buf), file)) {
36        n = 0;
37        s = buf;
38        while (1) {
39            switch (*s++) {
40            case ' ':
41                n++;
42                continue;
43            case '\t':
44                n = (n+8) & ~7;
45                continue;
46            case 0:
47            case '#':
48                goto next;
49            default:
50                break;
51            }
52            break;
53        }
54        for (p = e = --s; *p && *p != '#' && *p != '\n'; p++)
55            if (*p != ' ' && *p != '\t')
56                e = p;
57        if (!last && n) {
58            fprintf(stderr, "first entry must not be intended\n");
59            exit(1);
60        }
61        name = malloc(e-s+2);
62        if (!name) {
63            perror("malloc");
64            exit(1);
65        }
66        memcpy(name, s, e-s+1);
67        name[e-s+1] = 0;
68        node = alloc_type(struct node);
69        node->name = name;
70        node->lib = NULL;
71        node->comment = NULL;
72        node->indent = n;
73        node->child = node->next = NULL;
74        if (n > depth) {
75            if (last)
76                last->child = node;
77            else
78                tree = node;
79            node->parent = last;
80        } else {
81            while (last && last->indent != n)
82                last = last->parent;
83            if (!last && n) {
84                fprintf(stderr, "indentation error\n");
85                exit(1);
86            }
87            last->next = node;
88            node->parent = last->parent;
89        }
90        last = node;
91        depth = n;
92    }
93}
94
95
96static struct node *find_comp(struct node *node, const char *name)
97{
98    struct node *found;
99
100    while (node) {
101        if (!strcasecmp(node->name, name))
102            return node;
103        found = find_comp(node->child, name);
104        if (found)
105            return found;
106        node = node->next;
107    }
108    return NULL;
109}
110
111
112static struct line *new_line(char *s)
113{
114    struct line *line;
115
116    line = alloc_type(struct line);
117    line->s = stralloc(s);
118    line->next = NULL;
119    return line;
120}
121
122
123static void append_line(struct line *line, char *s)
124{
125    int len1, len2;
126
127    len1 = strlen(line->s);
128    len2 = strlen(s);
129    line->s = realloc(line->s, len1+len2+1+1); /* separating space */
130    if (!line->s) {
131        perror("realloc");
132        exit(1);
133    }
134    line->s[len1] = ' ';
135    memcpy(line->s+len1+1, s, len2);
136    line->s[len1+len2+1] = 0;
137}
138
139
140void read_desc(FILE *file)
141{
142    struct line **anchor = NULL;
143    char buf[1100]; /* more than enough */
144    struct node *node;
145    char *p, *end;
146    int skip = 0, lineno = 0;
147
148    while (fgets(buf, sizeof(buf), file)) {
149        lineno++;
150        p = strchr(buf, '\n');
151        if (p)
152            *p = 0;
153        p = buf;
154        if (*buf && !isspace(*buf)) {
155            /* tag is ^.*?:\s */
156            while (1) {
157                p = strchr(p, ':');
158                if (!p) {
159                    fprintf(stderr, "no tag in line %d\n",
160                        lineno);
161                    exit(1);
162                }
163                if (!p[1] || isspace(p[1]))
164                    break;
165                p++;
166            }
167            *p++ = 0;
168            node = find_comp(tree, buf);
169            if (!node) {
170                fprintf(stderr,
171                    "component \"%s\" not found in line %d\n",
172                    buf, lineno);
173                skip = 1;
174                continue;
175            }
176            for (anchor = &node->comment; *anchor;
177                anchor = &(*anchor)->next);
178            skip = 0;
179        }
180        if (skip)
181            continue;
182
183        /* remove leading whitespace */
184        while (*p && isspace(*p))
185            p++;
186        if (!*p) {
187            if (*anchor)
188                anchor = &(*anchor)->next;
189            continue;
190        }
191
192        /* remove training whitespace */
193        end = strrchr(p, 0);
194        while (isspace(end[-1]))
195            end--;
196        *end = 0;
197
198        if (*anchor)
199            append_line(*anchor, p);
200        else
201            *anchor = new_line(p);
202    }
203}
204
205
206void set_libs(struct node *node,
207    const char *(*find_lib)(const char *sym, const struct name **names,
208    int *units))
209{
210    while (node) {
211        if (!node->child) {
212            node->lib =
213                find_lib(node->name, &node->names, &node->units);
214            if (!node->lib) {
215                fprintf(stderr, "symbol %s not found\n",
216                    node->name);
217                exit(1);
218            }
219        }
220        set_libs(node->child, find_lib);
221        node = node->next;
222    }
223}
224
225
226static void dump_tree_level(const struct node *tree, int level)
227{
228    const struct node *n;
229    const struct line *line;
230    const struct name *name;
231
232    for (n = tree; n; n = n->next) {
233        printf("%*s%s", 4*level, "", n->name);
234        if (n->lib) {
235            for (name = n->names; name; name = name->next)
236                printf("%s%s",
237                    name == n->names ? " (" : ", ", name->s);
238            printf(")");
239        }
240        printf("\n");
241        for (line = n->comment; line; line = line->next)
242            printf("%*s\"%s\"\n", 4*level+2, "", line->s);
243        dump_tree_level(n->child, level+1);
244    }
245}
246
247
248void dump_tree(void)
249{
250    dump_tree_level(tree, 0);
251}
252
253
254static void dump_comp_level(const struct node *tree)
255{
256    const struct node *n;
257
258    for (n = tree; n; n = n->next) {
259        if (n->lib)
260            printf("%s\n", n->names->s);
261        dump_comp_level(n->child);
262    }
263}
264
265
266void dump_comp(void)
267{
268    dump_comp_level(tree);
269}
gencat/tree.h
1/*
2 * tree.h - Component hierarchy
3 *
4 * Copyright 2012 by Werner Almesberger
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#ifndef TREE_H
13#define TREE_H
14
15#include "libs.h"
16
17
18struct line {
19    char *s;
20    struct line *next;
21};
22
23struct node {
24    const char *name;
25    const char *lib; /* NULL if intermediate node */
26    const struct name *names;
27                /* canonical name and aliases of component */
28    int units; /* number of units; undefined if intermediate */
29    struct line *comment; /* NULL if intermediate node */
30    int indent; /* level of indentation (characters) */
31    struct node *parent;
32    struct node *child;
33    struct node *next;
34};
35
36
37extern struct node *tree;
38
39
40void read_tree(FILE *file);
41void read_desc(FILE *file);
42void set_libs(struct node *node,
43    const char *(*find_lib)(const char *sym, const struct name **names,
44    int *units));
45void dump_tree(void);
46void dump_comp(void);
47
48#endif /* !TREE_H */

Archive Download the corresponding diff file

Branches:
master



interactive