Commit | Line | Data |
---|---|---|
1ef31675 | 1 | /* |
00186a84 KB |
2 | * Copyright (c) 1989, 1993 |
3 | * The Regents of the University of California. All rights reserved. | |
1ef31675 | 4 | * |
f15db449 | 5 | * %sccs.include.redist.c% |
1ef31675 KB |
6 | */ |
7 | ||
8 | #ifndef lint | |
da0c0e56 | 9 | static char sccsid[] = "@(#)config.c 8.2 (Berkeley) %G%"; |
1ef31675 KB |
10 | #endif /* not lint */ |
11 | ||
da0c0e56 KB |
12 | #include <sys/types.h> |
13 | #include <sys/queue.h> | |
14 | ||
15 | #include <ctype.h> | |
16 | #include <err.h> | |
1ef31675 | 17 | #include <errno.h> |
da0c0e56 | 18 | #include <stdio.h> |
011519cd | 19 | #include <stdlib.h> |
da0c0e56 | 20 | #include <string.h> |
011519cd | 21 | |
da0c0e56 KB |
22 | #include "config.h" |
23 | #include "pathnames.h" | |
1ef31675 | 24 | |
da0c0e56 | 25 | struct queue_entry head; |
011519cd | 26 | |
1ef31675 | 27 | /* |
da0c0e56 KB |
28 | * config -- |
29 | * | |
30 | * Read the configuration file and build a doubly linked | |
31 | * list that looks like: | |
32 | * | |
33 | * tag1 <-> record <-> record <-> record | |
34 | * | | |
35 | * tag2 <-> record <-> record <-> record | |
1ef31675 | 36 | */ |
da0c0e56 KB |
37 | void |
38 | config() | |
1ef31675 | 39 | { |
da0c0e56 KB |
40 | ENTRY *ep, *qp; |
41 | FILE *cfp; | |
011519cd | 42 | size_t len; |
da0c0e56 KB |
43 | int lcnt; |
44 | char *p, *t; | |
45 | ||
46 | if ((cfp = fopen(_PATH_MANCONF, "r")) == NULL) | |
47 | err(1, "%s", _PATH_MANCONF); | |
48 | queue_init(&head); | |
49 | for (lcnt = 1; (p = fgetline(cfp, &len)) != NULL; ++lcnt) { | |
50 | if (!len) /* Skip empty lines. */ | |
51 | continue; | |
52 | if (p[len - 1] != '\n') { /* Skip corrupted lines. */ | |
53 | warnx("%s: line %d corrupted", _PATH_MANCONF, lcnt); | |
54 | continue; | |
011519cd | 55 | } |
da0c0e56 KB |
56 | p[len - 1] = '\0'; /* Terminate the line. */ |
57 | ||
58 | /* Skip leading space. */ | |
59 | for (; *p != '\0' && isspace(*p); ++p); | |
60 | /* Skip empty/comment lines. */ | |
61 | if (*p == '\0' || *p == '#') | |
011519cd | 62 | continue; |
da0c0e56 KB |
63 | /* Find first token. */ |
64 | for (t = p; *t && !isspace(*t); ++t); | |
65 | if (*t == '\0') /* Need more than one token.*/ | |
011519cd | 66 | continue; |
da0c0e56 KB |
67 | *t = '\0'; |
68 | ||
69 | for (qp = head.qe_next; /* Find any matching tag. */ | |
70 | qp != NULL && strcmp(p, qp->s); qp = qp->tags.qe_next); | |
71 | ||
72 | if (qp == NULL) /* Create a new tag. */ | |
73 | qp = addlist(p); | |
74 | ||
75 | /* | |
76 | * Attach new records. The keyword _build takes the rest of | |
77 | * the line as a single entity, everything else is white | |
78 | * space separated. The reason we're not just using strtok(3) | |
79 | * for all of the parsing is so we don't get caught if a line | |
80 | * has only a single token on it. | |
81 | */ | |
82 | if (!strcmp(p, "_build")) { | |
83 | while (*++t && isspace(*t)); | |
84 | if ((ep = malloc(sizeof(ENTRY))) == NULL || | |
85 | (ep->s = strdup(t)) == NULL) | |
86 | err(1, NULL); | |
87 | queue_enter_tail(&qp->list, ep, ENTRY *, list); | |
88 | } else while ((p = strtok(t + 1, " \t\n")) != NULL) { | |
89 | if ((ep = malloc(sizeof(ENTRY))) == NULL || | |
90 | (ep->s = strdup(p)) == NULL) | |
91 | err(1, NULL); | |
92 | queue_enter_tail(&qp->list, ep, ENTRY *, list); | |
93 | t = NULL; | |
011519cd KB |
94 | } |
95 | } | |
011519cd | 96 | } |
1ef31675 | 97 | |
da0c0e56 KB |
98 | /* |
99 | * addlist -- | |
100 | * Add a tag to the list. | |
101 | */ | |
102 | ENTRY * | |
103 | addlist(name) | |
104 | char *name; | |
011519cd | 105 | { |
da0c0e56 KB |
106 | ENTRY *ep; |
107 | ||
108 | if ((ep = malloc(sizeof(ENTRY))) == NULL || | |
109 | (ep->s = strdup(name)) == NULL) | |
110 | err(1, NULL); | |
111 | queue_init(&ep->list); | |
112 | queue_enter_head(&head, ep, ENTRY *, tags); | |
113 | return (head.qe_next); | |
011519cd KB |
114 | } |
115 | ||
da0c0e56 KB |
116 | /* |
117 | * getlist -- | |
118 | * Return the linked list for a tag if it exists. | |
119 | */ | |
120 | ENTRY * | |
121 | getlist(name) | |
122 | char *name; | |
011519cd | 123 | { |
da0c0e56 | 124 | ENTRY *qp; |
011519cd | 125 | |
da0c0e56 KB |
126 | for (qp = head.qe_next; qp != NULL; qp = qp->tags.qe_next) |
127 | if (!strcmp(name, qp->s)) | |
128 | return (qp); | |
129 | return (NULL); | |
1ef31675 KB |
130 | } |
131 | ||
da0c0e56 KB |
132 | void |
133 | debug(l) | |
134 | char *l; | |
011519cd | 135 | { |
da0c0e56 | 136 | ENTRY *ep, *qp; |
011519cd | 137 | |
da0c0e56 KB |
138 | (void)printf("%s ===============\n", l); |
139 | for (qp = head.qe_next; qp != NULL; qp = qp->tags.qe_next) { | |
140 | printf("%s\n", qp->s); | |
141 | for (ep = qp->list.qe_next; ep != NULL; ep = ep->list.qe_next) | |
142 | printf("\t%s\n", ep->s); | |
011519cd | 143 | } |
1ef31675 | 144 | } |