# 2.11BSD#431 - /usr/src/new/PORT/B/src/bed/getc.c

##### Functions

    adv               X
    append            X
    countdefs         X
    dump              X
    endgetc           X
    err               X
    getdef            X
    getitem           X
    getline           X
    getmem            X
    getname           X
    getnumber         X
    getrhs            X
    getstring         X
    inchar            X
    initgetc          X
    initkeys          X
    lookup            X
    outstring         X
    process           X
    readtermcap       X
    regetmem          X
    savestr           X
    skipsp            X
    store             X
    try               X

##### Variables

    Hidden            X
    Procedure         X
    deftab            X
    eof               X
    errcount          X
    filename          X
    lcount            X
    ndefs             X
    nextc             X

##### Macros

    COMMENT           X
    ESC               X
    I                 X
    MAXDEFS           X
    freemem           X
    getch             X
    syserr            X

##### struct's

    tabent            X

       1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
       2:
       3: /* $Header: getc.c,v 2.5 85/08/22 16:02:44 timo Exp $ */
       4:
       5: /* B editor -- read key definitions from file */
       6:
       7: #include "b.h"
       8: #include "feat.h"
       9: #ifdef LINDA
      10: #include "b1mem.h"
      11: #define syserr EDsyserr
      12: #else !LINDA
      13: #define freemem(p) free(p)
      14: #endif !LINDA
      15: #include "file.h"
      16: #include "keys.h"
      17:
      18: #include <ctype.h>
      19:
      20: extern bool dflag;
      21:
      22: #define ESC '\033'
      23:
      24: /*
      25: This file contains a little parser for key definition files.
      26: To allow sufficient freedom in preparing such a file, a simple
      27: grammar has been defined according to which the file is parsed.
      28: The parsing process is extremely simple, as it can be done
      29: top-down using recursive descent.
      30:
      31:
      32: Lexical conventions:
      33:
      34: - Blanks between lexical symbols are gnored.
      35: - From '#' to end of line is comment (except inside strings).
      36: - Strings are delimited by single or double quotes and
      37:   use the same escape sequences as C strings, plus:
      38:   \e or \E means an ESCape ('\033').
      39: - Command names are like C identifiers ([a-zA-Z_][a-zA-Z0-9_]*).
      40:   Upper/lower case distinction is significant.
      41: - numbers are octal or decimal integers in C-style (leading zero means octal)
      42: - After '^' a character is expected, this must be a letter or one of @^_[]\ .
      43:
      44: Syntax in modified BNF ([] mean 0 or 1, * means 0 or more, + means 1 or more):
      45:
      46:    file: line*
      47:    line: [def] [comment]
      48:    def: commandname '=' rhs
      49:    rhs: item+
      50:    item: string | '^' character | number
      51:
      52:
      53: Notes:
      54:
      55: - A definition for command "term_init" defines a string to be sent
      56:   TO the terminal at initialization time, e.g. to set programmable
      57:   function key definitions.  Similar for "term_done" on exiting.
      58: - Command names are  conventional editor commands.
      59:
      60: */
      61:
      62:
      63: #ifndef LINDA
      64: /* Defines subroutine that used to be in the support levels: */
      65:
      66: Hidden string getmem(nbytes)
      67:     unsigned nbytes;
      68: {
      69:     string malloc();
      70:     string pointer= malloc(nbytes);
      71:
      72:     if (pointer == NULL)
      73:         syserr("memory full in initkeys");
      74:     return pointer;
      75: }
      76:
      77: Hidden string regetmem(pp, nbytes)
      78:     string *pp;
      79:     unsigned nbytes;
      80: {
      81:     *pp= realloc(*pp, nbytes);
      82:     if (*pp == NULL)
      83:         syserr("memory full in initkeys (regetmem)");
      84: }
      85: #endif !LINDA
      86:
      87:
      88: #define COMMENT '#' /* Not B-like but very UNIX-like */
      89: #define MAXDEFS 100
      90:
      91: Hidden FILE *fp; /* File from which to read */
      92: Hidden string filename; /* File name for error messages */
      93: Hidden char nextc; /* Next character to be analyzed */
      94: Hidden bool eof; /* EOF seen? */
      95: Hidden int lcount; /* Current line number */
      96: Hidden bool errcount; /* Number of errors detected */
      97:
      98:
      99: struct tabent {
     100:     int code;
     101:     string name;
     102:     string def;
     103: };
     104:
     105: /* Table of key definitions, mostly filled by reading definitions from a file.
     106:    The "I" macro has two arguments: the default for termcap and that for
     107:    the IBM PC.  It expands to either depending on whether IBMPC is defined.
     108:    'def' fields initialized with a string starting with '=' are termcap names,
     109:    and are replaced by the corresponding termcap entry (NULL if none).
     110:    On the IBM PC, 'extended codes' are by convention a null character
     111:    followed by another character (usually the scan code).  Since the null
     112:    character is rather unsuitable for use in C strings, we use \377 (hex FF)
     113:    instead, a code which has no assigned graphic is the extended IBM PC
     114:    character set.  E.g., F1 is 0-59, which we encode as \377\073 (since
     115:    \073 is octal for 59 decimal).  For the exact codes, see for instance the
     116:    BASIC 2.0 manual, appendix G, or the XT Technical Reference, page 2-14.
     117: */
     118:
     119: #ifdef IBMPC
     120: #define I(tc, ibm) ibm
     121: #else !IBMPC
     122: #define I(tc, ibm) tc
     123: #endif !IBMPC
     124:
     125: Visible struct tabent deftab[MAXDEFS] = {
     126:     /* General rule:
     127: 	   unix => ctrl-x
     128: 	   IBM  => alt-x
     129: 	   where x is first letter of command name
     130: 	*/
     131:     {0377, "ignore", NULL}, /* Entry to ignore a key */
     132:     {COPY, "copy", I(NULL, "\377\056")},
     133:     {DELETE, "delete", I(NULL, "\377\040")},
     134:     {DELETE, "delete", I(NULL, "\377\123")}, /* IBM DEL key */
     135:     {ACCEPT, "accept", I(NULL, "\377\022")}, /* ^E, alt-E */
     136:     {ACCEPT, "end", I(NULL, "\377\117")}, /* IBM END key */
     137:     {'\t', "tab", NULL}, /* = ACCEPT in Bed, insert tab in Linda */
     138:     {UNDO, "undo"}, /* Always backspace = ^H */
     139:     {REDRAW, "redraw", I(NULL, "\377\046")}, /* ^L, alt-L */
     140:     {REDRAW, "look"},
     141:     {RETURN, "newline"}, /* Always ^M */
     142:     {REDO, "redo", I(NULL, "\177")}, /* IBM ctrl-BS = ASCII 177 (DEL) */
     143:     {EXIT, "exit", I(NULL, "\377\055")}, /* ^X, alt-X */
     144:
     145: #ifdef RECORDING
     146:     /*
     147: 	 * The IBM-PC has a problem here in ANSI.SYS mode: ctrl-P is
     148: 	 * unusable because it means Print Screen, and alt-R is unusable
     149: 	 * because it transmits 0, 19 but 19 is ctrl-S which means stop
     150: 	 * output :-(.
     151: 	 * The only reasonable place to put the things would then be on
     152: 	 * function keys.  You should do this in the key definitions file. (?)
     153: 	 */
     154:     {PLAYBACK, "play", I(NULL, "\377\031")},
     155:     {PLAYBACK, "playback", I(NULL, "\377\031")},
     156:     {RECORD, "record", I(NULL, "\377\023")},
     157: #endif RECORDING
     158:
     159: #ifdef LINDA
     160:     {BFIND, "bfind", I(NULL, "\377\060")},
     161:     {FIND, "find", I(NULL, "\377\041")},
     162:     {GLOBAL, "global", I(NULL, "\377\042")},
     163:     {JOIN, "join", I(NULL, "\377\044")},
     164:     {TOGGLE, "toggle", I(NULL, "\377\024")},
     165:     {YANK, "yank", I(NULL, "\377\025")},
     166:     {LITERAL, "literal", I(NULL, "\377\057")}, /* ^V, alt-V */
     167: #endif LINDA
     168:
     169:     {WIDEN, "widen", I("=k1", "\377\073")}, /* IBM F1 */
     170:     {NARROW, "narrow", I("=k2", "\377\075")}, /* IBM F3 (!!!) */
     171:     {NARROW, "first"},
     172:     {RNARROW, "rnarrow", I("=k3", "\377\076")}, /* IBM F4 (!!!) */
     173:     {RNARROW, "last"},
     174:     {EXTEND, "extend", I("=k4", "\377\074")}, /* IBM F2 (!!!) */
     175:     {UPARROW, "up", I("=ku", "\377\110")},
     176:     {UPLINE, "upline", I("=k5", "\377\110")},
     177:     {LEFTARROW, "left", I("=kl", "\377\113")},
     178:     {PREVIOUS, "previous", I("=k6", NULL)},
     179:     {RITEARROW, "right", I("=kr", "\377\115")},
     180:     {NEXT, "next", I("=k7", NULL)},
     181:     {DOWNARROW, "down", I("=kd", "\377\120")},
     182:     {DOWNLINE, "downline", I("=k8", "\377\120")},
     183:
     184:     {GOTO, "goto", I("\033g", NULL)}, /* Doesn't exist on IBM */
     185: #ifdef HELPFUL
     186:     {HELP, "help", I("\033?", "\377\104")}, /* ESC ?, IBM F10 */
     187: #endif HELPFUL
     188:
     189:     {0, "term_init", I("=ks", NULL)},
     190:     {0, "term_done", I("=ke", NULL)},
     191: };
     192:
     193: #undef I
     194:
     195: Hidden int ndefs;
     196:
     197:
     198: Hidden Procedure err(fmt, arg)
     199:     string fmt, arg;
     200: {
     201:     if (errcount == 0)
     202:         fprintf(stderr, "Errors in key definitions file:\n");
     203:     ++errcount;
     204:     fprintf(stderr, "%s, line %d: ", filename, lcount);
     205:     fprintf(stderr, fmt, arg);
     206:     fprintf(stderr, "\n");
     207: }
     208:
     209: Hidden Procedure adv()
     210: {
     211:     int c;
     212:
     213:     if (eof)
     214:         return;
     215:     c= getc(fp);
     216:     if (c == EOF) {
     217:         nextc= '\n';
     218:         eof= Yes;
     219:     }
     220:     else {
     221:         nextc= c;
     222:         if (c == '\n')
     223:             ++lcount;
     224:     }
     225: }
     226:
     227: Hidden Procedure skipsp()
     228: {
     229:     while (nextc == ' ' || nextc == '\t')
     230:         adv();
     231: }
     232:
     233: Hidden int lookup(name)
     234:     string name;
     235: {
     236:     int i;
     237:
     238:     for (i= 0; i < ndefs; ++i) {
     239:         if (deftab[i].name != NULL && strcmp(name, deftab[i].name) == 0)
     240:             return i;
     241:     }
     242:     return -1;
     243: }
     244:
     245: Hidden Procedure store(code, name, def)
     246:     int code;
     247:     string name;
     248:     string def;
     249: {
     250:     struct tabent *d, *last= deftab+ndefs;
     251:     string p, q;
     252:
     253:     /* Undefine conflicting definitions.  Conflicts arise
     254: 	   when a command definition is an initial subsequence
     255: 	   of another, or vice versa.  Key definitions (code < 0)
     256: 	   are not undefined. */
     257:     if (code > 0) {
     258:         for (d= deftab; d < last; ++d) {
     259:             if (d->code >= 0 && d->def != NULL) {
     260:                 for (p= def, q= d->def; *p == *q; ++p, ++q) {
     261:                     if (*p == '\0' || *q == '\0') {
     262:                         d->def= NULL;
     263:                         break;
     264:                     }
     265:                 }
     266:             }
     267:         }
     268:     }
     269:
     270:     /* Find a free slot with the same code and NULL definition */
     271:     /* (For code == 0, the name must match instead of the code,
     272: 	   and the definition need not be NULL) */
     273:     for (d= deftab; d < last; ++d) {
     274:         if (code == 0 ? strcmp(name, d->name) == 0
     275:             : (d->code == code && d->def == NULL))
     276:             break;
     277:     }
     278:     if (d == last) { /* Extend definition table */
     279:         if (ndefs >= MAXDEFS) {
     280:             err("Too many key definitions", "");
     281:             return;
     282:         }
     283:         ++ndefs;
     284:         d->code= code;
     285:         d->name= name;
     286:     }
     287:     d->def= def;
     288: }
     289:
     290: Hidden string savestr(s)
     291:     string s;
     292: {
     293:     string new;
     294:
     295:     new= getmem((unsigned) (strlen(s) + 1));
     296:     strcpy(new, s);
     297:     return new;
     298: }
     299:
     300: Hidden Procedure append(to, item)
     301:     string *to, item;
     302: {
     303:     int len= strlen(*to) + strlen(item) + 1;
     304:     regetmem(to, len);
     305:     strcat(*to, item);
     306: }
     307:
     308: Hidden string getname()
     309: {
     310:     char buffer[20];
     311:     string bp;
     312:
     313:     if (!isalpha(nextc) && nextc != '_') {
     314:         err("No name where expected", "");
     315:         return NULL;
     316:     }
     317:     for (bp= buffer; isalnum(nextc) || nextc == '_'; ) {
     318:         if (bp < buffer + sizeof buffer - 1)
     319:             *bp++ = nextc;
     320:         adv();
     321:     }
     322:     *bp= '\0';
     323:     return savestr(buffer);
     324: }
     325:
     326: Hidden int getnumber()
     327: {
     328:     int base= (nextc == '0') ? 8 : 10;
     329:     int i= 0;
     330:     int d;
     331:
     332:     for (;; adv()) {
     333:         d= nextc-'0';
     334:         if (d < 0 || d > 9)
     335:             break;
     336:         if (d > base) {
     337:             err("8 or 9 in octal number", "");
     338:             return 0;
     339:         }
     340:         i= i*base + d;
     341:     }
     342:     return i;
     343: }
     344:
     345: Hidden string getstring()
     346: {
     347:     char buf[256]; /* Arbitrary limit */
     348:     char quote= nextc;
     349:     char c;
     350:     int len= 0;
     351:
     352:     adv();
     353:     while (nextc != quote) {
     354:         if (nextc == '\n') {
     355:             err("closing string quote not found", "");
     356:             return NULL;
     357:         }
     358:         if (nextc != '\\') {
     359:             c= nextc;
     360:             adv();
     361:         }
     362:         else {
     363:             adv();
     364:             switch (nextc) {
     365:
     366:             case 'r': c= '\r'; adv(); break;
     367:             case 'n': c= '\n'; adv(); break;
     368:             case 'b': c= '\b'; adv(); break;
     369:             case 't': c= '\t'; adv(); break;
     370:             case 'f': c= '\f'; adv(); break;
     371:
     372:             case 'E':
     373:             case 'e': c= ESC; adv(); break;
     374:
     375:             case '0': case '1': case '2': case '3':
     376:             case '4': case '5': case '6': case '7':
     377:                 c= nextc-'0';
     378:                 adv();
     379:                 if (nextc >= '0' && nextc < '8') {
     380:                     c= 8*c + nextc-'0';
     381:                     adv();
     382:                     if (nextc >= '0' && nextc < '8') {
     383:                         c= 8*c + nextc-'0';
     384:                         adv();
     385:                     }
     386:                 }
     387:                 break;
     388:
     389:             default: c=nextc; adv(); break;
     390:
     391:             }
     392:         }
     393:         if (len >= sizeof buf) {
     394:             err("string too long", "");
     395:             return NULL;
     396:         }
     397:         buf[len++]= c;
     398:     }
     399:     adv();
     400:     buf[len]= '\0';
     401:     return savestr(buf);
     402: }
     403:
     404: Hidden string getitem()
     405: {
     406:     char buf[2];
     407:     string keyname;
     408:     int i;
     409:
     410:     switch (nextc) {
     411:     case '"':
     412:     case '\'':
     413:         return getstring();
     414:     case '^':
     415:         adv();
     416:         if (isalpha(nextc) || index("@^_[]\\?", nextc)) {
     417:             if (nextc == '?')
     418:                 buf[0]= '\177';
     419:             else
     420:                 buf[0]= nextc & 037;
     421:             buf[1]= '\0';
     422:             adv();
     423:             return savestr(buf);
     424:         }
     425:         err("Invalid character after '^'", "");
     426:         return NULL;
     427:     default:
     428:         if (isdigit(nextc)) {
     429:             buf[0]= getnumber();
     430:             buf[1]= '\0';
     431:             return savestr(buf);
     432:         }
     433:         if (isalpha(nextc) || nextc == '_') {
     434:             keyname= getname(); /* Cannot fail */
     435:             if (strlen(keyname) == 1)
     436:                 return savestr(keyname);
     437:                 /* Single letters stand for themselves */
     438:             i= lookup(keyname);
     439:             if (i < 0 || deftab[i].code <= 0) {
     440:                 err("%s: not a key name", keyname);
     441:                 freemem(keyname);
     442:                 return NULL;
     443:             }
     444:             else if (deftab[i].def == NULL) {
     445:                 err("%s: undefined key", keyname);
     446:                 freemem(keyname);
     447:                 return NULL;
     448:             }
     449:             else
     450:                 return savestr(deftab[i].def);
     451:         }
     452:         err("Invalid item", "");
     453:         return NULL;
     454:     }
     455: }
     456:
     457: Hidden string getrhs()
     458: {
     459:     string first, item;
     460:
     461:     skipsp();
     462:     first= getitem();
     463:     if (first != NULL) {
     464:         for (;;) {
     465:             skipsp();
     466:             if (nextc == '\n' || nextc == COMMENT)
     467:                 break;
     468:             item= getitem();
     469:             if (item == NULL) {
     470:                 freemem(first);
     471:                 return NULL;
     472:             }
     473:             append(&first, item);
     474:             freemem(item);
     475:         }
     476:     }
     477:     return first;
     478: }
     479:
     480: Hidden Procedure getdef()
     481: {
     482:     string name;
     483:     int key;
     484:     string rhs;
     485:
     486:     name= getname();
     487:     if (name == NULL)
     488:         return;
     489:     skipsp();
     490:     if (nextc != '=') {
     491:         err("Command name %s not followed by '='", name);
     492:         return;
     493:     }
     494:     key= lookup(name);
     495:     if (key < 0) {
     496:         err("Unknown command: %s", name);
     497:         return;
     498:     }
     499:     if (deftab[key].code < 0) {
     500:         err("No redefinition of %s allowed", name);
     501:         return;
     502:     }
     503:     adv();
     504:     rhs= getrhs();
     505:     if (rhs != NULL)
     506:         store(deftab[key].code, name, rhs);
     507: }
     508:
     509: Hidden Procedure getline()
     510: {
     511:     adv();
     512:     skipsp();
     513:     if (nextc != COMMENT && nextc != '\n')
     514:         getdef();
     515:     while (nextc != '\n')
     516:         adv();
     517: }
     518:
     519: #ifndef NDEBUG
     520: Hidden Procedure dump(where)
     521:     string where;
     522: {
     523:     int i;
     524:     string s;
     525:
     526:     printf("\nDump of key definitions %s.\n\n", where);
     527:     printf("Code    Name            Definition\n");
     528:     for (i= 0; i < ndefs; ++i) {
     529:         printf("%04o    ", deftab[i].code);
     530:         if (deftab[i].name != NULL)
     531:             printf("%-15s ", deftab[i].name);
     532:         else
     533:             printf("%16s", "");
     534:         s= deftab[i].def;
     535:         if (s != NULL) {
     536:             for (; *s != '\0'; ++s) {
     537:                 if (isascii(*s) && (isprint(*s) || *s == ' '))
     538:                     fputc(*s, stdout);
     539:                 else
     540:                     printf("\\%03o", *s&0377);
     541:             }
     542:         }
     543:         printf("\n");
     544:     }
     545:     fflush(stdout);
     546: }
     547: #endif !NDEBUG
     548:
     549: Hidden Procedure countdefs()
     550: {
     551:     struct tabent *d;
     552:
     553:     d= deftab;
     554:     while (d->name != NULL || d->code != 0 || d->def != NULL) {
     555:         ++d;
     556:         if (d >= deftab+MAXDEFS)
     557:             syserr("too many predefined keys");
     558:     }
     559:     ndefs= d-deftab;
     560: }
     561:
     562: Hidden Procedure process()
     563: {
     564:     errcount= 0;
     565:     lcount= 1;
     566:     eof= No;
     567:     do {
     568:         getline();
     569:     } while (!eof);
     570: }
     571:
     572: Hidden bool try(dir, file, type)
     573:     string dir, file, type;
     574: {
     575:     char buffer[200];
     576:
     577: #ifdef IBMPC
     578:     sprintf(buffer, "%.150s\\%.9s%.3s", dir, file, type);
     579: #else !IBMPC
     580:     sprintf(buffer, "%.150s/%.20s%.20s", dir, file, type);
     581: #endif !IBMPC
     582:     fp= fopen(buffer, "r");
     583:     if (fp == NULL)
     584:         return No;
     585:     filename= buffer;
     586:     process();
     587:     fclose(fp);
     588: #ifndef NDEBUG
     589:     if (dflag)
     590:         dump("after try");
     591: #endif NDEBUG
     592:     return Yes;
     593: }
     594:
     595: #ifndef IBMPC
     596: Hidden Procedure readtermcap()
     597: {
     598:     string tgetstr();
     599:     char buffer[1024]; /* Constant dictated by termcap manual entry */
     600:     static char area[1024];
     601:     string endarea= area;
     602:     string anentry;
     603:     struct tabent *d, *last;
     604:
     605:     switch (tgetent(buffer, getenv("TERM"))) {
     606:
     607:     default:
     608:         fprintf(stderr, "*** Bad tgetent() return value.\n");
     609:         /* Fall through */
     610:     case -1:
     611:         fprintf(stderr, "*** Can't read termcap.\n");
     612:         /* Fall through again */
     613:     case 0:
     614:         fprintf(stderr, "*** No description for your terminal.\n");
     615:         exit(1);
     616:
     617:     case 1:
     618:         break;
     619:     }
     620:     last= deftab+ndefs;
     621:     for (d= deftab; d < last; ++d) {
     622:         if (d->def != NULL && d->def[0] == '=') {
     623:             anentry= tgetstr(d->def+1, &endarea);
     624:             if (anentry != NULL && anentry[0] != '\0')
     625:                 d->def= anentry;
     626:             else
     627:                 d->def= NULL;
     628:         }
     629:     }
     630: }
     631: #endif !IBMPC
     632:
     633: Visible Procedure initkeys()
     634: {
     635:     string term= NULL;
     636:
     637:     countdefs();
     638: #ifndef NDEBUG
     639:     if (dflag)
     640:         dump("before termcap");
     641: #endif NDEBUG
     642: #ifndef IBMPC
     643:     readtermcap();
     644: #ifndef NDEBUG
     645:     if (dflag)
     646:         dump("after termcap");
     647: #endif NDEBUG
     648:     term= getenv("TERM");
     649:     if (term != NULL && term[0] == '\0')
     650:         term= NULL;
     651: #endif !IBMPC
     652: #ifdef DEBUG
     653:     /* Try in the current directory. Only for debugging porpoises. */
     654:     if (term != NULL)
     655:         if (try(".", keyfile, term)) return;
     656: #endif DEBUG
     657:     if (term != NULL) {
     658:         if (try(homedir, keyfile, term)) return;
     659:         if (try(libdir, keyfile, term)) return;
     660:     }
     661: #ifdef DEBUG
     662:     if (try(".", keyfile, deftype)) return;
     663: #endif DEBUG
     664:     if (try(homedir, keyfile, deftype)) return;
     665:     if (try(libdir, keyfile, deftype)) return;
     666: #ifndef NDEBUG
     667:     printf("[No key definitions file found, using defaults.]\n");
     668: #endif !NDEBUG
     669: }
     670:
     671:
     672: /* Output a named string to the terminal */
     673:
     674: Hidden Procedure outstring(name)
     675:     string name;
     676: {
     677:     int i= lookup(name);
     678:     string def;
     679:
     680:     if (i >= 0 && (def= deftab[i].def) != NULL)
     681:         fputs(def, stdout);
     682: }
     683:
     684:
     685: /* Output the terminal's initialization sequence, if any. */
     686:
     687: Visible Procedure
     688: initgetc()
     689: {
     690:     outstring("term_init");
     691: }
     692:
     693:
     694: /* Output a sequence, if any, to return the terminal to a 'normal' state. */
     695:
     696: Visible Procedure endgetc()
     697: {
     698:     outstring("term_done");
     699: }
     700:
     701:
     702: /* Read a command from the keyboard, decoding composite key definitions. */
     703:
     704: #ifndef IBMPC
     705: /* Strip high bit from input characters (matters only on PWB systems?) */
     706: #define getch() (getchar() & 0177)
     707: #endif !IBMPC
     708:
     709: Visible int inchar()
     710: {
     711:     int c;
     712:     struct tabent *d, *last;
     713:     char buffer[100];
     714:     int len;
     715:
     716:     c= getch();
     717:     if (c == EOF)
     718:         return c;
     719: #ifdef IBMPC
     720:     if (c == 0)
     721:         c= 0377;
     722: #endif IBMPC
     723:     last= deftab+ndefs;
     724:     for (d= deftab; d < last; ++d) {
     725:         if (d->code > 0 && d->def != NULL && c == (d->def[0] & 0377))
     726:             break;
     727:     }
     728:     if (d == last) {
     729:         if (c == ESC) {
     730:             /* Kludge to make ESC-char by default equal to
     731: 			   char|MASK -- the command definitions do the rest:
     732: 			   e.g. WIDEN is 'w'|MASK, so ESC-w means WIDEN. */
     733:             c= getch();
     734:             if (c == EOF)
     735:                 return EOF;
     736:             return (c&0177) | MASK;
     737:         }
     738:         return c;
     739:     }
     740:     if (d->def[1] == '\0')
     741:         return d->code;
     742:     buffer[0]= c;
     743:     len= 1;
     744:     for (;;) {
     745:         c= getch();
     746:         if (c == EOF)
     747:             return EOF;
     748:         buffer[len]= c;
     749:         if (len < sizeof buffer - 1)
     750:             ++len;
     751:         for (d= deftab; d < last; ++d) {
     752:             if (d->code > 0 && d->def != NULL
     753:                 && strncmp(buffer, d->def, len) == 0)
     754:                 break;
     755:         }
     756:         if (d == last) {
     757:             if (buffer[0] == ESC && len == 2) {
     758:                 /* Same kludge as above */
     759:                 return c&0177 | MASK;
     760:             }
     761:             return 0377; /* Hope this rings a bell */
     762:         }
     763:         if (d->def[len] == '\0')
     764:             return d->code;
     765:     }
     766: }

