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 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 * 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 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