xref: /minix3/external/bsd/bind/dist/lib/isc/lex.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek /*	$NetBSD: lex.c,v 1.6 2014/12/10 04:37:59 christos Exp $	*/
2*00b67f09SDavid van Moolenbroek 
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek  * Copyright (C) 2004, 2005, 2007, 2013, 2014  Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek  * Copyright (C) 1998-2003  Internet Software Consortium.
6*00b67f09SDavid van Moolenbroek  *
7*00b67f09SDavid van Moolenbroek  * Permission to use, copy, modify, and/or distribute this software for any
8*00b67f09SDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
9*00b67f09SDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
10*00b67f09SDavid van Moolenbroek  *
11*00b67f09SDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12*00b67f09SDavid van Moolenbroek  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13*00b67f09SDavid van Moolenbroek  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14*00b67f09SDavid van Moolenbroek  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15*00b67f09SDavid van Moolenbroek  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16*00b67f09SDavid van Moolenbroek  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*00b67f09SDavid van Moolenbroek  * PERFORMANCE OF THIS SOFTWARE.
18*00b67f09SDavid van Moolenbroek  */
19*00b67f09SDavid van Moolenbroek 
20*00b67f09SDavid van Moolenbroek /* Id: lex.c,v 1.86 2007/09/17 09:56:29 shane Exp  */
21*00b67f09SDavid van Moolenbroek 
22*00b67f09SDavid van Moolenbroek /*! \file */
23*00b67f09SDavid van Moolenbroek 
24*00b67f09SDavid van Moolenbroek #include <config.h>
25*00b67f09SDavid van Moolenbroek 
26*00b67f09SDavid van Moolenbroek #include <ctype.h>
27*00b67f09SDavid van Moolenbroek #include <errno.h>
28*00b67f09SDavid van Moolenbroek #include <stdlib.h>
29*00b67f09SDavid van Moolenbroek 
30*00b67f09SDavid van Moolenbroek #include <isc/buffer.h>
31*00b67f09SDavid van Moolenbroek #include <isc/file.h>
32*00b67f09SDavid van Moolenbroek #include <isc/lex.h>
33*00b67f09SDavid van Moolenbroek #include <isc/mem.h>
34*00b67f09SDavid van Moolenbroek #include <isc/msgs.h>
35*00b67f09SDavid van Moolenbroek #include <isc/parseint.h>
36*00b67f09SDavid van Moolenbroek #include <isc/print.h>
37*00b67f09SDavid van Moolenbroek #include <isc/stdio.h>
38*00b67f09SDavid van Moolenbroek #include <isc/string.h>
39*00b67f09SDavid van Moolenbroek #include <isc/util.h>
40*00b67f09SDavid van Moolenbroek 
41*00b67f09SDavid van Moolenbroek typedef struct inputsource {
42*00b67f09SDavid van Moolenbroek 	isc_result_t			result;
43*00b67f09SDavid van Moolenbroek 	isc_boolean_t			is_file;
44*00b67f09SDavid van Moolenbroek 	isc_boolean_t			need_close;
45*00b67f09SDavid van Moolenbroek 	isc_boolean_t			at_eof;
46*00b67f09SDavid van Moolenbroek 	isc_buffer_t *			pushback;
47*00b67f09SDavid van Moolenbroek 	unsigned int			ignored;
48*00b67f09SDavid van Moolenbroek 	void *				input;
49*00b67f09SDavid van Moolenbroek 	char *				name;
50*00b67f09SDavid van Moolenbroek 	unsigned long			line;
51*00b67f09SDavid van Moolenbroek 	unsigned long			saved_line;
52*00b67f09SDavid van Moolenbroek 	ISC_LINK(struct inputsource)	link;
53*00b67f09SDavid van Moolenbroek } inputsource;
54*00b67f09SDavid van Moolenbroek 
55*00b67f09SDavid van Moolenbroek #define LEX_MAGIC			ISC_MAGIC('L', 'e', 'x', '!')
56*00b67f09SDavid van Moolenbroek #define VALID_LEX(l)			ISC_MAGIC_VALID(l, LEX_MAGIC)
57*00b67f09SDavid van Moolenbroek 
58*00b67f09SDavid van Moolenbroek struct isc_lex {
59*00b67f09SDavid van Moolenbroek 	/* Unlocked. */
60*00b67f09SDavid van Moolenbroek 	unsigned int			magic;
61*00b67f09SDavid van Moolenbroek 	isc_mem_t *			mctx;
62*00b67f09SDavid van Moolenbroek 	size_t				max_token;
63*00b67f09SDavid van Moolenbroek 	char *				data;
64*00b67f09SDavid van Moolenbroek 	unsigned int			comments;
65*00b67f09SDavid van Moolenbroek 	isc_boolean_t			comment_ok;
66*00b67f09SDavid van Moolenbroek 	isc_boolean_t			last_was_eol;
67*00b67f09SDavid van Moolenbroek 	unsigned int			paren_count;
68*00b67f09SDavid van Moolenbroek 	unsigned int			saved_paren_count;
69*00b67f09SDavid van Moolenbroek 	isc_lexspecials_t		specials;
70*00b67f09SDavid van Moolenbroek 	LIST(struct inputsource)	sources;
71*00b67f09SDavid van Moolenbroek };
72*00b67f09SDavid van Moolenbroek 
73*00b67f09SDavid van Moolenbroek static inline isc_result_t
grow_data(isc_lex_t * lex,size_t * remainingp,char ** currp,char ** prevp)74*00b67f09SDavid van Moolenbroek grow_data(isc_lex_t *lex, size_t *remainingp, char **currp, char **prevp) {
75*00b67f09SDavid van Moolenbroek 	char *new;
76*00b67f09SDavid van Moolenbroek 
77*00b67f09SDavid van Moolenbroek 	new = isc_mem_get(lex->mctx, lex->max_token * 2 + 1);
78*00b67f09SDavid van Moolenbroek 	if (new == NULL)
79*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOMEMORY);
80*00b67f09SDavid van Moolenbroek 	memmove(new, lex->data, lex->max_token + 1);
81*00b67f09SDavid van Moolenbroek 	*currp = new + (*currp - lex->data);
82*00b67f09SDavid van Moolenbroek 	if (*prevp != NULL)
83*00b67f09SDavid van Moolenbroek 		*prevp = new + (*prevp - lex->data);
84*00b67f09SDavid van Moolenbroek 	isc_mem_put(lex->mctx, lex->data, lex->max_token + 1);
85*00b67f09SDavid van Moolenbroek 	lex->data = new;
86*00b67f09SDavid van Moolenbroek 	*remainingp += lex->max_token;
87*00b67f09SDavid van Moolenbroek 	lex->max_token *= 2;
88*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
89*00b67f09SDavid van Moolenbroek }
90*00b67f09SDavid van Moolenbroek 
91*00b67f09SDavid van Moolenbroek isc_result_t
isc_lex_create(isc_mem_t * mctx,size_t max_token,isc_lex_t ** lexp)92*00b67f09SDavid van Moolenbroek isc_lex_create(isc_mem_t *mctx, size_t max_token, isc_lex_t **lexp) {
93*00b67f09SDavid van Moolenbroek 	isc_lex_t *lex;
94*00b67f09SDavid van Moolenbroek 
95*00b67f09SDavid van Moolenbroek 	/*
96*00b67f09SDavid van Moolenbroek 	 * Create a lexer.
97*00b67f09SDavid van Moolenbroek 	 */
98*00b67f09SDavid van Moolenbroek 
99*00b67f09SDavid van Moolenbroek 	REQUIRE(lexp != NULL && *lexp == NULL);
100*00b67f09SDavid van Moolenbroek 	REQUIRE(max_token > 0U);
101*00b67f09SDavid van Moolenbroek 
102*00b67f09SDavid van Moolenbroek 	lex = isc_mem_get(mctx, sizeof(*lex));
103*00b67f09SDavid van Moolenbroek 	if (lex == NULL)
104*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOMEMORY);
105*00b67f09SDavid van Moolenbroek 	lex->data = isc_mem_get(mctx, max_token + 1);
106*00b67f09SDavid van Moolenbroek 	if (lex->data == NULL) {
107*00b67f09SDavid van Moolenbroek 		isc_mem_put(mctx, lex, sizeof(*lex));
108*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOMEMORY);
109*00b67f09SDavid van Moolenbroek 	}
110*00b67f09SDavid van Moolenbroek 	lex->mctx = mctx;
111*00b67f09SDavid van Moolenbroek 	lex->max_token = max_token;
112*00b67f09SDavid van Moolenbroek 	lex->comments = 0;
113*00b67f09SDavid van Moolenbroek 	lex->comment_ok = ISC_TRUE;
114*00b67f09SDavid van Moolenbroek 	lex->last_was_eol = ISC_TRUE;
115*00b67f09SDavid van Moolenbroek 	lex->paren_count = 0;
116*00b67f09SDavid van Moolenbroek 	lex->saved_paren_count = 0;
117*00b67f09SDavid van Moolenbroek 	memset(lex->specials, 0, 256);
118*00b67f09SDavid van Moolenbroek 	INIT_LIST(lex->sources);
119*00b67f09SDavid van Moolenbroek 	lex->magic = LEX_MAGIC;
120*00b67f09SDavid van Moolenbroek 
121*00b67f09SDavid van Moolenbroek 	*lexp = lex;
122*00b67f09SDavid van Moolenbroek 
123*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
124*00b67f09SDavid van Moolenbroek }
125*00b67f09SDavid van Moolenbroek 
126*00b67f09SDavid van Moolenbroek void
isc_lex_destroy(isc_lex_t ** lexp)127*00b67f09SDavid van Moolenbroek isc_lex_destroy(isc_lex_t **lexp) {
128*00b67f09SDavid van Moolenbroek 	isc_lex_t *lex;
129*00b67f09SDavid van Moolenbroek 
130*00b67f09SDavid van Moolenbroek 	/*
131*00b67f09SDavid van Moolenbroek 	 * Destroy the lexer.
132*00b67f09SDavid van Moolenbroek 	 */
133*00b67f09SDavid van Moolenbroek 
134*00b67f09SDavid van Moolenbroek 	REQUIRE(lexp != NULL);
135*00b67f09SDavid van Moolenbroek 	lex = *lexp;
136*00b67f09SDavid van Moolenbroek 	REQUIRE(VALID_LEX(lex));
137*00b67f09SDavid van Moolenbroek 
138*00b67f09SDavid van Moolenbroek 	while (!EMPTY(lex->sources))
139*00b67f09SDavid van Moolenbroek 		RUNTIME_CHECK(isc_lex_close(lex) == ISC_R_SUCCESS);
140*00b67f09SDavid van Moolenbroek 	if (lex->data != NULL)
141*00b67f09SDavid van Moolenbroek 		isc_mem_put(lex->mctx, lex->data, lex->max_token + 1);
142*00b67f09SDavid van Moolenbroek 	lex->magic = 0;
143*00b67f09SDavid van Moolenbroek 	isc_mem_put(lex->mctx, lex, sizeof(*lex));
144*00b67f09SDavid van Moolenbroek 
145*00b67f09SDavid van Moolenbroek 	*lexp = NULL;
146*00b67f09SDavid van Moolenbroek }
147*00b67f09SDavid van Moolenbroek 
148*00b67f09SDavid van Moolenbroek unsigned int
isc_lex_getcomments(isc_lex_t * lex)149*00b67f09SDavid van Moolenbroek isc_lex_getcomments(isc_lex_t *lex) {
150*00b67f09SDavid van Moolenbroek 	/*
151*00b67f09SDavid van Moolenbroek 	 * Return the current lexer commenting styles.
152*00b67f09SDavid van Moolenbroek 	 */
153*00b67f09SDavid van Moolenbroek 
154*00b67f09SDavid van Moolenbroek 	REQUIRE(VALID_LEX(lex));
155*00b67f09SDavid van Moolenbroek 
156*00b67f09SDavid van Moolenbroek 	return (lex->comments);
157*00b67f09SDavid van Moolenbroek }
158*00b67f09SDavid van Moolenbroek 
159*00b67f09SDavid van Moolenbroek void
isc_lex_setcomments(isc_lex_t * lex,unsigned int comments)160*00b67f09SDavid van Moolenbroek isc_lex_setcomments(isc_lex_t *lex, unsigned int comments) {
161*00b67f09SDavid van Moolenbroek 	/*
162*00b67f09SDavid van Moolenbroek 	 * Set allowed lexer commenting styles.
163*00b67f09SDavid van Moolenbroek 	 */
164*00b67f09SDavid van Moolenbroek 
165*00b67f09SDavid van Moolenbroek 	REQUIRE(VALID_LEX(lex));
166*00b67f09SDavid van Moolenbroek 
167*00b67f09SDavid van Moolenbroek 	lex->comments = comments;
168*00b67f09SDavid van Moolenbroek }
169*00b67f09SDavid van Moolenbroek 
170*00b67f09SDavid van Moolenbroek void
isc_lex_getspecials(isc_lex_t * lex,isc_lexspecials_t specials)171*00b67f09SDavid van Moolenbroek isc_lex_getspecials(isc_lex_t *lex, isc_lexspecials_t specials) {
172*00b67f09SDavid van Moolenbroek 	/*
173*00b67f09SDavid van Moolenbroek 	 * Put the current list of specials into 'specials'.
174*00b67f09SDavid van Moolenbroek 	 */
175*00b67f09SDavid van Moolenbroek 
176*00b67f09SDavid van Moolenbroek 	REQUIRE(VALID_LEX(lex));
177*00b67f09SDavid van Moolenbroek 
178*00b67f09SDavid van Moolenbroek 	memmove(specials, lex->specials, 256);
179*00b67f09SDavid van Moolenbroek }
180*00b67f09SDavid van Moolenbroek 
181*00b67f09SDavid van Moolenbroek void
isc_lex_setspecials(isc_lex_t * lex,isc_lexspecials_t specials)182*00b67f09SDavid van Moolenbroek isc_lex_setspecials(isc_lex_t *lex, isc_lexspecials_t specials) {
183*00b67f09SDavid van Moolenbroek 	/*
184*00b67f09SDavid van Moolenbroek 	 * The characters in 'specials' are returned as tokens.  Along with
185*00b67f09SDavid van Moolenbroek 	 * whitespace, they delimit strings and numbers.
186*00b67f09SDavid van Moolenbroek 	 */
187*00b67f09SDavid van Moolenbroek 
188*00b67f09SDavid van Moolenbroek 	REQUIRE(VALID_LEX(lex));
189*00b67f09SDavid van Moolenbroek 
190*00b67f09SDavid van Moolenbroek 	memmove(lex->specials, specials, 256);
191*00b67f09SDavid van Moolenbroek }
192*00b67f09SDavid van Moolenbroek 
193*00b67f09SDavid van Moolenbroek static inline isc_result_t
new_source(isc_lex_t * lex,isc_boolean_t is_file,isc_boolean_t need_close,void * input,const char * name)194*00b67f09SDavid van Moolenbroek new_source(isc_lex_t *lex, isc_boolean_t is_file, isc_boolean_t need_close,
195*00b67f09SDavid van Moolenbroek 	   void *input, const char *name)
196*00b67f09SDavid van Moolenbroek {
197*00b67f09SDavid van Moolenbroek 	inputsource *source;
198*00b67f09SDavid van Moolenbroek 	isc_result_t result;
199*00b67f09SDavid van Moolenbroek 
200*00b67f09SDavid van Moolenbroek 	source = isc_mem_get(lex->mctx, sizeof(*source));
201*00b67f09SDavid van Moolenbroek 	if (source == NULL)
202*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOMEMORY);
203*00b67f09SDavid van Moolenbroek 	source->result = ISC_R_SUCCESS;
204*00b67f09SDavid van Moolenbroek 	source->is_file = is_file;
205*00b67f09SDavid van Moolenbroek 	source->need_close = need_close;
206*00b67f09SDavid van Moolenbroek 	source->at_eof = ISC_FALSE;
207*00b67f09SDavid van Moolenbroek 	source->input = input;
208*00b67f09SDavid van Moolenbroek 	source->name = isc_mem_strdup(lex->mctx, name);
209*00b67f09SDavid van Moolenbroek 	if (source->name == NULL) {
210*00b67f09SDavid van Moolenbroek 		isc_mem_put(lex->mctx, source, sizeof(*source));
211*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOMEMORY);
212*00b67f09SDavid van Moolenbroek 	}
213*00b67f09SDavid van Moolenbroek 	source->pushback = NULL;
214*00b67f09SDavid van Moolenbroek 	result = isc_buffer_allocate(lex->mctx, &source->pushback,
215*00b67f09SDavid van Moolenbroek 				     (unsigned int)lex->max_token);
216*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS) {
217*00b67f09SDavid van Moolenbroek 		isc_mem_free(lex->mctx, source->name);
218*00b67f09SDavid van Moolenbroek 		isc_mem_put(lex->mctx, source, sizeof(*source));
219*00b67f09SDavid van Moolenbroek 		return (result);
220*00b67f09SDavid van Moolenbroek 	}
221*00b67f09SDavid van Moolenbroek 	source->ignored = 0;
222*00b67f09SDavid van Moolenbroek 	source->line = 1;
223*00b67f09SDavid van Moolenbroek 	ISC_LIST_INITANDPREPEND(lex->sources, source, link);
224*00b67f09SDavid van Moolenbroek 
225*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
226*00b67f09SDavid van Moolenbroek }
227*00b67f09SDavid van Moolenbroek 
228*00b67f09SDavid van Moolenbroek isc_result_t
isc_lex_openfile(isc_lex_t * lex,const char * filename)229*00b67f09SDavid van Moolenbroek isc_lex_openfile(isc_lex_t *lex, const char *filename) {
230*00b67f09SDavid van Moolenbroek 	isc_result_t result;
231*00b67f09SDavid van Moolenbroek 	FILE *stream = NULL;
232*00b67f09SDavid van Moolenbroek 
233*00b67f09SDavid van Moolenbroek 	/*
234*00b67f09SDavid van Moolenbroek 	 * Open 'filename' and make it the current input source for 'lex'.
235*00b67f09SDavid van Moolenbroek 	 */
236*00b67f09SDavid van Moolenbroek 
237*00b67f09SDavid van Moolenbroek 	REQUIRE(VALID_LEX(lex));
238*00b67f09SDavid van Moolenbroek 
239*00b67f09SDavid van Moolenbroek 	result = isc_stdio_open(filename, "r", &stream);
240*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
241*00b67f09SDavid van Moolenbroek 		return (result);
242*00b67f09SDavid van Moolenbroek 
243*00b67f09SDavid van Moolenbroek 	result = new_source(lex, ISC_TRUE, ISC_TRUE, stream, filename);
244*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
245*00b67f09SDavid van Moolenbroek 		(void)fclose(stream);
246*00b67f09SDavid van Moolenbroek 	return (result);
247*00b67f09SDavid van Moolenbroek }
248*00b67f09SDavid van Moolenbroek 
249*00b67f09SDavid van Moolenbroek isc_result_t
isc_lex_openstream(isc_lex_t * lex,FILE * stream)250*00b67f09SDavid van Moolenbroek isc_lex_openstream(isc_lex_t *lex, FILE *stream) {
251*00b67f09SDavid van Moolenbroek 	char name[128];
252*00b67f09SDavid van Moolenbroek 
253*00b67f09SDavid van Moolenbroek 	/*
254*00b67f09SDavid van Moolenbroek 	 * Make 'stream' the current input source for 'lex'.
255*00b67f09SDavid van Moolenbroek 	 */
256*00b67f09SDavid van Moolenbroek 
257*00b67f09SDavid van Moolenbroek 	REQUIRE(VALID_LEX(lex));
258*00b67f09SDavid van Moolenbroek 
259*00b67f09SDavid van Moolenbroek 	snprintf(name, sizeof(name), "stream-%p", stream);
260*00b67f09SDavid van Moolenbroek 
261*00b67f09SDavid van Moolenbroek 	return (new_source(lex, ISC_TRUE, ISC_FALSE, stream, name));
262*00b67f09SDavid van Moolenbroek }
263*00b67f09SDavid van Moolenbroek 
264*00b67f09SDavid van Moolenbroek isc_result_t
isc_lex_openbuffer(isc_lex_t * lex,isc_buffer_t * buffer)265*00b67f09SDavid van Moolenbroek isc_lex_openbuffer(isc_lex_t *lex, isc_buffer_t *buffer) {
266*00b67f09SDavid van Moolenbroek 	char name[128];
267*00b67f09SDavid van Moolenbroek 
268*00b67f09SDavid van Moolenbroek 	/*
269*00b67f09SDavid van Moolenbroek 	 * Make 'buffer' the current input source for 'lex'.
270*00b67f09SDavid van Moolenbroek 	 */
271*00b67f09SDavid van Moolenbroek 
272*00b67f09SDavid van Moolenbroek 	REQUIRE(VALID_LEX(lex));
273*00b67f09SDavid van Moolenbroek 
274*00b67f09SDavid van Moolenbroek 	snprintf(name, sizeof(name), "buffer-%p", buffer);
275*00b67f09SDavid van Moolenbroek 
276*00b67f09SDavid van Moolenbroek 	return (new_source(lex, ISC_FALSE, ISC_FALSE, buffer, name));
277*00b67f09SDavid van Moolenbroek }
278*00b67f09SDavid van Moolenbroek 
279*00b67f09SDavid van Moolenbroek isc_result_t
isc_lex_close(isc_lex_t * lex)280*00b67f09SDavid van Moolenbroek isc_lex_close(isc_lex_t *lex) {
281*00b67f09SDavid van Moolenbroek 	inputsource *source;
282*00b67f09SDavid van Moolenbroek 
283*00b67f09SDavid van Moolenbroek 	/*
284*00b67f09SDavid van Moolenbroek 	 * Close the most recently opened object (i.e. file or buffer).
285*00b67f09SDavid van Moolenbroek 	 */
286*00b67f09SDavid van Moolenbroek 
287*00b67f09SDavid van Moolenbroek 	REQUIRE(VALID_LEX(lex));
288*00b67f09SDavid van Moolenbroek 
289*00b67f09SDavid van Moolenbroek 	source = HEAD(lex->sources);
290*00b67f09SDavid van Moolenbroek 	if (source == NULL)
291*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOMORE);
292*00b67f09SDavid van Moolenbroek 
293*00b67f09SDavid van Moolenbroek 	ISC_LIST_UNLINK(lex->sources, source, link);
294*00b67f09SDavid van Moolenbroek 	if (source->is_file) {
295*00b67f09SDavid van Moolenbroek 		if (source->need_close)
296*00b67f09SDavid van Moolenbroek 			(void)fclose((FILE *)(source->input));
297*00b67f09SDavid van Moolenbroek 	}
298*00b67f09SDavid van Moolenbroek 	isc_mem_free(lex->mctx, source->name);
299*00b67f09SDavid van Moolenbroek 	isc_buffer_free(&source->pushback);
300*00b67f09SDavid van Moolenbroek 	isc_mem_put(lex->mctx, source, sizeof(*source));
301*00b67f09SDavid van Moolenbroek 
302*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
303*00b67f09SDavid van Moolenbroek }
304*00b67f09SDavid van Moolenbroek 
305*00b67f09SDavid van Moolenbroek typedef enum {
306*00b67f09SDavid van Moolenbroek 	lexstate_start,
307*00b67f09SDavid van Moolenbroek 	lexstate_crlf,
308*00b67f09SDavid van Moolenbroek 	lexstate_string,
309*00b67f09SDavid van Moolenbroek 	lexstate_number,
310*00b67f09SDavid van Moolenbroek 	lexstate_maybecomment,
311*00b67f09SDavid van Moolenbroek 	lexstate_ccomment,
312*00b67f09SDavid van Moolenbroek 	lexstate_ccommentend,
313*00b67f09SDavid van Moolenbroek 	lexstate_eatline,
314*00b67f09SDavid van Moolenbroek 	lexstate_qstring
315*00b67f09SDavid van Moolenbroek } lexstate;
316*00b67f09SDavid van Moolenbroek 
317*00b67f09SDavid van Moolenbroek #define IWSEOL (ISC_LEXOPT_INITIALWS | ISC_LEXOPT_EOL)
318*00b67f09SDavid van Moolenbroek 
319*00b67f09SDavid van Moolenbroek static void
pushback(inputsource * source,int c)320*00b67f09SDavid van Moolenbroek pushback(inputsource *source, int c) {
321*00b67f09SDavid van Moolenbroek 	REQUIRE(source->pushback->current > 0);
322*00b67f09SDavid van Moolenbroek 	if (c == EOF) {
323*00b67f09SDavid van Moolenbroek 		source->at_eof = ISC_FALSE;
324*00b67f09SDavid van Moolenbroek 		return;
325*00b67f09SDavid van Moolenbroek 	}
326*00b67f09SDavid van Moolenbroek 	source->pushback->current--;
327*00b67f09SDavid van Moolenbroek 	if (c == '\n')
328*00b67f09SDavid van Moolenbroek 		source->line--;
329*00b67f09SDavid van Moolenbroek }
330*00b67f09SDavid van Moolenbroek 
331*00b67f09SDavid van Moolenbroek static isc_result_t
pushandgrow(isc_lex_t * lex,inputsource * source,int c)332*00b67f09SDavid van Moolenbroek pushandgrow(isc_lex_t *lex, inputsource *source, int c) {
333*00b67f09SDavid van Moolenbroek 	if (isc_buffer_availablelength(source->pushback) == 0) {
334*00b67f09SDavid van Moolenbroek 		isc_buffer_t *tbuf = NULL;
335*00b67f09SDavid van Moolenbroek 		unsigned int oldlen;
336*00b67f09SDavid van Moolenbroek 		isc_region_t used;
337*00b67f09SDavid van Moolenbroek 		isc_result_t result;
338*00b67f09SDavid van Moolenbroek 
339*00b67f09SDavid van Moolenbroek 		oldlen = isc_buffer_length(source->pushback);
340*00b67f09SDavid van Moolenbroek 		result = isc_buffer_allocate(lex->mctx, &tbuf, oldlen * 2);
341*00b67f09SDavid van Moolenbroek 		if (result != ISC_R_SUCCESS)
342*00b67f09SDavid van Moolenbroek 			return (result);
343*00b67f09SDavid van Moolenbroek 		isc_buffer_usedregion(source->pushback, &used);
344*00b67f09SDavid van Moolenbroek 		result = isc_buffer_copyregion(tbuf, &used);
345*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS);
346*00b67f09SDavid van Moolenbroek 		tbuf->current = source->pushback->current;
347*00b67f09SDavid van Moolenbroek 		isc_buffer_free(&source->pushback);
348*00b67f09SDavid van Moolenbroek 		source->pushback = tbuf;
349*00b67f09SDavid van Moolenbroek 	}
350*00b67f09SDavid van Moolenbroek 	isc_buffer_putuint8(source->pushback, (isc_uint8_t)c);
351*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
352*00b67f09SDavid van Moolenbroek }
353*00b67f09SDavid van Moolenbroek 
354*00b67f09SDavid van Moolenbroek isc_result_t
isc_lex_gettoken(isc_lex_t * lex,unsigned int options,isc_token_t * tokenp)355*00b67f09SDavid van Moolenbroek isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) {
356*00b67f09SDavid van Moolenbroek 	inputsource *source;
357*00b67f09SDavid van Moolenbroek 	int c;
358*00b67f09SDavid van Moolenbroek 	isc_boolean_t done = ISC_FALSE;
359*00b67f09SDavid van Moolenbroek 	isc_boolean_t no_comments = ISC_FALSE;
360*00b67f09SDavid van Moolenbroek 	isc_boolean_t escaped = ISC_FALSE;
361*00b67f09SDavid van Moolenbroek 	lexstate state = lexstate_start;
362*00b67f09SDavid van Moolenbroek 	lexstate saved_state = lexstate_start;
363*00b67f09SDavid van Moolenbroek 	isc_buffer_t *buffer;
364*00b67f09SDavid van Moolenbroek 	FILE *stream;
365*00b67f09SDavid van Moolenbroek 	char *curr, *prev;
366*00b67f09SDavid van Moolenbroek 	size_t remaining;
367*00b67f09SDavid van Moolenbroek 	isc_uint32_t as_ulong;
368*00b67f09SDavid van Moolenbroek 	unsigned int saved_options;
369*00b67f09SDavid van Moolenbroek 	isc_result_t result;
370*00b67f09SDavid van Moolenbroek 
371*00b67f09SDavid van Moolenbroek 	/*
372*00b67f09SDavid van Moolenbroek 	 * Get the next token.
373*00b67f09SDavid van Moolenbroek 	 */
374*00b67f09SDavid van Moolenbroek 
375*00b67f09SDavid van Moolenbroek 	REQUIRE(VALID_LEX(lex));
376*00b67f09SDavid van Moolenbroek 	source = HEAD(lex->sources);
377*00b67f09SDavid van Moolenbroek 	REQUIRE(tokenp != NULL);
378*00b67f09SDavid van Moolenbroek 
379*00b67f09SDavid van Moolenbroek 	if (source == NULL) {
380*00b67f09SDavid van Moolenbroek 		if ((options & ISC_LEXOPT_NOMORE) != 0) {
381*00b67f09SDavid van Moolenbroek 			tokenp->type = isc_tokentype_nomore;
382*00b67f09SDavid van Moolenbroek 			return (ISC_R_SUCCESS);
383*00b67f09SDavid van Moolenbroek 		}
384*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOMORE);
385*00b67f09SDavid van Moolenbroek 	}
386*00b67f09SDavid van Moolenbroek 
387*00b67f09SDavid van Moolenbroek 	if (source->result != ISC_R_SUCCESS)
388*00b67f09SDavid van Moolenbroek 		return (source->result);
389*00b67f09SDavid van Moolenbroek 
390*00b67f09SDavid van Moolenbroek 	lex->saved_paren_count = lex->paren_count;
391*00b67f09SDavid van Moolenbroek 	source->saved_line = source->line;
392*00b67f09SDavid van Moolenbroek 
393*00b67f09SDavid van Moolenbroek 	if (isc_buffer_remaininglength(source->pushback) == 0 &&
394*00b67f09SDavid van Moolenbroek 	    source->at_eof)
395*00b67f09SDavid van Moolenbroek 	{
396*00b67f09SDavid van Moolenbroek 		if ((options & ISC_LEXOPT_DNSMULTILINE) != 0 &&
397*00b67f09SDavid van Moolenbroek 		    lex->paren_count != 0) {
398*00b67f09SDavid van Moolenbroek 			lex->paren_count = 0;
399*00b67f09SDavid van Moolenbroek 			return (ISC_R_UNBALANCED);
400*00b67f09SDavid van Moolenbroek 		}
401*00b67f09SDavid van Moolenbroek 		if ((options & ISC_LEXOPT_EOF) != 0) {
402*00b67f09SDavid van Moolenbroek 			tokenp->type = isc_tokentype_eof;
403*00b67f09SDavid van Moolenbroek 			return (ISC_R_SUCCESS);
404*00b67f09SDavid van Moolenbroek 		}
405*00b67f09SDavid van Moolenbroek 		return (ISC_R_EOF);
406*00b67f09SDavid van Moolenbroek 	}
407*00b67f09SDavid van Moolenbroek 
408*00b67f09SDavid van Moolenbroek 	isc_buffer_compact(source->pushback);
409*00b67f09SDavid van Moolenbroek 
410*00b67f09SDavid van Moolenbroek 	saved_options = options;
411*00b67f09SDavid van Moolenbroek 	if ((options & ISC_LEXOPT_DNSMULTILINE) != 0 && lex->paren_count > 0)
412*00b67f09SDavid van Moolenbroek 		options &= ~IWSEOL;
413*00b67f09SDavid van Moolenbroek 
414*00b67f09SDavid van Moolenbroek 	curr = lex->data;
415*00b67f09SDavid van Moolenbroek 	*curr = '\0';
416*00b67f09SDavid van Moolenbroek 
417*00b67f09SDavid van Moolenbroek 	prev = NULL;
418*00b67f09SDavid van Moolenbroek 	remaining = lex->max_token;
419*00b67f09SDavid van Moolenbroek 
420*00b67f09SDavid van Moolenbroek #ifdef HAVE_FLOCKFILE
421*00b67f09SDavid van Moolenbroek 	if (source->is_file)
422*00b67f09SDavid van Moolenbroek 		flockfile(source->input);
423*00b67f09SDavid van Moolenbroek #endif
424*00b67f09SDavid van Moolenbroek 
425*00b67f09SDavid van Moolenbroek 	do {
426*00b67f09SDavid van Moolenbroek 		if (isc_buffer_remaininglength(source->pushback) == 0) {
427*00b67f09SDavid van Moolenbroek 			if (source->is_file) {
428*00b67f09SDavid van Moolenbroek 				stream = source->input;
429*00b67f09SDavid van Moolenbroek 
430*00b67f09SDavid van Moolenbroek #if defined(HAVE_FLOCKFILE) && defined(HAVE_GETCUNLOCKED)
431*00b67f09SDavid van Moolenbroek 				c = getc_unlocked(stream);
432*00b67f09SDavid van Moolenbroek #else
433*00b67f09SDavid van Moolenbroek 				c = getc(stream);
434*00b67f09SDavid van Moolenbroek #endif
435*00b67f09SDavid van Moolenbroek 				if (c == EOF) {
436*00b67f09SDavid van Moolenbroek 					if (ferror(stream)) {
437*00b67f09SDavid van Moolenbroek 						source->result = ISC_R_IOERROR;
438*00b67f09SDavid van Moolenbroek 						result = source->result;
439*00b67f09SDavid van Moolenbroek 						goto done;
440*00b67f09SDavid van Moolenbroek 					}
441*00b67f09SDavid van Moolenbroek 					source->at_eof = ISC_TRUE;
442*00b67f09SDavid van Moolenbroek 				}
443*00b67f09SDavid van Moolenbroek 			} else {
444*00b67f09SDavid van Moolenbroek 				buffer = source->input;
445*00b67f09SDavid van Moolenbroek 
446*00b67f09SDavid van Moolenbroek 				if (buffer->current == buffer->used) {
447*00b67f09SDavid van Moolenbroek 					c = EOF;
448*00b67f09SDavid van Moolenbroek 					source->at_eof = ISC_TRUE;
449*00b67f09SDavid van Moolenbroek 				} else {
450*00b67f09SDavid van Moolenbroek 					c = *((unsigned char *)buffer->base +
451*00b67f09SDavid van Moolenbroek 					      buffer->current);
452*00b67f09SDavid van Moolenbroek 					buffer->current++;
453*00b67f09SDavid van Moolenbroek 				}
454*00b67f09SDavid van Moolenbroek 			}
455*00b67f09SDavid van Moolenbroek 			if (c != EOF) {
456*00b67f09SDavid van Moolenbroek 				source->result = pushandgrow(lex, source, c);
457*00b67f09SDavid van Moolenbroek 				if (source->result != ISC_R_SUCCESS) {
458*00b67f09SDavid van Moolenbroek 					result = source->result;
459*00b67f09SDavid van Moolenbroek 					goto done;
460*00b67f09SDavid van Moolenbroek 				}
461*00b67f09SDavid van Moolenbroek 			}
462*00b67f09SDavid van Moolenbroek 		}
463*00b67f09SDavid van Moolenbroek 
464*00b67f09SDavid van Moolenbroek 		if (!source->at_eof) {
465*00b67f09SDavid van Moolenbroek 			if (state == lexstate_start)
466*00b67f09SDavid van Moolenbroek 				/* Token has not started yet. */
467*00b67f09SDavid van Moolenbroek 				source->ignored =
468*00b67f09SDavid van Moolenbroek 				   isc_buffer_consumedlength(source->pushback);
469*00b67f09SDavid van Moolenbroek 			c = isc_buffer_getuint8(source->pushback);
470*00b67f09SDavid van Moolenbroek 		} else {
471*00b67f09SDavid van Moolenbroek 			c = EOF;
472*00b67f09SDavid van Moolenbroek 		}
473*00b67f09SDavid van Moolenbroek 
474*00b67f09SDavid van Moolenbroek 		if (c == '\n')
475*00b67f09SDavid van Moolenbroek 			source->line++;
476*00b67f09SDavid van Moolenbroek 
477*00b67f09SDavid van Moolenbroek 		if (lex->comment_ok && !no_comments) {
478*00b67f09SDavid van Moolenbroek 			if (!escaped && c == ';' &&
479*00b67f09SDavid van Moolenbroek 			    ((lex->comments & ISC_LEXCOMMENT_DNSMASTERFILE)
480*00b67f09SDavid van Moolenbroek 			     != 0)) {
481*00b67f09SDavid van Moolenbroek 				saved_state = state;
482*00b67f09SDavid van Moolenbroek 				state = lexstate_eatline;
483*00b67f09SDavid van Moolenbroek 				no_comments = ISC_TRUE;
484*00b67f09SDavid van Moolenbroek 				continue;
485*00b67f09SDavid van Moolenbroek 			} else if (c == '/' &&
486*00b67f09SDavid van Moolenbroek 				   (lex->comments &
487*00b67f09SDavid van Moolenbroek 				    (ISC_LEXCOMMENT_C|
488*00b67f09SDavid van Moolenbroek 				     ISC_LEXCOMMENT_CPLUSPLUS)) != 0) {
489*00b67f09SDavid van Moolenbroek 				saved_state = state;
490*00b67f09SDavid van Moolenbroek 				state = lexstate_maybecomment;
491*00b67f09SDavid van Moolenbroek 				no_comments = ISC_TRUE;
492*00b67f09SDavid van Moolenbroek 				continue;
493*00b67f09SDavid van Moolenbroek 			} else if (c == '#' &&
494*00b67f09SDavid van Moolenbroek 				   ((lex->comments & ISC_LEXCOMMENT_SHELL)
495*00b67f09SDavid van Moolenbroek 				    != 0)) {
496*00b67f09SDavid van Moolenbroek 				saved_state = state;
497*00b67f09SDavid van Moolenbroek 				state = lexstate_eatline;
498*00b67f09SDavid van Moolenbroek 				no_comments = ISC_TRUE;
499*00b67f09SDavid van Moolenbroek 				continue;
500*00b67f09SDavid van Moolenbroek 			}
501*00b67f09SDavid van Moolenbroek 		}
502*00b67f09SDavid van Moolenbroek 
503*00b67f09SDavid van Moolenbroek 	no_read:
504*00b67f09SDavid van Moolenbroek 		/* INSIST(c == EOF || (c >= 0 && c <= 255)); */
505*00b67f09SDavid van Moolenbroek 		switch (state) {
506*00b67f09SDavid van Moolenbroek 		case lexstate_start:
507*00b67f09SDavid van Moolenbroek 			if (c == EOF) {
508*00b67f09SDavid van Moolenbroek 				lex->last_was_eol = ISC_FALSE;
509*00b67f09SDavid van Moolenbroek 				if ((options & ISC_LEXOPT_DNSMULTILINE) != 0 &&
510*00b67f09SDavid van Moolenbroek 				    lex->paren_count != 0) {
511*00b67f09SDavid van Moolenbroek 					lex->paren_count = 0;
512*00b67f09SDavid van Moolenbroek 					result = ISC_R_UNBALANCED;
513*00b67f09SDavid van Moolenbroek 					goto done;
514*00b67f09SDavid van Moolenbroek 				}
515*00b67f09SDavid van Moolenbroek 				if ((options & ISC_LEXOPT_EOF) == 0) {
516*00b67f09SDavid van Moolenbroek 					result = ISC_R_EOF;
517*00b67f09SDavid van Moolenbroek 					goto done;
518*00b67f09SDavid van Moolenbroek 				}
519*00b67f09SDavid van Moolenbroek 				tokenp->type = isc_tokentype_eof;
520*00b67f09SDavid van Moolenbroek 				done = ISC_TRUE;
521*00b67f09SDavid van Moolenbroek 			} else if (c == ' ' || c == '\t') {
522*00b67f09SDavid van Moolenbroek 				if (lex->last_was_eol &&
523*00b67f09SDavid van Moolenbroek 				    (options & ISC_LEXOPT_INITIALWS)
524*00b67f09SDavid van Moolenbroek 				    != 0) {
525*00b67f09SDavid van Moolenbroek 					lex->last_was_eol = ISC_FALSE;
526*00b67f09SDavid van Moolenbroek 					tokenp->type = isc_tokentype_initialws;
527*00b67f09SDavid van Moolenbroek 					tokenp->value.as_char = c;
528*00b67f09SDavid van Moolenbroek 					done = ISC_TRUE;
529*00b67f09SDavid van Moolenbroek 				}
530*00b67f09SDavid van Moolenbroek 			} else if (c == '\n') {
531*00b67f09SDavid van Moolenbroek 				if ((options & ISC_LEXOPT_EOL) != 0) {
532*00b67f09SDavid van Moolenbroek 					tokenp->type = isc_tokentype_eol;
533*00b67f09SDavid van Moolenbroek 					done = ISC_TRUE;
534*00b67f09SDavid van Moolenbroek 				}
535*00b67f09SDavid van Moolenbroek 				lex->last_was_eol = ISC_TRUE;
536*00b67f09SDavid van Moolenbroek 			} else if (c == '\r') {
537*00b67f09SDavid van Moolenbroek 				if ((options & ISC_LEXOPT_EOL) != 0)
538*00b67f09SDavid van Moolenbroek 					state = lexstate_crlf;
539*00b67f09SDavid van Moolenbroek 			} else if (c == '"' &&
540*00b67f09SDavid van Moolenbroek 				   (options & ISC_LEXOPT_QSTRING) != 0) {
541*00b67f09SDavid van Moolenbroek 				lex->last_was_eol = ISC_FALSE;
542*00b67f09SDavid van Moolenbroek 				no_comments = ISC_TRUE;
543*00b67f09SDavid van Moolenbroek 				state = lexstate_qstring;
544*00b67f09SDavid van Moolenbroek 			} else if (lex->specials[c]) {
545*00b67f09SDavid van Moolenbroek 				lex->last_was_eol = ISC_FALSE;
546*00b67f09SDavid van Moolenbroek 				if ((c == '(' || c == ')') &&
547*00b67f09SDavid van Moolenbroek 				    (options & ISC_LEXOPT_DNSMULTILINE) != 0) {
548*00b67f09SDavid van Moolenbroek 					if (c == '(') {
549*00b67f09SDavid van Moolenbroek 						if (lex->paren_count == 0)
550*00b67f09SDavid van Moolenbroek 							options &= ~IWSEOL;
551*00b67f09SDavid van Moolenbroek 						lex->paren_count++;
552*00b67f09SDavid van Moolenbroek 					} else {
553*00b67f09SDavid van Moolenbroek 						if (lex->paren_count == 0) {
554*00b67f09SDavid van Moolenbroek 						    result = ISC_R_UNBALANCED;
555*00b67f09SDavid van Moolenbroek 						    goto done;
556*00b67f09SDavid van Moolenbroek 						}
557*00b67f09SDavid van Moolenbroek 						lex->paren_count--;
558*00b67f09SDavid van Moolenbroek 						if (lex->paren_count == 0)
559*00b67f09SDavid van Moolenbroek 							options =
560*00b67f09SDavid van Moolenbroek 								saved_options;
561*00b67f09SDavid van Moolenbroek 					}
562*00b67f09SDavid van Moolenbroek 					continue;
563*00b67f09SDavid van Moolenbroek 				}
564*00b67f09SDavid van Moolenbroek 				tokenp->type = isc_tokentype_special;
565*00b67f09SDavid van Moolenbroek 				tokenp->value.as_char = c;
566*00b67f09SDavid van Moolenbroek 				done = ISC_TRUE;
567*00b67f09SDavid van Moolenbroek 			} else if (isdigit((unsigned char)c) &&
568*00b67f09SDavid van Moolenbroek 				   (options & ISC_LEXOPT_NUMBER) != 0) {
569*00b67f09SDavid van Moolenbroek 				lex->last_was_eol = ISC_FALSE;
570*00b67f09SDavid van Moolenbroek 				if ((options & ISC_LEXOPT_OCTAL) != 0 &&
571*00b67f09SDavid van Moolenbroek 				    (c == '8' || c == '9'))
572*00b67f09SDavid van Moolenbroek 					state = lexstate_string;
573*00b67f09SDavid van Moolenbroek 				else
574*00b67f09SDavid van Moolenbroek 					state = lexstate_number;
575*00b67f09SDavid van Moolenbroek 				goto no_read;
576*00b67f09SDavid van Moolenbroek 			} else {
577*00b67f09SDavid van Moolenbroek 				lex->last_was_eol = ISC_FALSE;
578*00b67f09SDavid van Moolenbroek 				state = lexstate_string;
579*00b67f09SDavid van Moolenbroek 				goto no_read;
580*00b67f09SDavid van Moolenbroek 			}
581*00b67f09SDavid van Moolenbroek 			break;
582*00b67f09SDavid van Moolenbroek 		case lexstate_crlf:
583*00b67f09SDavid van Moolenbroek 			if (c != '\n')
584*00b67f09SDavid van Moolenbroek 				pushback(source, c);
585*00b67f09SDavid van Moolenbroek 			tokenp->type = isc_tokentype_eol;
586*00b67f09SDavid van Moolenbroek 			done = ISC_TRUE;
587*00b67f09SDavid van Moolenbroek 			lex->last_was_eol = ISC_TRUE;
588*00b67f09SDavid van Moolenbroek 			break;
589*00b67f09SDavid van Moolenbroek 		case lexstate_number:
590*00b67f09SDavid van Moolenbroek 			if (c == EOF || !isdigit((unsigned char)c)) {
591*00b67f09SDavid van Moolenbroek 				if (c == ' ' || c == '\t' || c == '\r' ||
592*00b67f09SDavid van Moolenbroek 				    c == '\n' || c == EOF ||
593*00b67f09SDavid van Moolenbroek 				    lex->specials[c]) {
594*00b67f09SDavid van Moolenbroek 					int base;
595*00b67f09SDavid van Moolenbroek 					if ((options & ISC_LEXOPT_OCTAL) != 0)
596*00b67f09SDavid van Moolenbroek 						base = 8;
597*00b67f09SDavid van Moolenbroek 					else if ((options & ISC_LEXOPT_CNUMBER) != 0)
598*00b67f09SDavid van Moolenbroek 						base = 0;
599*00b67f09SDavid van Moolenbroek 					else
600*00b67f09SDavid van Moolenbroek 						base = 10;
601*00b67f09SDavid van Moolenbroek 					pushback(source, c);
602*00b67f09SDavid van Moolenbroek 
603*00b67f09SDavid van Moolenbroek 					result = isc_parse_uint32(&as_ulong,
604*00b67f09SDavid van Moolenbroek 								  lex->data,
605*00b67f09SDavid van Moolenbroek 								  base);
606*00b67f09SDavid van Moolenbroek 					if (result == ISC_R_SUCCESS) {
607*00b67f09SDavid van Moolenbroek 						tokenp->type =
608*00b67f09SDavid van Moolenbroek 							isc_tokentype_number;
609*00b67f09SDavid van Moolenbroek 						tokenp->value.as_ulong =
610*00b67f09SDavid van Moolenbroek 							as_ulong;
611*00b67f09SDavid van Moolenbroek 					} else if (result == ISC_R_BADNUMBER) {
612*00b67f09SDavid van Moolenbroek 						isc_tokenvalue_t *v;
613*00b67f09SDavid van Moolenbroek 
614*00b67f09SDavid van Moolenbroek 						tokenp->type =
615*00b67f09SDavid van Moolenbroek 							isc_tokentype_string;
616*00b67f09SDavid van Moolenbroek 						v = &(tokenp->value);
617*00b67f09SDavid van Moolenbroek 						v->as_textregion.base =
618*00b67f09SDavid van Moolenbroek 							lex->data;
619*00b67f09SDavid van Moolenbroek 						v->as_textregion.length =
620*00b67f09SDavid van Moolenbroek 							(unsigned int)
621*00b67f09SDavid van Moolenbroek 							(lex->max_token -
622*00b67f09SDavid van Moolenbroek 							 remaining);
623*00b67f09SDavid van Moolenbroek 					} else
624*00b67f09SDavid van Moolenbroek 						goto done;
625*00b67f09SDavid van Moolenbroek 					done = ISC_TRUE;
626*00b67f09SDavid van Moolenbroek 					continue;
627*00b67f09SDavid van Moolenbroek 				} else if (!(options & ISC_LEXOPT_CNUMBER) ||
628*00b67f09SDavid van Moolenbroek 					   ((c != 'x' && c != 'X') ||
629*00b67f09SDavid van Moolenbroek 					   (curr != &lex->data[1]) ||
630*00b67f09SDavid van Moolenbroek 					   (lex->data[0] != '0'))) {
631*00b67f09SDavid van Moolenbroek 					/* Above test supports hex numbers */
632*00b67f09SDavid van Moolenbroek 					state = lexstate_string;
633*00b67f09SDavid van Moolenbroek 				}
634*00b67f09SDavid van Moolenbroek 			} else if ((options & ISC_LEXOPT_OCTAL) != 0 &&
635*00b67f09SDavid van Moolenbroek 				   (c == '8' || c == '9')) {
636*00b67f09SDavid van Moolenbroek 				state = lexstate_string;
637*00b67f09SDavid van Moolenbroek 			}
638*00b67f09SDavid van Moolenbroek 			if (remaining == 0U) {
639*00b67f09SDavid van Moolenbroek 				result = grow_data(lex, &remaining,
640*00b67f09SDavid van Moolenbroek 						   &curr, &prev);
641*00b67f09SDavid van Moolenbroek 				if (result != ISC_R_SUCCESS)
642*00b67f09SDavid van Moolenbroek 					goto done;
643*00b67f09SDavid van Moolenbroek 			}
644*00b67f09SDavid van Moolenbroek 			INSIST(remaining > 0U);
645*00b67f09SDavid van Moolenbroek 			*curr++ = c;
646*00b67f09SDavid van Moolenbroek 			*curr = '\0';
647*00b67f09SDavid van Moolenbroek 			remaining--;
648*00b67f09SDavid van Moolenbroek 			break;
649*00b67f09SDavid van Moolenbroek 		case lexstate_string:
650*00b67f09SDavid van Moolenbroek 			/*
651*00b67f09SDavid van Moolenbroek 			 * EOF needs to be checked before lex->specials[c]
652*00b67f09SDavid van Moolenbroek 			 * as lex->specials[EOF] is not a good idea.
653*00b67f09SDavid van Moolenbroek 			 */
654*00b67f09SDavid van Moolenbroek 			if (c == '\r' || c == '\n' || c == EOF ||
655*00b67f09SDavid van Moolenbroek 			    (!escaped &&
656*00b67f09SDavid van Moolenbroek 			     (c == ' ' || c == '\t' || lex->specials[c]))) {
657*00b67f09SDavid van Moolenbroek 				pushback(source, c);
658*00b67f09SDavid van Moolenbroek 				if (source->result != ISC_R_SUCCESS) {
659*00b67f09SDavid van Moolenbroek 					result = source->result;
660*00b67f09SDavid van Moolenbroek 					goto done;
661*00b67f09SDavid van Moolenbroek 				}
662*00b67f09SDavid van Moolenbroek 				tokenp->type = isc_tokentype_string;
663*00b67f09SDavid van Moolenbroek 				tokenp->value.as_textregion.base = lex->data;
664*00b67f09SDavid van Moolenbroek 				tokenp->value.as_textregion.length =
665*00b67f09SDavid van Moolenbroek 					(unsigned int)
666*00b67f09SDavid van Moolenbroek 					(lex->max_token - remaining);
667*00b67f09SDavid van Moolenbroek 				done = ISC_TRUE;
668*00b67f09SDavid van Moolenbroek 				continue;
669*00b67f09SDavid van Moolenbroek 			}
670*00b67f09SDavid van Moolenbroek 			if ((options & ISC_LEXOPT_ESCAPE) != 0)
671*00b67f09SDavid van Moolenbroek 				escaped = (!escaped && c == '\\') ?
672*00b67f09SDavid van Moolenbroek 						ISC_TRUE : ISC_FALSE;
673*00b67f09SDavid van Moolenbroek 			if (remaining == 0U) {
674*00b67f09SDavid van Moolenbroek 				result = grow_data(lex, &remaining,
675*00b67f09SDavid van Moolenbroek 						   &curr, &prev);
676*00b67f09SDavid van Moolenbroek 				if (result != ISC_R_SUCCESS)
677*00b67f09SDavid van Moolenbroek 					goto done;
678*00b67f09SDavid van Moolenbroek 			}
679*00b67f09SDavid van Moolenbroek 			INSIST(remaining > 0U);
680*00b67f09SDavid van Moolenbroek 			*curr++ = c;
681*00b67f09SDavid van Moolenbroek 			*curr = '\0';
682*00b67f09SDavid van Moolenbroek 			remaining--;
683*00b67f09SDavid van Moolenbroek 			break;
684*00b67f09SDavid van Moolenbroek 		case lexstate_maybecomment:
685*00b67f09SDavid van Moolenbroek 			if (c == '*' &&
686*00b67f09SDavid van Moolenbroek 			    (lex->comments & ISC_LEXCOMMENT_C) != 0) {
687*00b67f09SDavid van Moolenbroek 				state = lexstate_ccomment;
688*00b67f09SDavid van Moolenbroek 				continue;
689*00b67f09SDavid van Moolenbroek 			} else if (c == '/' &&
690*00b67f09SDavid van Moolenbroek 			    (lex->comments & ISC_LEXCOMMENT_CPLUSPLUS) != 0) {
691*00b67f09SDavid van Moolenbroek 				state = lexstate_eatline;
692*00b67f09SDavid van Moolenbroek 				continue;
693*00b67f09SDavid van Moolenbroek 			}
694*00b67f09SDavid van Moolenbroek 			pushback(source, c);
695*00b67f09SDavid van Moolenbroek 			c = '/';
696*00b67f09SDavid van Moolenbroek 			no_comments = ISC_FALSE;
697*00b67f09SDavid van Moolenbroek 			state = saved_state;
698*00b67f09SDavid van Moolenbroek 			goto no_read;
699*00b67f09SDavid van Moolenbroek 		case lexstate_ccomment:
700*00b67f09SDavid van Moolenbroek 			if (c == EOF) {
701*00b67f09SDavid van Moolenbroek 				result = ISC_R_UNEXPECTEDEND;
702*00b67f09SDavid van Moolenbroek 				goto done;
703*00b67f09SDavid van Moolenbroek 			}
704*00b67f09SDavid van Moolenbroek 			if (c == '*')
705*00b67f09SDavid van Moolenbroek 				state = lexstate_ccommentend;
706*00b67f09SDavid van Moolenbroek 			break;
707*00b67f09SDavid van Moolenbroek 		case lexstate_ccommentend:
708*00b67f09SDavid van Moolenbroek 			if (c == EOF) {
709*00b67f09SDavid van Moolenbroek 				result = ISC_R_UNEXPECTEDEND;
710*00b67f09SDavid van Moolenbroek 				goto done;
711*00b67f09SDavid van Moolenbroek 			}
712*00b67f09SDavid van Moolenbroek 			if (c == '/') {
713*00b67f09SDavid van Moolenbroek 				/*
714*00b67f09SDavid van Moolenbroek 				 * C-style comments become a single space.
715*00b67f09SDavid van Moolenbroek 				 * We do this to ensure that a comment will
716*00b67f09SDavid van Moolenbroek 				 * act as a delimiter for strings and
717*00b67f09SDavid van Moolenbroek 				 * numbers.
718*00b67f09SDavid van Moolenbroek 				 */
719*00b67f09SDavid van Moolenbroek 				c = ' ';
720*00b67f09SDavid van Moolenbroek 				no_comments = ISC_FALSE;
721*00b67f09SDavid van Moolenbroek 				state = saved_state;
722*00b67f09SDavid van Moolenbroek 				goto no_read;
723*00b67f09SDavid van Moolenbroek 			} else if (c != '*')
724*00b67f09SDavid van Moolenbroek 				state = lexstate_ccomment;
725*00b67f09SDavid van Moolenbroek 			break;
726*00b67f09SDavid van Moolenbroek 		case lexstate_eatline:
727*00b67f09SDavid van Moolenbroek 			if ((c == '\n') || (c == EOF)) {
728*00b67f09SDavid van Moolenbroek 				no_comments = ISC_FALSE;
729*00b67f09SDavid van Moolenbroek 				state = saved_state;
730*00b67f09SDavid van Moolenbroek 				goto no_read;
731*00b67f09SDavid van Moolenbroek 			}
732*00b67f09SDavid van Moolenbroek 			break;
733*00b67f09SDavid van Moolenbroek 		case lexstate_qstring:
734*00b67f09SDavid van Moolenbroek 			if (c == EOF) {
735*00b67f09SDavid van Moolenbroek 				result = ISC_R_UNEXPECTEDEND;
736*00b67f09SDavid van Moolenbroek 				goto done;
737*00b67f09SDavid van Moolenbroek 			}
738*00b67f09SDavid van Moolenbroek 			if (c == '"') {
739*00b67f09SDavid van Moolenbroek 				if (escaped) {
740*00b67f09SDavid van Moolenbroek 					escaped = ISC_FALSE;
741*00b67f09SDavid van Moolenbroek 					/*
742*00b67f09SDavid van Moolenbroek 					 * Overwrite the preceding backslash.
743*00b67f09SDavid van Moolenbroek 					 */
744*00b67f09SDavid van Moolenbroek 					INSIST(prev != NULL);
745*00b67f09SDavid van Moolenbroek 					*prev = '"';
746*00b67f09SDavid van Moolenbroek 				} else {
747*00b67f09SDavid van Moolenbroek 					tokenp->type = isc_tokentype_qstring;
748*00b67f09SDavid van Moolenbroek 					tokenp->value.as_textregion.base =
749*00b67f09SDavid van Moolenbroek 						lex->data;
750*00b67f09SDavid van Moolenbroek 					tokenp->value.as_textregion.length =
751*00b67f09SDavid van Moolenbroek 						(unsigned int)
752*00b67f09SDavid van Moolenbroek 						(lex->max_token - remaining);
753*00b67f09SDavid van Moolenbroek 					no_comments = ISC_FALSE;
754*00b67f09SDavid van Moolenbroek 					done = ISC_TRUE;
755*00b67f09SDavid van Moolenbroek 				}
756*00b67f09SDavid van Moolenbroek 			} else {
757*00b67f09SDavid van Moolenbroek 				if (c == '\n' && !escaped &&
758*00b67f09SDavid van Moolenbroek 			    (options & ISC_LEXOPT_QSTRINGMULTILINE) == 0) {
759*00b67f09SDavid van Moolenbroek 					pushback(source, c);
760*00b67f09SDavid van Moolenbroek 					result = ISC_R_UNBALANCEDQUOTES;
761*00b67f09SDavid van Moolenbroek 					goto done;
762*00b67f09SDavid van Moolenbroek 				}
763*00b67f09SDavid van Moolenbroek 				if (c == '\\' && !escaped)
764*00b67f09SDavid van Moolenbroek 					escaped = ISC_TRUE;
765*00b67f09SDavid van Moolenbroek 				else
766*00b67f09SDavid van Moolenbroek 					escaped = ISC_FALSE;
767*00b67f09SDavid van Moolenbroek 				if (remaining == 0U) {
768*00b67f09SDavid van Moolenbroek 					result = grow_data(lex, &remaining,
769*00b67f09SDavid van Moolenbroek 							   &curr, &prev);
770*00b67f09SDavid van Moolenbroek 					if (result != ISC_R_SUCCESS)
771*00b67f09SDavid van Moolenbroek 						goto done;
772*00b67f09SDavid van Moolenbroek 				}
773*00b67f09SDavid van Moolenbroek 				INSIST(remaining > 0U);
774*00b67f09SDavid van Moolenbroek 				prev = curr;
775*00b67f09SDavid van Moolenbroek 				*curr++ = c;
776*00b67f09SDavid van Moolenbroek 				*curr = '\0';
777*00b67f09SDavid van Moolenbroek 				remaining--;
778*00b67f09SDavid van Moolenbroek 			}
779*00b67f09SDavid van Moolenbroek 			break;
780*00b67f09SDavid van Moolenbroek 		default:
781*00b67f09SDavid van Moolenbroek 			FATAL_ERROR(__FILE__, __LINE__,
782*00b67f09SDavid van Moolenbroek 				    isc_msgcat_get(isc_msgcat, ISC_MSGSET_LEX,
783*00b67f09SDavid van Moolenbroek 						   ISC_MSG_UNEXPECTEDSTATE,
784*00b67f09SDavid van Moolenbroek 						   "Unexpected state %d"),
785*00b67f09SDavid van Moolenbroek 				    state);
786*00b67f09SDavid van Moolenbroek 			/* Does not return. */
787*00b67f09SDavid van Moolenbroek 		}
788*00b67f09SDavid van Moolenbroek 
789*00b67f09SDavid van Moolenbroek 	} while (!done);
790*00b67f09SDavid van Moolenbroek 
791*00b67f09SDavid van Moolenbroek 	result = ISC_R_SUCCESS;
792*00b67f09SDavid van Moolenbroek  done:
793*00b67f09SDavid van Moolenbroek #ifdef HAVE_FLOCKFILE
794*00b67f09SDavid van Moolenbroek 	if (source->is_file)
795*00b67f09SDavid van Moolenbroek 		funlockfile(source->input);
796*00b67f09SDavid van Moolenbroek #endif
797*00b67f09SDavid van Moolenbroek 	return (result);
798*00b67f09SDavid van Moolenbroek }
799*00b67f09SDavid van Moolenbroek 
800*00b67f09SDavid van Moolenbroek isc_result_t
isc_lex_getmastertoken(isc_lex_t * lex,isc_token_t * token,isc_tokentype_t expect,isc_boolean_t eol)801*00b67f09SDavid van Moolenbroek isc_lex_getmastertoken(isc_lex_t *lex, isc_token_t *token,
802*00b67f09SDavid van Moolenbroek 		       isc_tokentype_t expect, isc_boolean_t eol)
803*00b67f09SDavid van Moolenbroek {
804*00b67f09SDavid van Moolenbroek 	unsigned int options = ISC_LEXOPT_EOL | ISC_LEXOPT_EOF |
805*00b67f09SDavid van Moolenbroek 			       ISC_LEXOPT_DNSMULTILINE | ISC_LEXOPT_ESCAPE;
806*00b67f09SDavid van Moolenbroek 	isc_result_t result;
807*00b67f09SDavid van Moolenbroek 
808*00b67f09SDavid van Moolenbroek 	if (expect == isc_tokentype_qstring)
809*00b67f09SDavid van Moolenbroek 		options |= ISC_LEXOPT_QSTRING;
810*00b67f09SDavid van Moolenbroek 	else if (expect == isc_tokentype_number)
811*00b67f09SDavid van Moolenbroek 		options |= ISC_LEXOPT_NUMBER;
812*00b67f09SDavid van Moolenbroek 	result = isc_lex_gettoken(lex, options, token);
813*00b67f09SDavid van Moolenbroek 	if (result == ISC_R_RANGE)
814*00b67f09SDavid van Moolenbroek 		isc_lex_ungettoken(lex, token);
815*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
816*00b67f09SDavid van Moolenbroek 		return (result);
817*00b67f09SDavid van Moolenbroek 
818*00b67f09SDavid van Moolenbroek 	if (eol && ((token->type == isc_tokentype_eol) ||
819*00b67f09SDavid van Moolenbroek 		    (token->type == isc_tokentype_eof)))
820*00b67f09SDavid van Moolenbroek 		return (ISC_R_SUCCESS);
821*00b67f09SDavid van Moolenbroek 	if (token->type == isc_tokentype_string &&
822*00b67f09SDavid van Moolenbroek 	    expect == isc_tokentype_qstring)
823*00b67f09SDavid van Moolenbroek 		return (ISC_R_SUCCESS);
824*00b67f09SDavid van Moolenbroek 	if (token->type != expect) {
825*00b67f09SDavid van Moolenbroek 		isc_lex_ungettoken(lex, token);
826*00b67f09SDavid van Moolenbroek 		if (token->type == isc_tokentype_eol ||
827*00b67f09SDavid van Moolenbroek 		    token->type == isc_tokentype_eof)
828*00b67f09SDavid van Moolenbroek 			return (ISC_R_UNEXPECTEDEND);
829*00b67f09SDavid van Moolenbroek 		if (expect == isc_tokentype_number)
830*00b67f09SDavid van Moolenbroek 			return (ISC_R_BADNUMBER);
831*00b67f09SDavid van Moolenbroek 		return (ISC_R_UNEXPECTEDTOKEN);
832*00b67f09SDavid van Moolenbroek 	}
833*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
834*00b67f09SDavid van Moolenbroek }
835*00b67f09SDavid van Moolenbroek 
836*00b67f09SDavid van Moolenbroek isc_result_t
isc_lex_getoctaltoken(isc_lex_t * lex,isc_token_t * token,isc_boolean_t eol)837*00b67f09SDavid van Moolenbroek isc_lex_getoctaltoken(isc_lex_t *lex, isc_token_t *token, isc_boolean_t eol)
838*00b67f09SDavid van Moolenbroek {
839*00b67f09SDavid van Moolenbroek 	unsigned int options = ISC_LEXOPT_EOL | ISC_LEXOPT_EOF |
840*00b67f09SDavid van Moolenbroek 			       ISC_LEXOPT_DNSMULTILINE | ISC_LEXOPT_ESCAPE|
841*00b67f09SDavid van Moolenbroek 			       ISC_LEXOPT_NUMBER | ISC_LEXOPT_OCTAL;
842*00b67f09SDavid van Moolenbroek 	isc_result_t result;
843*00b67f09SDavid van Moolenbroek 
844*00b67f09SDavid van Moolenbroek 	result = isc_lex_gettoken(lex, options, token);
845*00b67f09SDavid van Moolenbroek 	if (result == ISC_R_RANGE)
846*00b67f09SDavid van Moolenbroek 		isc_lex_ungettoken(lex, token);
847*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
848*00b67f09SDavid van Moolenbroek 		return (result);
849*00b67f09SDavid van Moolenbroek 
850*00b67f09SDavid van Moolenbroek 	if (eol && ((token->type == isc_tokentype_eol) ||
851*00b67f09SDavid van Moolenbroek 		    (token->type == isc_tokentype_eof)))
852*00b67f09SDavid van Moolenbroek 		return (ISC_R_SUCCESS);
853*00b67f09SDavid van Moolenbroek 	if (token->type != isc_tokentype_number) {
854*00b67f09SDavid van Moolenbroek 		isc_lex_ungettoken(lex, token);
855*00b67f09SDavid van Moolenbroek 		if (token->type == isc_tokentype_eol ||
856*00b67f09SDavid van Moolenbroek 		    token->type == isc_tokentype_eof)
857*00b67f09SDavid van Moolenbroek 			return (ISC_R_UNEXPECTEDEND);
858*00b67f09SDavid van Moolenbroek 		return (ISC_R_BADNUMBER);
859*00b67f09SDavid van Moolenbroek 	}
860*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
861*00b67f09SDavid van Moolenbroek }
862*00b67f09SDavid van Moolenbroek 
863*00b67f09SDavid van Moolenbroek void
isc_lex_ungettoken(isc_lex_t * lex,isc_token_t * tokenp)864*00b67f09SDavid van Moolenbroek isc_lex_ungettoken(isc_lex_t *lex, isc_token_t *tokenp) {
865*00b67f09SDavid van Moolenbroek 	inputsource *source;
866*00b67f09SDavid van Moolenbroek 	/*
867*00b67f09SDavid van Moolenbroek 	 * Unget the current token.
868*00b67f09SDavid van Moolenbroek 	 */
869*00b67f09SDavid van Moolenbroek 
870*00b67f09SDavid van Moolenbroek 	REQUIRE(VALID_LEX(lex));
871*00b67f09SDavid van Moolenbroek 	source = HEAD(lex->sources);
872*00b67f09SDavid van Moolenbroek 	REQUIRE(source != NULL);
873*00b67f09SDavid van Moolenbroek 	REQUIRE(tokenp != NULL);
874*00b67f09SDavid van Moolenbroek 	REQUIRE(isc_buffer_consumedlength(source->pushback) != 0 ||
875*00b67f09SDavid van Moolenbroek 		tokenp->type == isc_tokentype_eof);
876*00b67f09SDavid van Moolenbroek 
877*00b67f09SDavid van Moolenbroek 	UNUSED(tokenp);
878*00b67f09SDavid van Moolenbroek 
879*00b67f09SDavid van Moolenbroek 	isc_buffer_first(source->pushback);
880*00b67f09SDavid van Moolenbroek 	lex->paren_count = lex->saved_paren_count;
881*00b67f09SDavid van Moolenbroek 	source->line = source->saved_line;
882*00b67f09SDavid van Moolenbroek 	source->at_eof = ISC_FALSE;
883*00b67f09SDavid van Moolenbroek }
884*00b67f09SDavid van Moolenbroek 
885*00b67f09SDavid van Moolenbroek void
isc_lex_getlasttokentext(isc_lex_t * lex,isc_token_t * tokenp,isc_region_t * r)886*00b67f09SDavid van Moolenbroek isc_lex_getlasttokentext(isc_lex_t *lex, isc_token_t *tokenp, isc_region_t *r)
887*00b67f09SDavid van Moolenbroek {
888*00b67f09SDavid van Moolenbroek 	inputsource *source;
889*00b67f09SDavid van Moolenbroek 
890*00b67f09SDavid van Moolenbroek 	REQUIRE(VALID_LEX(lex));
891*00b67f09SDavid van Moolenbroek 	source = HEAD(lex->sources);
892*00b67f09SDavid van Moolenbroek 	REQUIRE(source != NULL);
893*00b67f09SDavid van Moolenbroek 	REQUIRE(tokenp != NULL);
894*00b67f09SDavid van Moolenbroek 	REQUIRE(isc_buffer_consumedlength(source->pushback) != 0 ||
895*00b67f09SDavid van Moolenbroek 		tokenp->type == isc_tokentype_eof);
896*00b67f09SDavid van Moolenbroek 
897*00b67f09SDavid van Moolenbroek 	UNUSED(tokenp);
898*00b67f09SDavid van Moolenbroek 
899*00b67f09SDavid van Moolenbroek 	INSIST(source->ignored <= isc_buffer_consumedlength(source->pushback));
900*00b67f09SDavid van Moolenbroek 	r->base = (unsigned char *)isc_buffer_base(source->pushback) +
901*00b67f09SDavid van Moolenbroek 		  source->ignored;
902*00b67f09SDavid van Moolenbroek 	r->length = isc_buffer_consumedlength(source->pushback) -
903*00b67f09SDavid van Moolenbroek 		    source->ignored;
904*00b67f09SDavid van Moolenbroek }
905*00b67f09SDavid van Moolenbroek 
906*00b67f09SDavid van Moolenbroek 
907*00b67f09SDavid van Moolenbroek char *
isc_lex_getsourcename(isc_lex_t * lex)908*00b67f09SDavid van Moolenbroek isc_lex_getsourcename(isc_lex_t *lex) {
909*00b67f09SDavid van Moolenbroek 	inputsource *source;
910*00b67f09SDavid van Moolenbroek 
911*00b67f09SDavid van Moolenbroek 	REQUIRE(VALID_LEX(lex));
912*00b67f09SDavid van Moolenbroek 	source = HEAD(lex->sources);
913*00b67f09SDavid van Moolenbroek 
914*00b67f09SDavid van Moolenbroek 	if (source == NULL)
915*00b67f09SDavid van Moolenbroek 		return (NULL);
916*00b67f09SDavid van Moolenbroek 
917*00b67f09SDavid van Moolenbroek 	return (source->name);
918*00b67f09SDavid van Moolenbroek }
919*00b67f09SDavid van Moolenbroek 
920*00b67f09SDavid van Moolenbroek unsigned long
isc_lex_getsourceline(isc_lex_t * lex)921*00b67f09SDavid van Moolenbroek isc_lex_getsourceline(isc_lex_t *lex) {
922*00b67f09SDavid van Moolenbroek 	inputsource *source;
923*00b67f09SDavid van Moolenbroek 
924*00b67f09SDavid van Moolenbroek 	REQUIRE(VALID_LEX(lex));
925*00b67f09SDavid van Moolenbroek 	source = HEAD(lex->sources);
926*00b67f09SDavid van Moolenbroek 
927*00b67f09SDavid van Moolenbroek 	if (source == NULL)
928*00b67f09SDavid van Moolenbroek 		return (0);
929*00b67f09SDavid van Moolenbroek 
930*00b67f09SDavid van Moolenbroek 	return (source->line);
931*00b67f09SDavid van Moolenbroek }
932*00b67f09SDavid van Moolenbroek 
933*00b67f09SDavid van Moolenbroek 
934*00b67f09SDavid van Moolenbroek isc_result_t
isc_lex_setsourcename(isc_lex_t * lex,const char * name)935*00b67f09SDavid van Moolenbroek isc_lex_setsourcename(isc_lex_t *lex, const char *name) {
936*00b67f09SDavid van Moolenbroek 	inputsource *source;
937*00b67f09SDavid van Moolenbroek 	char *newname;
938*00b67f09SDavid van Moolenbroek 
939*00b67f09SDavid van Moolenbroek 	REQUIRE(VALID_LEX(lex));
940*00b67f09SDavid van Moolenbroek 	source = HEAD(lex->sources);
941*00b67f09SDavid van Moolenbroek 
942*00b67f09SDavid van Moolenbroek 	if (source == NULL)
943*00b67f09SDavid van Moolenbroek 		return(ISC_R_NOTFOUND);
944*00b67f09SDavid van Moolenbroek 	newname = isc_mem_strdup(lex->mctx, name);
945*00b67f09SDavid van Moolenbroek 	if (newname == NULL)
946*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOMEMORY);
947*00b67f09SDavid van Moolenbroek 	isc_mem_free(lex->mctx, source->name);
948*00b67f09SDavid van Moolenbroek 	source->name = newname;
949*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
950*00b67f09SDavid van Moolenbroek }
951*00b67f09SDavid van Moolenbroek 
952*00b67f09SDavid van Moolenbroek isc_boolean_t
isc_lex_isfile(isc_lex_t * lex)953*00b67f09SDavid van Moolenbroek isc_lex_isfile(isc_lex_t *lex) {
954*00b67f09SDavid van Moolenbroek 	inputsource *source;
955*00b67f09SDavid van Moolenbroek 
956*00b67f09SDavid van Moolenbroek 	REQUIRE(VALID_LEX(lex));
957*00b67f09SDavid van Moolenbroek 
958*00b67f09SDavid van Moolenbroek 	source = HEAD(lex->sources);
959*00b67f09SDavid van Moolenbroek 
960*00b67f09SDavid van Moolenbroek 	if (source == NULL)
961*00b67f09SDavid van Moolenbroek 		return (ISC_FALSE);
962*00b67f09SDavid van Moolenbroek 
963*00b67f09SDavid van Moolenbroek 	return (source->is_file);
964*00b67f09SDavid van Moolenbroek }
965