Commit | Line | Data |
---|---|---|
15637ed4 RG |
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 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 | } |