121970Sdist /* 235500Sbostic * Copyright (c) 1985 Sun Microsystems, Inc. 335500Sbostic * Copyright (c) 1980 The Regents of the University of California. 433767Sbostic * Copyright (c) 1976 Board of Trustees of the University of Illinois. 533767Sbostic * All rights reserved. 633767Sbostic * 733767Sbostic * Redistribution and use in source and binary forms are permitted 834885Sbostic * provided that the above copyright notice and this paragraph are 934885Sbostic * duplicated in all such forms and that any documentation, 1034885Sbostic * advertising materials, and other materials related to such 1134885Sbostic * distribution and use acknowledge that the software was developed 1235500Sbostic * by the University of California, Berkeley, the University of Illinois, 1335500Sbostic * Urbana, and Sun Microsystems, Inc. The name of either University 1435500Sbostic * or Sun Microsystems may not be used to endorse or promote products 1535500Sbostic * derived from this software without specific prior written permission. 1634885Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1734885Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1834885Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1921970Sdist */ 208804Smckusick 2121970Sdist #ifndef lint 22*35504Sbostic static char sccsid[] = "@(#)lexi.c 5.10 (Berkeley) 09/15/88"; 2333767Sbostic #endif /* not lint */ 2421970Sdist 2533767Sbostic /* 2635500Sbostic * Here we have the token scanner for indent. It scans off one token and puts 2735500Sbostic * it in the global variable "token". It returns a code, indicating the type 2835500Sbostic * of token scanned. 2924455Smckusick */ 308804Smckusick 31*35504Sbostic #include "indent_globs.h" 32*35504Sbostic #include "indent_codes.h" 3324455Smckusick #include "ctype.h" 348804Smckusick 358804Smckusick #define alphanum 1 368804Smckusick #define opchar 3 378804Smckusick 388804Smckusick struct templ { 3924455Smckusick char *rwd; 4024455Smckusick int rwcode; 418804Smckusick }; 428804Smckusick 4324455Smckusick struct templ specials[100] = 448804Smckusick { 458804Smckusick "switch", 1, 468804Smckusick "case", 2, 4724455Smckusick "break", 0, 488804Smckusick "struct", 3, 4924455Smckusick "union", 3, 5024455Smckusick "enum", 3, 518804Smckusick "default", 2, 528804Smckusick "int", 4, 538804Smckusick "char", 4, 548804Smckusick "float", 4, 558804Smckusick "double", 4, 568804Smckusick "long", 4, 578804Smckusick "short", 4, 588804Smckusick "typdef", 4, 598804Smckusick "unsigned", 4, 608804Smckusick "register", 4, 618804Smckusick "static", 4, 628804Smckusick "global", 4, 638804Smckusick "extern", 4, 6424455Smckusick "void", 4, 6524455Smckusick "goto", 0, 6624455Smckusick "return", 0, 678804Smckusick "if", 5, 688804Smckusick "while", 5, 698804Smckusick "for", 5, 708804Smckusick "else", 6, 718804Smckusick "do", 6, 7224455Smckusick "sizeof", 7, 738804Smckusick 0, 0 748804Smckusick }; 758804Smckusick 7624455Smckusick char chartype[128] = 7735500Sbostic { /* this is used to facilitate the decision of 7835500Sbostic * what type (alphanumeric, operator) each 7935500Sbostic * character is */ 808804Smckusick 0, 0, 0, 0, 0, 0, 0, 0, 818804Smckusick 0, 0, 0, 0, 0, 0, 0, 0, 828804Smckusick 0, 0, 0, 0, 0, 0, 0, 0, 838804Smckusick 0, 0, 0, 0, 0, 0, 0, 0, 8433768Sbostic 0, 3, 0, 0, 1, 3, 3, 0, 8535500Sbostic 0, 0, 3, 3, 0, 3, 0, 3, 868804Smckusick 1, 1, 1, 1, 1, 1, 1, 1, 878804Smckusick 1, 1, 0, 0, 3, 3, 3, 3, 888804Smckusick 0, 1, 1, 1, 1, 1, 1, 1, 898804Smckusick 1, 1, 1, 1, 1, 1, 1, 1, 908804Smckusick 1, 1, 1, 1, 1, 1, 1, 1, 918804Smckusick 1, 1, 1, 0, 0, 0, 3, 1, 928804Smckusick 0, 1, 1, 1, 1, 1, 1, 1, 938804Smckusick 1, 1, 1, 1, 1, 1, 1, 1, 948804Smckusick 1, 1, 1, 1, 1, 1, 1, 1, 958804Smckusick 1, 1, 1, 0, 3, 0, 3, 0 968804Smckusick }; 978804Smckusick 988804Smckusick 998804Smckusick 1008804Smckusick 10135500Sbostic int 10224455Smckusick lexi() 10324455Smckusick { 10424455Smckusick register char *tok; /* local pointer to next char in token */ 10535500Sbostic int unary_delim; /* this is set to 1 if the current token 10635500Sbostic * 10724455Smckusick * forces a following operator to be unary */ 10824455Smckusick static int last_code; /* the last token type returned */ 10924455Smckusick static int l_struct; /* set to 1 if the last token was 'struct' */ 11024455Smckusick int code; /* internal code to be returned */ 11124455Smckusick char qchar; /* the delimiter character for a string */ 1128804Smckusick 11324455Smckusick tok = token; /* point to start of place to save token */ 1148804Smckusick unary_delim = false; 11524455Smckusick ps.col_1 = ps.last_nl; /* tell world that this token started in 11635500Sbostic * column 1 iff the last thing scanned was nl */ 11724455Smckusick ps.last_nl = false; 1188804Smckusick 11924455Smckusick while (*buf_ptr == ' ' || *buf_ptr == '\t') { /* get rid of blanks */ 12035500Sbostic ps.col_1 = false; /* leading blanks imply token is not in column 12135500Sbostic * 1 */ 1228804Smckusick if (++buf_ptr >= buf_end) 12324455Smckusick fill_buffer(); 1248804Smckusick } 1258804Smckusick 12635500Sbostic /* Scan an alphanumeric token */ 12735500Sbostic if (chartype[*buf_ptr] == alphanum || buf_ptr[0] == '.' && isdigit(buf_ptr[1])) { 12835500Sbostic /* 12935500Sbostic * we have a character or number 13035500Sbostic */ 13135500Sbostic register char *j; /* used for searching thru list of 13235500Sbostic * 13324455Smckusick * reserved words */ 13424455Smckusick register struct templ *p; 1358804Smckusick 13635500Sbostic if (isdigit(*buf_ptr) || buf_ptr[0] == '.' && isdigit(buf_ptr[1])) { 13735500Sbostic int seendot = 0, 13835500Sbostic seenexp = 0; 13935500Sbostic if (*buf_ptr == '0' && 14035500Sbostic (buf_ptr[1] == 'x' || buf_ptr[1] == 'X')) { 14135500Sbostic *tok++ = *buf_ptr++; 14235500Sbostic *tok++ = *buf_ptr++; 14335500Sbostic while (isxdigit(*buf_ptr)) 14435500Sbostic *tok++ = *buf_ptr++; 14535500Sbostic } 14635500Sbostic else 14735500Sbostic while (1) { 14835500Sbostic if (*buf_ptr == '.') 14935500Sbostic if (seendot) 15035500Sbostic break; 15135500Sbostic else 15235500Sbostic seendot++; 15335500Sbostic *tok++ = *buf_ptr++; 15435500Sbostic if (!isdigit(*buf_ptr) && *buf_ptr != '.') 15535500Sbostic if ((*buf_ptr != 'E' && *buf_ptr != 'e') || seenexp) 15635500Sbostic break; 15735500Sbostic else { 15835500Sbostic seenexp++; 15935500Sbostic seendot++; 16035500Sbostic *tok++ = *buf_ptr++; 16135500Sbostic if (*buf_ptr == '+' || *buf_ptr == '-') 16235500Sbostic *tok++ = *buf_ptr++; 16335500Sbostic } 16435500Sbostic } 16535500Sbostic if (*buf_ptr == 'L' || *buf_ptr == 'l') 16635500Sbostic *tok++ = *buf_ptr++; 16735500Sbostic } 16835500Sbostic else 16935500Sbostic while (chartype[*buf_ptr] == alphanum) { /* copy it over */ 17035500Sbostic *tok++ = *buf_ptr++; 17135500Sbostic if (buf_ptr >= buf_end) 17235500Sbostic fill_buffer(); 17335500Sbostic } 1748804Smckusick *tok++ = '\0'; 17524455Smckusick while (*buf_ptr == ' ' || *buf_ptr == '\t') { /* get rid of blanks */ 17624455Smckusick if (++buf_ptr >= buf_end) 17724455Smckusick fill_buffer(); 17824455Smckusick } 17924455Smckusick ps.its_a_keyword = false; 18024455Smckusick ps.sizeof_keyword = false; 18135500Sbostic if (l_struct) { /* if last token was 'struct', then this token 18235500Sbostic * should be treated as a declaration */ 1838804Smckusick l_struct = false; 1848804Smckusick last_code = ident; 18524455Smckusick ps.last_u_d = true; 1868804Smckusick return (decl); 1878804Smckusick } 18824455Smckusick ps.last_u_d = false; /* Operator after indentifier is binary */ 18924455Smckusick last_code = ident; /* Remember that this is the code we will 19024455Smckusick * return */ 1918804Smckusick 19224455Smckusick /* 19335500Sbostic * This loop will check if the token is a keyword. 19424455Smckusick */ 19524455Smckusick for (p = specials; (j = p->rwd) != 0; p++) { 19624455Smckusick tok = token; /* point at scanned token */ 19724455Smckusick if (*j++ != *tok++ || *j++ != *tok++) 19824455Smckusick continue; /* This test depends on the fact that 19935500Sbostic * identifiers are always at least 1 character 20035500Sbostic * long (ie. the first two bytes of the 20135500Sbostic * identifier are always meaningful) */ 20224455Smckusick if (tok[-1] == 0) 20324455Smckusick break; /* If its a one-character identifier */ 20424455Smckusick while (*tok++ == *j) 20524455Smckusick if (*j++ == 0) 20624455Smckusick goto found_keyword; /* I wish that C had a multi-level 20724455Smckusick * break... */ 20824455Smckusick } 20924455Smckusick if (p->rwd) { /* we have a keyword */ 21024455Smckusick found_keyword: 21124455Smckusick ps.its_a_keyword = true; 21224455Smckusick ps.last_u_d = true; 21324455Smckusick switch (p->rwcode) { 21435500Sbostic case 1: /* it is a switch */ 21535500Sbostic return (swstmt); 21635500Sbostic case 2: /* a case or default */ 21735500Sbostic return (casestmt); 2188804Smckusick 21935500Sbostic case 3: /* a "struct" */ 22035500Sbostic if (ps.p_l_follow) 22135500Sbostic break; /* inside parens: cast */ 22235500Sbostic l_struct = true; 2238804Smckusick 22435500Sbostic /* 22535500Sbostic * Next time around, we will want to know that we have had a 22635500Sbostic * 'struct' 22735500Sbostic */ 22835500Sbostic case 4: /* one of the declaration keywords */ 22935500Sbostic if (ps.p_l_follow) { 23035500Sbostic ps.cast_mask |= 1 << ps.p_l_follow; 23135500Sbostic break; /* inside parens: cast */ 23235500Sbostic } 23335500Sbostic last_code = decl; 23435500Sbostic return (decl); 2358804Smckusick 23635500Sbostic case 5: /* if, while, for */ 23735500Sbostic return (sp_paren); 2388804Smckusick 23935500Sbostic case 6: /* do, else */ 24035500Sbostic return (sp_nparen); 2418804Smckusick 24235500Sbostic case 7: 24335500Sbostic ps.sizeof_keyword = true; 24435500Sbostic default: /* all others are treated like any other 24524455Smckusick * identifier */ 24635500Sbostic return (ident); 24724455Smckusick } /* end of switch */ 24824455Smckusick } /* end of if (found_it) */ 24935500Sbostic if (*buf_ptr == '(' && ps.tos <= 1 && ps.ind_level == 0) { 25035500Sbostic register char *p = buf_ptr; 25135500Sbostic while (p < buf_end) 25235500Sbostic if (*p++ == ')' && *p == ';') 25335500Sbostic goto not_proc; 25424455Smckusick strncpy(ps.procname, token, sizeof ps.procname - 1); 25524455Smckusick ps.in_parameter_declaration = 1; 25635500Sbostic not_proc:; 25724455Smckusick } 25824455Smckusick /* 25924455Smckusick * The following hack attempts to guess whether or not the current 26024455Smckusick * token is in fact a declaration keyword -- one that has been 26135500Sbostic * typedefd 26224455Smckusick */ 26335500Sbostic if (((*buf_ptr == '*' && buf_ptr[1] != '=') || isalpha(*buf_ptr) || *buf_ptr == '_') 26435500Sbostic && !ps.p_l_follow 26535500Sbostic && !ps.block_init 26635500Sbostic && (ps.last_token == rparen || ps.last_token == semicolon || 26735500Sbostic ps.last_token == decl || 26835500Sbostic ps.last_token == lbrace || ps.last_token == rbrace)) { 26924455Smckusick ps.its_a_keyword = true; 27024455Smckusick ps.last_u_d = true; 27124455Smckusick last_code = decl; 27224455Smckusick return decl; 2738804Smckusick } 27424455Smckusick if (last_code == decl) /* if this is a declared variable, then 27524455Smckusick * following sign is unary */ 27624455Smckusick ps.last_u_d = true; /* will make "int a -1" work */ 2778804Smckusick last_code = ident; 27824455Smckusick return (ident); /* the ident is not in the list */ 27924455Smckusick } /* end of procesing for alpanum character */ 28035500Sbostic /* l l l Scan a non-alphanumeric token */ 2818804Smckusick 28235500Sbostic *tok++ = *buf_ptr; /* if it is only a one-character token, it is 28335500Sbostic * moved here */ 2848804Smckusick *tok = '\0'; 2858804Smckusick if (++buf_ptr >= buf_end) 28624455Smckusick fill_buffer(); 2878804Smckusick 2888804Smckusick switch (*token) { 28935500Sbostic case '\n': 29035500Sbostic unary_delim = ps.last_u_d; 29135500Sbostic ps.last_nl = true; /* remember that we just had a newline */ 29235500Sbostic code = (had_eof ? 0 : newline); 29324455Smckusick 29435500Sbostic /* 29535500Sbostic * if data has been exausted, the newline is a dummy, and we should 29635500Sbostic * return code to stop 29735500Sbostic */ 29835500Sbostic break; 2998804Smckusick 30035500Sbostic case '\'': /* start of quoted character */ 30135500Sbostic case '"': /* start of string */ 30235500Sbostic qchar = *token; 30335500Sbostic if (troff) { 30435500Sbostic tok[-1] = '`'; 30535500Sbostic if (qchar == '"') 30635500Sbostic *tok++ = '`'; 30735500Sbostic tok = chfont(&bodyf, &stringf, tok); 30835500Sbostic } 30935500Sbostic do { /* copy the string */ 31035500Sbostic while (1) { /* move one character or [/<char>]<char> */ 31135500Sbostic if (*buf_ptr == '\n') { 31235500Sbostic printf("%d: Unterminated literal\n", line_no); 31335500Sbostic goto stop_lit; 31435500Sbostic } 31535500Sbostic *tok = *buf_ptr++; 31635500Sbostic if (buf_ptr >= buf_end) 31735500Sbostic fill_buffer(); 31835500Sbostic if (had_eof || ((tok - token) > (bufsize - 2))) { 31935500Sbostic printf("Unterminated literal\n"); 32035500Sbostic ++tok; 32135500Sbostic goto stop_lit; 32235500Sbostic /* get outof literal copying loop */ 32335500Sbostic } 32435500Sbostic if (*tok == BACKSLASH) { /* if escape, copy extra char */ 32535500Sbostic if (*buf_ptr == '\n') /* check for escaped newline */ 32635500Sbostic ++line_no; 32735500Sbostic if (troff) { 32835500Sbostic *++tok = BACKSLASH; 32935500Sbostic if (*buf_ptr == BACKSLASH) 33035500Sbostic *++tok = BACKSLASH; 3318804Smckusick } 33235500Sbostic *++tok = *buf_ptr++; 33335500Sbostic ++tok; /* we must increment this again because we 33435500Sbostic * copied two chars */ 3358804Smckusick if (buf_ptr >= buf_end) 33624455Smckusick fill_buffer(); 33735500Sbostic } 33835500Sbostic else 33935500Sbostic break; /* we copied one character */ 34035500Sbostic } /* end of while (1) */ 34135500Sbostic } while (*tok++ != qchar); 34235500Sbostic if (troff) { 34335500Sbostic tok = chfont(&stringf, &bodyf, tok - 1); 34435500Sbostic if (qchar == '"') 34524455Smckusick *tok++ = '\''; 34635500Sbostic } 34735500Sbostic stop_lit: 34835500Sbostic code = ident; 34935500Sbostic break; 3508804Smckusick 35135500Sbostic case ('('): 35235500Sbostic case ('['): 35335500Sbostic unary_delim = true; 35435500Sbostic code = lparen; 35535500Sbostic break; 3568804Smckusick 35735500Sbostic case (')'): 35835500Sbostic case (']'): 35935500Sbostic code = rparen; 36035500Sbostic break; 3618804Smckusick 36235500Sbostic case '#': 36335500Sbostic unary_delim = ps.last_u_d; 36435500Sbostic code = preesc; 36535500Sbostic break; 3668804Smckusick 36735500Sbostic case '?': 36835500Sbostic unary_delim = true; 36935500Sbostic code = question; 37035500Sbostic break; 3718804Smckusick 37235500Sbostic case (':'): 37335500Sbostic code = colon; 37435500Sbostic unary_delim = true; 37535500Sbostic break; 3768804Smckusick 37735500Sbostic case (';'): 37835500Sbostic unary_delim = true; 37935500Sbostic code = semicolon; 38035500Sbostic break; 3818804Smckusick 38235500Sbostic case ('{'): 38335500Sbostic unary_delim = true; 38424455Smckusick 38535500Sbostic /* 38635500Sbostic * if (ps.in_or_st) ps.block_init = 1; 38735500Sbostic */ 38835500Sbostic /* ? code = ps.block_init ? lparen : lbrace; */ 38935500Sbostic code = lbrace; 39035500Sbostic break; 3918804Smckusick 39235500Sbostic case ('}'): 39335500Sbostic unary_delim = true; 39435500Sbostic /* ? code = ps.block_init ? rparen : rbrace; */ 39535500Sbostic code = rbrace; 39635500Sbostic break; 3978804Smckusick 39835500Sbostic case 014: /* a form feed */ 39935500Sbostic unary_delim = ps.last_u_d; 40035500Sbostic ps.last_nl = true; /* remember this so we can set 'ps.col_1' 40124455Smckusick * right */ 40235500Sbostic code = form_feed; 40335500Sbostic break; 4048804Smckusick 40535500Sbostic case (','): 40635500Sbostic unary_delim = true; 40735500Sbostic code = comma; 40835500Sbostic break; 4098804Smckusick 41035500Sbostic case '.': 41135500Sbostic unary_delim = false; 41235500Sbostic code = period; 41335500Sbostic break; 4148804Smckusick 41535500Sbostic case '-': 41635500Sbostic case '+': /* check for -, +, --, ++ */ 41735500Sbostic code = (ps.last_u_d ? unary_op : binary_op); 41835500Sbostic unary_delim = true; 4198804Smckusick 42035500Sbostic if (*buf_ptr == token[0]) { 42135500Sbostic /* check for doubled character */ 42235500Sbostic *tok++ = *buf_ptr++; 42335500Sbostic /* buffer overflow will be checked at end of loop */ 42435500Sbostic if (last_code == ident || last_code == rparen) { 42535500Sbostic code = (ps.last_u_d ? unary_op : postop); 42635500Sbostic /* check for following ++ or -- */ 42735500Sbostic unary_delim = false; 4288804Smckusick } 42935500Sbostic } 43035500Sbostic else if (*buf_ptr == '=') 43135500Sbostic /* check for operator += */ 43235500Sbostic *tok++ = *buf_ptr++; 43335500Sbostic else if (*buf_ptr == '>') { 43435500Sbostic /* check for operator -> */ 43535500Sbostic *tok++ = *buf_ptr++; 43635500Sbostic if (!pointer_as_binop) { 43735500Sbostic unary_delim = false; 43835500Sbostic code = unary_op; 43935500Sbostic ps.want_blank = false; 44024455Smckusick } 44135500Sbostic } 44235500Sbostic break; /* buffer overflow will be checked at end of 44335500Sbostic * switch */ 4448804Smckusick 44535500Sbostic case '=': 44635500Sbostic if (ps.in_or_st) 44735500Sbostic ps.block_init = 1; 44835500Sbostic #ifdef undef 44935500Sbostic if (chartype[*buf_ptr] == opchar) { /* we have two char assignment */ 45035500Sbostic tok[-1] = *buf_ptr++; 45135500Sbostic if ((tok[-1] == '<' || tok[-1] == '>') && tok[-1] == *buf_ptr) 45235500Sbostic *tok++ = *buf_ptr++; 45335500Sbostic *tok++ = '='; /* Flip =+ to += */ 45435500Sbostic *tok = 0; 45535500Sbostic } 45635500Sbostic #else 45735500Sbostic if (*buf_ptr == '=') {/* == */ 45835500Sbostic *tok++ = '='; /* Flip =+ to += */ 45935500Sbostic buf_ptr++; 46035500Sbostic *tok = 0; 46135500Sbostic } 46235500Sbostic #endif 46335500Sbostic code = binary_op; 46435500Sbostic unary_delim = true; 46535500Sbostic break; 46635500Sbostic /* can drop thru!!! */ 4678804Smckusick 46835500Sbostic case '>': 46935500Sbostic case '<': 47035500Sbostic case '!': /* ops like <, <<, <=, !=, etc */ 47135500Sbostic if (*buf_ptr == '>' || *buf_ptr == '<' || *buf_ptr == '=') { 47235500Sbostic *tok++ = *buf_ptr; 47335500Sbostic if (++buf_ptr >= buf_end) 47435500Sbostic fill_buffer(); 47535500Sbostic } 47635500Sbostic if (*buf_ptr == '=') 47735500Sbostic *tok++ = *buf_ptr++; 47835500Sbostic code = (ps.last_u_d ? unary_op : binary_op); 47935500Sbostic unary_delim = true; 48035500Sbostic break; 4818804Smckusick 48235500Sbostic default: 48335500Sbostic if (token[0] == '/' && *buf_ptr == '*') { 48435500Sbostic /* it is start of comment */ 48535500Sbostic *tok++ = '*'; 4868804Smckusick 48735500Sbostic if (++buf_ptr >= buf_end) 48835500Sbostic fill_buffer(); 4898804Smckusick 49035500Sbostic code = comment; 49135500Sbostic unary_delim = ps.last_u_d; 49235500Sbostic break; 49335500Sbostic } 49435500Sbostic while (*(tok - 1) == *buf_ptr || *buf_ptr == '=') { 49535500Sbostic /* 49635500Sbostic * handle ||, &&, etc, and also things as in int *****i 49735500Sbostic */ 49835500Sbostic *tok++ = *buf_ptr; 49935500Sbostic if (++buf_ptr >= buf_end) 50035500Sbostic fill_buffer(); 50135500Sbostic } 50235500Sbostic code = (ps.last_u_d ? unary_op : binary_op); 50335500Sbostic unary_delim = true; 5048804Smckusick 5058804Smckusick 50624455Smckusick } /* end of switch */ 5078804Smckusick if (code != newline) { 5088804Smckusick l_struct = false; 5098804Smckusick last_code = code; 5108804Smckusick } 51124455Smckusick if (buf_ptr >= buf_end) /* check for input buffer empty */ 51224455Smckusick fill_buffer(); 51324455Smckusick ps.last_u_d = unary_delim; 51424455Smckusick *tok = '\0'; /* null terminate the token */ 5158804Smckusick return (code); 5168804Smckusick }; 51724455Smckusick 51835500Sbostic /* 51935500Sbostic * Add the given keyword to the keyword table, using val as the keyword type 52035500Sbostic */ 52135500Sbostic addkey(key, val) 52235500Sbostic char *key; 52324455Smckusick { 52424455Smckusick register struct templ *p = specials; 52524455Smckusick while (p->rwd) 52624455Smckusick if (p->rwd[0] == key[0] && strcmp(p->rwd, key) == 0) 52724455Smckusick return; 52824455Smckusick else 52924455Smckusick p++; 53024455Smckusick if (p >= specials + sizeof specials / sizeof specials[0]) 53124455Smckusick return; /* For now, table overflows are silently 53235500Sbostic * ignored */ 53324455Smckusick p->rwd = key; 53424455Smckusick p->rwcode = val; 53524455Smckusick p[1].rwd = 0; 53624455Smckusick p[1].rwcode = 0; 53724455Smckusick return; 53824455Smckusick } 539