Annotation of 43BSDReno/contrib/emacs-18.55/src/termcap.c, revision 1.1.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.