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 */ 42char externtext[] = "extern"; 43char 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 */ 52struct 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 100static struct keystruct *hashtab[HASHMOD]; /* pointer table */ 101 102/* put the keywords into the symbol table */ 103 104void 105initsymtab(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 120struct keystruct * 121lookup(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 141int 142hash(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