#### Defined functions

adv defined in line 209; used 22 times

- in line 230, 320, 332, 352, 360-389(12), 399, 415, 422, 503, 511-516(2)

append defined in line 300; used 1 times

- in line 473

countdefs defined in line 549; used 1 times

- in line 637

dump defined in line 520; used 3 times

- in line 590, 640, 646

endgetc defined in line 696; used 1 times

- in /usr/src/new/PORT/B/src/bed/term.c line 51

err defined in line 198; used 12 times

- in line 280, 314, 337, 355, 394, 425, 440-445(2), 452, 491-500(3)

getdef defined in line 480; used 1 times

- in line 514

getitem defined in line 404; used 2 times

- in line 462, 468

getline defined in line 509; used 1 times

- in line 568

getmem defined in line 66; never used
getname defined in line 308; used 2 times

- in line 434, 486

getnumber defined in line 326; used 1 times

- in line 429

getrhs defined in line 457; used 1 times

- in line 504

getstring defined in line 345; used 1 times

- in line 413

inchar defined in line 709; used 1 times

- in /usr/src/new/PORT/B/src/bed/demo.c line 316

initgetc defined in line 687; used 1 times

- in /usr/src/new/PORT/B/src/bed/term.c line 33

initkeys defined in line 633; used 1 times

