1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /* Copyright (c) 1988 AT&T */
23 /* All Rights Reserved */
24
25
26 /*
27 * Copyright (c) 1999 by Sun Microsystems, Inc.
28 * All rights reserved.
29 */
30
31 /*
32 * cscope - interactive C symbol cross-reference
33 *
34 * keyword look-up routine for the C symbol scanner
35 */
36
37 #include "global.h"
38
39 /* keyword text for fast testing of keywords in the scanner */
40 char externtext[] = "extern";
41 char typedeftext[] = "typedef";
42
43 /*
44 * This keyword table is also used for keyword text compression. Keywords
45 * with an index less than the numeric value of a space are replaced with the
46 * control character corresponding to the index, so they cannot be moved
47 * without changing the database file version and adding compatibility code
48 * for old databases.
49 */
50 struct keystruct keyword[] = {
51 { "#define", ' ', MISC, NULL }, /* must be table entry 0 */
52 /* for old databases */
53 { "#include", ' ', MISC, NULL }, /* must be table entry 1 */
54 { "break", '\0', FLOW, NULL }, /* rarely in cross-reference */
55 { "case", ' ', FLOW, NULL },
56 { "char", ' ', DECL, NULL },
57 { "continue", '\0', FLOW, NULL }, /* rarely in cross-reference */
58 { "default", '\0', FLOW, NULL }, /* rarely in cross-reference */
59 { "#define", ' ', MISC, NULL }, /* must be table entry 7 */
60 { "double", ' ', DECL, NULL },
61 { "\t", '\0', MISC, NULL }, /* must be table entry 9 */
62 { "\n", '\0', MISC, NULL }, /* must be table entry 10 */
63 { "else", ' ', FLOW, NULL },
64 { "enum", ' ', DECL, NULL },
65 { externtext, ' ', DECL, NULL },
66 { "float", ' ', DECL, NULL },
67 { "for", '(', FLOW, NULL },
68 { "goto", ' ', FLOW, NULL },
69 { "if", '(', FLOW, NULL },
70 { "int", ' ', DECL, NULL },
71 { "long", ' ', DECL, NULL },
72 { "register", ' ', DECL, NULL },
73 { "return", '\0', FLOW, NULL },
74 { "short", ' ', DECL, NULL },
75 { "sizeof", '\0', MISC, NULL },
76 { "static", ' ', DECL, NULL },
77 { "struct", ' ', DECL, NULL },
78 { "switch", '(', FLOW, NULL },
79 { typedeftext, ' ', DECL, NULL },
80 { "union", ' ', DECL, NULL },
81 { "unsigned", ' ', DECL, NULL },
82 { "void", ' ', DECL, NULL },
83 { "while", '(', FLOW, NULL },
84
85 /* these keywords are not compressed */
86 { "auto", ' ', DECL, NULL },
87 { "do", ' ', FLOW, NULL },
88 { "fortran", ' ', DECL, NULL },
89 { "const", ' ', DECL, NULL },
90 { "signed", ' ', DECL, NULL },
91 { "volatile", ' ', DECL, NULL },
92 };
93
94 #define KEYWORDS (sizeof (keyword) / sizeof (struct keystruct))
95
96 #define HASHMOD (KEYWORDS * 2 + 1)
97
98 static struct keystruct *hashtab[HASHMOD]; /* pointer table */
99
100 /* put the keywords into the symbol table */
101
102 void
initsymtab(void)103 initsymtab(void)
104 {
105 int i, j;
106 struct keystruct *p;
107
108 for (i = 1; i < KEYWORDS; ++i) {
109 p = &keyword[i];
110 j = hash(p->text) % HASHMOD;
111 p->next = hashtab[j];
112 hashtab[j] = p;
113 }
114 }
115
116 /* see if this identifier is a keyword */
117
118 struct keystruct *
lookup(char * ident)119 lookup(char *ident)
120 {
121 struct keystruct *p;
122 int c;
123
124 /* look up the identifier in the keyword table */
125 for (p = hashtab[hash(ident) % HASHMOD]; p != NULL; p = p->next) {
126 if (strequal(ident, p->text)) {
127 if (compress == YES && (c = p - keyword) < ' ') {
128 ident[0] = c; /* compress the keyword */
129 }
130 return (p);
131 }
132 }
133 /* this is an identifier */
134 return (NULL);
135 }
136
137 /* form hash value for string */
138
139 int
hash(char * s)140 hash(char *s)
141 {
142 unsigned i;
143
144 for (i = 0; *s != '\0'; )
145 i += *s++; /* += is faster than <<= for cscope */
146 return (i);
147 }
148