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