1/*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 1987, 1993, 1994
5 *	The Regents of the University of California.  All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following 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 * 3. Neither the name of the University nor the names of its contributors
16 *    may be used to endorse or promote products derived from this software
17 *    without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#if 0
33#ifndef lint
34static char sccsid[] = "@(#)yacc.c	8.3 (Berkeley) 4/2/94";
35#endif
36#endif
37
38#include <sys/cdefs.h>
39__FBSDID("$FreeBSD$");
40
41#include <ctype.h>
42#include <limits.h>
43#include <stdio.h>
44
45#include "ctags.h"
46
47/*
48 * y_entries:
49 *	find the yacc tags and put them in.
50 */
51void
52y_entries(void)
53{
54	int	c;
55	char	*sp;
56	bool	in_rule;
57	char	tok[MAXTOKEN];
58
59	in_rule = NO;
60
61	while (GETC(!=, EOF))
62		switch (c) {
63		case '\n':
64			SETLINE;
65			/* FALLTHROUGH */
66		case ' ':
67		case '\f':
68		case '\r':
69		case '\t':
70			break;
71		case '{':
72			if (skip_key('}'))
73				in_rule = NO;
74			break;
75		case '\'':
76		case '"':
77			if (skip_key(c))
78				in_rule = NO;
79			break;
80		case '%':
81			if (GETC(==, '%'))
82				return;
83			(void)ungetc(c, inf);
84			break;
85		case '/':
86			if (GETC(==, '*') || c == '/')
87				skip_comment(c);
88			else
89				(void)ungetc(c, inf);
90			break;
91		case '|':
92		case ';':
93			in_rule = NO;
94			break;
95		default:
96			if (in_rule || (!isalpha(c) && c != '.' && c != '_'))
97				break;
98			sp = tok;
99			*sp++ = c;
100			while (GETC(!=, EOF) && (intoken(c) || c == '.'))
101				*sp++ = c;
102			*sp = EOS;
103			get_line();		/* may change before ':' */
104			while (iswhite(c)) {
105				if (c == '\n')
106					SETLINE;
107				if (GETC(==, EOF))
108					return;
109			}
110			if (c == ':') {
111				pfnote(tok, lineno);
112				in_rule = YES;
113			}
114			else
115				(void)ungetc(c, inf);
116		}
117}
118
119/*
120 * toss_yysec --
121 *	throw away lines up to the next "\n%%\n"
122 */
123void
124toss_yysec(void)
125{
126	int	c;			/* read character */
127	int	state;
128
129	/*
130	 * state == 0 : waiting
131	 * state == 1 : received a newline
132	 * state == 2 : received first %
133	 * state == 3 : received second %
134	 */
135	lineftell = ftell(inf);
136	for (state = 0; GETC(!=, EOF);)
137		switch (c) {
138		case '\n':
139			++lineno;
140			lineftell = ftell(inf);
141			if (state == 3)		/* done! */
142				return;
143			state = 1;		/* start over */
144			break;
145		case '%':
146			if (state)		/* if 1 or 2 */
147				++state;	/* goto 3 */
148			break;
149		default:
150			state = 0;		/* reset */
151			break;
152		}
153}
154