perl 4.0 patch 14: patch #11, continued
[p5sagit/p5-mst-13.2.git] / form.c
diff --git a/form.c b/form.c
index c4b248a..27835fe 100644 (file)
--- a/form.c
+++ b/form.c
@@ -1,19 +1,17 @@
-/* $Header: form.c,v 3.0.1.2 90/08/09 03:38:40 lwall Locked $
+/* $RCSfile: form.c,v $$Revision: 4.0.1.1 $$Date: 91/06/07 11:07:59 $
  *
- *    Copyright (c) 1989, Larry Wall
+ *    Copyright (c) 1991, Larry Wall
  *
- *    You may distribute under the terms of the GNU General Public License
- *    as specified in the README file that comes with the perl 3.0 kit.
+ *    You may distribute under the terms of either the GNU General Public
+ *    License or the Artistic License, as specified in the README file.
  *
  * $Log:       form.c,v $
- * Revision 3.0.1.2  90/08/09  03:38:40  lwall
- * patch19: did preliminary work toward debugging packages and evals
+ * Revision 4.0.1.1  91/06/07  11:07:59  lwall
+ * patch4: new copyright notice
+ * patch4: default top-of-form format is now FILEHANDLE_TOP
  * 
- * Revision 3.0.1.1  90/02/28  17:39:34  lwall
- * patch9: ... in format threw off subsequent field
- * 
- * Revision 3.0  89/10/18  15:17:26  lwall
- * 3.0 baseline
+ * Revision 4.0  91/03/20  01:19:23  lwall
+ * 4.0 baseline.
  * 
  */
 
@@ -112,6 +110,8 @@ int sp;
                        }
                        else if (fcmd->f_flags & FC_REPEAT)
                            nextfcmd = linebeg;
+                       else
+                           linebeg = fcmd->f_next;
                    }
                    else
                        linebeg = fcmd->f_next;
@@ -275,35 +275,66 @@ int sp;
            str = stack->ary_array[sp+1];
            s = str_get(str);
            size = str_len(str);
-           CHKLEN(size);
-           orec->o_lines += countlines(s);
+           CHKLEN(size+1);
+           orec->o_lines += countlines(s,size) - 1;
            (void)bcopy(s,d,size);
            d += size;
+           if (size && s[size-1] != '\n') {
+               *d++ = '\n';
+               orec->o_lines++;
+           }
            linebeg = fcmd->f_next;
            break;
+       case F_DECIMAL: {
+           double value;
+
+           (void)eval(fcmd->f_expr,G_SCALAR,sp);
+           str = stack->ary_array[sp+1];
+           size = fcmd->f_size;
+           CHKLEN(size);
+           /* If the field is marked with ^ and the value is undefined,
+              blank it out. */
+           if ((fcmd->f_flags & FC_CHOP) && !str->str_pok && !str->str_nok) {
+               while (size) {
+                   size--;
+                   *d++ = ' ';
+               }
+               break;
+           }
+           value = str_gnum(str);
+           if (fcmd->f_flags & FC_DP) {
+               sprintf(d, "%#*.*f", size, fcmd->f_decimals, value);
+           } else {
+               sprintf(d, "%*.0f", size, value);
+           }
+           d += size;
+           break;
+       }
        }
     }
     CHKLEN(1);
     *d++ = '\0';
 }
 
-countlines(s)
+countlines(s,size)
 register char *s;
+register int size;
 {
     register int count = 0;
 
-    while (*s) {
+    while (size--) {
        if (*s++ == '\n')
            count++;
     }
     return count;
 }
 
-do_write(orec,stio,sp)
+do_write(orec,stab,sp)
 struct outrec *orec;
-register STIO *stio;
+STAB *stab;
 int sp;
 {
+    register STIO *stio = stab_io(stab);
     FILE *ofp = stio->ofp;
 
 #ifdef DEBUGGING
@@ -314,9 +345,18 @@ int sp;
     if (stio->lines_left < orec->o_lines) {
        if (!stio->top_stab) {
            STAB *topstab;
+           char tmpbuf[256];
 
-           if (!stio->top_name)
-               stio->top_name = savestr("top");
+           if (!stio->top_name) {
+               if (!stio->fmt_name)
+                   stio->fmt_name = savestr(stab_name(stab));
+               sprintf(tmpbuf, "%s_TOP", stio->fmt_name);
+               topstab = stabent(tmpbuf,FALSE);
+               if (topstab && stab_form(topstab))
+                   stio->top_name = savestr(tmpbuf);
+               else
+                   stio->top_name = savestr("top");
+           }
            topstab = stabent(stio->top_name,FALSE);
            if (!topstab || !stab_form(topstab)) {
                stio->lines_left = 100000000;