1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 2: /* hack.topl.c - version 1.0.2 */ 3: 4: #include "hack.h" 5: #include <stdio.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 3 /* 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 ", STRLEN("You "))) { 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: }