1 /* $NetBSD: hack.topl.c,v 1.5 2001/03/25 20:44:03 jsm Exp $ */ 2 3 /* 4 * Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. 5 */ 6 7 #include <sys/cdefs.h> 8 #ifndef lint 9 __RCSID("$NetBSD: hack.topl.c,v 1.5 2001/03/25 20:44:03 jsm Exp $"); 10 #endif /* not lint */ 11 12 #include <stdlib.h> 13 #include "hack.h" 14 #include "extern.h" 15 16 char toplines[BUFSZ]; 17 xchar tlx, tly; /* set by pline; used by addtopl */ 18 19 struct topl { 20 struct topl *next_topl; 21 char *topl_text; 22 } *old_toplines, *last_redone_topl; 23 #define OTLMAX 20 /* max nr of old toplines remembered */ 24 25 int 26 doredotopl() 27 { 28 if (last_redone_topl) 29 last_redone_topl = last_redone_topl->next_topl; 30 if (!last_redone_topl) 31 last_redone_topl = old_toplines; 32 if (last_redone_topl) { 33 (void) strcpy(toplines, last_redone_topl->topl_text); 34 } 35 redotoplin(); 36 return (0); 37 } 38 39 void 40 redotoplin() 41 { 42 home(); 43 if (strchr(toplines, '\n')) 44 cl_end(); 45 putstr(toplines); 46 cl_end(); 47 tlx = curx; 48 tly = cury; 49 flags.toplin = 1; 50 if (tly > 1) 51 more(); 52 } 53 54 void 55 remember_topl() 56 { 57 struct topl *tl; 58 int cnt = OTLMAX; 59 if (last_redone_topl && 60 !strcmp(toplines, last_redone_topl->topl_text)) 61 return; 62 if (old_toplines && 63 !strcmp(toplines, old_toplines->topl_text)) 64 return; 65 last_redone_topl = 0; 66 tl = (struct topl *) 67 alloc((unsigned) (strlen(toplines) + sizeof(struct topl) + 1)); 68 tl->next_topl = old_toplines; 69 tl->topl_text = (char *) (tl + 1); 70 (void) strcpy(tl->topl_text, toplines); 71 old_toplines = tl; 72 while (cnt && tl) { 73 cnt--; 74 tl = tl->next_topl; 75 } 76 if (tl && tl->next_topl) { 77 free((char *) tl->next_topl); 78 tl->next_topl = 0; 79 } 80 } 81 82 void 83 addtopl(s) 84 const char *s; 85 { 86 curs(tlx, tly); 87 if (tlx + strlen(s) > CO) 88 putsym('\n'); 89 putstr(s); 90 tlx = curx; 91 tly = cury; 92 flags.toplin = 1; 93 } 94 95 void 96 xmore(s) 97 const char *s; /* allowed chars besides space/return */ 98 { 99 if (flags.toplin) { 100 curs(tlx, tly); 101 if (tlx + 8 > CO) 102 putsym('\n'), tly++; 103 } 104 if (flags.standout) 105 standoutbeg(); 106 putstr("--More--"); 107 if (flags.standout) 108 standoutend(); 109 110 xwaitforspace(s); 111 if (flags.toplin && tly > 1) { 112 home(); 113 cl_end(); 114 docorner(1, tly - 1); 115 } 116 flags.toplin = 0; 117 } 118 119 void 120 more() 121 { 122 xmore(""); 123 } 124 125 void 126 cmore(s) 127 const char *s; 128 { 129 xmore(s); 130 } 131 132 void 133 clrlin() 134 { 135 if (flags.toplin) { 136 home(); 137 cl_end(); 138 if (tly > 1) 139 docorner(1, tly - 1); 140 remember_topl(); 141 } 142 flags.toplin = 0; 143 } 144 145 void 146 #ifdef __STDC__ 147 pline(const char *fmt, ...) 148 #else 149 pline(va_alist) 150 va_dcl 151 #endif 152 { 153 va_list ap; 154 #ifndef __STDC__ 155 const char *fmt; 156 va_start(ap); 157 fmt = va_arg(ap, const char *); 158 #else 159 va_start(ap, fmt); 160 #endif 161 vpline(fmt, ap); 162 va_end(ap); 163 } 164 165 void 166 vpline(line, ap) 167 const char *line; 168 va_list ap; 169 { 170 char pbuf[BUFSZ]; 171 char *bp = pbuf, *tl; 172 int n, n0; 173 174 if (!line || !*line) 175 return; 176 if (!strchr(line, '%')) 177 (void) strcpy(pbuf, line); 178 else 179 (void) vsprintf(pbuf, line, ap); 180 if (flags.toplin == 1 && !strcmp(pbuf, toplines)) 181 return; 182 nscr(); /* %% */ 183 184 /* If there is room on the line, print message on same line */ 185 /* But messages like "You die..." deserve their own line */ 186 n0 = strlen(bp); 187 if (flags.toplin == 1 && tly == 1 && 188 n0 + strlen(toplines) + 3 < CO - 8 && /* leave room for 189 * --More-- */ 190 strncmp(bp, "You ", 4)) { 191 (void) strcat(toplines, " "); 192 (void) strcat(toplines, bp); 193 tlx += 2; 194 addtopl(bp); 195 return; 196 } 197 if (flags.toplin == 1) 198 more(); 199 remember_topl(); 200 toplines[0] = 0; 201 while (n0) { 202 if (n0 >= CO) { 203 /* look for appropriate cut point */ 204 n0 = 0; 205 for (n = 0; n < CO; n++) 206 if (bp[n] == ' ') 207 n0 = n; 208 if (!n0) 209 for (n = 0; n < CO - 1; n++) 210 if (!letter(bp[n])) 211 n0 = n; 212 if (!n0) 213 n0 = CO - 2; 214 } 215 (void) strncpy((tl = eos(toplines)), bp, n0); 216 tl[n0] = 0; 217 bp += n0; 218 219 /* remove trailing spaces, but leave one */ 220 while (n0 > 1 && tl[n0 - 1] == ' ' && tl[n0 - 2] == ' ') 221 tl[--n0] = 0; 222 223 n0 = strlen(bp); 224 if (n0 && tl[0]) 225 (void) strcat(tl, "\n"); 226 } 227 redotoplin(); 228 } 229 230 void 231 putsym(c) 232 char c; 233 { 234 switch (c) { 235 case '\b': 236 backsp(); 237 return; 238 case '\n': 239 curx = 1; 240 cury++; 241 if (cury > tly) 242 tly = cury; 243 break; 244 default: 245 if (curx == CO) 246 putsym('\n'); /* 1 <= curx <= CO; avoid CO */ 247 else 248 curx++; 249 } 250 (void) putchar(c); 251 } 252 253 void 254 putstr(s) 255 const char *s; 256 { 257 while (*s) 258 putsym(*s++); 259 } 260