Commit | Line | Data |
8d063cd8 |
1 | /* $Header: form.c,v 1.0 87/12/18 13:05:07 root Exp $ |
2 | * |
3 | * $Log: form.c,v $ |
4 | * Revision 1.0 87/12/18 13:05:07 root |
5 | * Initial revision |
6 | * |
7 | */ |
8 | |
9 | #include "handy.h" |
10 | #include "EXTERN.h" |
11 | #include "search.h" |
12 | #include "util.h" |
13 | #include "perl.h" |
14 | |
15 | /* Forms stuff */ |
16 | |
17 | #define CHKLEN(allow) \ |
18 | if (d - orec->o_str + (allow) >= curlen) { \ |
19 | curlen = d - orec->o_str; \ |
20 | GROWSTR(&orec->o_str,&orec->o_len,orec->o_len + (allow)); \ |
21 | d = orec->o_str + curlen; /* in case it moves */ \ |
22 | curlen = orec->o_len - 2; \ |
23 | } |
24 | |
25 | format(orec,fcmd) |
26 | register struct outrec *orec; |
27 | register FCMD *fcmd; |
28 | { |
29 | register char *d = orec->o_str; |
30 | register char *s; |
31 | register int curlen = orec->o_len - 2; |
32 | register int size; |
33 | char tmpchar; |
34 | char *t; |
35 | CMD mycmd; |
36 | STR *str; |
37 | char *chophere; |
38 | |
39 | mycmd.c_type = C_NULL; |
40 | orec->o_lines = 0; |
41 | for (; fcmd; fcmd = fcmd->f_next) { |
42 | CHKLEN(fcmd->f_presize); |
43 | for (s=fcmd->f_pre; *s;) { |
44 | if (*s == '\n') { |
45 | while (d > orec->o_str && (d[-1] == ' ' || d[-1] == '\t')) |
46 | d--; |
47 | if (fcmd->f_flags & FC_NOBLANK && |
48 | (d == orec->o_str || d[-1] == '\n') ) { |
49 | orec->o_lines--; /* don't print blank line */ |
50 | break; |
51 | } |
52 | } |
53 | *d++ = *s++; |
54 | } |
55 | switch (fcmd->f_type) { |
56 | case F_NULL: |
57 | orec->o_lines++; |
58 | break; |
59 | case F_LEFT: |
60 | str = eval(fcmd->f_expr,Null(char***),(double*)0); |
61 | s = str_get(str); |
62 | size = fcmd->f_size; |
63 | CHKLEN(size); |
64 | chophere = Nullch; |
65 | while (size && *s && *s != '\n') { |
66 | size--; |
67 | if ((*d++ = *s++) == ' ') |
68 | chophere = s; |
69 | } |
70 | if (size) |
71 | chophere = s; |
72 | if (fcmd->f_flags & FC_CHOP) { |
73 | if (!chophere) |
74 | chophere = s; |
75 | size += (s - chophere); |
76 | d -= (s - chophere); |
77 | if (fcmd->f_flags & FC_MORE && |
78 | *chophere && strNE(chophere,"\n")) { |
79 | while (size < 3) { |
80 | d--; |
81 | size++; |
82 | } |
83 | while (d[-1] == ' ' && size < fcmd->f_size) { |
84 | d--; |
85 | size++; |
86 | } |
87 | *d++ = '.'; |
88 | *d++ = '.'; |
89 | *d++ = '.'; |
90 | } |
91 | s = chophere; |
92 | while (*chophere == ' ' || *chophere == '\n') |
93 | chophere++; |
94 | str_chop(str,chophere); |
95 | } |
96 | if (fcmd->f_next && fcmd->f_next->f_pre[0] == '\n') |
97 | size = 0; /* no spaces before newline */ |
98 | while (size) { |
99 | size--; |
100 | *d++ = ' '; |
101 | } |
102 | break; |
103 | case F_RIGHT: |
104 | t = s = str_get(eval(fcmd->f_expr,Null(char***),(double*)0)); |
105 | size = fcmd->f_size; |
106 | CHKLEN(size); |
107 | chophere = Nullch; |
108 | while (size && *s && *s != '\n') { |
109 | size--; |
110 | if (*s++ == ' ') |
111 | chophere = s; |
112 | } |
113 | if (size) |
114 | chophere = s; |
115 | if (fcmd->f_flags & FC_CHOP) { |
116 | if (!chophere) |
117 | chophere = s; |
118 | size += (s - chophere); |
119 | d -= (s - chophere); |
120 | if (fcmd->f_flags & FC_MORE && |
121 | *chophere && strNE(chophere,"\n")) { |
122 | while (size < 3) { |
123 | d--; |
124 | size++; |
125 | } |
126 | while (d[-1] == ' ' && size < fcmd->f_size) { |
127 | d--; |
128 | size++; |
129 | } |
130 | *d++ = '.'; |
131 | *d++ = '.'; |
132 | *d++ = '.'; |
133 | } |
134 | s = chophere; |
135 | while (*chophere == ' ' || *chophere == '\n') |
136 | chophere++; |
137 | str_chop(str,chophere); |
138 | } |
139 | tmpchar = *s; |
140 | *s = '\0'; |
141 | while (size) { |
142 | size--; |
143 | *d++ = ' '; |
144 | } |
145 | size = s - t; |
146 | bcopy(t,d,size); |
147 | d += size; |
148 | *s = tmpchar; |
149 | break; |
150 | case F_CENTER: { |
151 | int halfsize; |
152 | |
153 | t = s = str_get(eval(fcmd->f_expr,Null(char***),(double*)0)); |
154 | size = fcmd->f_size; |
155 | CHKLEN(size); |
156 | chophere = Nullch; |
157 | while (size && *s && *s != '\n') { |
158 | size--; |
159 | if (*s++ == ' ') |
160 | chophere = s; |
161 | } |
162 | if (size) |
163 | chophere = s; |
164 | if (fcmd->f_flags & FC_CHOP) { |
165 | if (!chophere) |
166 | chophere = s; |
167 | size += (s - chophere); |
168 | d -= (s - chophere); |
169 | if (fcmd->f_flags & FC_MORE && |
170 | *chophere && strNE(chophere,"\n")) { |
171 | while (size < 3) { |
172 | d--; |
173 | size++; |
174 | } |
175 | while (d[-1] == ' ' && size < fcmd->f_size) { |
176 | d--; |
177 | size++; |
178 | } |
179 | *d++ = '.'; |
180 | *d++ = '.'; |
181 | *d++ = '.'; |
182 | } |
183 | s = chophere; |
184 | while (*chophere == ' ' || *chophere == '\n') |
185 | chophere++; |
186 | str_chop(str,chophere); |
187 | } |
188 | tmpchar = *s; |
189 | *s = '\0'; |
190 | halfsize = size / 2; |
191 | while (size > halfsize) { |
192 | size--; |
193 | *d++ = ' '; |
194 | } |
195 | size = s - t; |
196 | bcopy(t,d,size); |
197 | d += size; |
198 | *s = tmpchar; |
199 | if (fcmd->f_next && fcmd->f_next->f_pre[0] == '\n') |
200 | size = 0; /* no spaces before newline */ |
201 | else |
202 | size = halfsize; |
203 | while (size) { |
204 | size--; |
205 | *d++ = ' '; |
206 | } |
207 | break; |
208 | } |
209 | case F_LINES: |
210 | str = eval(fcmd->f_expr,Null(char***),(double*)0); |
211 | s = str_get(str); |
212 | size = str_len(str); |
213 | CHKLEN(size); |
214 | orec->o_lines += countlines(s); |
215 | bcopy(s,d,size); |
216 | d += size; |
217 | break; |
218 | } |
219 | } |
220 | *d++ = '\0'; |
221 | } |
222 | |
223 | countlines(s) |
224 | register char *s; |
225 | { |
226 | register int count = 0; |
227 | |
228 | while (*s) { |
229 | if (*s++ == '\n') |
230 | count++; |
231 | } |
232 | return count; |
233 | } |
234 | |
235 | do_write(orec,stio) |
236 | struct outrec *orec; |
237 | register STIO *stio; |
238 | { |
239 | FILE *ofp = stio->fp; |
240 | |
241 | #ifdef DEBUGGING |
242 | if (debug & 256) |
243 | fprintf(stderr,"left=%d, todo=%d\n",stio->lines_left, orec->o_lines); |
244 | #endif |
245 | if (stio->lines_left < orec->o_lines) { |
246 | if (!stio->top_stab) { |
247 | STAB *topstab; |
248 | |
249 | if (!stio->top_name) |
250 | stio->top_name = savestr("top"); |
251 | topstab = stabent(stio->top_name,FALSE); |
252 | if (!topstab || !topstab->stab_form) { |
253 | stio->lines_left = 100000000; |
254 | goto forget_top; |
255 | } |
256 | stio->top_stab = topstab; |
257 | } |
258 | if (stio->lines_left >= 0) |
259 | putc('\f',ofp); |
260 | stio->lines_left = stio->page_len; |
261 | stio->page++; |
262 | format(&toprec,stio->top_stab->stab_form); |
263 | fputs(toprec.o_str,ofp); |
264 | stio->lines_left -= toprec.o_lines; |
265 | } |
266 | forget_top: |
267 | fputs(orec->o_str,ofp); |
268 | stio->lines_left -= orec->o_lines; |
269 | } |