Annotation of 43BSDReno/contrib/emacs-18.55/src/termcap.c, revision 1.1

1.1     ! root        1: /* Work-alike for termcap, plus extra features.
        !             2:    Copyright (C) 1985, 1986 Free Software Foundation, Inc.
        !             3: 
        !             4:                       NO WARRANTY
        !             5: 
        !             6:   BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
        !             7: NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW.  EXCEPT
        !             8: WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
        !             9: RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS"
        !            10: WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
        !            11: BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
        !            12: FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY
        !            13: AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE PROGRAM PROVE
        !            14: DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
        !            15: CORRECTION.
        !            16: 
        !            17:  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
        !            18: STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
        !            19: WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE
        !            20: LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR
        !            21: OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
        !            22: USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
        !            23: DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR
        !            24: A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS
        !            25: PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
        !            26: DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
        !            27: 
        !            28:                GENERAL PUBLIC LICENSE TO COPY
        !            29: 
        !            30:   1. You may copy and distribute verbatim copies of this source file
        !            31: as you receive it, in any medium, provided that you conspicuously and
        !            32: appropriately publish on each copy a valid copyright notice "Copyright
        !            33: (C) 1986 Free Software Foundation, Inc."; and include following the
        !            34: copyright notice a verbatim copy of the above disclaimer of warranty
        !            35: and of this License.  You may charge a distribution fee for the
        !            36: physical act of transferring a copy.
        !            37: 
        !            38:   2. You may modify your copy or copies of this source file or
        !            39: any portion of it, and copy and distribute such modifications under
        !            40: the terms of Paragraph 1 above, provided that you also do the following:
        !            41: 
        !            42:     a) cause the modified files to carry prominent notices stating
        !            43:     that you changed the files and the date of any change; and
        !            44: 
        !            45:     b) cause the whole of any work that you distribute or publish,
        !            46:     that in whole or in part contains or is a derivative of this
        !            47:     program or any part thereof, to be licensed at no charge to all
        !            48:     third parties on terms identical to those contained in this
        !            49:     License Agreement (except that you may choose to grant more extensive
        !            50:     warranty protection to some or all third parties, at your option).
        !            51: 
        !            52:     c) You may charge a distribution fee for the physical act of
        !            53:     transferring a copy, and you may at your option offer warranty
        !            54:     protection in exchange for a fee.
        !            55: 
        !            56: Mere aggregation of another unrelated program with this program (or its
        !            57: derivative) on a volume of a storage or distribution medium does not bring
        !            58: the other program under the scope of these terms.
        !            59: 
        !            60:   3. You may copy and distribute this program (or a portion or derivative
        !            61: of it, under Paragraph 2) in object code or executable form under the terms
        !            62: of Paragraphs 1 and 2 above provided that you also do one of the following:
        !            63: 
        !            64:     a) accompany it with the complete corresponding machine-readable
        !            65:     source code, which must be distributed under the terms of
        !            66:     Paragraphs 1 and 2 above; or,
        !            67: 
        !            68:     b) accompany it with a written offer, valid for at least three
        !            69:     years, to give any third party free (except for a nominal
        !            70:     shipping charge) a complete machine-readable copy of the
        !            71:     corresponding source code, to be distributed under the terms of
        !            72:     Paragraphs 1 and 2 above; or,
        !            73: 
        !            74:     c) accompany it with the information you received as to where the
        !            75:     corresponding source code may be obtained.  (This alternative is
        !            76:     allowed only for noncommercial distribution and only if you
        !            77:     received the program in object code or executable form alone.)
        !            78: 
        !            79: For an executable file, complete source code means all the source code for
        !            80: all modules it contains; but, as a special exception, it need not include
        !            81: source code for modules which are standard libraries that accompany the
        !            82: operating system on which the executable file runs.
        !            83: 
        !            84:   4. You may not copy, sublicense, distribute or transfer this program
        !            85: except as expressly provided under this License Agreement.  Any attempt
        !            86: otherwise to copy, sublicense, distribute or transfer this program is void and
        !            87: your rights to use the program under this License agreement shall be
        !            88: automatically terminated.  However, parties who have received computer
        !            89: software programs from you with this License Agreement will not have
        !            90: their licenses terminated so long as such parties remain in full compliance.
        !            91: 
        !            92:   5. If you wish to incorporate parts of this program into other free
        !            93: programs whose distribution conditions are different, write to the Free
        !            94: Software Foundation at 675 Mass Ave, Cambridge, MA 02139.  We have not yet
        !            95: worked out a simple rule that can be stated here, but we will often permit
        !            96: this.  We will be guided by the two goals of preserving the free status of
        !            97: all derivatives of our free software and of promoting the sharing and reuse of
        !            98: software.
        !            99: 
        !           100: 
        !           101: In other words, you are welcome to use, share and improve this program.
        !           102: You are forbidden to forbid anyone else to use, share and improve
        !           103: what you give them.   Help stamp out software-hoarding!  */
        !           104: 
        !           105: 
        !           106: 
        !           107: /* BUFSIZE is the initial size allocated for the buffer
        !           108:    for reading the termcap file.
        !           109:    It is not a limit.
        !           110:    Make it large normally for speed.
        !           111:    Make it variable when debugging, so can exercise
        !           112:    increasing the space dynamically.  */
        !           113: 
        !           114: #ifdef emacs
        !           115: #include "config.h"
        !           116: #endif
        !           117: 
        !           118: #ifndef BUFSIZE
        !           119: #ifdef DEBUG
        !           120: #define BUFSIZE bufsize
        !           121: 
        !           122: int bufsize = 128;
        !           123: #else
        !           124: #define BUFSIZE 2048
        !           125: #endif
        !           126: #endif
        !           127: 
        !           128: #ifndef emacs
        !           129: static
        !           130: memory_out ()
        !           131: {
        !           132:   write (2, "Virtual memory exhausted\n", 25);
        !           133:   exit (1);
        !           134: }
        !           135: 
        !           136: static int
        !           137: xmalloc (size)
        !           138:      int size;
        !           139: {
        !           140:   register tem = malloc (size);
        !           141:   if (!tem)
        !           142:     memory_out ();
        !           143:   return tem;
        !           144: }
        !           145: 
        !           146: static int
        !           147: xrealloc (ptr, size)
        !           148:      int ptr;
        !           149:      int size;
        !           150: {
        !           151:   register tem = realloc (ptr, size);
        !           152:   if (!tem)
        !           153:     memory_out ();
        !           154:   return tem;
        !           155: }
        !           156: #endif /* not emacs */
        !           157: 
        !           158: /* Looking up capabilities in the entry already found */
        !           159: 
        !           160: /* The pointer to the data made by tgetent is left here
        !           161:    for tgetnum, tgetflag and tgetstr to find.  */
        !           162: 
        !           163: static char *term_entry;
        !           164: 
        !           165: static char *tgetst1 ();
        !           166: 
        !           167: /* This is the main subroutine that is used to search
        !           168:    an entry for a particular capability */
        !           169: 
        !           170: static char *
        !           171: find_capability (bp, cap)
        !           172:      register char *bp, *cap;
        !           173: {
        !           174:   for (; *bp; bp++)
        !           175:     if (bp[0] == ':'
        !           176:        && bp[1] == cap[0]
        !           177:        && bp[2] == cap[1])
        !           178:       return &bp[4];
        !           179:   return 0;
        !           180: }
        !           181: 
        !           182: int
        !           183: tgetnum (cap)
        !           184:      char *cap;
        !           185: {
        !           186:   register char *ptr = find_capability (term_entry, cap);
        !           187:   if (!ptr || ptr[-1] != '#')
        !           188:     return -1;
        !           189:   return atoi (ptr);
        !           190: }
        !           191: 
        !           192: int
        !           193: tgetflag (cap)
        !           194:      char *cap;
        !           195: {
        !           196:   register char *ptr = find_capability (term_entry, cap);
        !           197:   return 0 != ptr && ptr[-1] == ':';
        !           198: }
        !           199: 
        !           200: /* Look up a string-valued capability `cap'.
        !           201:    If `area' is nonzero, it points to a pointer to a block in which
        !           202:    to store the string.  That pointer is advanced over the space used.
        !           203:    If `area' is zero, space is allocated with `malloc'.  */
        !           204: 
        !           205: char *
        !           206: tgetstr (cap, area)
        !           207:      char *cap;
        !           208:      char **area;
        !           209: {
        !           210:   register char *ptr = find_capability (term_entry, cap);
        !           211:   if (!ptr || (ptr[-1] != '=' && ptr[-1] != '~'))
        !           212:     return 0;
        !           213:   return tgetst1 (ptr, area);
        !           214: }
        !           215: 
        !           216: /* Table, indexed by a character in range 0100 to 0140 with 0100 subtracted,
        !           217:    gives meaning of character following \, or a space if no special meaning.
        !           218:    Eight characters per line within the string.  */
        !           219: 
        !           220: static char esctab[]
        !           221:   = " \007\010  \033\014 \
        !           222:       \012 \
        !           223:   \015 \011 \013 \
        !           224:         ";
        !           225: 
        !           226: /* Given a pointer to a string value inside a termcap entry (`ptr'),
        !           227:    copy the value and process \ and ^ abbreviations.
        !           228:    Copy into block that *area points to,
        !           229:    or to newly allocated storage if area is 0.  */
        !           230: 
        !           231: static char *
        !           232: tgetst1 (ptr, area)
        !           233:      char *ptr;
        !           234:      char **area;
        !           235: {
        !           236:   register char *p, *r;
        !           237:   register int c;
        !           238:   register int size;
        !           239:   char *ret;
        !           240:   register int c1;
        !           241: 
        !           242:   if (!ptr)
        !           243:     return 0;
        !           244: 
        !           245:   /* `ret' gets address of where to store the string */
        !           246:   if (!area)
        !           247:     {
        !           248:       /* Compute size of block needed (may overestimate) */
        !           249:       p = ptr;
        !           250:       while ((c = *p++) && c != ':' && c != '\n');
        !           251:       ret = (char *) xmalloc (p - ptr + 1);
        !           252:     }
        !           253:   else
        !           254:     ret = *area;
        !           255: 
        !           256:   /* Copy the string value, stopping at null or colon.  */
        !           257:   /* Also process ^ and \ abbreviations.  */
        !           258:   p = ptr;
        !           259:   r = ret;
        !           260:   while ((c = *p++) && c != ':' && c != '\n')
        !           261:     {
        !           262:       if (c == '^')
        !           263:        c = *p++ & 037;
        !           264:       else if (c == '\\')
        !           265:        {
        !           266:          c = *p++;
        !           267:          if (c >= '0' && c <= '7')
        !           268:            {
        !           269:              c -= '0';
        !           270:              size = 0;
        !           271: 
        !           272:              while (++size < 3 && (c1 = *p) >= '0' && c1 <= '7')
        !           273:                {
        !           274:                  c *= 8;
        !           275:                  c += c1 - '0';
        !           276:                  p++;
        !           277:                }
        !           278:            }
        !           279:          else if (c >= 0100 && c < 0200)
        !           280:            {
        !           281:              c1 = esctab[(c & ~040) - 0100];
        !           282:              if (c1 != ' ')
        !           283:                c = c1;
        !           284:            }
        !           285:        }
        !           286:       *r++ = c;
        !           287:     }
        !           288:   *r = 0;
        !           289:   /* Update *area */
        !           290:   if (area)
        !           291:     *area = r + 1;
        !           292:   return ret;
        !           293: }
        !           294: 
        !           295: /* Outputting a string with padding */
        !           296: 
        !           297: short ospeed;
        !           298: char PC;
        !           299: 
        !           300: /* Actual baud rate if positive;
        !           301:    - baud rate / 100 if negative.  */
        !           302: 
        !           303: static short speeds[] =
        !           304:   {
        !           305: #ifdef VMS
        !           306:     0, 50, 75, 110, 134, 150, -3, -6, -12, -18,
        !           307:     -20, -24, -36, -48, -72, -96, -192
        !           308: #else /* not VMS */
        !           309:     0, 50, 75, 110, 135, 150, -2, -3, -6, -12,
        !           310:     -18, -24, -48, -96, -192, -384
        !           311: #endif /* not VMS */
        !           312:   };
        !           313: 
        !           314: tputs (string, nlines, outfun)
        !           315:      register char *string;
        !           316:      int nlines;
        !           317:      register int (*outfun) ();
        !           318: {
        !           319:   register int padcount = 0;
        !           320: 
        !           321:   if (string == (char *) 0)
        !           322:     return;
        !           323:   while (*string >= '0' && *string <= '9')
        !           324:     {
        !           325:       padcount += *string++ - '0';
        !           326:       padcount *= 10;
        !           327:     }
        !           328:   if (*string == '.')
        !           329:     {
        !           330:       string++;
        !           331:       padcount += *string++ - '0';
        !           332:     }
        !           333:   if (*string == '*')
        !           334:     {
        !           335:       string++;
        !           336:       padcount *= nlines;
        !           337:     }
        !           338:   while (*string)
        !           339:     (*outfun) (*string++);
        !           340: 
        !           341:   /* padcount is now in units of tenths of msec.  */
        !           342:   padcount *= speeds[ospeed];
        !           343:   padcount += 500;
        !           344:   padcount /= 1000;
        !           345:   if (speeds[ospeed] < 0)
        !           346:     padcount = -padcount;
        !           347:   else
        !           348:     {
        !           349:       padcount += 50;
        !           350:       padcount /= 100;
        !           351:     }
        !           352: 
        !           353:   while (padcount-- > 0)
        !           354:     (*outfun) (PC);
        !           355: }
        !           356: 
        !           357: /* Finding the termcap entry in the termcap data base */
        !           358: 
        !           359: struct buffer
        !           360:   {
        !           361:     char *beg;
        !           362:     int size;
        !           363:     char *ptr;
        !           364:     int ateof;
        !           365:     int full;
        !           366:   };
        !           367: 
        !           368: /* Forward declarations of static functions */
        !           369: 
        !           370: static int scan_file ();
        !           371: static char *gobble_line ();
        !           372: static int compare_contin ();
        !           373: static int name_match ();
        !           374: 
        !           375: #ifdef VMS
        !           376: 
        !           377: #include <rmsdef.h>
        !           378: #include <fab.h>
        !           379: #include <nam.h>
        !           380: 
        !           381: static int
        !           382: legal_filename_p (fn)
        !           383:      char *fn;
        !           384: {
        !           385:   struct FAB fab = cc$rms_fab;
        !           386:   struct NAM nam = cc$rms_nam;
        !           387:   char esa[NAM$C_MAXRSS];
        !           388: 
        !           389:   fab.fab$l_fna = fn;
        !           390:   fab.fab$b_fns = strlen(fn);
        !           391:   fab.fab$l_nam = &nam;
        !           392:   fab.fab$l_fop = FAB$M_NAM;
        !           393: 
        !           394:   nam.nam$l_esa = esa;
        !           395:   nam.nam$b_ess = sizeof esa;
        !           396: 
        !           397:   return SYS$PARSE(&fab, 0, 0) == RMS$_NORMAL;
        !           398: }
        !           399: 
        !           400: #endif /* VMS */
        !           401: 
        !           402: /* Find the termcap entry data for terminal type `name'
        !           403:    and store it in the block that `bp' points to.
        !           404:    Record its address for future use.
        !           405: 
        !           406:    If `bp' is zero, space is dynamically allocated.  */
        !           407: 
        !           408: int
        !           409: tgetent (bp, name)
        !           410:      char *bp, *name;
        !           411: {
        !           412:   register char *tem;
        !           413:   register int fd;
        !           414:   struct buffer buf;
        !           415:   register char *bp1;
        !           416:   char *bp2;
        !           417:   char *term;
        !           418:   int malloc_size = 0;
        !           419:   register int c;
        !           420:   char *tcenv;                 /* TERMCAP value, if it contais :tc=.  */
        !           421:   char *indirect = 0;          /* Terminal type in :tc= in TERMCAP value.  */
        !           422:   int filep;
        !           423: 
        !           424:   tem = (char *) getenv ("TERMCAP");
        !           425:   if (tem && *tem == 0) tem = 0;
        !           426: 
        !           427: #ifdef VMS
        !           428:   filep = tem && legal_filename_p (tem);
        !           429: #else
        !           430:   filep = tem && (*tem == '/');
        !           431: #endif /* VMS */
        !           432: 
        !           433:   /* If tem is non-null and starts with / (in the un*x case, that is),
        !           434:      it is a file name to use instead of /etc/termcap.
        !           435:      If it is non-null and does not start with /,
        !           436:      it is the entry itself, but only if
        !           437:      the name the caller requested matches the TERM variable.  */
        !           438: 
        !           439:   if (tem && !filep && !strcmp (name, getenv ("TERM")))
        !           440:     {
        !           441:       indirect = tgetst1 (find_capability (tem, "tc"), 0);
        !           442:       if (!indirect)
        !           443:        {
        !           444:          if (!bp)
        !           445:            bp = tem;
        !           446:          else
        !           447:            strcpy (bp, tem);
        !           448:          goto ret;
        !           449:        }
        !           450:       else
        !           451:        {                       /* we will need to read /etc/termcap */
        !           452:          tcenv = tem;
        !           453:          tem = 0;
        !           454:        }
        !           455:     }
        !           456:   else
        !           457:     indirect = (char *) 0;
        !           458: 
        !           459:   if (!tem)
        !           460: #ifdef VMS
        !           461:     tem = "emacs_library:[etc]termcap.dat";
        !           462: #else
        !           463:     tem = "/usr/share/misc/termcap";
        !           464: #endif
        !           465: 
        !           466:   /* Here we know we must search a file and tem has its name.  */
        !           467: 
        !           468:   fd = open (tem, 0, 0);
        !           469:   if (fd < 0)
        !           470:     return -1;
        !           471: 
        !           472:   buf.size = BUFSIZE;
        !           473:   buf.beg = (char *) xmalloc (buf.size);
        !           474:   term = indirect ? indirect : name;
        !           475: 
        !           476:   if (!bp)
        !           477:     {
        !           478:       malloc_size = indirect ? strlen (tcenv) + 1 : buf.size;
        !           479:       bp = (char *) xmalloc (malloc_size);
        !           480:     }
        !           481:   bp1 = bp;
        !           482: 
        !           483:   if (indirect)                        /* copy the data from the environment variable */
        !           484:     {
        !           485:       strcpy (bp, tcenv);
        !           486:       bp1 += strlen (tcenv);
        !           487:     }
        !           488: 
        !           489:   while (term)
        !           490:     {
        !           491:       /* Scan file, reading it via buf, till find start of main entry */
        !           492:       if (scan_file (term, fd, &buf) == 0)
        !           493:        return 0;
        !           494: 
        !           495:       /* Free old `term' if appropriate.  */
        !           496:       if (term != name)
        !           497:        free (term);
        !           498: 
        !           499:       /* If `bp' is malloc'd by us, make sure it is big enough.  */
        !           500:       if (malloc_size)
        !           501:        {
        !           502:          malloc_size = bp1 - bp + buf.size;
        !           503:          tem = (char *) xrealloc (bp, malloc_size);
        !           504:          bp1 += tem - bp;
        !           505:          bp = tem;
        !           506:        }
        !           507: 
        !           508:       bp2 = bp1;
        !           509: 
        !           510:       /* Copy the line of the entry from buf into bp.  */
        !           511:       tem = buf.ptr;
        !           512:       while ((*bp1++ = c = *tem++) && c != '\n')
        !           513:        /* Drop out any \ newline sequence. */
        !           514:        if (c == '\\' && *tem == '\n')
        !           515:          {
        !           516:            bp1--;
        !           517:            tem++;
        !           518:          }
        !           519:       *bp1 = 0;
        !           520: 
        !           521:       /* Does this entry refer to another terminal type's entry?  */
        !           522:       /* If something is found, copy it into heap and null-terminate it */
        !           523:       term = tgetst1 (find_capability (bp2, "tc"), 0);
        !           524:     }
        !           525: 
        !           526:   close (fd);
        !           527:   free (buf.beg);
        !           528: 
        !           529:   if (malloc_size)
        !           530:     {
        !           531:       bp = (char *) xrealloc (bp, bp1 - bp + 1);
        !           532:     }
        !           533: 
        !           534:  ret:
        !           535:   term_entry = bp;
        !           536:   if (malloc_size)
        !           537:     return (int) bp;
        !           538:   return 1;
        !           539: }
        !           540: 
        !           541: /* Given file open on `fd' and buffer `bufp',
        !           542:    scan the file from the beginning until a line is found
        !           543:    that starts the entry for terminal type `string'.
        !           544:    Returns 1 if successful, with that line in `bufp',
        !           545:    or returns 0 if no entry found in the file.  */
        !           546: 
        !           547: static int
        !           548: scan_file (string, fd, bufp)
        !           549:      char *string;
        !           550:      int fd;
        !           551:      register struct buffer *bufp;
        !           552: {
        !           553:   register char *tem;
        !           554:   register char *end;
        !           555: 
        !           556:   bufp->ptr = bufp->beg;
        !           557:   bufp->full = 0;
        !           558:   bufp->ateof = 0;
        !           559:   *bufp->ptr = 0;
        !           560: 
        !           561:   lseek (fd, 0L, 0);
        !           562: 
        !           563:   while (!bufp->ateof)
        !           564:     {
        !           565:       /* Read a line into the buffer */
        !           566:       end = 0;
        !           567:       do
        !           568:        {
        !           569:          /* if it is continued, append another line to it,
        !           570:             until a non-continued line ends */
        !           571:          end = gobble_line (fd, bufp, end);
        !           572:        }
        !           573:       while (!bufp->ateof && end[-2] == '\\');
        !           574: 
        !           575:       if (*bufp->ptr != '#'
        !           576:          && name_match (bufp->ptr, string))
        !           577:        return 1;
        !           578: 
        !           579:       /* Discard the line just processed */
        !           580:       bufp->ptr = end;
        !           581:     }
        !           582:   return 0;
        !           583: }
        !           584: 
        !           585: /* Return nonzero if NAME is one of the names specified
        !           586:    by termcap entry LINE.  */
        !           587: 
        !           588: static int
        !           589: name_match (line, name)
        !           590:      char *line, *name;
        !           591: {
        !           592:   register char *tem;
        !           593: 
        !           594:   if (!compare_contin (line, name))
        !           595:     return 1;
        !           596:   /* This line starts an entry.  Is it the right one?  */
        !           597:   for (tem = line; *tem && *tem != '\n' && *tem != ':'; tem++)
        !           598:     if (*tem == '|' && !compare_contin (tem + 1, name))
        !           599:       return 1;
        !           600: 
        !           601:   return 0;
        !           602: }
        !           603: 
        !           604: static int
        !           605: compare_contin (str1, str2)
        !           606:      register char *str1, *str2;
        !           607: {
        !           608:   register int c1, c2;
        !           609:   while (1)
        !           610:     {
        !           611:       c1 = *str1++;
        !           612:       c2 = *str2++;
        !           613:       while (c1 == '\\' && *str1 == '\n')
        !           614:        {
        !           615:          str1++;
        !           616:          while ((c1 = *str1++) == ' ' || c1 == '\t');
        !           617:        }
        !           618:       if (c2 == '\0')          /* end of type being looked up */
        !           619:        {
        !           620:          if (c1 == '|' || c1 == ':') /* If end of name in data base, */
        !           621:            return 0;           /* we win. */
        !           622:          else
        !           623:            return 1;
        !           624:         }
        !           625:       else if (c1 != c2)
        !           626:        return 1;
        !           627:     }
        !           628: }
        !           629: 
        !           630: /* Make sure that the buffer <- `bufp' contains a full line
        !           631:    of the file open on `fd', starting at the place `bufp->ptr'
        !           632:    points to.  Can read more of the file, discard stuff before
        !           633:    `bufp->ptr', or make the buffer bigger.
        !           634: 
        !           635:    Returns the pointer to after the newline ending the line,
        !           636:    or to the end of the file, if there is no newline to end it.
        !           637: 
        !           638:    Can also merge on continuation lines.  If `append_end' is
        !           639:    nonzero, it points past the newline of a line that is
        !           640:    continued; we add another line onto it and regard the whole
        !           641:    thing as one line.  The caller decides when a line is continued.  */
        !           642: 
        !           643: static char *
        !           644: gobble_line (fd, bufp, append_end)
        !           645:      int fd;
        !           646:      register struct buffer *bufp;
        !           647:      char *append_end;
        !           648: {
        !           649:   register char *end;
        !           650:   register int nread;
        !           651:   register char *buf = bufp->beg;
        !           652:   register char *tem;
        !           653: 
        !           654:   if (append_end == 0)
        !           655:     append_end = bufp->ptr;
        !           656: 
        !           657:   while (1)
        !           658:     {
        !           659:       end = append_end;
        !           660:       while (*end && *end != '\n') end++;
        !           661:       if (*end)
        !           662:         break;
        !           663:       if (bufp->ateof)
        !           664:        return buf + bufp->full;
        !           665:       if (bufp->ptr == buf)
        !           666:        {
        !           667:          if (bufp->full == bufp->size)
        !           668:            {
        !           669:              bufp->size *= 2;
        !           670:              tem = (char *) xrealloc (buf, bufp->size);
        !           671:              bufp->ptr += tem - buf;
        !           672:              append_end += tem - buf;
        !           673:              bufp->beg = buf = tem;
        !           674:            }
        !           675:        }
        !           676:       else
        !           677:        {
        !           678:          append_end -= bufp->ptr - buf;
        !           679:          bcopy (bufp->ptr, buf, bufp->full -= bufp->ptr - buf);
        !           680:          bufp->ptr = buf;
        !           681:        }
        !           682:       if (!(nread = read (fd, buf + bufp->full, bufp->size - bufp->full)))
        !           683:        bufp->ateof = 1;
        !           684:       bufp->full += nread;
        !           685:       if (bufp->full != bufp->size)
        !           686:        buf[bufp->full] = 0;
        !           687:     }
        !           688:   return end + 1;
        !           689: }
        !           690: 
        !           691: #ifdef TEST
        !           692: 
        !           693: #include <stdio.h>
        !           694: 
        !           695: main (argc, argv)
        !           696:      int argc;
        !           697:      char **argv;
        !           698: {
        !           699:   char *term;
        !           700:   char *buf;
        !           701: 
        !           702:   term = argv[1];
        !           703:   printf ("TERM: %s\n", term);
        !           704: 
        !           705:   buf = (char *) tgetent (0, term);
        !           706:   if ((int) buf <= 0)
        !           707:     {
        !           708:       printf ("No entry.\n");
        !           709:       return 0;
        !           710:     }
        !           711: 
        !           712:   printf ("Entry: %s\n", buf);
        !           713: 
        !           714:   tprint ("cm");
        !           715:   tprint ("AL");
        !           716: 
        !           717:   printf ("co: %d\n", tgetnum ("co"));
        !           718:   printf ("am: %d\n", tgetflag ("am"));
        !           719: }
        !           720: 
        !           721: tprint (cap)
        !           722:      char *cap;
        !           723: {
        !           724:   char *x = tgetstr (cap, 0);
        !           725:   register char *y;
        !           726: 
        !           727:   printf ("%s: ", cap);
        !           728:   if (x)
        !           729:     {
        !           730:       for (y = x; *y; y++)
        !           731:        if (*y <= ' ' || *y == 0177)
        !           732:          printf ("\\%0o", *y);
        !           733:        else
        !           734:          putchar (*y);
        !           735:       free (x);
        !           736:     }
        !           737:   else
        !           738:     printf ("none");
        !           739:   putchar ('\n');
        !           740: }
        !           741: 
        !           742: #endif /* TEST */
        !           743: 

unix.superglobalmegacorp.com

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