1 /* $RCSfile: form.c,v $$Revision: 4.0.1.1 $$Date: 91/06/07 11:07:59 $
3 * Copyright (c) 1991, Larry Wall
5 * You may distribute under the terms of either the GNU General Public
6 * License or the Artistic License, as specified in the README file.
9 * Revision 4.0.1.1 91/06/07 11:07:59 lwall
10 * patch4: new copyright notice
11 * patch4: default top-of-form format is now FILEHANDLE_TOP
13 * Revision 4.0 91/03/20 01:19:23 lwall
32 line_t oldline = curcmd->c_line;
33 int oldsave = savestack->ary_fill;
35 str = fcmd->f_unparsed;
36 curcmd->c_line = fcmd->f_line;
37 fcmd->f_unparsed = Nullstr;
38 (void)savehptr(&curstash);
39 curstash = str->str_u.str_hash;
43 items = arg->arg_len - 1; /* ignore $$ on end */
44 for (i = 1; i <= items; i++) {
45 if (!fcmd || fcmd->f_type == F_NULL)
46 fatal("Too many field values");
48 fcmd->f_expr = make_op(O_ITEM,1,
49 arg[i].arg_ptr.arg_arg,Nullarg,Nullarg);
50 if (fcmd->f_flags & FC_CHOP) {
51 if ((fcmd->f_expr[1].arg_type & A_MASK) == A_STAB)
52 fcmd->f_expr[1].arg_type = A_LVAL;
53 else if ((fcmd->f_expr[1].arg_type & A_MASK) == A_EXPR)
54 fcmd->f_expr[1].arg_type = A_LEXPR;
56 fatal("^ field requires scalar lvalue");
60 if (fcmd && fcmd->f_type)
61 fatal("Not enough field values");
62 curcmd->c_line = oldline;
69 #define CHKLEN(allow) \
70 newsize = (d - orec->o_str) + (allow); \
71 if (newsize >= curlen) { \
72 curlen = d - orec->o_str; \
73 GROWSTR(&orec->o_str,&orec->o_len,orec->o_len + (allow)); \
74 d = orec->o_str + curlen; /* in case it moves */ \
75 curlen = orec->o_len - 2; \
79 register struct outrec *orec;
83 register char *d = orec->o_str;
85 register int curlen = orec->o_len - 2;
95 mycmd.c_type = C_NULL;
97 for (; fcmd; fcmd = nextfcmd) {
98 nextfcmd = fcmd->f_next;
99 CHKLEN(fcmd->f_presize);
100 if (s = fcmd->f_pre) {
103 while (d > orec->o_str && (d[-1] == ' ' || d[-1] == '\t'))
105 if (fcmd->f_flags & FC_NOBLANK) {
106 if (d == orec->o_str || d[-1] == '\n') {
107 orec->o_lines--; /* don't print blank line */
108 linebeg = fcmd->f_next;
111 else if (fcmd->f_flags & FC_REPEAT)
114 linebeg = fcmd->f_next;
117 linebeg = fcmd->f_next;
122 if (fcmd->f_unparsed)
123 form_parseargs(fcmd);
124 switch (fcmd->f_type) {
129 (void)eval(fcmd->f_expr,G_SCALAR,sp);
130 str = stack->ary_array[sp+1];
135 while (size && *s && *s != '\n') {
139 if (*s && index(chopset,(*d++ = *s++)))
141 if (*s == '\n' && (fcmd->f_flags & FC_CHOP))
146 else if (chophere && chophere < s && *s && index(chopset,*s))
148 if (fcmd->f_flags & FC_CHOP) {
151 size += (s - chophere);
153 if (fcmd->f_flags & FC_MORE &&
154 *chophere && strNE(chophere,"\n")) {
159 while (d[-1] == ' ' && size < fcmd->f_size) {
168 while (*chophere && index(chopset,*chophere))
170 str_chop(str,chophere);
172 if (fcmd->f_next && fcmd->f_next->f_pre[0] == '\n')
173 size = 0; /* no spaces before newline */
180 (void)eval(fcmd->f_expr,G_SCALAR,sp);
181 str = stack->ary_array[sp+1];
182 t = s = str_get(str);
186 while (size && *s && *s != '\n') {
190 if (*s && index(chopset,*s++))
192 if (*s == '\n' && (fcmd->f_flags & FC_CHOP))
197 else if (chophere && chophere < s && *s && index(chopset,*s))
199 if (fcmd->f_flags & FC_CHOP) {
202 size += (s - chophere);
204 while (*chophere && index(chopset,*chophere))
214 (void)bcopy(t,d,size);
217 if (fcmd->f_flags & FC_CHOP)
218 str_chop(str,chophere);
223 (void)eval(fcmd->f_expr,G_SCALAR,sp);
224 str = stack->ary_array[sp+1];
225 t = s = str_get(str);
229 while (size && *s && *s != '\n') {
233 if (*s && index(chopset,*s++))
235 if (*s == '\n' && (fcmd->f_flags & FC_CHOP))
240 else if (chophere && chophere < s && *s && index(chopset,*s))
242 if (fcmd->f_flags & FC_CHOP) {
245 size += (s - chophere);
247 while (*chophere && index(chopset,*chophere))
253 while (size > halfsize) {
258 (void)bcopy(t,d,size);
261 if (fcmd->f_next && fcmd->f_next->f_pre[0] == '\n')
262 size = 0; /* no spaces before newline */
269 if (fcmd->f_flags & FC_CHOP)
270 str_chop(str,chophere);
274 (void)eval(fcmd->f_expr,G_SCALAR,sp);
275 str = stack->ary_array[sp+1];
279 orec->o_lines += countlines(s,size) - 1;
280 (void)bcopy(s,d,size);
282 if (size && s[size-1] != '\n') {
286 linebeg = fcmd->f_next;
291 (void)eval(fcmd->f_expr,G_SCALAR,sp);
292 str = stack->ary_array[sp+1];
295 /* If the field is marked with ^ and the value is undefined,
297 if ((fcmd->f_flags & FC_CHOP) && !str->str_pok && !str->str_nok) {
304 value = str_gnum(str);
305 if (fcmd->f_flags & FC_DP) {
306 sprintf(d, "%#*.*f", size, fcmd->f_decimals, value);
308 sprintf(d, "%*.0f", size, value);
323 register int count = 0;
332 do_write(orec,stab,sp)
337 register STIO *stio = stab_io(stab);
338 FILE *ofp = stio->ofp;
342 fprintf(stderr,"left=%ld, todo=%ld\n",
343 (long)stio->lines_left, (long)orec->o_lines);
345 if (stio->lines_left < orec->o_lines) {
346 if (!stio->top_stab) {
350 if (!stio->top_name) {
352 stio->fmt_name = savestr(stab_name(stab));
353 sprintf(tmpbuf, "%s_TOP", stio->fmt_name);
354 topstab = stabent(tmpbuf,FALSE);
355 if (topstab && stab_form(topstab))
356 stio->top_name = savestr(tmpbuf);
358 stio->top_name = savestr("top");
360 topstab = stabent(stio->top_name,FALSE);
361 if (!topstab || !stab_form(topstab)) {
362 stio->lines_left = 100000000;
365 stio->top_stab = topstab;
367 if (stio->lines_left >= 0 && stio->page > 0)
368 (void)putc('\f',ofp);
369 stio->lines_left = stio->page_len;
371 format(&toprec,stab_form(stio->top_stab),sp);
372 fputs(toprec.o_str,ofp);
373 stio->lines_left -= toprec.o_lines;
376 fputs(orec->o_str,ofp);
377 stio->lines_left -= orec->o_lines;