This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
perl 1.0 patch 9: 3 portability problems
[perl5.git] / form.c
CommitLineData
8d063cd8
LW
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) \
18if (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
25format(orec,fcmd)
26register struct outrec *orec;
27register 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
223countlines(s)
224register char *s;
225{
226 register int count = 0;
227
228 while (*s) {
229 if (*s++ == '\n')
230 count++;
231 }
232 return count;
233}
234
235do_write(orec,stio)
236struct outrec *orec;
237register 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}