summaryrefslogtreecommitdiff
path: root/form.c
diff options
context:
space:
mode:
Diffstat (limited to 'form.c')
-rw-r--r--form.c269
1 files changed, 269 insertions, 0 deletions
diff --git a/form.c b/form.c
new file mode 100644
index 0000000000..8894621c9f
--- /dev/null
+++ b/form.c
@@ -0,0 +1,269 @@
+/* $Header: form.c,v 1.0 87/12/18 13:05:07 root Exp $
+ *
+ * $Log: form.c,v $
+ * Revision 1.0 87/12/18 13:05:07 root
+ * Initial revision
+ *
+ */
+
+#include "handy.h"
+#include "EXTERN.h"
+#include "search.h"
+#include "util.h"
+#include "perl.h"
+
+/* Forms stuff */
+
+#define CHKLEN(allow) \
+if (d - orec->o_str + (allow) >= curlen) { \
+ curlen = d - orec->o_str; \
+ GROWSTR(&orec->o_str,&orec->o_len,orec->o_len + (allow)); \
+ d = orec->o_str + curlen; /* in case it moves */ \
+ curlen = orec->o_len - 2; \
+}
+
+format(orec,fcmd)
+register struct outrec *orec;
+register FCMD *fcmd;
+{
+ register char *d = orec->o_str;
+ register char *s;
+ register int curlen = orec->o_len - 2;
+ register int size;
+ char tmpchar;
+ char *t;
+ CMD mycmd;
+ STR *str;
+ char *chophere;
+
+ mycmd.c_type = C_NULL;
+ orec->o_lines = 0;
+ for (; fcmd; fcmd = fcmd->f_next) {
+ CHKLEN(fcmd->f_presize);
+ for (s=fcmd->f_pre; *s;) {
+ if (*s == '\n') {
+ while (d > orec->o_str && (d[-1] == ' ' || d[-1] == '\t'))
+ d--;
+ if (fcmd->f_flags & FC_NOBLANK &&
+ (d == orec->o_str || d[-1] == '\n') ) {
+ orec->o_lines--; /* don't print blank line */
+ break;
+ }
+ }
+ *d++ = *s++;
+ }
+ switch (fcmd->f_type) {
+ case F_NULL:
+ orec->o_lines++;
+ break;
+ case F_LEFT:
+ str = eval(fcmd->f_expr,Null(char***),(double*)0);
+ s = str_get(str);
+ size = fcmd->f_size;
+ CHKLEN(size);
+ chophere = Nullch;
+ while (size && *s && *s != '\n') {
+ size--;
+ if ((*d++ = *s++) == ' ')
+ chophere = s;
+ }
+ if (size)
+ chophere = s;
+ if (fcmd->f_flags & FC_CHOP) {
+ if (!chophere)
+ chophere = s;
+ size += (s - chophere);
+ d -= (s - chophere);
+ if (fcmd->f_flags & FC_MORE &&
+ *chophere && strNE(chophere,"\n")) {
+ while (size < 3) {
+ d--;
+ size++;
+ }
+ while (d[-1] == ' ' && size < fcmd->f_size) {
+ d--;
+ size++;
+ }
+ *d++ = '.';
+ *d++ = '.';
+ *d++ = '.';
+ }
+ s = chophere;
+ while (*chophere == ' ' || *chophere == '\n')
+ chophere++;
+ str_chop(str,chophere);
+ }
+ if (fcmd->f_next && fcmd->f_next->f_pre[0] == '\n')
+ size = 0; /* no spaces before newline */
+ while (size) {
+ size--;
+ *d++ = ' ';
+ }
+ break;
+ case F_RIGHT:
+ t = s = str_get(eval(fcmd->f_expr,Null(char***),(double*)0));
+ size = fcmd->f_size;
+ CHKLEN(size);
+ chophere = Nullch;
+ while (size && *s && *s != '\n') {
+ size--;
+ if (*s++ == ' ')
+ chophere = s;
+ }
+ if (size)
+ chophere = s;
+ if (fcmd->f_flags & FC_CHOP) {
+ if (!chophere)
+ chophere = s;
+ size += (s - chophere);
+ d -= (s - chophere);
+ if (fcmd->f_flags & FC_MORE &&
+ *chophere && strNE(chophere,"\n")) {
+ while (size < 3) {
+ d--;
+ size++;
+ }
+ while (d[-1] == ' ' && size < fcmd->f_size) {
+ d--;
+ size++;
+ }
+ *d++ = '.';
+ *d++ = '.';
+ *d++ = '.';
+ }
+ s = chophere;
+ while (*chophere == ' ' || *chophere == '\n')
+ chophere++;
+ str_chop(str,chophere);
+ }
+ tmpchar = *s;
+ *s = '\0';
+ while (size) {
+ size--;
+ *d++ = ' ';
+ }
+ size = s - t;
+ bcopy(t,d,size);
+ d += size;
+ *s = tmpchar;
+ break;
+ case F_CENTER: {
+ int halfsize;
+
+ t = s = str_get(eval(fcmd->f_expr,Null(char***),(double*)0));
+ size = fcmd->f_size;
+ CHKLEN(size);
+ chophere = Nullch;
+ while (size && *s && *s != '\n') {
+ size--;
+ if (*s++ == ' ')
+ chophere = s;
+ }
+ if (size)
+ chophere = s;
+ if (fcmd->f_flags & FC_CHOP) {
+ if (!chophere)
+ chophere = s;
+ size += (s - chophere);
+ d -= (s - chophere);
+ if (fcmd->f_flags & FC_MORE &&
+ *chophere && strNE(chophere,"\n")) {
+ while (size < 3) {
+ d--;
+ size++;
+ }
+ while (d[-1] == ' ' && size < fcmd->f_size) {
+ d--;
+ size++;
+ }
+ *d++ = '.';
+ *d++ = '.';
+ *d++ = '.';
+ }
+ s = chophere;
+ while (*chophere == ' ' || *chophere == '\n')
+ chophere++;
+ str_chop(str,chophere);
+ }
+ tmpchar = *s;
+ *s = '\0';
+ halfsize = size / 2;
+ while (size > halfsize) {
+ size--;
+ *d++ = ' ';
+ }
+ size = s - t;
+ bcopy(t,d,size);
+ d += size;
+ *s = tmpchar;
+ if (fcmd->f_next && fcmd->f_next->f_pre[0] == '\n')
+ size = 0; /* no spaces before newline */
+ else
+ size = halfsize;
+ while (size) {
+ size--;
+ *d++ = ' ';
+ }
+ break;
+ }
+ case F_LINES:
+ str = eval(fcmd->f_expr,Null(char***),(double*)0);
+ s = str_get(str);
+ size = str_len(str);
+ CHKLEN(size);
+ orec->o_lines += countlines(s);
+ bcopy(s,d,size);
+ d += size;
+ break;
+ }
+ }
+ *d++ = '\0';
+}
+
+countlines(s)
+register char *s;
+{
+ register int count = 0;
+
+ while (*s) {
+ if (*s++ == '\n')
+ count++;
+ }
+ return count;
+}
+
+do_write(orec,stio)
+struct outrec *orec;
+register STIO *stio;
+{
+ FILE *ofp = stio->fp;
+
+#ifdef DEBUGGING
+ if (debug & 256)
+ fprintf(stderr,"left=%d, todo=%d\n",stio->lines_left, orec->o_lines);
+#endif
+ if (stio->lines_left < orec->o_lines) {
+ if (!stio->top_stab) {
+ STAB *topstab;
+
+ if (!stio->top_name)
+ stio->top_name = savestr("top");
+ topstab = stabent(stio->top_name,FALSE);
+ if (!topstab || !topstab->stab_form) {
+ stio->lines_left = 100000000;
+ goto forget_top;
+ }
+ stio->top_stab = topstab;
+ }
+ if (stio->lines_left >= 0)
+ putc('\f',ofp);
+ stio->lines_left = stio->page_len;
+ stio->page++;
+ format(&toprec,stio->top_stab->stab_form);
+ fputs(toprec.o_str,ofp);
+ stio->lines_left -= toprec.o_lines;
+ }
+ forget_top:
+ fputs(orec->o_str,ofp);
+ stio->lines_left -= orec->o_lines;
+}