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