1/*
2 * Copyright (C) 2004, 2005, 2007  Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1998-2001  Internet Software Consortium.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/* $Id: lex_test.c,v 1.23 2007/06/19 23:46:59 tbox Exp $ */
19
20/*! \file */
21#include <config.h>
22
23#include <isc/commandline.h>
24#include <isc/lex.h>
25#include <isc/mem.h>
26#include <isc/util.h>
27
28isc_mem_t *mctx;
29isc_lex_t *lex;
30
31isc_lexspecials_t specials;
32
33static void
34print_token(isc_token_t *tokenp, FILE *stream) {
35	switch (tokenp->type) {
36	case isc_tokentype_unknown:
37		fprintf(stream, "UNKNOWN");
38		break;
39	case isc_tokentype_string:
40		fprintf(stream, "STRING %.*s",
41			(int)tokenp->value.as_region.length,
42			tokenp->value.as_region.base);
43		break;
44	case isc_tokentype_number:
45		fprintf(stream, "NUMBER %lu", tokenp->value.as_ulong);
46		break;
47	case isc_tokentype_qstring:
48		fprintf(stream, "QSTRING \"%.*s\"",
49			(int)tokenp->value.as_region.length,
50			tokenp->value.as_region.base);
51		break;
52	case isc_tokentype_eol:
53		fprintf(stream, "EOL");
54		break;
55	case isc_tokentype_eof:
56		fprintf(stream, "EOF");
57		break;
58	case isc_tokentype_initialws:
59		fprintf(stream, "INITIALWS");
60		break;
61	case isc_tokentype_special:
62		fprintf(stream, "SPECIAL %c", tokenp->value.as_char);
63		break;
64	case isc_tokentype_nomore:
65		fprintf(stream, "NOMORE");
66		break;
67	default:
68		FATAL_ERROR(__FILE__, __LINE__, "Unexpected type %d",
69			    tokenp->type);
70	}
71}
72
73int
74main(int argc, char *argv[]) {
75	isc_token_t token;
76	isc_result_t result;
77	int quiet = 0;
78	int c;
79	int masterfile = 1;
80	int stats = 0;
81	unsigned int options = 0;
82	int done = 0;
83
84	while ((c = isc_commandline_parse(argc, argv, "qmcs")) != -1) {
85		switch (c) {
86		case 'q':
87			quiet = 1;
88			break;
89		case 'm':
90			masterfile = 1;
91			break;
92		case 'c':
93			masterfile = 0;
94			break;
95		case 's':
96			stats = 1;
97			break;
98		}
99	}
100
101	RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
102	RUNTIME_CHECK(isc_lex_create(mctx, 256, &lex) == ISC_R_SUCCESS);
103
104	if (masterfile) {
105		/* Set up to lex DNS master file. */
106
107		specials['('] = 1;
108		specials[')'] = 1;
109		specials['"'] = 1;
110		isc_lex_setspecials(lex, specials);
111		options = ISC_LEXOPT_DNSMULTILINE | ISC_LEXOPT_ESCAPE |
112			ISC_LEXOPT_EOF |
113			ISC_LEXOPT_QSTRING | ISC_LEXOPT_NOMORE;
114		isc_lex_setcomments(lex, ISC_LEXCOMMENT_DNSMASTERFILE);
115	} else {
116		/* Set up to lex DNS config file. */
117
118		specials['{'] = 1;
119		specials['}'] = 1;
120		specials[';'] = 1;
121		specials['/'] = 1;
122		specials['"'] = 1;
123		specials['!'] = 1;
124		specials['*'] = 1;
125		isc_lex_setspecials(lex, specials);
126		options = ISC_LEXOPT_EOF |
127			ISC_LEXOPT_QSTRING |
128			ISC_LEXOPT_NUMBER | ISC_LEXOPT_NOMORE;
129		isc_lex_setcomments(lex, (ISC_LEXCOMMENT_C|
130					  ISC_LEXCOMMENT_CPLUSPLUS|
131					  ISC_LEXCOMMENT_SHELL));
132	}
133
134	RUNTIME_CHECK(isc_lex_openstream(lex, stdin) == ISC_R_SUCCESS);
135
136	while ((result = isc_lex_gettoken(lex, options, &token)) ==
137	       ISC_R_SUCCESS && !done) {
138		if (!quiet) {
139			char *name = isc_lex_getsourcename(lex);
140			print_token(&token, stdout);
141			printf(" line = %lu file = %s\n",
142				isc_lex_getsourceline(lex),
143				(name == NULL) ? "<none>" : name);
144		}
145		if (token.type == isc_tokentype_eof)
146			isc_lex_close(lex);
147		if (token.type == isc_tokentype_nomore)
148			done = 1;
149	}
150	if (result != ISC_R_SUCCESS)
151		printf("Result: %s\n", isc_result_totext(result));
152
153	isc_lex_close(lex);
154	isc_lex_destroy(&lex);
155	if (!quiet && stats)
156		isc_mem_stats(mctx, stdout);
157	isc_mem_destroy(&mctx);
158
159	return (0);
160}
161