(linenum→info "unix/slp.c:2238")

bsd-games/2.17/hack/hack.topl.c

    1: /*      $NetBSD: hack.topl.c,v 1.7 2003/04/02 18:36:41 jsm Exp $     */
    2: 
    3: /*
    4:  * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
    5:  * Amsterdam
    6:  * All rights reserved.
    7:  *
    8:  * Redistribution and use in source and binary forms, with or without
    9:  * modification, are permitted provided that the following conditions are
   10:  * met:
   11:  *
   12:  * - Redistributions of source code must retain the above copyright notice,
   13:  * this list of conditions and the following disclaimer.
   14:  *
   15:  * - Redistributions in binary form must reproduce the above copyright
   16:  * notice, this list of conditions and the following disclaimer in the
   17:  * documentation and/or other materials provided with the distribution.
   18:  *
   19:  * - Neither the name of the Stichting Centrum voor Wiskunde en
   20:  * Informatica, nor the names of its contributors may be used to endorse or
   21:  * promote products derived from this software without specific prior
   22:  * written permission.
   23:  *
   24:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
   25:  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   26:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
   27:  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   28:  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   29:  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   30:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   31:  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   32:  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   33:  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   34:  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   35:  */
   36: 
   37: /*
   38:  * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
   39:  * All rights reserved.
   40:  *
   41:  * Redistribution and use in source and binary forms, with or without
   42:  * modification, are permitted provided that the following conditions
   43:  * are met:
   44:  * 1. Redistributions of source code must retain the above copyright
   45:  *    notice, this list of conditions and the following disclaimer.
   46:  * 2. Redistributions in binary form must reproduce the above copyright
   47:  *    notice, this list of conditions and the following disclaimer in the
   48:  *    documentation and/or other materials provided with the distribution.
   49:  * 3. The name of the author may not be used to endorse or promote products
   50:  *    derived from this software without specific prior written permission.
   51:  *
   52:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
   53:  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
   54:  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
   55:  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   56:  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   57:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   58:  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   59:  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   60:  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   61:  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   62:  */
   63: 
   64: #include <sys/cdefs.h>
   65: #ifndef lint
   66: __RCSID("$NetBSD: hack.topl.c,v 1.7 2003/04/02 18:36:41 jsm Exp $");
   67: #endif                          /* not lint */
   68: 
   69: #include <stdlib.h>
   70: #include "hack.h"
   71: #include "extern.h"
   72: 
   73: char            toplines[BUFSZ];
   74: xchar           tlx, tly;       /* set by pline; used by addtopl */
   75: 
   76: struct topl {
   77:         struct topl    *next_topl;
   78:         char           *topl_text;
   79: }              *old_toplines, *last_redone_topl;
   80: #define OTLMAX  20               /* max nr of old toplines remembered */
   81: 
   82: int
   83: doredotopl()
   84: {
   85:         if (last_redone_topl)
   86:                 last_redone_topl = last_redone_topl->next_topl;
   87:         if (!last_redone_topl)
   88:                 last_redone_topl = old_toplines;
   89:         if (last_redone_topl) {
   90:                 (void) strcpy(toplines, last_redone_topl->topl_text);
   91:         }
   92:         redotoplin();
   93:         return (0);
   94: }
   95: 
   96: void
   97: redotoplin()
   98: {
   99:         home();
  100:         if (strchr(toplines, '\n'))
  101:                 cl_end();
  102:         putstr(toplines);
  103:         cl_end();
  104:         tlx = curx;
  105:         tly = cury;
  106:         flags.toplin = 1;
  107:         if (tly > 1)
  108:                 more();
  109: }
  110: 
  111: void
  112: remember_topl()
  113: {
  114:         struct topl    *tl;
  115:         int             cnt = OTLMAX;
  116:         if (last_redone_topl &&
  117:             !strcmp(toplines, last_redone_topl->topl_text))
  118:                 return;
  119:         if (old_toplines &&
  120:             !strcmp(toplines, old_toplines->topl_text))
  121:                 return;
  122:         last_redone_topl = 0;
  123:         tl = (struct topl *)
  124:                 alloc((unsigned) (strlen(toplines) + sizeof(struct topl) + 1));
  125:         tl->next_topl = old_toplines;
  126:         tl->topl_text = (char *) (tl + 1);
  127:         (void) strcpy(tl->topl_text, toplines);
  128:         old_toplines = tl;
  129:         while (cnt && tl) {
  130:                 cnt--;
  131:                 tl = tl->next_topl;
  132:         }
  133:         if (tl && tl->next_topl) {
  134:                 free((char *) tl->next_topl);
  135:                 tl->next_topl = 0;
  136:         }
  137: }
  138: 
  139: void
  140: addtopl(s)
  141:         const char           *s;
  142: {
  143:         curs(tlx, tly);
  144:         if (tlx + (int)strlen(s) > CO)
  145:                 putsym('\n');
  146:         putstr(s);
  147:         tlx = curx;
  148:         tly = cury;
  149:         flags.toplin = 1;
  150: }
  151: 
  152: void
  153: xmore(s)
  154:         const char *s; /* allowed chars besides space/return */
  155: {
  156:         if (flags.toplin) {
  157:                 curs(tlx, tly);
  158:                 if (tlx + 8 > CO)
  159:                         putsym('\n'), tly++;
  160:         }
  161:         if (flags.standout)
  162:                 standoutbeg();
  163:         putstr("--More--");
  164:         if (flags.standout)
  165:                 standoutend();
  166: 
  167:         xwaitforspace(s);
  168:         if (flags.toplin && tly > 1) {
  169:                 home();
  170:                 cl_end();
  171:                 docorner(1, tly - 1);
  172:         }
  173:         flags.toplin = 0;
  174: }
  175: 
  176: void
  177: more()
  178: {
  179:         xmore("");
  180: }
  181: 
  182: void
  183: cmore(s)
  184:         const char           *s;
  185: {
  186:         xmore(s);
  187: }
  188: 
  189: void
  190: clrlin()
  191: {
  192:         if (flags.toplin) {
  193:                 home();
  194:                 cl_end();
  195:                 if (tly > 1)
  196:                         docorner(1, tly - 1);
  197:                 remember_topl();
  198:         }
  199:         flags.toplin = 0;
  200: }
  201: 
  202: void
  203: pline(const char *fmt, ...)
  204: {
  205:         va_list ap;
  206: 
  207:         va_start(ap, fmt);
  208:         vpline(fmt, ap);
  209:         va_end(ap);
  210: }
  211: 
  212: void
  213: vpline(line, ap)
  214:         const char *line;
  215:         va_list ap;
  216: {
  217:         char            pbuf[BUFSZ];
  218:         char           *bp = pbuf, *tl;
  219:         int             n, n0;
  220: 
  221:         if (!line || !*line)
  222:                 return;
  223:         if (!strchr(line, '%'))
  224:                 (void) strcpy(pbuf, line);
  225:         else
  226:                 (void) vsprintf(pbuf, line, ap);
  227:         if (flags.toplin == 1 && !strcmp(pbuf, toplines))
  228:                 return;
  229:         nscr();                        /* %% */
  230: 
  231:         /* If there is room on the line, print message on same line */
  232:         /* But messages like "You die..." deserve their own line */
  233:         n0 = strlen(bp);
  234:         if (flags.toplin == 1 && tly == 1 &&
  235:             n0 + (int)strlen(toplines) + 3 < CO - 8 && /* leave room for
  236:                                                          * --More-- */
  237:             strncmp(bp, "You ", 4)) {
  238:                 (void) strcat(toplines, "  ");
  239:                 (void) strcat(toplines, bp);
  240:                 tlx += 2;
  241:                 addtopl(bp);
  242:                 return;
  243:         }
  244:         if (flags.toplin == 1)
  245:                 more();
  246:         remember_topl();
  247:         toplines[0] = 0;
  248:         while (n0) {
  249:                 if (n0 >= CO) {
  250:                         /* look for appropriate cut point */
  251:                         n0 = 0;
  252:                         for (n = 0; n < CO; n++)
  253:                                 if (bp[n] == ' ')
  254:                                         n0 = n;
  255:                         if (!n0)
  256:                                 for (n = 0; n < CO - 1; n++)
  257:                                         if (!letter(bp[n]))
  258:                                                 n0 = n;
  259:                         if (!n0)
  260:                                 n0 = CO - 2;
  261:                 }
  262:                 (void) strncpy((tl = eos(toplines)), bp, n0);
  263:                 tl[n0] = 0;
  264:                 bp += n0;
  265: 
  266:                 /* remove trailing spaces, but leave one */
  267:                 while (n0 > 1 && tl[n0 - 1] == ' ' && tl[n0 - 2] == ' ')
  268:                         tl[--n0] = 0;
  269: 
  270:                 n0 = strlen(bp);
  271:                 if (n0 && tl[0])
  272:                         (void) strcat(tl, "\n");
  273:         }
  274:         redotoplin();
  275: }
  276: 
  277: void
  278: putsym(c)
  279:         char            c;
  280: {
  281:         switch (c) {
  282:         case '\b':
  283:                 backsp();
  284:                 return;
  285:         case '\n':
  286:                 curx = 1;
  287:                 cury++;
  288:                 if (cury > tly)
  289:                         tly = cury;
  290:                 break;
  291:         default:
  292:                 if (curx == CO)
  293:                         putsym('\n');        /* 1 <= curx <= CO; avoid CO */
  294:                 else
  295:                         curx++;
  296:         }
  297:         (void) putchar(c);
  298: }
  299: 
  300: void
  301: putstr(s)
  302:         const char           *s;
  303: {
  304:         while (*s)
  305:                 putsym(*s++);
  306: }
Syntax (Markdown)