1 /* $Header: form.c,v 3.0.1.4 91/01/11 18:04:07 lwall Locked $
3 * Copyright (c) 1989, Larry Wall
5 * You may distribute under the terms of the GNU General Public License
6 * as specified in the README file that comes with the perl 3.0 kit.
9 * Revision 3.0.1.4 91/01/11 18:04:07 lwall
10 * patch42: the @* format counted lines wrong
11 * patch42: the @* format didn't handle lines with nulls or without newline
13 * Revision 3.0.1.3 90/10/15 17:26:24 lwall
14 * patch29: added @###.## fields to format
16 * Revision 3.0.1.2 90/08/09 03:38:40 lwall
17 * patch19: did preliminary work toward debugging packages and evals
19 * Revision 3.0.1.1 90/02/28 17:39:34 lwall
20 * patch9: ... in format threw off subsequent field
22 * Revision 3.0 89/10/18 15:17:26 lwall
41 line_t oldline = curcmd->c_line;
42 int oldsave = savestack->ary_fill;
44 str = fcmd->f_unparsed;
45 curcmd->c_line = fcmd->f_line;
46 fcmd->f_unparsed = Nullstr;
47 (void)savehptr(&curstash);
48 curstash = str->str_u.str_hash;
52 items = arg->arg_len - 1; /* ignore $$ on end */
53 for (i = 1; i <= items; i++) {
54 if (!fcmd || fcmd->f_type == F_NULL)
55 fatal("Too many field values");
57 fcmd->f_expr = make_op(O_ITEM,1,
58 arg[i].arg_ptr.arg_arg,Nullarg,Nullarg);
59 if (fcmd->f_flags & FC_CHOP) {
60 if ((fcmd->f_expr[1].arg_type & A_MASK) == A_STAB)
61 fcmd->f_expr[1].arg_type = A_LVAL;
62 else if ((fcmd->f_expr[1].arg_type & A_MASK) == A_EXPR)
63 fcmd->f_expr[1].arg_type = A_LEXPR;
65 fatal("^ field requires scalar lvalue");
69 if (fcmd && fcmd->f_type)
70 fatal("Not enough field values");
71 curcmd->c_line = oldline;
78 #define CHKLEN(allow) \
79 newsize = (d - orec->o_str) + (allow); \
80 if (newsize >= curlen) { \
81 curlen = d - orec->o_str; \
82 GROWSTR(&orec->o_str,&orec->o_len,orec->o_len + (allow)); \
83 d = orec->o_str + curlen; /* in case it moves */ \
84 curlen = orec->o_len - 2; \
88 register struct outrec *orec;
92 register char *d = orec->o_str;
94 register int curlen = orec->o_len - 2;
104 mycmd.c_type = C_NULL;
106 for (; fcmd; fcmd = nextfcmd) {
107 nextfcmd = fcmd->f_next;
108 CHKLEN(fcmd->f_presize);
109 if (s = fcmd->f_pre) {
112 while (d > orec->o_str && (d[-1] == ' ' || d[-1] == '\t'))
114 if (fcmd->f_flags & FC_NOBLANK) {
115 if (d == orec->o_str || d[-1] == '\n') {
116 orec->o_lines--; /* don't print blank line */
117 linebeg = fcmd->f_next;
120 else if (fcmd->f_flags & FC_REPEAT)
124 linebeg = fcmd->f_next;
129 if (fcmd->f_unparsed)
130 form_parseargs(fcmd);
131 switch (fcmd->f_type) {
136 (void)eval(fcmd->f_expr,G_SCALAR,sp);
137 str = stack->ary_array[sp+1];
142 while (size && *s && *s != '\n') {
146 if (*s && index(chopset,(*d++ = *s++)))
148 if (*s == '\n' && (fcmd->f_flags & FC_CHOP))
153 else if (chophere && chophere < s && *s && index(chopset,*s))
155 if (fcmd->f_flags & FC_CHOP) {
158 size += (s - chophere);
160 if (fcmd->f_flags & FC_MORE &&
161 *chophere && strNE(chophere,"\n")) {
166 while (d[-1] == ' ' && size < fcmd->f_size) {
175 while (*chophere && index(chopset,*chophere))
177 str_chop(str,chophere);
179 if (fcmd->f_next && fcmd->f_next->f_pre[0] == '\n')
180 size = 0; /* no spaces before newline */
187 (void)eval(fcmd->f_expr,G_SCALAR,sp);
188 str = stack->ary_array[sp+1];
189 t = s = str_get(str);
193 while (size && *s && *s != '\n') {
197 if (*s && index(chopset,*s++))
199 if (*s == '\n' && (fcmd->f_flags & FC_CHOP))
204 else if (chophere && chophere < s && *s && index(chopset,*s))
206 if (fcmd->f_flags & FC_CHOP) {
209 size += (s - chophere);
211 while (*chophere && index(chopset,*chophere))
221 (void)bcopy(t,d,size);
224 if (fcmd->f_flags & FC_CHOP)
225 str_chop(str,chophere);
230 (void)eval(fcmd->f_expr,G_SCALAR,sp);
231 str = stack->ary_array[sp+1];
232 t = s = str_get(str);
236 while (size && *s && *s != '\n') {
240 if (*s && index(chopset,*s++))
242 if (*s == '\n' && (fcmd->f_flags & FC_CHOP))
247 else if (chophere && chophere < s && *s && index(chopset,*s))
249 if (fcmd->f_flags & FC_CHOP) {
252 size += (s - chophere);
254 while (*chophere && index(chopset,*chophere))
260 while (size > halfsize) {
265 (void)bcopy(t,d,size);
268 if (fcmd->f_next && fcmd->f_next->f_pre[0] == '\n')
269 size = 0; /* no spaces before newline */
276 if (fcmd->f_flags & FC_CHOP)
277 str_chop(str,chophere);
281 (void)eval(fcmd->f_expr,G_SCALAR,sp);
282 str = stack->ary_array[sp+1];
286 orec->o_lines += countlines(s,size) - 1;
287 (void)bcopy(s,d,size);
289 if (size && s[size-1] != '\n') {
293 linebeg = fcmd->f_next;
298 (void)eval(fcmd->f_expr,G_SCALAR,sp);
299 str = stack->ary_array[sp+1];
302 /* If the field is marked with ^ and the value is undefined,
304 if ((fcmd->f_flags & FC_CHOP) && !str->str_pok && !str->str_nok) {
311 value = str_gnum(str);
312 if (fcmd->f_flags & FC_DP) {
313 sprintf(d, "%#*.*f", size, fcmd->f_decimals, value);
315 sprintf(d, "%*.0f", size, value);
330 register int count = 0;
339 do_write(orec,stio,sp)
344 FILE *ofp = stio->ofp;
348 fprintf(stderr,"left=%ld, todo=%ld\n",
349 (long)stio->lines_left, (long)orec->o_lines);
351 if (stio->lines_left < orec->o_lines) {
352 if (!stio->top_stab) {
356 stio->top_name = savestr("top");
357 topstab = stabent(stio->top_name,FALSE);
358 if (!topstab || !stab_form(topstab)) {
359 stio->lines_left = 100000000;
362 stio->top_stab = topstab;
364 if (stio->lines_left >= 0 && stio->page > 0)
365 (void)putc('\f',ofp);
366 stio->lines_left = stio->page_len;
368 format(&toprec,stab_form(stio->top_stab),sp);
369 fputs(toprec.o_str,ofp);
370 stio->lines_left -= toprec.o_lines;
373 fputs(orec->o_str,ofp);
374 stio->lines_left -= orec->o_lines;