1 /*        $NetBSD: fancy.c,v 1.20 2024/11/29 21:48:44 dholland Exp $  */
2 
3 /*
4  * Copyright (c) 1980, 1993
5  *        The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the University nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 
32 #include <sys/cdefs.h>
33 #ifndef lint
34 #if 0
35 static char sccsid[] = "@(#)fancy.c     8.1 (Berkeley) 5/31/93";
36 #else
37 __RCSID("$NetBSD: fancy.c,v 1.20 2024/11/29 21:48:44 dholland Exp $");
38 #endif
39 #endif /* not lint */
40 
41 #include "back.h"
42 
43 static void bsect(int, int, int, int);
44 static void fixpos(int, int, int, int, int);
45 static void fixcol(int, int, int, int, int);
46 static void newline(void);
47 
48 /*
49  * These need to be declared so they come out as commons, because
50  * termcap might or might not define some of them. Our termcap defines
51  * PC, BC, and UP only. This is gross.
52  *
53  * XXX: rewrite this crap using curses.
54  */
55 #if 0
56 char    PC;                             /* padding character */
57 char   *BC;                             /* backspace sequence */
58 #endif
59 static char   *CD;            /* clear to end of screen sequence */
60 static char   *CE;            /* clear to end of line sequence */
61 static char   *CL;            /* clear screen sequence */
62 static char   *CM;            /* cursor movement instructions */
63 static char   *HO;            /* home cursor sequence */
64 static char   *MC;            /* column cursor movement map */
65 static char   *ML;            /* row cursor movement map */
66 static char   *ND;            /* forward cursor sequence */
67 #if 0
68 char   *UP;                             /* up cursor sequence */
69 #endif
70 
71 static int lHO;                         /* length of HO */
72 static int lBC;                         /* length of BC */
73 static int lND;                         /* length of ND */
74 static int lUP;                         /* length of UP */
75 static int CO;                          /* number of columns */
76 static int LI;                          /* number of lines */
77 static int *linect;           /* array of lengths of lines on screen (the
78                                          * actual screen is not stored) */
79 
80  /* two letter codes */
81 static char tcap[] = "bccdceclcmhomcmlndup";
82  /* corresponding strings */
83 static char **tstr[] = {&BC, &CD, &CE, &CL, &CM, &HO, &MC, &ML, &ND, &UP};
84 
85 static char tbuf[1024];                 /* buffer for decoded termcap entries */
86 
87 static int oldb[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
88                          0, 0, 0, 0, 0, 0};
89 
90 static int oldr;
91 static int oldw;
92  /* "real" cursor positions, so it knows when to reposition. These are -1 if
93   * curr and curc are accurate */
94 static int realr;
95 static int realc;
96 
97 void
fboard(void)98 fboard(void)
99 {
100           int     i, j, l;
101 
102           curmove(0, 0);                /* do top line */
103           for (i = 0; i < 53; i++)
104                     fancyc('_');
105 
106           curmove(15, 0);               /* do bottom line */
107           for (i = 0; i < 53; i++)
108                     fancyc('_');
109 
110           l = 1;                        /* do vertical lines */
111           for (i = 52; i > -1; i -= 28) {
112                     curmove((l == 1 ? 1 : 15), i);
113                     fancyc('|');
114                     for (j = 0; j < 14; j++) {
115                               curmove(curr + l, curc - 1);
116                               fancyc('|');
117                     }
118                     if (i == 24)
119                               i += 32;
120                     l = -l;             /* alternate directions */
121           }
122 
123           curmove(2, 1);                /* label positions 13-18 */
124           for (i = 13; i < 18; i++) {
125                     fancyc('1');
126                     fancyc((i % 10) + '0');
127                     curmove(curr, curc + 2);
128           }
129           fancyc('1');
130           fancyc('8');
131 
132           curmove(2, 29);               /* label positions 19-24 */
133           fancyc('1');
134           fancyc('9');
135           for (i = 20; i < 25; i++) {
136                     curmove(curr, curc + 2);
137                     fancyc('2');
138                     fancyc((i % 10) + '0');
139           }
140 
141           curmove(14, 1);               /* label positions 12-7 */
142           fancyc('1');
143           fancyc('2');
144           for (i = 11; i > 6; i--) {
145                     curmove(curr, curc + 2);
146                     fancyc(i > 9 ? '1' : ' ');
147                     fancyc((i % 10) + '0');
148           }
149 
150           curmove(14, 30);    /* label positions 6-1 */
151           fancyc('6');
152           for (i = 5; i > 0; i--) {
153                     curmove(curr, curc + 3);
154                     fancyc(i + '0');
155           }
156 
157           for (i = 12; i > 6; i--)/* print positions 12-7 */
158                     if (board[i])
159                               bsect(board[i], 13, 1 + 4 * (12 - i), -1);
160 
161           if (board[0])                 /* print red men on bar */
162                     bsect(board[0], 13, 25, -1);
163 
164           for (i = 6; i > 0; i--)       /* print positions 6-1 */
165                     if (board[i])
166                               bsect(board[i], 13, 29 + 4 * (6 - i), -1);
167 
168           l = (off[1] < 0 ? off[1] + 15 : off[1]);          /* print white's home */
169           bsect(l, 3, 54, 1);
170 
171           curmove(8, 25);               /* print the word BAR */
172           fancyc('B');
173           fancyc('A');
174           fancyc('R');
175 
176           for (i = 13; i < 19; i++)     /* print positions 13-18 */
177                     if (board[i])
178                               bsect(board[i], 3, 1 + 4 * (i - 13), 1);
179 
180           if (board[25])                /* print white's men on bar */
181                     bsect(board[25], 3, 25, 1);
182 
183           for (i = 19; i < 25; i++)     /* print positions 19-24 */
184                     if (board[i])
185                               bsect(board[i], 3, 29 + 4 * (i - 19), 1);
186 
187           l = (off[0] < 0 ? off[0] + 15 : off[0]);          /* print red's home */
188           bsect(-l, 13, 54, -1);
189 
190           for (i = 0; i < 26; i++)/* save board position for refresh later */
191                     oldb[i] = board[i];
192           oldr = (off[1] < 0 ? off[1] + 15 : off[1]);
193           oldw = -(off[0] < 0 ? off[0] + 15 : off[0]);
194 }
195 /*
196  * bsect (b,rpos,cpos,cnext)
197  *        Print the contents of a board position.  "b" has the value of the
198  * position, "rpos" is the row to start printing, "cpos" is the column to
199  * start printing, and "cnext" is positive if the position starts at the top
200  * and negative if it starts at the bottom.  The value of "cpos" is checked
201  * to see if the position is a player's home, since those are printed
202  * differently.
203  */
204 static void
bsect(int b,int rpos,int cpos,int cnext)205 bsect(int b, int rpos, int cpos, int cnext)
206 {
207           int     j;                    /* index */
208           int     n;                    /* number of men on position */
209           int     bct;                  /* counter */
210           int     k;                    /* index */
211           char    pc;                   /* color of men on position */
212 
213           bct = 0;
214           n = abs(b);                   /* initialize n and pc */
215           pc = (b > 0 ? 'r' : 'w');
216 
217           if (n < 6 && cpos < 54)       /* position cursor at start */
218                     curmove(rpos, cpos + 1);
219           else
220                     curmove(rpos, cpos);
221 
222           for (j = 0; j < 5; j++) {     /* print position row by row */
223 
224                     for (k = 0; k < 15; k += 5)   /* print men */
225                               if (n > j + k)
226                                         fancyc(pc);
227 
228                     if (j < 4) {        /* figure how far to back up for next row */
229                               if (n < 6) {        /* stop if none left */
230                                         if (j + 1 == n)
231                                                   break;
232                                         bct = 1;  /* single column */
233                               } else {
234                                         if (n < 11) {       /* two columns */
235                                                   if (cpos == 54) {   /* home pos */
236                                                             if (j + 5 >= n)
237                                                                       bct = 1;
238                                                             else
239                                                                       bct = 2;
240                                                   }
241                                                   if (cpos < 54) {    /* not home */
242                                                             if (j + 6 >= n)
243                                                                       bct = 1;
244                                                             else
245                                                                       bct = 2;
246                                                   }
247                                         } else {  /* three columns */
248                                                   if (j + 10 >= n)
249                                                             bct = 2;
250                                                   else
251                                                             bct = 3;
252                                         }
253                               }
254                               /* reposition cursor */
255                               curmove(curr + cnext, curc - bct);
256                     }
257           }
258 }
259 
260 void
refresh(void)261 refresh(void)
262 {
263           int     i, r, c;
264 
265           r = curr;           /* save current position */
266           c = curc;
267 
268           for (i = 12; i > 6; i--)/* fix positions 12-7 */
269                     if (board[i] != oldb[i]) {
270                               fixpos(oldb[i], board[i], 13, 1 + (12 - i) * 4, -1);
271                               oldb[i] = board[i];
272                     }
273           if (board[0] != oldb[0]) {    /* fix red men on bar */
274                     fixpos(oldb[0], board[0], 13, 25, -1);
275                     oldb[0] = board[0];
276           }
277           for (i = 6; i > 0; i--)       /* fix positions 6-1 */
278                     if (board[i] != oldb[i]) {
279                               fixpos(oldb[i], board[i], 13, 29 + (6 - i) * 4, -1);
280                               oldb[i] = board[i];
281                     }
282           i = -(off[0] < 0 ? off[0] + 15 : off[0]);         /* fix white's home */
283           if (oldw != i) {
284                     fixpos(oldw, i, 13, 54, -1);
285                     oldw = i;
286           }
287           for (i = 13; i < 19; i++)     /* fix positions 13-18 */
288                     if (board[i] != oldb[i]) {
289                               fixpos(oldb[i], board[i], 3, 1 + (i - 13) * 4, 1);
290                               oldb[i] = board[i];
291                     }
292           if (board[25] != oldb[25]) {  /* fix white men on bar */
293                     fixpos(oldb[25], board[25], 3, 25, 1);
294                     oldb[25] = board[25];
295           }
296           for (i = 19; i < 25; i++)     /* fix positions 19-24 */
297                     if (board[i] != oldb[i]) {
298                               fixpos(oldb[i], board[i], 3, 29 + (i - 19) * 4, 1);
299                               oldb[i] = board[i];
300                     }
301           i = (off[1] < 0 ? off[1] + 15 : off[1]);          /* fix red's home */
302           if (oldr != i) {
303                     fixpos(oldr, i, 3, 54, 1);
304                     oldr = i;
305           }
306           curmove(r, c);                /* return to saved position */
307           newpos();
308           buflush();
309 }
310 
311 static void
fixpos(int cur,int new,int r,int c,int inc)312 fixpos(int cur, int new, int r, int c, int inc)
313 {
314           int     o, n, nv;
315           int     ov, nc;
316           char    col;
317 
318           nc = 0;
319           if (cur * new >= 0) {
320                     ov = abs(cur);
321                     nv = abs(new);
322                     col = (cur + new > 0 ? 'r' : 'w');
323                     o = (ov - 1) / 5;
324                     n = (nv - 1) / 5;
325                     if (o == n) {
326                               if (o == 2)
327                                         nc = c + 2;
328                               if (o == 1)
329                                         nc = c < 54 ? c : c + 1;
330                               if (o == 0)
331                                         nc = c < 54 ? c + 1 : c;
332                               if (ov > nv)
333                                         fixcol(r + inc * (nv - n * 5), nc,
334                                             abs(ov - nv), ' ', inc);
335                               else
336                                         fixcol(r + inc * (ov - o * 5), nc,
337                                             abs(ov - nv), col, inc);
338                               return;
339                     } else {
340                               if (c < 54) {
341                                         if (o + n == 1) {
342                                                   if (n) {
343                                                             fixcol(r, c, abs(nv - 5), col,
344                                                                 inc);
345                                                             if (ov != 5)
346                                                                       fixcol(r + inc * ov,
347                                                                           c + 1, abs(ov - 5),
348                                                                           col, inc);
349                                                   } else {
350                                                             fixcol(r, c, abs(ov - 5), ' ',
351                                                                 inc);
352                                                             if (nv != 5)
353                                                                       fixcol(r + inc * nv,
354                                                                           c + 1, abs(nv - 5),
355                                                                           ' ', inc);
356                                                   }
357                                                   return;
358                                         }
359                                         if (n == 2) {
360                                                   if (ov != 10)
361                                                             fixcol(r + inc * (ov - 5), c,
362                                                                 abs(ov - 10), col, inc);
363                                                   fixcol(r, c + 2, abs(nv - 10), col,
364                                                       inc);
365                                         } else {
366                                                   if (nv != 10)
367                                                             fixcol(r + inc * (nv - 5), c,
368                                                                 abs(nv - 10), ' ', inc);
369                                                   fixcol(r, c + 2, abs(ov - 10), ' ',
370                                                       inc);
371                                         }
372                                         return;
373                               }
374                               if (n > o) {
375                                         fixcol(r + inc * (ov % 5), c + o,
376                                             abs(5 * n - ov), col, inc);
377                                         if (nv != 5 * n)
378                                                   fixcol(r, c + n, abs(5 * n - nv),
379                                                       col, inc);
380                               } else {
381                                         fixcol(r + inc * (nv % 5), c + n,
382                                             abs(5 * n - nv), ' ', inc);
383                                         if (ov != 5 * o)
384                                                   fixcol(r, c + o, abs(5 * o - ov),
385                                                       ' ', inc);
386                               }
387                               return;
388                     }
389           }
390           nv = abs(new);
391           fixcol(r, c + 1, nv, new > 0 ? 'r' : 'w', inc);
392           if (abs(cur) <= abs(new))
393                     return;
394           fixcol(r + inc * new, c + 1, abs(cur + new), ' ', inc);
395 }
396 
397 static void
fixcol(int r,int c,int l,int ch,int inc)398 fixcol(int r, int c, int l, int ch, int inc)
399 {
400           int     i;
401 
402           curmove(r, c);
403           fancyc(ch);
404           for (i = 1; i < l; i++) {
405                     curmove(curr + inc, curc - 1);
406                     fancyc(ch);
407           }
408 }
409 
410 void
curmove(int r,int c)411 curmove(int r, int c)
412 {
413           if (curr == r && curc == c)
414                     return;
415           if (realr == -1) {
416                     realr = curr;
417                     realc = curc;
418           }
419           curr = r;
420           curc = c;
421 }
422 
423 void
newpos(void)424 newpos(void)
425 {
426           int     r;                    /* destination row */
427           int     c;                    /* destination column */
428           int     mode = -1;  /* mode of movement */
429 
430           int     ccount = 1000;        /* character count */
431           int     i;                    /* index */
432           int     n;                    /* temporary variable */
433           char   *m;                    /* string containing CM movement */
434 
435 
436           m = NULL;
437           if (realr == -1)    /* see if already there */
438                     return;
439 
440           r = curr;           /* set current and dest. positions */
441           c = curc;
442           curr = realr;
443           curc = realc;
444 
445           /* double check position */
446           if (curr == r && curc == c) {
447                     realr = realc = -1;
448                     return;
449           }
450           if (CM) {           /* try CM to get there */
451                     mode = 0;
452                     m = (char *) tgoto(CM, c, r);
453                     ccount = (int)strlen(m);
454           }
455           /* try HO and local movement */
456           if (HO && (n = r + c * lND + lHO) < ccount) {
457                     mode = 1;
458                     ccount = n;
459           }
460           /* try various LF combinations */
461           if (r >= curr) {
462                     /* CR, LF, and ND */
463                     if ((n = (r - curr) + c * lND + 1) < ccount) {
464                               mode = 2;
465                               ccount = n;
466                     }
467                     /* LF, ND */
468                     if (c >= curc && (n = (r - curr) + (c - curc) * lND) < ccount) {
469                               mode = 3;
470                               ccount = n;
471                     }
472                     /* LF, BS */
473                     if (c < curc && (n = (r - curr) + (curc - c) * lBC) < ccount) {
474                               mode = 4;
475                               ccount = n;
476                     }
477           }
478           /* try corresponding UP combinations */
479           if (r < curr) {
480                     /* CR, UP, and ND */
481                     if ((n = (curr - r) * lUP + c * lND + 1) < ccount) {
482                               mode = 5;
483                               ccount = n;
484                     }
485                     /* UP and ND */
486                     if (c >= curc &&
487                         (n = (curr - r) * lUP + (c - curc) * lND) < ccount) {
488                               mode = 6;
489                               ccount = n;
490                     }
491                     /* UP and BS */
492                     if (c < curc &&
493                         (n = (curr - r) * lUP + (curc - c) * lBC) < ccount) {
494                               mode = 7;
495                               ccount = n;
496                     }
497           }
498           /* space over */
499           if (curr == r && c > curc && linect[r] < curc && c - curc < ccount)
500                     mode = 8;
501 
502           switch (mode) {
503 
504           case -1:            /* error! */
505                     write(2, "\r\nInternal cursor error.\r\n", 26);
506                     getout(0);
507                     /* NOTREACHED */
508 
509                     /* direct cursor motion */
510           case 0:
511                     tputs(m, abs(curr - r), addbuf);
512                     break;
513 
514                     /* relative to "home" */
515           case 1:
516                     tputs(HO, r, addbuf);
517                     for (i = 0; i < r; i++)
518                               addbuf('\012');
519                     for (i = 0; i < c; i++)
520                               tputs(ND, 1, addbuf);
521                     break;
522 
523                     /* CR and down and over */
524           case 2:
525                     addbuf('\015');
526                     for (i = 0; i < r - curr; i++)
527                               addbuf('\012');
528                     for (i = 0; i < c; i++)
529                               tputs(ND, 1, addbuf);
530                     break;
531 
532                     /* down and over */
533           case 3:
534                     for (i = 0; i < r - curr; i++)
535                               addbuf('\012');
536                     for (i = 0; i < c - curc; i++)
537                               tputs(ND, 1, addbuf);
538                     break;
539 
540                     /* down and back */
541           case 4:
542                     for (i = 0; i < r - curr; i++)
543                               addbuf('\012');
544                     for (i = 0; i < curc - c; i++)
545                               addbuf('\010');
546                     break;
547 
548                     /* CR and up and over */
549           case 5:
550                     addbuf('\015');
551                     for (i = 0; i < curr - r; i++)
552                               tputs(UP, 1, addbuf);
553                     for (i = 0; i < c; i++)
554                               tputs(ND, 1, addbuf);
555                     break;
556 
557                     /* up and over */
558           case 6:
559                     for (i = 0; i < curr - r; i++)
560                               tputs(UP, 1, addbuf);
561                     for (i = 0; i < c - curc; i++)
562                               tputs(ND, 1, addbuf);
563                     break;
564 
565                     /* up and back */
566           case 7:
567                     for (i = 0; i < curr - r; i++)
568                               tputs(UP, 1, addbuf);
569                     for (i = 0; i < curc - c; i++) {
570                               if (BC)
571                                         tputs(BC, 1, addbuf);
572                               else
573                                         addbuf('\010');
574                     }
575                     break;
576 
577                     /* safe space */
578           case 8:
579                     for (i = 0; i < c - curc; i++)
580                               addbuf(' ');
581           }
582 
583           /* fix positions */
584           curr = r;
585           curc = c;
586           realr = -1;
587           realc = -1;
588 }
589 
590 void
clear(void)591 clear(void)
592 {
593           int     i;
594 
595           /* double space if can't clear */
596           if (CL == NULL) {
597                     writel("\n\n");
598                     return;
599           }
600           curr = curc = 0;    /* fix position markers */
601           realr = realc = -1;
602           for (i = 0; i < 24; i++)/* clear line counts */
603                     linect[i] = -1;
604           buffnum = -1;                 /* ignore leftover buffer contents */
605           tputs(CL, CO, addbuf);        /* put CL in buffer */
606 }
607 
608 void
fancyc(int c)609 fancyc(int c)
610 {
611           int     sp;                   /* counts spaces in a tab */
612 
613           if (c == '\007') {  /* bells go in blindly */
614                     addbuf(c);
615                     return;
616           }
617           /* process tabs, use spaces if the tab should be erasing things,
618            * otherwise use cursor movement routines.  Note this does not use
619            * hardware tabs at all. */
620           if (c == '\t') {
621                     sp = (curc + 8) & (~7);       /* compute spaces */
622                     /* check line length */
623                     if (linect[curr] >= curc || sp < 4) {
624                               for (; sp > curc; sp--)
625                                         addbuf(' ');
626                               curc = sp;          /* fix curc */
627                     } else
628                               curmove(curr, sp);
629                     return;
630           }
631           /* do newline be calling newline */
632           if (c == '\n') {
633                     newline();
634                     return;
635           }
636           /* ignore any other control chars */
637           if (c < ' ')
638                     return;
639 
640           /* if an erasing space or non-space, just add it to buffer.  Otherwise
641            * use cursor movement routine, so that multiple spaces will be
642            * grouped together */
643           if (c > ' ' || linect[curr] >= curc) {
644                     newpos(); /* make sure position correct */
645                     addbuf(c);          /* add character to buffer */
646                     /* fix line length */
647                     if (c == ' ' && linect[curr] == curc)
648                               linect[curr]--;
649                     else
650                               if (linect[curr] < curc)
651                                         linect[curr] = curc;
652                     curc++;             /* fix curc */
653           } else
654                     /* use cursor movement routine */
655                     curmove(curr, curc + 1);
656 }
657 
658 void
clend(void)659 clend(void)
660 {
661           int     i;
662 
663           if (CD) {
664                     tputs(CD, CO - curr, addbuf);
665                     for (i = curr; i < LI; i++)
666                               linect[i] = -1;
667                     return;
668           }
669           curmove(i = curr, 0);
670           cline();
671           while (curr < LI - 1) {
672                     curmove(curr + 1, 0);
673                     if (linect[curr] > -1)
674                               cline();
675           }
676           curmove(i, 0);
677 }
678 
679 void
cline(void)680 cline(void)
681 {
682           int     c;
683 
684           if (curc > linect[curr])
685                     return;
686           newpos();
687           if (CE) {
688                     tputs(CE, 1, addbuf);
689                     linect[curr] = curc - 1;
690           } else {
691                     c = curc - 1;
692                     while (linect[curr] > c) {
693                               addbuf(' ');
694                               curc++;
695                               linect[curr]--;
696                     }
697                     curmove(curr, c + 1);
698           }
699 }
700 
701 static void
newline(void)702 newline(void)
703 {
704           cline();
705           if (curr == LI - 1)
706                     curmove(begscr, 0);
707           else
708                     curmove(curr + 1, 0);
709 }
710 
711 int
getcaps(const char * s)712 getcaps(const char *s)
713 {
714           char   *code;                 /* two letter code */
715           char ***cap;                  /* pointer to cap string */
716           char   *bufp;                 /* pointer to cap buffer */
717           char    tentry[1024];         /* temporary uncoded caps buffer */
718 
719           tgetent(tentry, s); /* get uncoded termcap entry */
720 
721           LI = tgetnum("li"); /* get number of lines */
722           if (LI == -1)
723                     LI = 12;
724           CO = tgetnum("co"); /* get number of columns */
725           if (CO == -1)
726                     CO = 65;
727 
728           bufp = tbuf;                  /* get padding character */
729           tgetstr("pc", &bufp);
730           if (bufp != tbuf)
731                     PC = *tbuf;
732           else
733                     PC = 0;
734 
735           bufp = tbuf;                  /* get string entries */
736           cap = tstr;
737           for (code = tcap; *code; code += 2)
738                     **cap++ = (char *) tgetstr(code, &bufp);
739 
740           /* get pertinent lengths */
741           if (HO)
742                     lHO = (int)strlen(HO);
743           if (BC)
744                     lBC = (int)strlen(BC);
745           else
746                     lBC = 1;
747           if (UP)
748                     lUP = (int)strlen(UP);
749           if (ND)
750                     lND = (int)strlen(ND);
751           if (LI < 24 || CO < 72 || !(CL && UP && ND)) {
752                     /* force CL to null because this is what's tested in clear() */
753                     CL = NULL;
754                     return (0);
755           }
756           linect = (int *) calloc(LI + 1, sizeof(int));
757           if (linect == NULL) {
758                     write(2, "\r\nOut of memory!\r\n", 18);
759                     getout(0);
760           }
761           return (1);
762 }
763