Tue Jun 25 02:59:11 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
[glibc.git] / nss / nss_files / files-parse.c
bloba93bee1ab3aee65014effc5066cb358dcc9f6298
1 /* Common code for file-based database parsers in nss_files module.
2 Copyright (C) 1996 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If
17 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
18 Cambridge, MA 02139, USA. */
20 #include <ctype.h>
21 #include <errno.h>
22 #include <string.h>
23 #include <stdlib.h>
26 #define CONCAT(a,b) CONCAT1(a,b)
27 #define CONCAT1(a,b) a##b
29 #ifndef STRUCTURE
30 #define STRUCTURE ENTNAME
31 #endif
34 struct parser_data
36 struct CONCAT(ENTNAME,_data) entdata;
37 char linebuffer[0];
40 #define LINE_PARSER(BODY) \
41 static inline int \
42 parse_line (char *line, struct STRUCTURE *result, \
43 struct parser_data *data, int datalen) \
44 { \
45 struct CONCAT(ENTNAME,_data) *const entdata __attribute__ ((unused)) \
46 = &data->entdata; \
47 BODY; \
48 TRAILING_LIST_PARSER; \
49 return 1; \
53 /* Comments can come mid-line; trim the line at the first # seen. */
54 #define MIDLINE_COMMENTS \
55 { \
56 char *p = strchr (line, '#'); \
57 if (p) \
58 *p = '\0'; \
61 #define STRING_FIELD(variable, terminator_p, swallow) \
62 { \
63 variable = line; \
64 while (!terminator_p (*line)) \
65 if (*++line == '\0') \
66 return 0; \
67 *line = '\0'; \
68 do \
69 ++line; \
70 while (swallow && terminator_p (*line)); \
73 #define INT_FIELD(variable, terminator_p, swallow, base, convert) \
74 { \
75 char *endp; \
76 variable = convert (strtol (line, &endp, base)); \
77 if (endp == line) \
78 return 0; \
79 else if (terminator_p (*endp)) \
80 do \
81 ++endp; \
82 while (swallow && terminator_p (*endp)); \
83 else if (*endp != '\0') \
84 return 0; \
85 line = endp; \
88 #define ISCOLON(c) ((c) == ':')
91 #ifndef TRAILING_LIST_MEMBER
92 #define TRAILING_LIST_PARSER /* Nothing to do. */
93 #else
95 #define TRAILING_LIST_PARSER \
96 { \
97 char **list = parse_list (line, data, datalen); \
98 if (list) \
99 result->TRAILING_LIST_MEMBER = list; \
100 else \
101 return 0; \
104 static inline char **
105 parse_list (char *line, struct parser_data *data, int datalen)
107 char *eol, **list, **p;
109 /* Find the end of the line buffer. */
110 eol = strchr (line, '\0');
111 /* Adjust the pointer so it is aligned for storing pointers. */
112 eol += (eol - (char *) 0) % __alignof__ (char *);
113 /* We will start the storage here for the vector of pointers. */
114 list = (char **) eol;
116 p = list;
117 while (1)
119 char *elt;
121 if ((char *) &p[1] - (char *) data > datalen)
123 /* We cannot fit another pointer in the buffer. */
124 errno = ERANGE;
125 return NULL;
127 if (*line == '\0')
128 break;
130 elt = line;
131 while (1)
133 if (TRAILING_LIST_SEPARATOR_P (*line))
135 *p++ = elt;
136 *line = '\0';
138 ++line;
139 while (TRAILING_LIST_SEPARATOR_P (*line));
141 else if (*line == '\0' || *line == '\n')
143 /* End of the line. */
144 if (line > elt)
145 /* Last element. */
146 *p++ = elt;
147 *line = '\0';
148 break;
150 else
151 ++line;
154 *p = NULL;
156 return list;
159 #define LOOKUP_NAME(nameelt, aliaselt) \
161 char **ap; \
162 if (! strcmp (name, result->nameelt)) \
163 break; \
164 for (ap = result->aliaselt; *ap; ++ap) \
165 if (! strcmp (name, *ap)) \
166 break; \
167 if (*ap) \
168 break; \
171 #endif