Annotation of coherent/g/usr/lib/ncurses/comp_parse.c, revision 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_parse.c -- The high-level (ha!) parts of the compiler,
        !            27:  *                     that is, the routines which drive the scanner,
        !            28:  *                     etc.
        !            29:  *
        !            30:  *   $Log:     comp_parse.c,v $
        !            31:  * Revision 1.11  93/04/12  14:13:03  bin
        !            32:  * Udo: third color update
        !            33:  * 
        !            34:  * Revision 1.5  92/06/02  12:04:31  bin
        !            35:  * *** empty log message ***
        !            36:  * 
        !            37:  * Revision 1.2  92/04/13  14:36:22  bin
        !            38:  * update by vlad
        !            39:  * 
        !            40:  * Revision 3.2  91/07/28  13:59:10  munk
        !            41:  * Made all the large arrays static
        !            42:  *
        !            43:  * Revision 3.1  84/12/13  11:19:32  john
        !            44:  * Revisions by Mark Horton
        !            45:  * 
        !            46:  * Revision 2.1  82/10/25  14:45:43  pavel
        !            47:  * Added Copyright Notice
        !            48:  * 
        !            49:  * Revision 2.0  82/10/24  15:16:39  pavel
        !            50:  * Beta-one Test Release
        !            51:  * 
        !            52:  * Revision 1.3  82/08/23  22:29:39  pavel
        !            53:  * The REAL Alpha-one Release Version
        !            54:  * 
        !            55:  * Revision 1.2  82/08/19  19:09:53  pavel
        !            56:  * Alpha Test Release One
        !            57:  * 
        !            58:  * Revision 1.1  82/08/12  18:37:12  pavel
        !            59:  * Initial revision
        !            60:  * 
        !            61:  *
        !            62:  */
        !            63: 
        !            64: #ifdef RCSHDR
        !            65: static char RCSid[] =
        !            66:        "$Header: /src386/usr/lib/ncurses/RCS/comp_parse.c,v 1.11 93/04/12 14:13:03 bin Exp Locker: bin $";
        !            67: #endif
        !            68: 
        !            69: #include <sys/types.h>
        !            70: #include <sys/stat.h>
        !            71: #include <stdio.h>
        !            72: #include <ctype.h>
        !            73: #include "compiler.h"
        !            74: #include "term.h"
        !            75: #include "object.h"
        !            76: 
        !            77: char   *string_table;
        !            78: int    next_free;      /* next free character in string_table */
        !            79: int    table_size = 0; /* current string_table size */
        !            80: short  term_names;     /* string table offset - current terminal */
        !            81: int    part2 = 0;      /* set to allow old compiled defns to be used */
        !            82: int    complete = 0;   /* 1 if entry done with no forward uses */
        !            83: 
        !            84: struct use_item
        !            85: {
        !            86:        long    offset;
        !            87:        struct use_item *fptr, *bptr;
        !            88: };
        !            89: 
        !            90: struct use_header
        !            91: {
        !            92:        struct use_item *head, *tail;
        !            93: };
        !            94: 
        !            95: struct use_header      use_list = {NULL, NULL};
        !            96: int                    use_count = 0;
        !            97: 
        !            98: /*
        !            99:  *  The use_list is a doubly-linked list with NULLs terminating the lists:
        !           100:  *
        !           101:  *        use_item    use_item    use_item
        !           102:  *       ---------   ---------   ---------
        !           103:  *       |       |   |       |   |       |   offset
        !           104:  *        |-------|   |-------|   |-------|
        !           105:  *       |   ----+-->|   ----+-->|  NULL |   fptr
        !           106:  *       |-------|   |-------|   |-------|
        !           107:  *       |  NULL |<--+----   |<--+----   |   bptr
        !           108:  *       ---------   ---------   ---------
        !           109:  *       ^                       ^
        !           110:  *       |  ------------------   |
        !           111:  *       |  |       |        |   |
        !           112:  *       +--+----   |    ----+---+
        !           113:  *          |       |        |
        !           114:  *          ------------------
        !           115:  *            head     tail
        !           116:  *               use_list
        !           117:  *
        !           118:  */
        !           119: 
        !           120: 
        !           121: /*
        !           122:  *     compile()
        !           123:  *
        !           124:  *     Main loop of the compiler.
        !           125:  *
        !           126:  *     get_token()
        !           127:  *     if curr_token != NAMES
        !           128:  *         err_abort()
        !           129:  *     while (not at end of file)
        !           130:  *         do an entry
        !           131:  *
        !           132:  */
        !           133: 
        !           134: compile()
        !           135: {
        !           136:        static char             line[1024];
        !           137:        int                     token_type;
        !           138:        struct use_item *ptr;
        !           139:        int                     old_use_count;
        !           140: 
        !           141:        token_type = get_token();
        !           142: 
        !           143:        if (token_type != NAMES)
        !           144:            err_abort("File does not start with terminal names in column one");
        !           145:        
        !           146:        while (token_type != EOF)
        !           147:            token_type = do_entry((struct use_item *) 0);
        !           148: 
        !           149:        DEBUG(2, "Starting handling of forward USE's\n", "");
        !           150: 
        !           151:        for (part2=0; part2<2; part2++) {
        !           152:            old_use_count = -1;
        !           153:        DEBUG(2, "\n\nPART %d\n\n", part2);
        !           154:            while (use_list.head != NULL  &&  old_use_count != use_count)
        !           155:            {
        !           156:                old_use_count = use_count;
        !           157:                for (ptr = use_list.tail; ptr != NULL; ptr = ptr->bptr)
        !           158:                {
        !           159:                    fseek(stdin, ptr->offset, 0);
        !           160:                    reset_input();
        !           161:                    if ((token_type = get_token()) != NAMES)
        !           162:                        syserr_abort("Token after a seek not NAMES");
        !           163:                    (void) do_entry(ptr);
        !           164:                    if (complete)
        !           165:                        dequeue(ptr);
        !           166:                }
        !           167: 
        !           168:                for (ptr = use_list.head; ptr != NULL; ptr = ptr->fptr)
        !           169:                {
        !           170:                    fseek(stdin, ptr->offset, 0);
        !           171:                    reset_input();
        !           172:                    if ((token_type = get_token()) != NAMES)
        !           173:                        syserr_abort("Token after a seek not NAMES");
        !           174:                    (void) do_entry(ptr);
        !           175:                    if (complete)
        !           176:                        dequeue(ptr);
        !           177:                }
        !           178:                
        !           179:                DEBUG(2, "Finished a pass through enqueued forward USE's\n", "");
        !           180:            }
        !           181:        }
        !           182: 
        !           183:        if (use_list.head != NULL)
        !           184:        {
        !           185:            fprintf(stderr, "\nError in following up use-links.  Either there is\n");
        !           186:            fprintf(stderr, "a loop in the links or they reference non-existant\n");
        !           187:            fprintf(stderr, "terminals.  The following is a list of the entries\n");
        !           188:            fprintf(stderr, "involved:\n\n");
        !           189: 
        !           190:            for (ptr = use_list.head; ptr != NULL; ptr = ptr->fptr)
        !           191:            {
        !           192:                fseek(stdin, ptr->offset, 0);
        !           193:                fgets(line, 1024, stdin);
        !           194:                fprintf(stderr, "%s", line);
        !           195:            }
        !           196: 
        !           197:            exit(1);
        !           198:        }
        !           199: }
        !           200: 
        !           201: 
        !           202: dump_list(str)
        !           203: char *str;
        !           204: {
        !           205:        struct use_item *ptr;
        !           206:        static char line[512];
        !           207: 
        !           208:        fprintf(stderr, "dump_list %s\n", str);
        !           209:        for (ptr = use_list.head; ptr != NULL; ptr = ptr->fptr)
        !           210:        {
        !           211:                fseek(stdin, ptr->offset, 0);
        !           212:                fgets(line, 1024, stdin);
        !           213:                fprintf(stderr, "ptr %x off %d bptr %x fptr %x str %s",
        !           214:                ptr, ptr->offset, ptr->bptr, ptr->fptr, line);
        !           215:        }
        !           216:        fprintf(stderr, "\n");
        !           217: }
        !           218: 
        !           219: 
        !           220: /*
        !           221:  *     int
        !           222:  *     do_entry(item_ptr)
        !           223:  *
        !           224:  *     Compile one entry.  During the first pass, item_ptr is NULL.  In pass
        !           225:  *     two, item_ptr points to the current entry in the use_list.
        !           226:  *
        !           227:  *     found-forward-use = FALSE
        !           228:  *     re-initialise internal arrays
        !           229:  *     save names in string_table
        !           230:  *     get_token()
        !           231:  *     while (not EOF and not NAMES)
        !           232:  *         if found-forward-use
        !           233:  *             do nothing
        !           234:  *         else if 'use'
        !           235:  *             if handle_use() < 0
        !           236:  *                 found-forward-use = TRUE
        !           237:  *          else
        !           238:  *             check for existance and type-correctness
        !           239:  *             enter cap into structure
        !           240:  *             if STRING
        !           241:  *                 save string in string_table
        !           242:  *         get_token()
        !           243:  *      if ! found-forward-use
        !           244:  *         clear CANCELS out of the structure
        !           245:  *         dump compiled entry into filesystem
        !           246:  *
        !           247:  */
        !           248: 
        !           249: int
        !           250: do_entry(item_ptr)
        !           251: struct use_item        *item_ptr;
        !           252: {
        !           253:        long                                    entry_offset;
        !           254:        int                                     i;
        !           255:        register int                            token_type;
        !           256:        register struct name_table_entry        *entry_ptr;
        !           257:        int                                     found_forward_use = FALSE;
        !           258:        static char                             Booleans[BOOLCOUNT];
        !           259:        static short                            Numbers[NUMCOUNT],
        !           260:                                                Strings[STRCOUNT];
        !           261: 
        !           262:        init_structure(Booleans, Numbers, Strings);
        !           263:        complete = 0;
        !           264:        term_names = save_str(curr_token.tk_name);
        !           265:        DEBUG(2, "Starting '%s'\n", curr_token.tk_name);
        !           266:        entry_offset = curr_file_pos;
        !           267: 
        !           268:        for (token_type = get_token();
        !           269:                token_type != EOF  &&  token_type != NAMES;
        !           270:                token_type = get_token())
        !           271:        {
        !           272:            if (found_forward_use)
        !           273:                /* do nothing */ ;
        !           274:            else if (strcmp(curr_token.tk_name, "use") == 0)
        !           275:            {
        !           276:                if (handle_use(item_ptr, entry_offset,
        !           277:                                        Booleans, Numbers, Strings) < 0)
        !           278:                    found_forward_use = TRUE;
        !           279:            }
        !           280:            else
        !           281:            {
        !           282:                entry_ptr = find_entry(curr_token.tk_name);
        !           283: 
        !           284:                if (entry_ptr == NOTFOUND) {
        !           285:                    warning("Unknown Capability - '%s'",
        !           286:                                                           curr_token.tk_name);
        !           287:                    continue;
        !           288:                }
        !           289: 
        !           290: 
        !           291:                if (token_type != CANCEL
        !           292:                                         &&  entry_ptr->nte_type != token_type)
        !           293:                    warning("Wrong type used for capability '%s'",
        !           294:                                                          curr_token.tk_name);
        !           295:                switch (token_type)
        !           296:                {
        !           297:                    case CANCEL:
        !           298:                        switch (entry_ptr->nte_type)
        !           299:                        {
        !           300:                            case BOOLEAN:
        !           301:                                Booleans[entry_ptr->nte_index] = -2;
        !           302:                                break;
        !           303: 
        !           304:                            case NUMBER:
        !           305:                                Numbers[entry_ptr->nte_index] = -2;
        !           306:                                break;
        !           307: 
        !           308:                            case STRING:
        !           309:                                Strings[entry_ptr->nte_index] = -2;
        !           310:                                break;
        !           311:                        }
        !           312:                        break;
        !           313:                
        !           314:                    case BOOLEAN:
        !           315:                        Booleans[entry_ptr->nte_index] = TRUE;
        !           316:                        break;
        !           317:                    
        !           318:                    case NUMBER:
        !           319:                        Numbers[entry_ptr->nte_index] =
        !           320:                                                       curr_token.tk_valnumber;
        !           321:                        break;
        !           322: 
        !           323:                    case STRING:
        !           324:                        Strings[entry_ptr->nte_index] =
        !           325:                                             save_str(curr_token.tk_valstring);
        !           326:                        break;
        !           327: 
        !           328:                    default:
        !           329:                        warning("Unknown token type");
        !           330:                        panic_mode(',');
        !           331:                        continue;
        !           332:                }
        !           333:            } /* end else cur_token.name != "use" */
        !           334: 
        !           335:        } /* endwhile (not EOF and not NAMES) */
        !           336: 
        !           337:        if (found_forward_use)
        !           338:            return(token_type);
        !           339: 
        !           340:        for (i=0; i < BOOLCOUNT; i++)
        !           341:        {
        !           342:            if (Booleans[i] == -2)
        !           343:                Booleans[i] = FALSE;
        !           344:        }
        !           345: 
        !           346:        for (i=0; i < NUMCOUNT; i++)
        !           347:        {
        !           348:            if (Numbers[i] == -2)
        !           349:                Numbers[i] = -1;
        !           350:        }
        !           351: 
        !           352:        for (i=0; i < STRCOUNT; i++)
        !           353:        {
        !           354:            if (Strings[i] == -2)
        !           355:                Strings[i] = -1;
        !           356:        }
        !           357: 
        !           358:        dump_structure(term_names, Booleans, Numbers, Strings);
        !           359: 
        !           360:        complete = 1;
        !           361:        return(token_type);
        !           362: }
        !           363: 
        !           364: 
        !           365: /*
        !           366:  *     enqueue(offset)
        !           367:  *
        !           368:  *      Put a record of the given offset onto the use-list.
        !           369:  *
        !           370:  */
        !           371: 
        !           372: enqueue(offset)
        !           373: long   offset;
        !           374: {
        !           375:        struct use_item *item;
        !           376:        char *malloc();
        !           377: 
        !           378:        item = (struct use_item *) malloc(sizeof(struct use_item));
        !           379: 
        !           380:        if (item == NULL)
        !           381:            syserr_abort("Not enough memory for use_list element");
        !           382: 
        !           383:        item->offset = offset;
        !           384: 
        !           385:        if (use_list.head != NULL)
        !           386:        {
        !           387:            item->bptr = use_list.tail;
        !           388:            use_list.tail->fptr = item;
        !           389:            item->fptr = NULL;
        !           390:            use_list.tail = item;
        !           391:        }
        !           392:        else
        !           393:        {
        !           394:            use_list.tail = use_list.head = item;
        !           395:            item->fptr = item->bptr = NULL;
        !           396:        }
        !           397: 
        !           398:        use_count ++;
        !           399: }
        !           400: 
        !           401: 
        !           402: /*
        !           403:  *     dequeue(ptr)
        !           404:  *
        !           405:  *     remove the pointed-to item from the use_list
        !           406:  *
        !           407:  */
        !           408: 
        !           409: dequeue(ptr)
        !           410: struct use_item        *ptr;
        !           411: {
        !           412:        if (ptr->fptr == NULL)
        !           413:            use_list.tail = ptr->bptr;
        !           414:        else
        !           415:            (ptr->fptr)->bptr = ptr->bptr;
        !           416: 
        !           417:        if (ptr->bptr == NULL)
        !           418:            use_list.head = ptr->fptr;
        !           419:        else
        !           420:            (ptr->bptr)->fptr = ptr->fptr;
        !           421:        
        !           422:        use_count --;
        !           423: }
        !           424: 
        !           425: 
        !           426: /*
        !           427:  *     dump_structure()
        !           428:  *
        !           429:  *     Save the compiled version of a description in the filesystem.
        !           430:  *
        !           431:  *     make a copy of the name-list
        !           432:  *     break it up into first-name and all-but-last-name
        !           433:  *     creat(first-name)
        !           434:  *     write object information to first-name
        !           435:  *     close(first-name)
        !           436:  *      for each name in all-but-last-name
        !           437:  *         link to first-name
        !           438:  *
        !           439:  */
        !           440: 
        !           441: dump_structure(term_names, Booleans, Numbers, Strings)
        !           442: short  term_names;
        !           443: char   Booleans[];
        !           444: short  Numbers[];
        !           445: short  Strings[];
        !           446: {
        !           447:        char            *strcpy();
        !           448:        struct stat     statbuf;
        !           449:        FILE            *fp;
        !           450:        static char     name_list[1024];
        !           451:        register char   *first_name, *other_names;
        !           452:        register char   *ptr;
        !           453:        static char     filename[50];
        !           454:        static char     linkname[50];
        !           455:        extern char check_only;
        !           456: 
        !           457:        strcpy(name_list, term_names + string_table);
        !           458:        DEBUG(7, "Name list = '%s'\n", name_list);
        !           459: 
        !           460:        first_name = name_list;
        !           461: 
        !           462:        ptr = &name_list[strlen(name_list) - 1];
        !           463:        other_names = ptr + 1;
        !           464: 
        !           465:        while (ptr > name_list  &&  *ptr != '|')
        !           466:            ptr--;
        !           467: 
        !           468:        if (ptr != name_list)
        !           469:        {
        !           470:            *ptr = '\0';
        !           471: 
        !           472:            for (ptr = name_list; *ptr != '\0'  &&  *ptr != '|'; ptr++)
        !           473:                ;
        !           474:            
        !           475:            if (*ptr == '\0')
        !           476:                other_names = ptr;
        !           477:            else
        !           478:            {
        !           479:                *ptr = '\0';
        !           480:                other_names = ptr + 1;
        !           481:            }
        !           482:        }
        !           483: 
        !           484:        if (check_only) {
        !           485:                DEBUG(1, "Checked %s\n", first_name);
        !           486:                return;
        !           487:        }
        !           488: 
        !           489:        DEBUG(7, "First name = '%s'\n", first_name);
        !           490:        DEBUG(7, "Other names = '%s'\n", other_names);
        !           491: 
        !           492:        if (strlen(first_name) > 100)
        !           493:            warning("'%s': terminal name too long.", first_name);
        !           494: 
        !           495:        check_name(first_name);
        !           496: 
        !           497:        sprintf(filename, "%c/%s", first_name[0], first_name);
        !           498: 
        !           499:        if (stat(filename, &statbuf) >= 0  &&  statbuf.st_mtime >= start_time)
        !           500:        {
        !           501:            warning("'%s' defined in more than one entry.", first_name);
        !           502:            fprintf(stderr, "Entry being used is '%s'.\n",
        !           503:                            (unsigned) term_names + string_table);
        !           504:        }
        !           505: 
        !           506:        unlink(filename);
        !           507:        fp = fopen(filename, "w");
        !           508:        if (fp == NULL)
        !           509:        {
        !           510:            perror(filename);
        !           511:            syserr_abort("Can't open %s/%s\n", destination, filename);
        !           512:        }
        !           513:        DEBUG(1, "Created %s\n", filename);
        !           514: 
        !           515:        if (write_object(fp, term_names, Booleans, Numbers, Strings) < 0)
        !           516:        {
        !           517:            syserr_abort("Error in writing %s/%s", destination, filename);
        !           518:        }
        !           519:        fclose(fp);
        !           520: 
        !           521:        while (*other_names != '\0')
        !           522:        {
        !           523:            ptr = other_names++;
        !           524:            while (*other_names != '|'  &&  *other_names != '\0')
        !           525:                other_names++;
        !           526: 
        !           527:            if (*other_names != '\0')
        !           528:                *(other_names++) = '\0';
        !           529: 
        !           530:            if (strlen(ptr) > 100)
        !           531:            {
        !           532:                warning("'%s': terminal name too long.", ptr);
        !           533:                continue;
        !           534:            }
        !           535: 
        !           536:            sprintf(linkname, "%c/%s", ptr[0], ptr);
        !           537: 
        !           538:            if (strcmp(filename, linkname) == 0)
        !           539:            {
        !           540:                warning("Terminal name '%s' synonym for itself", first_name);
        !           541:            }
        !           542:            else if (stat(linkname, &statbuf) >= 0  &&
        !           543:                                                statbuf.st_mtime >= start_time)
        !           544:            {
        !           545:                warning("'%s' defined in more than one entry.", ptr);
        !           546:                fprintf(stderr, "Entry being used is '%s'.\n",
        !           547:                            (unsigned) term_names + string_table);
        !           548:            }
        !           549:            else
        !           550:            {
        !           551:                unlink(linkname);
        !           552:                if (link(filename, linkname) < 0)
        !           553:                    syserr_abort("Can't link %s to %s", filename, linkname);
        !           554:                DEBUG(1, "Linked %s\n", linkname);
        !           555:            }
        !           556:        }
        !           557: }
        !           558: 
        !           559: 
        !           560: /*
        !           561:  *     int
        !           562:  *     write_object(fp, term_names, Booleans, Numbers, Strings)
        !           563:  *
        !           564:  *     Write out the compiled entry to the given file.
        !           565:  *     Return 0 if OK or -1 if not.
        !           566:  *
        !           567:  */
        !           568: 
        !           569: #define swap(x)                (((x >> 8) & 0377) + 256 * (x & 0377))
        !           570: 
        !           571: #define might_swap(x)  (must_swap()  ?  swap(x)  :  (x))
        !           572: 
        !           573: 
        !           574: int
        !           575: write_object(fp, term_names, Booleans, Numbers, Strings)
        !           576: FILE   *fp;
        !           577: short  term_names;
        !           578: char   Booleans[];
        !           579: short  Numbers[];
        !           580: short  Strings[];
        !           581: {
        !           582:        struct header   header;
        !           583:        char            *namelist;
        !           584:        short           namelen;
        !           585:        char            zero = '\0';
        !           586:        int             i;
        !           587: 
        !           588:        namelist = term_names + string_table;
        !           589:        namelen = strlen(namelist) + 1;
        !           590: 
        !           591:        if (must_swap())
        !           592:        {
        !           593:            header.magic = swap(MAGIC);
        !           594:            header.name_size = swap(namelen);
        !           595:            header.bool_count = swap(BOOLCOUNT);
        !           596:            header.num_count = swap(NUMCOUNT);
        !           597:            header.str_count = swap(STRCOUNT);
        !           598:            header.str_size = swap(next_free);
        !           599:        }
        !           600:        else
        !           601:        {
        !           602:            header.magic = MAGIC;
        !           603:            header.name_size = namelen;
        !           604:            header.bool_count = BOOLCOUNT;
        !           605:            header.num_count = NUMCOUNT;
        !           606:            header.str_count = STRCOUNT;
        !           607:            header.str_size = next_free;
        !           608:        }
        !           609: 
        !           610:        if (fwrite(&header, sizeof(header), 1, fp) != 1
        !           611:                ||  fwrite(namelist, sizeof(char), namelen, fp) != namelen
        !           612:                ||  fwrite(Booleans, sizeof(char), BOOLCOUNT, fp) != BOOLCOUNT)
        !           613:            return(-1);
        !           614:        
        !           615:        if ((namelen+BOOLCOUNT) % 2 != 0  &&  fwrite(&zero, sizeof(char), 1, fp) != 1)
        !           616:            return(-1);
        !           617: 
        !           618:        if (must_swap())
        !           619:        {
        !           620:            for (i=0; i < NUMCOUNT; i++)
        !           621:                Numbers[i] = swap(Numbers[i]);
        !           622:            for (i=0; i < STRCOUNT; i++)
        !           623:                Strings[i] = swap(Strings[i]);
        !           624:        }
        !           625: 
        !           626:        if (fwrite((char *) Numbers, sizeof(short), NUMCOUNT, fp) != NUMCOUNT
        !           627:               ||  fwrite((char *) Strings, sizeof(short), STRCOUNT, fp) != STRCOUNT
        !           628:               ||  fwrite((char *) string_table, sizeof(char), next_free, fp)
        !           629:                                                                  != next_free)
        !           630:            return(-1);
        !           631: 
        !           632:        return(0);
        !           633: }
        !           634: 
        !           635: 
        !           636: /*
        !           637:  *     check_name(name)
        !           638:  *
        !           639:  *     Generate an error message if given name does not begin with a
        !           640:  *     digit or letter (should be lower-case letter, but SV likes capital)
        !           641:  *     Vlad 3-11-92
        !           642:  */
        !           643: 
        !           644: check_name(name)
        !           645: char   *name;
        !           646: {
        !           647:        if (!isalnum(name[0]))
        !           648:        {
        !           649:            fprintf(stderr, "tic: Line %d: Illegal terminal name - '%s'\n",
        !           650:                                                            curr_line, name);
        !           651:            fprintf(stderr,
        !           652:                        "Terminal names must start with letter or digit\n");
        !           653:            exit(1);
        !           654:        }
        !           655: }
        !           656: 
        !           657: 
        !           658: /*
        !           659:  *     int
        !           660:  *     save_str(string)
        !           661:  *
        !           662:  *     copy string into next free part of string_table, doing a realloc()
        !           663:  *     if necessary.  return offset of beginning of string from start of
        !           664:  *     string_table.
        !           665:  *
        !           666:  */
        !           667: 
        !           668: int
        !           669: save_str(string)
        !           670: char   *string;
        !           671: {
        !           672:        char    *malloc(), *realloc(), *strcpy();
        !           673:        int     old_next_free = next_free;
        !           674: 
        !           675:        if (table_size == 0)
        !           676:        {
        !           677:            if ((string_table = malloc(1024)) == NULL)
        !           678:                syserr_abort("Out of memory");
        !           679:            table_size = 1024;
        !           680:            DEBUG(5, "Made initial string table allocation.  Size is %d\n",
        !           681:                                                                    table_size);
        !           682:        }
        !           683: 
        !           684:        while (table_size < next_free + strlen(string))
        !           685:        {
        !           686:            if ((string_table = realloc(string_table, table_size + 1024))
        !           687:                                                                        == NULL)
        !           688:                syserr_abort("Out of memory");
        !           689:            table_size += 1024;
        !           690:            DEBUG(5, "Extended string table.  Size now %d\n", table_size);
        !           691:        }
        !           692: 
        !           693:        strcpy(&string_table[next_free], string);
        !           694:        DEBUG(7, "Saved string '%s' ", string);
        !           695:        DEBUG(7, "at location %d\n", next_free);
        !           696:        next_free += strlen(string) + 1;
        !           697: 
        !           698:        return(old_next_free);
        !           699: }
        !           700: 
        !           701: 
        !           702: /*
        !           703:  *     init_structure(Booleans, Numbers, Strings)
        !           704:  *
        !           705:  *     Initialise the given arrays
        !           706:  *     Reset the next_free counter to zero.
        !           707:  *
        !           708:  */
        !           709: 
        !           710: init_structure(Booleans, Numbers, Strings)
        !           711: char   Booleans[];
        !           712: short  Numbers[], Strings[];
        !           713: {
        !           714:        int     i;
        !           715: 
        !           716:        for (i=0; i < BOOLCOUNT; i++)
        !           717:            Booleans[i] = FALSE;
        !           718:        
        !           719:        for (i=0; i < NUMCOUNT; i++)
        !           720:            Numbers[i] = -1;
        !           721: 
        !           722:        for (i=0; i < STRCOUNT; i++)
        !           723:            Strings[i] = -1;
        !           724: 
        !           725:        next_free = 0;
        !           726: }
        !           727: 
        !           728: 
        !           729: /*
        !           730: **     int
        !           731: **     handle_use(item_ptr, entry_offset, Booleans, Numbers, Strings)
        !           732: **
        !           733: **     Merge the compiled file whose name is in cur_token.valstring
        !           734: **     with the current entry.
        !           735: **
        !           736: **             if it's a forward use-link
        !           737: **                 if item_ptr == NULL
        !           738: **                     queue it up for later handling
        !           739: **                 else
        !           740: **                     ignore it (we're already going through the queue)
        !           741: **             else it's a backward use-link
        !           742: **                 read in the object file for that terminal
        !           743: **                 merge contents with current structure
        !           744: **
        !           745: **     Returned value is 0 if it was a backward link and we
        !           746: **     successfully read it in, -1 if a forward link.
        !           747: */
        !           748: 
        !           749: int
        !           750: handle_use(item_ptr, entry_offset, Booleans, Numbers, Strings)
        !           751: long           entry_offset;
        !           752: struct use_item        *item_ptr;
        !           753: char           Booleans[];
        !           754: short          Numbers[];
        !           755: short          Strings[];
        !           756: {
        !           757:        struct term     use_term;
        !           758:        struct stat     statbuf;
        !           759:        static char     filename[50];
        !           760:         int             i;
        !           761: 
        !           762:        check_name(curr_token.tk_valstring);
        !           763: 
        !           764:        sprintf(filename, "%c/%s", curr_token.tk_valstring[0],
        !           765:                                                      curr_token.tk_valstring);
        !           766: 
        !           767:        if (stat(filename, &statbuf) < 0  ||  part2==0 && statbuf.st_mtime < start_time)
        !           768:        {
        !           769:            DEBUG(2, "Forward USE to %s", curr_token.tk_valstring);
        !           770: 
        !           771:            if (item_ptr == NULL)
        !           772:            {
        !           773:                DEBUG(2, " (enqueued)\n", "");
        !           774:                enqueue(entry_offset);
        !           775:            }
        !           776:            else 
        !           777:                DEBUG(2, " (skipped)\n", "");
        !           778:            
        !           779:            return(-1);
        !           780:        }
        !           781:        else
        !           782:        {
        !           783:            DEBUG(2, "Backward USE to %s\n", curr_token.tk_valstring);
        !           784:            if (read_entry(filename, &use_term) < 0)
        !           785:                syserr_abort("Error in re-reading compiled file %s", filename);
        !           786: 
        !           787:            for (i=0; i < BOOLCOUNT; i++)
        !           788:            {
        !           789:                if (Booleans[i] == FALSE  &&  use_term.Booleans[i] == TRUE)
        !           790:                    Booleans[i] = TRUE;
        !           791:            }
        !           792: 
        !           793:            for (i=0; i < NUMCOUNT; i++)
        !           794:            {
        !           795:                if (Numbers[i] == -1  &&  use_term.Numbers[i] != -1)
        !           796:                    Numbers[i] = use_term.Numbers[i];
        !           797:            }
        !           798: 
        !           799:            for (i=0; i < STRCOUNT; i++)
        !           800:            {
        !           801:                if (Strings[i] == -1  &&  use_term.Strings[i] != (char *) 0)
        !           802:                    Strings[i] = save_str(use_term.Strings[i]);
        !           803:            }
        !           804: 
        !           805:        }
        !           806:        return(0);
        !           807: }

unix.superglobalmegacorp.com

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