topl.c (3798B)
1 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 2 /* topl.c - version 1.0.2 */ 3 4 #include <stdio.h> 5 #include "hack.h" 6 extern char *eos(); 7 extern int CO; 8 9 char toplines[BUFSZ]; 10 xchar tlx, tly; /* set by pline; used by addtopl */ 11 12 struct topl { 13 struct topl *next_topl; 14 char *topl_text; 15 } *old_toplines, *last_redone_topl; 16 #define OTLMAX 20 /* max nr of old toplines remembered */ 17 18 doredotopl(){ 19 if(last_redone_topl) 20 last_redone_topl = last_redone_topl->next_topl; 21 if(!last_redone_topl) 22 last_redone_topl = old_toplines; 23 if(last_redone_topl){ 24 (void) strcpy(toplines, last_redone_topl->topl_text); 25 } 26 redotoplin(); 27 return(0); 28 } 29 30 redotoplin() { 31 home(); 32 if(index(toplines, '\n')) cl_end(); 33 putstr(toplines); 34 cl_end(); 35 tlx = curx; 36 tly = cury; 37 flags.toplin = 1; 38 if(tly > 1) 39 more(); 40 } 41 42 remember_topl() { 43 register struct topl *tl; 44 register int cnt = OTLMAX; 45 if(last_redone_topl && 46 !strcmp(toplines, last_redone_topl->topl_text)) return; 47 if(old_toplines && 48 !strcmp(toplines, old_toplines->topl_text)) return; 49 last_redone_topl = 0; 50 tl = (struct topl *) 51 alloc((unsigned)(strlen(toplines) + sizeof(struct topl) + 1)); 52 tl->next_topl = old_toplines; 53 tl->topl_text = (char *)(tl + 1); 54 (void) strcpy(tl->topl_text, toplines); 55 old_toplines = tl; 56 while(cnt && tl){ 57 cnt--; 58 tl = tl->next_topl; 59 } 60 if(tl && tl->next_topl){ 61 free((char *) tl->next_topl); 62 tl->next_topl = 0; 63 } 64 } 65 66 addtopl(s) char *s; { 67 curs(tlx,tly); 68 if(tlx + strlen(s) > CO) putsym('\n'); 69 putstr(s); 70 tlx = curx; 71 tly = cury; 72 flags.toplin = 1; 73 } 74 75 xmore(s) 76 char *s; /* allowed chars besides space/return */ 77 { 78 if(flags.toplin) { 79 curs(tlx, tly); 80 if(tlx + 8 > CO) putsym('\n'), tly++; 81 } 82 83 if(flags.standout) 84 standoutbeg(); 85 putstr("--More--"); 86 if(flags.standout) 87 standoutend(); 88 89 xwaitforspace(s); 90 if(flags.toplin && tly > 1) { 91 home(); 92 cl_end(); 93 docorner(1, tly-1); 94 } 95 flags.toplin = 0; 96 } 97 98 more(){ 99 xmore(""); 100 } 101 102 cmore(s) 103 register char *s; 104 { 105 xmore(s); 106 } 107 108 clrlin(){ 109 if(flags.toplin) { 110 home(); 111 cl_end(); 112 if(tly > 1) docorner(1, tly-1); 113 remember_topl(); 114 } 115 flags.toplin = 0; 116 } 117 118 /*VARARGS1*/ 119 pline(line,arg1,arg2,arg3,arg4,arg5,arg6) 120 register char *line,*arg1,*arg2,*arg3,*arg4,*arg5,*arg6; 121 { 122 char pbuf[BUFSZ]; 123 register char *bp = pbuf, *tl; 124 register int n,n0; 125 126 if(!line || !*line) return; 127 if(!index(line, '%')) (void) strcpy(pbuf,line); else 128 (void) sprintf(pbuf,line,arg1,arg2,arg3,arg4,arg5,arg6); 129 if(flags.toplin == 1 && !strcmp(pbuf, toplines)) return; 130 nscr(); /* %% */ 131 132 /* If there is room on the line, print message on same line */ 133 /* But messages like "You die..." deserve their own line */ 134 n0 = strlen(bp); 135 if(flags.toplin == 1 && tly == 1 && 136 n0 + strlen(toplines) + 3 < CO-8 && /* leave room for --More-- */ 137 strncmp(bp, "You ", 4)) { 138 (void) strcat(toplines, " "); 139 (void) strcat(toplines, bp); 140 tlx += 2; 141 addtopl(bp); 142 return; 143 } 144 if(flags.toplin == 1) more(); 145 remember_topl(); 146 toplines[0] = 0; 147 while(n0){ 148 if(n0 >= CO){ 149 /* look for appropriate cut point */ 150 n0 = 0; 151 for(n = 0; n < CO; n++) if(bp[n] == ' ') 152 n0 = n; 153 if(!n0) for(n = 0; n < CO-1; n++) 154 if(!letter(bp[n])) n0 = n; 155 if(!n0) n0 = CO-2; 156 } 157 (void) strncpy((tl = eos(toplines)), bp, n0); 158 tl[n0] = 0; 159 bp += n0; 160 161 /* remove trailing spaces, but leave one */ 162 while(n0 > 1 && tl[n0-1] == ' ' && tl[n0-2] == ' ') 163 tl[--n0] = 0; 164 165 n0 = strlen(bp); 166 if(n0 && tl[0]) (void) strcat(tl, "\n"); 167 } 168 redotoplin(); 169 } 170 171 putsym(c) char c; { 172 switch(c) { 173 case '\b': 174 backsp(); 175 return; 176 case '\n': 177 curx = 1; 178 cury++; 179 if(cury > tly) tly = cury; 180 break; 181 default: 182 if(curx == CO) 183 putsym('\n'); /* 1 <= curx <= CO; avoid CO */ 184 else 185 curx++; 186 } 187 (void) putchar(c); 188 } 189 190 putstr(s) register char *s; { 191 while(*s) putsym(*s++); 192 }