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 #pragma ident "%Z%%M% %I% %E% SMI" 32 33 /* 34 * cscope - interactive C symbol cross-reference 35 * 36 * keyword look-up routine for the C symbol scanner 37 */ 38 39 #include "global.h" 40 41 /* keyword text for fast testing of keywords in the scanner */ 42 char externtext[] = "extern"; 43 char typedeftext[] = "typedef"; 44 45 /* 46 * This keyword table is also used for keyword text compression. Keywords 47 * with an index less than the numeric value of a space are replaced with the 48 * control character corresponding to the index, so they cannot be moved 49 * without changing the database file version and adding compatibility code 50 * for old databases. 51 */ 52 struct keystruct keyword[] = { 53 { "#define", ' ', MISC, NULL }, /* must be table entry 0 */ 54 /* for old databases */ 55 { "#include", ' ', MISC, NULL }, /* must be table entry 1 */ 56 { "break", '\0', FLOW, NULL }, /* rarely in cross-reference */ 57 { "case", ' ', FLOW, NULL }, 58 { "char", ' ', DECL, NULL }, 59 { "continue", '\0', FLOW, NULL }, /* rarely in cross-reference */ 60 { "default", '\0', FLOW, NULL }, /* rarely in cross-reference */ 61 { "#define", ' ', MISC, NULL }, /* must be table entry 7 */ 62 { "double", ' ', DECL, NULL }, 63 { "\t", '\0', MISC, NULL }, /* must be table entry 9 */ 64 { "\n", '\0', MISC, NULL }, /* must be table entry 10 */ 65 { "else", ' ', FLOW, NULL }, 66 { "enum", ' ', DECL, NULL }, 67 { externtext, ' ', DECL, NULL }, 68 { "float", ' ', DECL, NULL }, 69 { "for", '(', FLOW, NULL }, 70 { "goto", ' ', FLOW, NULL }, 71 { "if", '(', FLOW, NULL }, 72 { "int", ' ', DECL, NULL }, 73 { "long", ' ', DECL, NULL }, 74 { "register", ' ', DECL, NULL }, 75 { "return", '\0', FLOW, NULL }, 76 { "short", ' ', DECL, NULL }, 77 { "sizeof", '\0', MISC, NULL }, 78 { "static", ' ', DECL, NULL }, 79 { "struct", ' ', DECL, NULL }, 80 { "switch", '(', FLOW, NULL }, 81 { typedeftext, ' ', DECL, NULL }, 82 { "union", ' ', DECL, NULL }, 83 { "unsigned", ' ', DECL, NULL }, 84 { "void", ' ', DECL, NULL }, 85 { "while", '(', FLOW, NULL }, 86 87 /* these keywords are not compressed */ 88 { "auto", ' ', DECL, NULL }, 89 { "do", ' ', FLOW, NULL }, 90 { "fortran", ' ', DECL, NULL }, 91 { "const", ' ', DECL, NULL }, 92 { "signed", ' ', DECL, NULL }, 93 { "volatile", ' ', DECL, NULL }, 94 }; 95 96 #define KEYWORDS (sizeof (keyword) / sizeof (struct keystruct)) 97 98 #define HASHMOD (KEYWORDS * 2 + 1) 99 100 static struct keystruct *hashtab[HASHMOD]; /* pointer table */ 101 102 /* put the keywords into the symbol table */ 103 104 void 105 initsymtab(void) 106 { 107 int i, j; 108 struct keystruct *p; 109 110 for (i = 1; i < KEYWORDS; ++i) { 111 p = &keyword[i]; 112 j = hash(p->text) % HASHMOD; 113 p->next = hashtab[j]; 114 hashtab[j] = p; 115 } 116 } 117 118 /* see if this identifier is a keyword */ 119 120 struct keystruct * 121 lookup(char *ident) 122 { 123 struct keystruct *p; 124 int c; 125 126 /* look up the identifier in the keyword table */ 127 for (p = hashtab[hash(ident) % HASHMOD]; p != NULL; p = p->next) { 128 if (strequal(ident, p->text)) { 129 if (compress == YES && (c = p - keyword) < ' ') { 130 ident[0] = c; /* compress the keyword */ 131 } 132 return (p); 133 } 134 } 135 /* this is an identifier */ 136 return (NULL); 137 } 138 139 /* form hash value for string */ 140 141 int 142 hash(char *s) 143 { 144 unsigned i; 145 146 for (i = 0; *s != '\0'; ) 147 i += *s++; /* += is faster than <<= for cscope */ 148 return (i); 149 } 150