xref: /freebsd/contrib/tcsh/gethost.c (revision c80476e4c3e6730697b9424f88dfa74d1907cabd)
1c80476e4SDavid E. O'Brien /* $Header: /src/pub/tcsh/gethost.c,v 1.7 1997/10/28 22:34:19 christos Exp $ */
2c80476e4SDavid E. O'Brien /*
3c80476e4SDavid E. O'Brien  * gethost.c: Create version file from prototype
4c80476e4SDavid E. O'Brien  */
5c80476e4SDavid E. O'Brien /*-
6c80476e4SDavid E. O'Brien  * Copyright (c) 1980, 1991 The Regents of the University of California.
7c80476e4SDavid E. O'Brien  * All rights reserved.
8c80476e4SDavid E. O'Brien  *
9c80476e4SDavid E. O'Brien  * Redistribution and use in source and binary forms, with or without
10c80476e4SDavid E. O'Brien  * modification, are permitted provided that the following conditions
11c80476e4SDavid E. O'Brien  * are met:
12c80476e4SDavid E. O'Brien  * 1. Redistributions of source code must retain the above copyright
13c80476e4SDavid E. O'Brien  *    notice, this list of conditions and the following disclaimer.
14c80476e4SDavid E. O'Brien  * 2. Redistributions in binary form must reproduce the above copyright
15c80476e4SDavid E. O'Brien  *    notice, this list of conditions and the following disclaimer in the
16c80476e4SDavid E. O'Brien  *    documentation and/or other materials provided with the distribution.
17c80476e4SDavid E. O'Brien  * 3. All advertising materials mentioning features or use of this software
18c80476e4SDavid E. O'Brien  *    must display the following acknowledgement:
19c80476e4SDavid E. O'Brien  *	This product includes software developed by the University of
20c80476e4SDavid E. O'Brien  *	California, Berkeley and its contributors.
21c80476e4SDavid E. O'Brien  * 4. Neither the name of the University nor the names of its contributors
22c80476e4SDavid E. O'Brien  *    may be used to endorse or promote products derived from this software
23c80476e4SDavid E. O'Brien  *    without specific prior written permission.
24c80476e4SDavid E. O'Brien  *
25c80476e4SDavid E. O'Brien  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26c80476e4SDavid E. O'Brien  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27c80476e4SDavid E. O'Brien  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28c80476e4SDavid E. O'Brien  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29c80476e4SDavid E. O'Brien  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30c80476e4SDavid E. O'Brien  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31c80476e4SDavid E. O'Brien  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32c80476e4SDavid E. O'Brien  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33c80476e4SDavid E. O'Brien  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34c80476e4SDavid E. O'Brien  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35c80476e4SDavid E. O'Brien  * SUCH DAMAGE.
36c80476e4SDavid E. O'Brien  */
37c80476e4SDavid E. O'Brien #include "sh.h"
38c80476e4SDavid E. O'Brien 
39c80476e4SDavid E. O'Brien RCSID("$Id: gethost.c,v 1.7 1997/10/28 22:34:19 christos Exp $")
40c80476e4SDavid E. O'Brien 
41c80476e4SDavid E. O'Brien #ifdef SCO
42c80476e4SDavid E. O'Brien # define perror __perror
43c80476e4SDavid E. O'Brien # define rename __rename
44c80476e4SDavid E. O'Brien # define getopt __getopt
45c80476e4SDavid E. O'Brien # define system __system
46c80476e4SDavid E. O'Brien #endif
47c80476e4SDavid E. O'Brien #include <stdio.h>
48c80476e4SDavid E. O'Brien #ifdef SCO
49c80476e4SDavid E. O'Brien # undef perror
50c80476e4SDavid E. O'Brien # undef rename
51c80476e4SDavid E. O'Brien # undef getopt
52c80476e4SDavid E. O'Brien # undef system
53c80476e4SDavid E. O'Brien #endif
54c80476e4SDavid E. O'Brien 
55c80476e4SDavid E. O'Brien #include <ctype.h>
56c80476e4SDavid E. O'Brien 
57c80476e4SDavid E. O'Brien /* Some people don't bother to declare these */
58c80476e4SDavid E. O'Brien #if defined(SUNOS4) || defined(ibm032)
59c80476e4SDavid E. O'Brien extern int fprintf();
60c80476e4SDavid E. O'Brien extern int fclose();
61c80476e4SDavid E. O'Brien #endif /* SUNOS4 || ibm032 */
62c80476e4SDavid E. O'Brien 
63c80476e4SDavid E. O'Brien #define ISSPACE(p)	(isspace((unsigned char) (p)) && (p) != '\n')
64c80476e4SDavid E. O'Brien 
65c80476e4SDavid E. O'Brien /*
66c80476e4SDavid E. O'Brien  * We cannot do that, because some compilers like #line and others
67c80476e4SDavid E. O'Brien  * like # <lineno>
68c80476e4SDavid E. O'Brien  * #define LINEDIRECTIVE
69c80476e4SDavid E. O'Brien  */
70c80476e4SDavid E. O'Brien 
71c80476e4SDavid E. O'Brien static const char *keyword[] =
72c80476e4SDavid E. O'Brien {
73c80476e4SDavid E. O'Brien     "vendor",
74c80476e4SDavid E. O'Brien #define T_VENDOR	0
75c80476e4SDavid E. O'Brien     "hosttype",
76c80476e4SDavid E. O'Brien #define T_HOSTTYPE	1
77c80476e4SDavid E. O'Brien     "machtype",
78c80476e4SDavid E. O'Brien #define T_MACHTYPE	2
79c80476e4SDavid E. O'Brien     "ostype",
80c80476e4SDavid E. O'Brien #define T_OSTYPE	3
81c80476e4SDavid E. O'Brien     "newdef",
82c80476e4SDavid E. O'Brien #define T_NEWDEF	4
83c80476e4SDavid E. O'Brien     "enddef",
84c80476e4SDavid E. O'Brien #define T_ENDDEF	5
85c80476e4SDavid E. O'Brien     "newcode",
86c80476e4SDavid E. O'Brien #define T_NEWCODE	6
87c80476e4SDavid E. O'Brien     "endcode",
88c80476e4SDavid E. O'Brien #define T_ENDCODE	7
89c80476e4SDavid E. O'Brien     "comment",
90c80476e4SDavid E. O'Brien #define T_COMMENT	8
91c80476e4SDavid E. O'Brien     "macro",
92c80476e4SDavid E. O'Brien #define T_MACRO		9
93c80476e4SDavid E. O'Brien     NULL
94c80476e4SDavid E. O'Brien #define T_NONE		10
95c80476e4SDavid E. O'Brien };
96c80476e4SDavid E. O'Brien 
97c80476e4SDavid E. O'Brien #define S_DISCARD	0
98c80476e4SDavid E. O'Brien #define S_COMMENT	1
99c80476e4SDavid E. O'Brien #define S_CODE		2
100c80476e4SDavid E. O'Brien #define S_KEYWORD	3
101c80476e4SDavid E. O'Brien 
102c80476e4SDavid E. O'Brien static int findtoken __P((char *));
103c80476e4SDavid E. O'Brien static char *gettoken __P((char **, char  *));
104c80476e4SDavid E. O'Brien 
105c80476e4SDavid E. O'Brien int main __P((int, char *[]));
106c80476e4SDavid E. O'Brien 
107c80476e4SDavid E. O'Brien /* findtoken():
108c80476e4SDavid E. O'Brien  *	Return the token number of the given token
109c80476e4SDavid E. O'Brien  */
110c80476e4SDavid E. O'Brien static int
111c80476e4SDavid E. O'Brien findtoken(ptr)
112c80476e4SDavid E. O'Brien     char *ptr;
113c80476e4SDavid E. O'Brien {
114c80476e4SDavid E. O'Brien     int i;
115c80476e4SDavid E. O'Brien 
116c80476e4SDavid E. O'Brien     if (ptr == NULL || *ptr == '\0')
117c80476e4SDavid E. O'Brien 	return T_NONE;
118c80476e4SDavid E. O'Brien 
119c80476e4SDavid E. O'Brien     for (i = 0; keyword[i] != NULL; i++)
120c80476e4SDavid E. O'Brien 	if (strcmp(keyword[i], ptr) == 0)
121c80476e4SDavid E. O'Brien 	    return i;
122c80476e4SDavid E. O'Brien 
123c80476e4SDavid E. O'Brien     return T_NONE;
124c80476e4SDavid E. O'Brien }
125c80476e4SDavid E. O'Brien 
126c80476e4SDavid E. O'Brien 
127c80476e4SDavid E. O'Brien /* gettoken():
128c80476e4SDavid E. O'Brien  *	Get : delimited token and remove leading/trailing blanks/newlines
129c80476e4SDavid E. O'Brien  */
130c80476e4SDavid E. O'Brien static char *
131c80476e4SDavid E. O'Brien gettoken(pptr, token)
132c80476e4SDavid E. O'Brien     char **pptr;
133c80476e4SDavid E. O'Brien     char  *token;
134c80476e4SDavid E. O'Brien {
135c80476e4SDavid E. O'Brien     char *ptr = *pptr;
136c80476e4SDavid E. O'Brien     char *tok = token;
137c80476e4SDavid E. O'Brien 
138c80476e4SDavid E. O'Brien     for (; *ptr && ISSPACE(*ptr); ptr++)
139c80476e4SDavid E. O'Brien 	continue;
140c80476e4SDavid E. O'Brien 
141c80476e4SDavid E. O'Brien     for (; *ptr && *ptr != ':'; *tok++ = *ptr++)
142c80476e4SDavid E. O'Brien 	continue;
143c80476e4SDavid E. O'Brien 
144c80476e4SDavid E. O'Brien     if (*ptr == ':')
145c80476e4SDavid E. O'Brien 	ptr++;
146c80476e4SDavid E. O'Brien     else
147c80476e4SDavid E. O'Brien 	tok--;
148c80476e4SDavid E. O'Brien 
149c80476e4SDavid E. O'Brien     for (tok--; tok >= token && *tok && ISSPACE(*tok); tok--)
150c80476e4SDavid E. O'Brien 	continue;
151c80476e4SDavid E. O'Brien 
152c80476e4SDavid E. O'Brien     *++tok = '\0';
153c80476e4SDavid E. O'Brien 
154c80476e4SDavid E. O'Brien     *pptr = ptr;
155c80476e4SDavid E. O'Brien     return token;
156c80476e4SDavid E. O'Brien }
157c80476e4SDavid E. O'Brien 
158c80476e4SDavid E. O'Brien 
159c80476e4SDavid E. O'Brien int
160c80476e4SDavid E. O'Brien main(argc, argv)
161c80476e4SDavid E. O'Brien     int argc;
162c80476e4SDavid E. O'Brien     char *argv[];
163c80476e4SDavid E. O'Brien {
164c80476e4SDavid E. O'Brien     char line[INBUFSIZE];
165c80476e4SDavid E. O'Brien     char *pname;
166c80476e4SDavid E. O'Brien     char *fname = "stdin";
167c80476e4SDavid E. O'Brien     char *ptr, *tok;
168c80476e4SDavid E. O'Brien     char defs[INBUFSIZE];
169c80476e4SDavid E. O'Brien     char stmt[INBUFSIZE];
170c80476e4SDavid E. O'Brien     FILE *fp = stdin;
171c80476e4SDavid E. O'Brien     int lineno = 0;
172c80476e4SDavid E. O'Brien     int inprocess = 0;
173c80476e4SDavid E. O'Brien     int token, state;
174c80476e4SDavid E. O'Brien     int errs = 0;
175c80476e4SDavid E. O'Brien 
176c80476e4SDavid E. O'Brien     if ((pname = strrchr(argv[0], '/')) == NULL)
177c80476e4SDavid E. O'Brien 	pname = argv[0];
178c80476e4SDavid E. O'Brien     else
179c80476e4SDavid E. O'Brien 	pname++;
180c80476e4SDavid E. O'Brien 
181c80476e4SDavid E. O'Brien     if (argc > 2) {
182c80476e4SDavid E. O'Brien 	(void) fprintf(stderr, "Usage: %s [<filename>]\n", pname);
183c80476e4SDavid E. O'Brien 	return 1;
184c80476e4SDavid E. O'Brien     }
185c80476e4SDavid E. O'Brien 
186c80476e4SDavid E. O'Brien     if (argc == 2)
187c80476e4SDavid E. O'Brien 	if ((fp = fopen(fname = argv[1], "r")) == NULL) {
188c80476e4SDavid E. O'Brien 	    (void) fprintf(stderr, "%s: Cannot open `%s'\n", pname, fname);
189c80476e4SDavid E. O'Brien 	    return 1;
190c80476e4SDavid E. O'Brien 	}
191c80476e4SDavid E. O'Brien 
192c80476e4SDavid E. O'Brien     state = S_DISCARD;
193c80476e4SDavid E. O'Brien 
194c80476e4SDavid E. O'Brien     while ((ptr = fgets(line, sizeof(line), fp)) != NULL) {
195c80476e4SDavid E. O'Brien 	lineno++;
196c80476e4SDavid E. O'Brien 	switch (token = findtoken(gettoken(&ptr, defs))) {
197c80476e4SDavid E. O'Brien 	case T_NEWCODE:
198c80476e4SDavid E. O'Brien 	    state = S_CODE;
199c80476e4SDavid E. O'Brien 	    break;
200c80476e4SDavid E. O'Brien 
201c80476e4SDavid E. O'Brien 	case T_ENDCODE:
202c80476e4SDavid E. O'Brien 	    state = S_DISCARD;
203c80476e4SDavid E. O'Brien 	    break;
204c80476e4SDavid E. O'Brien 
205c80476e4SDavid E. O'Brien 	case T_COMMENT:
206c80476e4SDavid E. O'Brien 	    state = S_COMMENT;
207c80476e4SDavid E. O'Brien 	    break;
208c80476e4SDavid E. O'Brien 
209c80476e4SDavid E. O'Brien 	case T_NEWDEF:
210c80476e4SDavid E. O'Brien 	    state = S_KEYWORD;
211c80476e4SDavid E. O'Brien 	    break;
212c80476e4SDavid E. O'Brien 
213c80476e4SDavid E. O'Brien 	case T_ENDDEF:
214c80476e4SDavid E. O'Brien 	    state = S_DISCARD;
215c80476e4SDavid E. O'Brien 	    break;
216c80476e4SDavid E. O'Brien 
217c80476e4SDavid E. O'Brien 	case T_VENDOR:
218c80476e4SDavid E. O'Brien 	    state = S_KEYWORD;
219c80476e4SDavid E. O'Brien 	    break;
220c80476e4SDavid E. O'Brien 
221c80476e4SDavid E. O'Brien 	case T_HOSTTYPE:
222c80476e4SDavid E. O'Brien 	    state = S_KEYWORD;
223c80476e4SDavid E. O'Brien 	    break;
224c80476e4SDavid E. O'Brien 
225c80476e4SDavid E. O'Brien 	case T_MACHTYPE:
226c80476e4SDavid E. O'Brien 	    state = S_KEYWORD;
227c80476e4SDavid E. O'Brien 	    break;
228c80476e4SDavid E. O'Brien 
229c80476e4SDavid E. O'Brien 	case T_OSTYPE:
230c80476e4SDavid E. O'Brien 	    state = S_KEYWORD;
231c80476e4SDavid E. O'Brien 	    break;
232c80476e4SDavid E. O'Brien 
233c80476e4SDavid E. O'Brien 	case T_MACRO:
234c80476e4SDavid E. O'Brien 	    if (gettoken(&ptr, defs) == NULL) {
235c80476e4SDavid E. O'Brien 		(void) fprintf(stderr, "%s: \"%s\", %d: Missing macro name\n",
236c80476e4SDavid E. O'Brien 			       pname, fname, lineno);
237c80476e4SDavid E. O'Brien 		break;
238c80476e4SDavid E. O'Brien 	    }
239c80476e4SDavid E. O'Brien 	    if (gettoken(&ptr, stmt) == NULL) {
240c80476e4SDavid E. O'Brien 		(void) fprintf(stderr, "%s: \"%s\", %d: Missing macro body\n",
241c80476e4SDavid E. O'Brien 			       pname, fname, lineno);
242c80476e4SDavid E. O'Brien 		break;
243c80476e4SDavid E. O'Brien 	    }
244c80476e4SDavid E. O'Brien 	    (void) fprintf(stdout, "\n#if %s\n# define %s\n#endif\n\n", stmt,
245c80476e4SDavid E. O'Brien 			   defs);
246c80476e4SDavid E. O'Brien 	    break;
247c80476e4SDavid E. O'Brien 
248c80476e4SDavid E. O'Brien 	case T_NONE:
249c80476e4SDavid E. O'Brien 	    if (state != S_CODE && defs && *defs != '\0') {
250c80476e4SDavid E. O'Brien 		(void) fprintf(stderr, "%s: \"%s\", %d: Discarded\n",
251c80476e4SDavid E. O'Brien 			       pname, fname, lineno);
252c80476e4SDavid E. O'Brien 		if (++errs == 30) {
253c80476e4SDavid E. O'Brien 		    (void) fprintf(stderr, "%s: Too many errors\n", pname);
254c80476e4SDavid E. O'Brien 		    return 1;
255c80476e4SDavid E. O'Brien 		}
256c80476e4SDavid E. O'Brien 		break;
257c80476e4SDavid E. O'Brien 	    }
258c80476e4SDavid E. O'Brien 	    (void) fprintf(stdout, "%s", line);
259c80476e4SDavid E. O'Brien 	    break;
260c80476e4SDavid E. O'Brien 
261c80476e4SDavid E. O'Brien 	default:
262c80476e4SDavid E. O'Brien 	    (void) fprintf(stderr, "%s: \"%s\", %d: Unexpected token\n",
263c80476e4SDavid E. O'Brien 			   pname, fname, lineno);
264c80476e4SDavid E. O'Brien 	    return 1;
265c80476e4SDavid E. O'Brien 	}
266c80476e4SDavid E. O'Brien 
267c80476e4SDavid E. O'Brien 	switch (state) {
268c80476e4SDavid E. O'Brien 	case S_DISCARD:
269c80476e4SDavid E. O'Brien 	    if (inprocess) {
270c80476e4SDavid E. O'Brien 		inprocess = 0;
271c80476e4SDavid E. O'Brien 		(void) fprintf(stdout, "#endif\n");
272c80476e4SDavid E. O'Brien 	    }
273c80476e4SDavid E. O'Brien 	    break;
274c80476e4SDavid E. O'Brien 
275c80476e4SDavid E. O'Brien 	case S_KEYWORD:
276c80476e4SDavid E. O'Brien 	    tok = gettoken(&ptr, defs);
277c80476e4SDavid E. O'Brien 	    if (token == T_NEWDEF) {
278c80476e4SDavid E. O'Brien 		if (inprocess) {
279c80476e4SDavid E. O'Brien 		    (void) fprintf(stderr, "%s: \"%s\", %d: Missing enddef\n",
280c80476e4SDavid E. O'Brien 				   pname, fname, lineno);
281c80476e4SDavid E. O'Brien 		    return 1;
282c80476e4SDavid E. O'Brien 		}
283c80476e4SDavid E. O'Brien 		if (tok == NULL) {
284c80476e4SDavid E. O'Brien 		    (void) fprintf(stderr, "%s: \"%s\", %d: No defs\n",
285c80476e4SDavid E. O'Brien 				   pname, fname, lineno);
286c80476e4SDavid E. O'Brien 		    return 1;
287c80476e4SDavid E. O'Brien 		}
288c80476e4SDavid E. O'Brien 		(void) fprintf(stdout, "\n\n");
289c80476e4SDavid E. O'Brien #ifdef LINEDIRECTIVE
290c80476e4SDavid E. O'Brien 		(void) fprintf(stdout, "# %d \"%s\"\n", lineno + 1, fname);
291c80476e4SDavid E. O'Brien #endif /* LINEDIRECTIVE */
292c80476e4SDavid E. O'Brien 		(void) fprintf(stdout, "#if %s\n", defs);
293c80476e4SDavid E. O'Brien 		inprocess = 1;
294c80476e4SDavid E. O'Brien 	    }
295c80476e4SDavid E. O'Brien 	    else {
296c80476e4SDavid E. O'Brien 		if (tok && *tok)
297c80476e4SDavid E. O'Brien 		    (void) fprintf(stdout, "# if (%s) && !defined(_%s_)\n",
298c80476e4SDavid E. O'Brien 				   defs, keyword[token]);
299c80476e4SDavid E. O'Brien 		else
300c80476e4SDavid E. O'Brien 		    (void) fprintf(stdout, "# if !defined(_%s_)\n",
301c80476e4SDavid E. O'Brien 				   keyword[token]);
302c80476e4SDavid E. O'Brien 
303c80476e4SDavid E. O'Brien 		if (gettoken(&ptr, stmt) == NULL) {
304c80476e4SDavid E. O'Brien 		    (void) fprintf(stderr, "%s: \"%s\", %d: No statement\n",
305c80476e4SDavid E. O'Brien 				   pname, fname, lineno);
306c80476e4SDavid E. O'Brien 		    return 1;
307c80476e4SDavid E. O'Brien 		}
308c80476e4SDavid E. O'Brien 		(void) fprintf(stdout, "# define _%s_\n", keyword[token]);
309c80476e4SDavid E. O'Brien 		(void) fprintf(stdout, "    %s = %s;\n", keyword[token], stmt);
310c80476e4SDavid E. O'Brien 		(void) fprintf(stdout, "# endif\n");
311c80476e4SDavid E. O'Brien 	    }
312c80476e4SDavid E. O'Brien 	    break;
313c80476e4SDavid E. O'Brien 
314c80476e4SDavid E. O'Brien 	case S_COMMENT:
315c80476e4SDavid E. O'Brien 	    if (gettoken(&ptr, defs))
316c80476e4SDavid E. O'Brien 		(void) fprintf(stdout, "    /* %s */\n", defs);
317c80476e4SDavid E. O'Brien 	    break;
318c80476e4SDavid E. O'Brien 
319c80476e4SDavid E. O'Brien 	case S_CODE:
320c80476e4SDavid E. O'Brien 	    if (token == T_NEWCODE) {
321c80476e4SDavid E. O'Brien #ifdef LINEDIRECTIVE
322c80476e4SDavid E. O'Brien 		(void) fprintf(stdout, "# %d \"%s\"\n", lineno + 1, fname);
323c80476e4SDavid E. O'Brien #endif /* LINEDIRECTIVE */
324c80476e4SDavid E. O'Brien 	    }
325c80476e4SDavid E. O'Brien 	    break;
326c80476e4SDavid E. O'Brien 
327c80476e4SDavid E. O'Brien 	default:
328c80476e4SDavid E. O'Brien 	    (void) fprintf(stderr, "%s: \"%s\", %d: Unexpected state\n",
329c80476e4SDavid E. O'Brien 			   pname, fname, lineno);
330c80476e4SDavid E. O'Brien 	    return 1;
331c80476e4SDavid E. O'Brien 	}
332c80476e4SDavid E. O'Brien     }
333c80476e4SDavid E. O'Brien 
334c80476e4SDavid E. O'Brien     if (inprocess) {
335c80476e4SDavid E. O'Brien 	(void) fprintf(stderr, "%s: \"%s\", %d: Missing enddef\n",
336c80476e4SDavid E. O'Brien 		       pname, fname, lineno);
337c80476e4SDavid E. O'Brien 	return 1;
338c80476e4SDavid E. O'Brien     }
339c80476e4SDavid E. O'Brien 
340c80476e4SDavid E. O'Brien     if (fp != stdin)
341c80476e4SDavid E. O'Brien 	(void) fclose(fp);
342c80476e4SDavid E. O'Brien 
343c80476e4SDavid E. O'Brien     return 0;
344c80476e4SDavid E. O'Brien }
345