7712 mandoc -Tlint does always exit with error code 0
[unleashed.git] / usr / src / lib / lvm / libmeta / common / meta_tab.c
blob06b31646e2ff687569990330ab7d778fd23646ce
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
29 * Just in case we're not in a build environment, make sure that
30 * TEXT_DOMAIN gets set to something.
32 #if !defined(TEXT_DOMAIN)
33 #define TEXT_DOMAIN "SYS_TEST"
34 #endif
36 #include <meta.h>
38 #include <ctype.h>
41 * free md.tab struct
43 void
44 meta_tab_free(
45 md_tab_t *tabp
48 size_t line;
50 Free(tabp->filename);
51 Free(tabp->data);
52 if (tabp->lines != NULL) {
53 assert(tabp->alloc > 0);
54 for (line = 0; (line < tabp->nlines); ++line) {
55 md_tab_line_t *linep = &tabp->lines[line];
57 if (linep->context != NULL)
58 Free(linep->context);
59 if (linep->cname != NULL)
60 Free(linep->cname);
61 if (linep->argv != NULL) {
62 assert(linep->alloc > 0);
63 Free(linep->argv);
66 Free(tabp->lines);
68 Free(tabp);
72 * (re)allocate argv array
74 static void
75 realloc_argv(
76 md_tab_line_t *linep,
77 size_t argc
80 /* allocate in chunks */
81 argc = roundup(argc, TAB_ARG_ALLOC);
82 if (argc < linep->alloc)
83 return;
85 /* (re)allocate */
86 if (linep->alloc == 0) {
87 linep->argv = Malloc(argc * sizeof (*linep->argv));
88 } else {
89 assert(linep->argv != NULL);
90 linep->argv =
91 Realloc(linep->argv, (argc * sizeof (*linep->argv)));
94 /* zero out new stuff */
95 (void) memset(&linep->argv[linep->alloc], 0,
96 ((argc - linep->alloc) * sizeof (*linep->argv)));
98 /* adjust for new size */
99 linep->alloc = argc;
103 * (re)allocate line array
105 static void
106 realloc_lines(
107 md_tab_t *tabp,
108 size_t nlines
111 /* allocate in chunks */
112 nlines = roundup(nlines, TAB_LINE_ALLOC);
113 if (nlines < tabp->alloc)
114 return;
116 /* (re)allocate */
117 if (tabp->alloc == 0) {
118 assert(tabp->lines == NULL);
119 tabp->lines = Malloc(nlines * sizeof (*tabp->lines));
120 } else {
121 assert(tabp->lines != NULL);
122 tabp->lines =
123 Realloc(tabp->lines, (nlines * sizeof (*tabp->lines)));
126 /* zero out new stuff */
127 (void) memset(&tabp->lines[tabp->alloc], 0,
128 ((nlines - tabp->alloc) * sizeof (*tabp->lines)));
130 /* adjust for new size */
131 tabp->alloc = nlines;
135 * parse up md.tab struct
137 static void
138 parse_tab(
139 md_tab_t *tabp,
140 char *metatab_name,
141 md_error_t *ep
144 uint_t lineno = 1;
145 char *p = tabp->data;
146 char *e = tabp->data + tabp->total - 1;
147 char *context;
148 size_t len;
150 /* we can count on '\n\0' as the last characters */
151 assert(tabp->total >= 2);
152 assert(tabp->data[tabp->total - 2] == '\n');
153 assert(tabp->data[tabp->total - 1] == '\0');
155 /* allocate context buffer "file line XXX" */
156 assert(tabp->filename != NULL);
157 len = strlen(tabp->filename) +
158 strlen(dgettext(TEXT_DOMAIN, "%s line %u")) + 20 + 1;
159 context = Malloc(len);
161 /* parse lines */
162 while (p < e && *p != '\0') {
163 md_tab_line_t *linep;
164 char *t;
166 /* allocate new line */
167 realloc_lines(tabp, (tabp->nlines + 1));
168 linep = &tabp->lines[tabp->nlines];
169 (void) snprintf(context, len,
170 dgettext(TEXT_DOMAIN, "%s line %u"), tabp->filename,
171 lineno);
173 /* comments */
174 if (*p == '#') {
175 while (*p != '\n')
176 ++p;
179 /* coalesce \ continuations */
180 t = p;
181 while (*t != '\n') {
182 if ((*t == '\\') && (*(t + 1) == '\n')) {
183 *t++ = ' ';
184 *t = ' ';
185 ++lineno;
187 ++t;
190 /* leading whitespace */
191 while ((*p != '\n') && (isspace(*p)))
192 ++p;
194 /* count lines */
195 if (*p == '\n') {
196 ++p;
197 ++lineno;
198 continue;
201 /* tokenize line */
202 while ((p < e) && (*p != '\n')) {
203 char **argvp;
205 /* allocate new token */
206 realloc_argv(linep, (linep->argc + 1));
207 argvp = &linep->argv[linep->argc++];
209 /* find end of token */
210 *argvp = p;
211 while ((*p != '\n') && (! isspace(*p)))
212 ++p;
214 /* terminate */
215 if (*p == '\n') {
216 *p++ = '\0';
217 ++lineno;
218 break;
221 /* eat white space */
222 *p++ = '\0';
223 while ((p < e) && (*p != '\n') && (isspace(*p)))
224 ++p;
226 tabp->nlines++;
228 /* fill in the rest */
229 assert((linep->argc > 0) && (linep->argv != NULL) &&
230 (linep->argv[0][0] != '\0') &&
231 (! isspace(linep->argv[0][0])));
232 linep->context = Strdup(context);
233 linep->type = meta_get_init_type(linep->argc, linep->argv);
234 linep->cname = meta_canonicalize(NULL, linep->argv[0]);
235 /* if cname is NULL then the meta/hsp name is invalid */
236 if (linep->cname == NULL) {
237 (void) mderror(ep, MDE_SYNTAX, metatab_name);
238 break;
242 /* cleanup */
243 Free(context);
247 * read in md.tab file and return struct
249 md_tab_t *
250 meta_tab_parse(
251 char *filename,
252 md_error_t *ep
255 md_tab_t *tabp = NULL;
256 int fd = -1;
257 struct stat statbuf;
258 size_t sofar;
259 char *p;
261 /* open tab file */
262 if (filename == NULL)
263 filename = METATAB;
264 if ((fd = open(filename, O_RDONLY, 0)) < 0) {
265 (void) mdsyserror(ep, errno, filename);
266 goto out;
268 if (fstat(fd, &statbuf) != 0) {
269 (void) mdsyserror(ep, errno, filename);
270 goto out;
273 /* allocate table */
274 tabp = Zalloc(sizeof (*tabp));
275 tabp->filename = Strdup(filename);
276 tabp->total = statbuf.st_size + 2; /* terminating "\n\0" */
277 tabp->data = Malloc(tabp->total);
279 /* read in data */
280 sofar = 0;
281 p = tabp->data;
282 while (sofar < statbuf.st_size) {
283 int cnt;
285 if ((cnt = read(fd, p, 8192)) < 0) {
286 (void) mdsyserror(ep, errno, filename);
287 goto out;
288 } else if (cnt == 0) {
289 (void) mderror(ep, MDE_SYNTAX, filename);
290 goto out;
292 sofar += cnt;
293 p += cnt;
295 tabp->data[tabp->total - 2] = '\n';
296 tabp->data[tabp->total - 1] = '\0';
298 /* close file */
299 if (close(fd) != 0) {
300 (void) mdsyserror(ep, errno, filename);
301 fd = -1;
302 goto out;
304 fd = -1;
306 /* parse it up */
307 parse_tab(tabp, filename, ep);
309 /* return success if file was correctly parsed */
310 if (mdisok(ep))
311 return (tabp);
313 /* cleanup, return error */
314 out:
315 if (fd >= 0)
316 (void) close(fd);
317 if (tabp != NULL)
318 meta_tab_free(tabp);
319 return (NULL);
323 * find line in md.tab
325 md_tab_line_t *
326 meta_tab_find(
327 mdsetname_t *sp,
328 md_tab_t *tabp,
329 char *name,
330 mdinittypes_t type
333 char *cname = meta_canonicalize(sp, name);
334 size_t line;
336 /* if name is not legal meta name then return NULL */
337 if (cname == NULL)
338 return (NULL);
340 for (line = 0; (line < tabp->nlines); ++line) {
341 md_tab_line_t *linep = &tabp->lines[line];
343 assert((linep->argc > 0) && (linep->argv[0] != NULL));
344 if (((linep->type & type) != 0) &&
345 (strcmp(linep->cname, cname) == 0)) {
346 Free(cname);
347 return (linep);
350 Free(cname);
351 return (NULL);