Files
Arquivotheca.Solaris-2.5/lib/libeti/form/form.c
seta75D 7c4988eac0 Init
2021-10-11 19:38:01 -03:00

462 lines
7.2 KiB
C
Executable File

/* Copyright (c) 1988 AT&T */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
#ident "@(#)form.c 1.2 92/07/14 SMI" /* SVr4.0 1.8 */
#include "utility.h"
#define MAX_BUF 81
/*****************
* default form *
*****************/
static FORM default_form =
{
0, /* status */
0, /* rows */
0, /* cols */
0, /* currow */
0, /* curcol */
0, /* toprow */
0, /* begincol */
-1, /* maxfield */
-1, /* maxpage */
-1, /* curpage */
O_NL_OVERLOAD |
O_BS_OVERLOAD, /* opts */
(WINDOW *) 0, /* win */
(WINDOW *) 0, /* sub */
(WINDOW *) 0, /* w */
(FIELD **) 0, /* field */
(FIELD *) 0, /* current */
(_PAGE *) 0, /* page */
(char *) 0, /* usrptr */
(PTF_void) 0, /* forminit */
(PTF_void) 0, /* formterm */
(PTF_void) 0, /* fieldinit */
(PTF_void) 0, /* fieldterm */
};
FORM * _DEFAULT_FORM = &default_form;
/***********
* insert *
***********/
static FIELD * insert (f, head)
FIELD * f;
FIELD * head;
{
/*
insert field f into sorted list pointed to by head.
return (possibly new) head of list.
*/
FIELD * p;
FIELD * newhead;
int frow, fcol;
if (head)
{
p = newhead = head;
frow = f -> frow;
fcol = f -> fcol;
while ( (p -> frow < frow)
|| (p -> frow == frow && p -> fcol < fcol))
{
p = p -> snext;
if (p == head)
{
head = (FIELD *) 0;
break;
}
}
f -> snext = p;
f -> sprev = p -> sprev;
f -> snext -> sprev = f;
f -> sprev -> snext = f;
if (p == head)
newhead = f; /* insert at head of list */
}
else
newhead = f -> sprev = f -> snext = f; /* initialize new list */
return newhead;
}
/**************
* sort_form *
**************/
static void sort_form (f)
FORM * f;
{
/*
sort fields on form (per page)
*/
FIELD ** field;
FIELD * p;
int i, page, pmin, pmax;
field = f -> field;
for (page = 0; page < f -> maxpage; ++page) /* for each page */
{
p = (FIELD *) 0;
pmin = Pmin (f, page);
pmax = Pmax (f, page);
for (i = pmin; i <= pmax; ++i) /* for each field */
{
field[i] -> index = i;
field[i] -> page = page;
p = insert (field[i], p);
}
Smin (f, page) = p -> index; /* set sorted min */
Smax (f, page) = p -> sprev -> index; /* set sorted max */
}
}
/**********
* merge *
**********/
static void merge (f, form) /* adjust form dimensions to include field f */
FIELD * f;
FORM * form;
{
/*
xmax/ymax is the minimum window size to hold field f
*/
int xmax = f -> fcol + f -> cols;
int ymax = f -> frow + f -> rows;
if (form -> rows < ymax) form -> rows = ymax;
if (form -> cols < xmax) form -> cols = xmax;
}
/**********************
* disconnect_fields *
**********************/
static void disconnect_fields (form)
FORM * form;
{
/*
disconnect fields from form
*/
FIELD ** f = form -> field;
if (f)
while (*f)
{
if ((*f) -> form == form)
(*f) -> form = (FORM *) 0;
++f;
}
form -> rows = 0;
form -> cols = 0;
form -> maxfield = -1;
form -> maxpage = -1;
form -> field = (FIELD **) 0;
}
/*******************
* connect_fields *
*******************/
static int connect_fields (f, x)
FORM * f;
FIELD ** x;
{
/*
connect fields to form
*/
_PAGE * page;
int nf, /* number of fields */
np; /* number of pages */
int i;
f -> field = x;
f -> maxfield = 0;
f -> maxpage = 0;
if (! x)
return E_OK; /* null field array */
for (nf = 0, np = 0; x[nf]; ++nf)
{
if (nf == 0 || Status (x[nf], NEW_PAGE))
++np; /* count pages */
if (x[nf] -> form)
return E_CONNECTED;
else
x[nf] -> form = f; /* connect field to form */
}
if (nf == 0)
return E_BAD_ARGUMENT; /* no fields */
if (arrayAlloc (f -> page, np, _PAGE))
{
page = f -> page;
for (i = 0; i < nf; ++i)
{
if (i == 0)
page -> pmin = i;
else if (Status (x[i], NEW_PAGE))
{
page -> pmax = i - 1;
++page;
page -> pmin = i;
}
merge (x[i], f);
}
page -> pmax = nf - 1;
f -> maxfield = nf;
f -> maxpage = np;
sort_form (f);
return E_OK;
}
return E_SYSTEM_ERROR;
}
/*************
* new_form *
*************/
FORM * new_form (field)
FIELD ** field;
{
FORM * f;
if (Alloc (f, FORM))
{
*f = *_DEFAULT_FORM;
if (connect_fields (f, field) == E_OK)
{
if (f -> maxpage)
{
P(f) = 0;
C(f) = _first_active (f);
}
else
{
P(f) = -1;
C(f) = (FIELD *) 0;
}
return f;
}
}
(void)free_form (f);
return (FORM *) 0;
}
/**************
* free_form *
**************/
int free_form (f)
FORM * f;
{
if (! f)
return E_BAD_ARGUMENT;
if (Status (f, POSTED))
return E_POSTED;
disconnect_fields (f);
Free (f -> page);
Free (f);
return E_OK;
}
/********************
* set_form_fields *
********************/
int set_form_fields (f, fields)
FORM * f;
FIELD ** fields;
{
FIELD ** p;
int v;
if (! f)
return E_BAD_ARGUMENT;
if (Status (f, POSTED))
return E_POSTED;
p = f -> field;
disconnect_fields (f);
if ((v = connect_fields (f, fields)) == E_OK)
{
if (f -> maxpage)
{
P(f) = 0;
C(f) = _first_active (f);
}
else
{
P(f) = -1;
C(f) = (FIELD *) 0;
}
}
else
(void)connect_fields (f, p); /* reconnect original fields */
return v;
}
FIELD ** form_fields (f)
FORM * f;
{
return Form (f) -> field;
}
/****************
* field_count *
****************/
int field_count (f)
FORM * f;
{
return Form (f) -> maxfield;
}
/***************
* scale_form *
***************/
int scale_form (f, rows, cols)
FORM * f;
int * rows;
int * cols;
{
if (! f)
return E_BAD_ARGUMENT;
if (! f -> field)
return E_NOT_CONNECTED;
*rows = f -> rows;
*cols = f -> cols;
return E_OK;
}
/****************
* data_behind *
****************/
BOOLEAN
data_behind( f )
FORM *f;
{
return OneRow(C(f)) ? B(f) != 0 : T(f) != 0;
}
/****************
* _data_ahead *
****************/
static
char * _data_ahead (v, pad, n)
char * v;
char pad;
int n;
{
/*
return ptr to last non-pad char in v[n] (v on failure)
*/
char * vend = v + n;
while (vend > v && *(vend - 1) == pad ) --vend;
return vend;
}
/***************
* data_ahead *
***************/
BOOLEAN
data_ahead( f )
FORM *f;
{
static char buf[ MAX_BUF ];
char *bptr = buf;
WINDOW *w = W(f);
FIELD *c = C(f);
int ret = FALSE;
int pad = Pad(c);
int cols = c->cols;
int dcols;
int drows;
int flag = cols > MAX_BUF - 1;
int start;
int chunk;
int i;
if ( flag )
bptr = malloc( cols + 1 );
if ( OneRow( c ))
{
dcols = c->dcols;
start = B(f) + cols;
while ( start < dcols )
{
chunk = MIN( cols, dcols - start );
(void)wmove( w, 0, start );
(void)winnstr( w, bptr, chunk );
if ( bptr != _data_ahead( bptr, pad, chunk ))
{
ret = TRUE;
break;
}
start += cols;
}
}
else /* else multi-line field */
{
drows = c->drows;
start = T(f) + c->rows;
while ( start < drows )
{
(void)wmove( w, start++, 0 );
(void)winnstr( w, bptr, cols );
if ( bptr != _data_ahead( bptr, pad, cols ))
{
ret = TRUE;
break;
}
}
}
if ( flag )
(void)free( bptr );
(void)wmove( w, Y(f), X(f));
return ret;
}