- in /usr/src/new/PORT/B/src/bed/main.c line 162

lookup defined in line 233; used 3 times

- in line 438, 494, 677

outstring defined in line 674; used 2 times

- in line 690, 698

process defined in line 562; used 1 times

- in line 586

readtermcap defined in line 596; used 1 times

- in line 643

regetmem defined in line 77; used 1 times

- in line 304

savestr defined in line 290; used 6 times

- in line 323, 401, 423, 431-436(2), 450

skipsp defined in line 227; used 4 times

- in line 461-465(2), 489, 512

store defined in line 245; used 1 times

- in line 506

try defined in line 572; used 6 times

- in line 655-665(6)

#### Defined variables

Hidden defined in line 520; never used
Procedure defined in line 520; never used
deftab defined in line 125; used 23 times

- in line 239(2), 250, 258, 273, 439-444(2), 450, 499, 506, 529-534(4), 553-559(3), 620-621(2), 680, 723-724(2), 751

eof defined in line 94; used 4 times

- in line 213-218(2), 566-569(2)

errcount defined in line 96; used 3 times

- in line 201-203(2), 564

filename defined in line 92; used 2 times

- in line 204, 585

lcount defined in line 95; used 3 times

- in line 204, 223, 565

ndefs defined in line 195; used 8 times

- in line 238, 250, 279-283(2), 528, 559, 620, 723

nextc defined in line 93; used 39 times

- in line 217-221(2), 229(2), 313-319(5), 328-333(2), 348-364(6), 377-383(7), 389, 410, 416-420(4), 428-433(3), 466(2), 490, 513-515(3)

#### Defined struct's

tabent defined in line 99; used 10 times

- in line 125(2), 250(2), 551(2), 603(2), 712(2)

#### Defined macros

COMMENT defined in line 88; used 2 times

- in line 466, 513

ESC defined in line 22; used 3 times

- in line 373, 729, 757

I defined in line 122; used 35 times

- in line 132-143(8), 154-193(27)

MAXDEFS defined in line 89; used 3 times

- in line 125, 279, 556

freemem defined in line 13; used 4 times

- in line 441-446(2), 470-474(2)

getch defined in line 706; used 3 times

- in line 716, 733, 745

syserr defined in line 11; used 3 times

- in line 73, 83, 557

Last modified: 1985-09-13 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2541 |