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