1 /*
2 * Copyright 2000
3 * Traakan, Inc., Los Altos, CA
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice unmodified, this list of conditions, and the following
11 * disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29 /*
30 * Project: NDMJOB
31 * Ident: $Id: $
32 *
33 * Description:
34 * Stanza files look about like this:
35 * [stanza name line]
36 * stanza body lines
37 *
38 * These are used for config files.
39 */
40
41
42 #include "ndmlib.h"
43
44
ndmstz_getline(FILE * fp,char * buf,int n_buf)45 int ndmstz_getline(FILE* fp, char* buf, int n_buf)
46 {
47 int c;
48 char* p;
49
50 again:
51 c = getc(fp);
52 if (c == EOF) return EOF;
53
54 if (c == '[') {
55 /* end-of-stanza */
56 ungetc(c, fp);
57 return -2;
58 }
59
60 if (c == '#') {
61 /* comment */
62 while ((c = getc(fp)) != EOF && c != '\n') continue;
63 goto again;
64 }
65
66 ungetc(c, fp);
67 p = buf;
68 while ((c = getc(fp)) != EOF && c != '\n') {
69 if (p < &buf[n_buf - 1]) *p++ = c;
70 }
71 *p = 0;
72 return p - buf;
73 }
74
ndmstz_getstanza(FILE * fp,char * buf,int n_buf)75 int ndmstz_getstanza(FILE* fp, char* buf, int n_buf)
76 {
77 int c;
78 char* p;
79
80 again:
81 c = getc(fp);
82 if (c == EOF) return EOF;
83
84 if (c == '\n') goto again; /* blank line */
85
86 if (c != '[') {
87 /* not a stanza header, eat line */
88 while ((c = getc(fp)) != EOF && c != '\n') continue;
89 goto again;
90 }
91
92 p = buf;
93 while ((c = getc(fp)) != EOF && c != '\n' && c != ']') {
94 if (p < &buf[n_buf - 1]) *p++ = c;
95 }
96 *p = 0;
97
98 if (c == ']') {
99 /* eat rest of line */
100 while ((c = getc(fp)) != EOF && c != '\n') continue;
101 }
102
103 /* fp is left pointing to begining of first line */
104
105 return p - buf;
106 }
107
ndmstz_parse(char * buf,char * argv[],int max_argv)108 int ndmstz_parse(char* buf, char* argv[], int max_argv)
109 {
110 char* p = buf;
111 char* q = buf;
112 int inword = 0;
113 int inquote = 0;
114 int argc = 0;
115 int c;
116
117 while ((c = *p++) != 0) {
118 if (inquote) {
119 if (c == inquote) {
120 inquote = 0;
121 } else {
122 *q++ = c;
123 }
124 continue;
125 }
126
127 if (isspace(c)) {
128 if (inword) {
129 *q++ = 0;
130 inword = 0;
131 }
132 continue;
133 }
134
135 if (!inword) {
136 if (argc > max_argv - 1) break;
137 argv[argc++] = q;
138 inword = 1;
139 }
140
141 if (c == '"' || c == '\'') {
142 inquote = c;
143 continue;
144 }
145
146 *q++ = c;
147 }
148 if (inword) *q++ = 0;
149 argv[argc] = 0;
150
151 return argc;
152 }
153
154
155 #ifdef SELF_TEST
156
main(int ac,char * av[])157 int main(int ac, char* av[])
158 {
159 int i, found, argc;
160 FILE* fp;
161 char buf[512];
162 char* argv[100];
163
164 if (ac < 2) {
165 printf("bad usage\n");
166 return 1;
167 }
168
169 fp = fopen(av[1], "r");
170 if (!fp) {
171 perror(av[1]);
172 return 2;
173 }
174
175 if (ac == 2) {
176 while (ndmstz_getstanza(fp, buf, sizeof buf) >= 0) printf("%s\n", buf);
177 } else {
178 for (i = 2; i < ac; i++) {
179 rewind(fp);
180 found = 0;
181 while (ndmstz_getstanza(fp, buf, sizeof buf) >= 0) {
182 if (strcmp(av[i], buf) == 0) {
183 found = 1;
184 break;
185 }
186 }
187 if (!found) {
188 printf("Search for '%s' failed\n", av[i]);
189 continue;
190 }
191 printf("'%s'\n", buf);
192 printf("========================================\n");
193 while (ndmstz_getline(fp, buf, sizeof buf) >= 0) {
194 printf("= %s", buf);
195 argc = ndmstz_parse(buf, argv, 100);
196 printf(" [%d]\n", argc);
197 }
198 printf("========================================\n");
199 }
200 }
201
202 fclose(fp);
203
204 return 0;
205 }
206
207 #endif /* SELF_TEST */
208