Annotation of coherent/g/usr/bin/tic/comp_scan.c, revision 1.1.1.1

1.1       root        1: /*********************************************************************
                      2: *                         COPYRIGHT NOTICE                           *
                      3: **********************************************************************
                      4: *        This software is copyright (C) 1982 by Pavel Curtis         *
                      5: *                                                                    *
                      6: *        Permission is granted to reproduce and distribute           *
                      7: *        this file by any means so long as no fee is charged         *
                      8: *        above a nominal handling fee and so long as this            *
                      9: *        notice is always included in the copies.                    *
                     10: *                                                                    *
                     11: *        Other rights are reserved except as explicitly granted      *
                     12: *        by written permission of the author.                        *
                     13: *                Pavel Curtis                                        *
                     14: *                Computer Science Dept.                              *
                     15: *                405 Upson Hall                                      *
                     16: *                Cornell University                                  *
                     17: *                Ithaca, NY 14853                                    *
                     18: *                                                                    *
                     19: *                Ph- (607) 256-4934                                  *
                     20: *                                                                    *
                     21: *                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
                     22: *                decvax!cornell!pavel       (UUCPnet)                *
                     23: *********************************************************************/
                     24: 
                     25: /*
                     26:  *     comp_scan.c --- Lexical scanner for terminfo compiler.
                     27:  *
                     28:  *   $Log:     comp_scan.c,v $
                     29:  * Revision 1.1  92/03/13  10:45:48  bin
                     30:  * Initial revision
                     31:  * 
                     32:  * Revision 2.1  82/10/25  14:45:55  pavel
                     33:  * Added Copyright Notice
                     34:  * 
                     35:  * Revision 2.0  82/10/24  15:17:12  pavel
                     36:  * Beta-one Test Release
                     37:  * 
                     38:  * Revision 1.3  82/08/23  22:30:03  pavel
                     39:  * The REAL Alpha-one Release Version
                     40:  * 
                     41:  * Revision 1.2  82/08/19  19:10:06  pavel
                     42:  * Alpha Test Release One
                     43:  * 
                     44:  * Revision 1.1  82/08/12  18:37:46  pavel
                     45:  * Initial revision
                     46:  * 
                     47:  *
                     48:  */
                     49: 
                     50: #ifndef COHERENT
                     51: static char RCSid[] =
                     52:        "$Header: /src386/usr/bin/tic/RCS/comp_scan.c,v 1.1 92/03/13 10:45:48 bin Exp $";
                     53: #endif
                     54: 
                     55: #include <stdio.h>
                     56: #include <ctype.h>
                     57: #include "compiler.h"
                     58: 
                     59: #define iswhite(ch)    (ch == ' '  ||  ch == '\t')
                     60: 
                     61: 
                     62: static int     first_column;           /* See 'next_char()' below */
                     63: 
                     64: 
                     65: 
                     66: /*
                     67:  *     int
                     68:  *     get_token()
                     69:  *
                     70:  *     Scans the input for the next token, storing the specifics in the
                     71:  *     global structure 'curr_token' and returning one of the following:
                     72:  *
                     73:  *             NAMES           A line beginning in column 1.  'name'
                     74:  *                             will be set to point to everything up to
                     75:  *                             but not including the first comma on the line.
                     76:  *             BOOLEAN         An entry consisting of a name followed by
                     77:  *                             a comma.  'name' will be set to point to the
                     78:  *                             name of the capability.
                     79:  *             NUMBER          An entry of the form
                     80:  *                                     name#digits,
                     81:  *                             'name' will be set to point to the capability
                     82:  *                             name and 'valnumber' to the number given.
                     83:  *             STRING          An entry of the form
                     84:  *                                     name=characters,
                     85:  *                             'name' is set to the capability name and
                     86:  *                             'valstring' to the string of characters, with
                     87:  *                             input translations done.
                     88:  *             CANCEL          An entry of the form
                     89:  *                                     name@,
                     90:  *                             'name' is set to the capability name and
                     91:  *                             'valnumber' to -1.
                     92:  *             EOF             The end of the file has been reached.
                     93:  *
                     94:  */
                     95: 
                     96: int
                     97: get_token()
                     98: {
                     99:        long            number;
                    100:        int             type;
                    101:        register char   ch;
                    102:        static char     buffer[1024];
                    103:        register char   *ptr;
                    104:        int             dot_flag = FALSE;
                    105: 
                    106:        while ((ch = next_char()) == '\n'  ||  iswhite(ch))
                    107:            ;
                    108:        
                    109:        if (ch == EOF)
                    110:            type = EOF;
                    111:        else
                    112:        {
                    113:            if (ch == '.')
                    114:            {
                    115:                dot_flag = TRUE;
                    116: 
                    117:                while ((ch = next_char()) == ' '  ||  ch == '\t')
                    118:                    ;
                    119:            }
                    120: 
                    121:            if (! isalnum(ch))
                    122:            {
                    123:                 warning("Illegal character - '%c'", ch);
                    124:                 panic_mode(',');
                    125:            }
                    126: 
                    127:            ptr = buffer;
                    128:            *(ptr++) = ch;
                    129: 
                    130:            if (first_column)
                    131:            {
                    132:                while ((ch = next_char()) != ',' && ch != '\n' && ch != EOF)
                    133:                    *(ptr++) = ch;
                    134:                
                    135:                if (ch == EOF)
                    136:                    err_abort("Premature EOF");
                    137:                else if (ch == '\n') {
                    138:                    warning("Newline in middle of terminal name");
                    139:                    panic_mode(',');
                    140:                }
                    141:                
                    142:                *ptr = '\0';
                    143:                curr_token.tk_name = buffer;
                    144:                type = NAMES;
                    145:            }
                    146:            else
                    147:            {
                    148:                ch = next_char();
                    149:                while (isalnum(ch))
                    150:                {
                    151:                    *(ptr++) = ch;
                    152:                    ch = next_char();
                    153:                }
                    154: 
                    155:                *ptr++ = '\0';
                    156:                switch (ch)
                    157:                {
                    158:                    case ',':
                    159:                        curr_token.tk_name = buffer;
                    160:                        type = BOOLEAN;
                    161:                        break;
                    162: 
                    163:                    case '@':
                    164:                        if (next_char() != ',')
                    165:                            warning("Missing comma");
                    166:                        curr_token.tk_name = buffer;
                    167:                        type = CANCEL;
                    168:                        break;
                    169: 
                    170:                    case '#':
                    171:                        number = 0;
                    172:                        while (isdigit(ch = next_char()))
                    173:                            number = number * 10 + ch - '0';
                    174:                        if (ch != ',')
                    175:                            warning("Missing comma");
                    176:                        curr_token.tk_name = buffer;
                    177:                        curr_token.tk_valnumber = number;
                    178:                        type = NUMBER;
                    179:                        break;
                    180:                    
                    181:                    case '=':
                    182:                        ch = trans_string(ptr);
                    183:                        if (ch != ',')
                    184:                            warning("Missing comma");
                    185:                        curr_token.tk_name = buffer;
                    186:                        curr_token.tk_valstring = ptr;
                    187:                        type = STRING;
                    188:                        break;
                    189: 
                    190:                    default:
                    191:                        warning("Illegal character - '%c'", ch);
                    192:                }
                    193:            } /* end else (first_column == FALSE) */
                    194:        } /* end else (ch != EOF) */
                    195: 
                    196:        if (dot_flag == TRUE)
                    197:            DEBUG(8, "Commented out ", "");
                    198: 
                    199:        if (debug_level >= 8)
                    200:        {
                    201:            fprintf(stderr, "Token: ");
                    202:            switch (type)
                    203:            {
                    204:                case BOOLEAN:
                    205:                    fprintf(stderr, "Boolean;  name='%s'\n",
                    206:                                                           curr_token.tk_name);
                    207:                    break;
                    208:                
                    209:                case NUMBER:
                    210:                    fprintf(stderr, "Number; name='%s', value=%d\n",
                    211:                                curr_token.tk_name, curr_token.tk_valnumber);
                    212:                    break;
                    213:                
                    214:                case STRING:
                    215:                    fprintf(stderr, "String; name='%s', value='%s'\n",
                    216:                                curr_token.tk_name, curr_token.tk_valstring);
                    217:                    break;
                    218:                
                    219:                case CANCEL:
                    220:                    fprintf(stderr, "Cancel; name='%s'\n",
                    221:                                                           curr_token.tk_name);
                    222:                    break;
                    223:                
                    224:                case NAMES:
                    225: 
                    226:                    fprintf(stderr, "Names; value='%s'\n",
                    227:                                                           curr_token.tk_name);
                    228:                    break;
                    229: 
                    230:                case EOF:
                    231:                    fprintf(stderr, "End of file\n");
                    232:                    break;
                    233: 
                    234:                default:
                    235:                    warning("Bad token type");
                    236:            }
                    237:        }
                    238: 
                    239:        if (dot_flag == TRUE)           /* if commented out, use the next one */
                    240:            type = get_token();
                    241: 
                    242:        return(type);
                    243: }
                    244: 
                    245: 
                    246: 
                    247: /*
                    248:  *     char
                    249:  *     next_char()
                    250:  *
                    251:  *     Returns the next character in the input stream.  Comments and leading
                    252:  *     white space are stripped.  The global state variable 'firstcolumn' is
                    253:  *     set TRUE if the character returned is from the first column of the input
                    254:  *     line.  The global variable curr_line is incremented for each new line.
                    255:  *     The global variable curr_file_pos is set to the file offset of the
                    256:  *     beginning of each line.
                    257:  *
                    258:  */
                    259: 
                    260: int    curr_column = -1;
                    261: char   line[1024];
                    262: 
                    263: char
                    264: next_char()
                    265: {
                    266:        char    *rtn_value;
                    267:        long    ftell();
                    268: 
                    269:        if (curr_column < 0  ||  curr_column > 1023  ||
                    270:                                                    line[curr_column] == '\0')
                    271:        {
                    272:            do
                    273:            {
                    274:                curr_file_pos = ftell(stdin);
                    275: 
                    276:                if ((rtn_value = fgets(line, 1024, stdin)) != NULL)
                    277:                    curr_line++;
                    278:            } while (rtn_value != NULL  &&  line[0] == '#');
                    279: 
                    280:            if (rtn_value == NULL)
                    281:                return (EOF);
                    282: 
                    283:            curr_column = 0;
                    284:            while (iswhite(line[curr_column]))
                    285:                curr_column++;
                    286:        }
                    287: 
                    288:        if (curr_column == 0  &&  line[0] != '\n')
                    289:            first_column = TRUE;
                    290:        else
                    291:            first_column = FALSE;
                    292:        
                    293:        return (line[curr_column++]);
                    294: }
                    295: 
                    296: 
                    297: backspace()
                    298: {
                    299:        curr_column--;
                    300: 
                    301:        if (curr_column < 0)
                    302:            syserr_abort("Backspaced off beginning of line");
                    303: }
                    304: 
                    305: 
                    306: 
                    307: /*
                    308:  *     reset_input()
                    309:  *
                    310:  *     Resets the input-reading routines.  Used after a seek has been done.
                    311:  *
                    312:  */
                    313: 
                    314: reset_input()
                    315: {
                    316:        curr_column = -1;
                    317: }
                    318: 
                    319: 
                    320: 
                    321: /*
                    322:  *     char
                    323:  *     trans_string(ptr)
                    324:  *
                    325:  *     Reads characters using next_char() until encountering a comma, newline
                    326:  *     or end-of-file.  The returned value is the character which caused
                    327:  *     reading to stop.  The following translations are done on the input:
                    328:  *
                    329:  *             ^X  goes to  ctrl-X (i.e. X & 037)
                    330:  *             {\E,\n,\r,\b,\t,\f}  go to
                    331:  *                     {ESCAPE,newline,carriage-return,backspace,tab,formfeed}
                    332:  *             {\^,\\}  go to  {carat,backslash}
                    333:  *             \ddd (for ddd = up to three octal digits)  goes to
                    334:  *                                                     the character ddd
                    335:  *
                    336:  *             \e == \E
                    337:  *             \0 == \200
                    338:  *
                    339:  */
                    340: 
                    341: char
                    342: trans_string(ptr)
                    343: char   *ptr;
                    344: {
                    345:        register int    count = 0;
                    346:        int             number;
                    347:        int             i;
                    348:         char           ch;
                    349: 
                    350:        while ((ch = next_char()) != ','  &&  ch != EOF)
                    351:        {
                    352:            if (ch == '^')
                    353:            {
                    354:                ch = next_char();
                    355:                if (ch == EOF)
                    356:                    err_abort("Premature EOF");
                    357: 
                    358:                if (! isprint(ch))
                    359:                {
                    360:                    warning("Illegal ^ character - '%c'", ch);
                    361:                }
                    362: 
                    363:                *(ptr++) = ch & 037;
                    364:            }
                    365:            else if (ch == '\\')
                    366:            {
                    367:                ch = next_char();
                    368:                if (ch == EOF)
                    369:                    err_abort("Premature EOF");
                    370:                
                    371:                if (ch >= '0'  &&  ch <= '7')
                    372:                {
                    373:                    number = ch - '0';
                    374:                    for (i=0; i < 2; i++)
                    375:                    {
                    376:                        ch = next_char();
                    377:                        if (ch == EOF)
                    378:                            err_abort("Premature EOF");
                    379:                        
                    380:                        if (ch < '0'  ||  ch > '7')
                    381:                        {
                    382:                            backspace();
                    383:                            break;
                    384:                        }
                    385: 
                    386:                        number = number * 8 + ch - '0';
                    387:                    }
                    388: 
                    389:                    if (number == 0)
                    390:                        number = 0200;
                    391:                    *(ptr++) = (char) number;
                    392:                }
                    393:                else
                    394:                {
                    395:                    switch (ch)
                    396:                    {
                    397:                        case 'E':
                    398:                        case 'e':       *(ptr++) = '\033';      break;
                    399:                        
                    400:                        case 'l':
                    401:                        case 'n':       *(ptr++) = '\n';        break;
                    402:                        
                    403:                        case 'r':       *(ptr++) = '\r';        break;
                    404: 
                    405:                        case 'b':       *(ptr++) = '\b';        break;
                    406: 
                    407:                        case 's':       *(ptr++) = ' ';         break;
                    408:                        
                    409:                        case 'f':       *(ptr++) = '\014';      break;
                    410:                        
                    411:                        case 't':       *(ptr++) = '\t';        break;
                    412:                        
                    413:                        case '\\':      *(ptr++) = '\\';        break;
                    414:                        
                    415:                        case '^':       *(ptr++) = '^';         break;
                    416: 
                    417:                        case ',':       *(ptr++) = ',';         break;
                    418: 
                    419:                        case ':':       *(ptr++) = ':';         break;
                    420: 
                    421:                        default:
                    422:                            warning("Illegal character in \\ sequence");
                    423:                            *(ptr++) = ch;
                    424:                    } /* endswitch (ch) */
                    425:                } /* endelse (ch < '0' ||  ch > '7') */
                    426:            } /* end else if (ch == '\\') */
                    427:            else
                    428:            {
                    429:                *(ptr++) = ch;
                    430:            }
                    431:            
                    432:            count ++;
                    433: 
                    434:            if (count > 500)
                    435:                warning("Very long string found.  Missing comma?");
                    436:        } /* end while */
                    437: 
                    438:        *ptr = '\0';
                    439: 
                    440:        return(ch);
                    441: }
                    442: 
                    443: /*
                    444:  * Panic mode error recovery - skip everything until a "ch" is found.
                    445:  */
                    446: panic_mode(ch)
                    447: char ch;
                    448: {
                    449:        int c;
                    450: 
                    451:        for (;;) {
                    452:                c = next_char();
                    453:                if (c == ch)
                    454:                        return;
                    455:                if (c == EOF);
                    456:                        return;
                    457:        }
                    458: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.