fld_def.c revision 50276
1/****************************************************************************
2 * Copyright (c) 1998 Free Software Foundation, Inc.                        *
3 *                                                                          *
4 * Permission is hereby granted, free of charge, to any person obtaining a  *
5 * copy of this software and associated documentation files (the            *
6 * "Software"), to deal in the Software without restriction, including      *
7 * without limitation the rights to use, copy, modify, merge, publish,      *
8 * distribute, distribute with modifications, sublicense, and/or sell       *
9 * copies of the Software, and to permit persons to whom the Software is    *
10 * furnished to do so, subject to the following conditions:                 *
11 *                                                                          *
12 * The above copyright notice and this permission notice shall be included  *
13 * in all copies or substantial portions of the Software.                   *
14 *                                                                          *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
18 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
21 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
22 *                                                                          *
23 * Except as contained in this notice, the name(s) of the above copyright   *
24 * holders shall not be used in advertising or otherwise to promote the     *
25 * sale, use or other dealings in this Software without prior written       *
26 * authorization.                                                           *
27 ****************************************************************************/
28
29/****************************************************************************
30 *   Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997            *
31 ****************************************************************************/
32
33#include "form.priv.h"
34
35MODULE_ID("$Id: fld_def.c,v 1.12 1999/05/16 17:37:48 juergen Exp $")
36
37/* this can't be readonly */
38static FIELD default_field = {
39  0,                       /* status */
40  0,                       /* rows   */
41  0,                       /* cols   */
42  0,                       /* frow   */
43  0,                       /* fcol   */
44  0,                       /* drows  */
45  0,                       /* dcols  */
46  0,                       /* maxgrow*/
47  0,                       /* nrow   */
48  0,                       /* nbuf   */
49  NO_JUSTIFICATION,        /* just   */
50  0,                       /* page   */
51  0,                       /* index  */
52  (int)' ',                /* pad    */
53  A_NORMAL,                /* fore   */
54  A_NORMAL,                /* back   */
55  ALL_FIELD_OPTS,          /* opts   */
56  (FIELD *)0,              /* snext  */
57  (FIELD *)0,              /* sprev  */
58  (FIELD *)0,              /* link   */
59  (FORM *)0,               /* form   */
60  (FIELDTYPE *)0,          /* type   */
61  (char *)0,               /* arg    */
62  (char *)0,               /* buf    */
63  (char *)0                /* usrptr */
64};
65
66FIELD *_nc_Default_Field = &default_field;
67
68/*---------------------------------------------------------------------------
69|   Facility      :  libnform
70|   Function      :  TypeArgument *_nc_Make_Argument(
71|                              const FIELDTYPE *typ,
72|                              va_list *ap,
73|                              int *err )
74|
75|   Description   :  Create an argument structure for the specified type.
76|                    Use the type-dependant argument list to construct
77|                    it.
78|
79|   Return Values :  Pointer to argument structure. Maybe NULL.
80|                    In case of an error in *err an errorcounter is increased.
81+--------------------------------------------------------------------------*/
82TypeArgument*
83_nc_Make_Argument(const FIELDTYPE *typ, va_list *ap, int *err)
84{
85  TypeArgument *res = (TypeArgument *)0;
86  TypeArgument *p;
87
88  if (typ && (typ->status & _HAS_ARGS))
89    {
90      assert(err && ap);
91      if (typ->status & _LINKED_TYPE)
92	{
93	  p = (TypeArgument *)malloc(sizeof(TypeArgument));
94	  if (p)
95	    {
96	      p->left  = _nc_Make_Argument(typ->left ,ap,err);
97	      p->right = _nc_Make_Argument(typ->right,ap,err);
98	      return p;
99	    }
100	  else
101	    *err += 1;
102      } else
103	{
104	  assert(typ->makearg);
105	  if ( !(res=(TypeArgument *)typ->makearg(ap)) )
106	    *err += 1;
107	}
108    }
109  return res;
110}
111
112/*---------------------------------------------------------------------------
113|   Facility      :  libnform
114|   Function      :  TypeArgument *_nc_Copy_Argument(const FIELDTYPE *typ,
115|                                                    const TypeArgument *argp,
116|                                                    int *err )
117|
118|   Description   :  Create a copy of an argument structure for the specified
119|                    type.
120|
121|   Return Values :  Pointer to argument structure. Maybe NULL.
122|                    In case of an error in *err an errorcounter is increased.
123+--------------------------------------------------------------------------*/
124TypeArgument*
125_nc_Copy_Argument(const FIELDTYPE *typ,
126		  const TypeArgument *argp, int *err)
127{
128  TypeArgument *res = (TypeArgument *)0;
129  TypeArgument *p;
130
131  if ( typ && (typ->status & _HAS_ARGS) )
132    {
133      assert(err && argp);
134      if (typ->status & _LINKED_TYPE)
135	{
136	  p = (TypeArgument *)malloc(sizeof(TypeArgument));
137	  if (p)
138	    {
139	      p->left  = _nc_Copy_Argument(typ,argp->left ,err);
140	      p->right = _nc_Copy_Argument(typ,argp->right,err);
141	      return p;
142	    }
143	  *err += 1;
144      }
145      else
146	{
147	  if (typ->copyarg)
148	    {
149	      if (!(res = (TypeArgument *)(typ->copyarg((const void *)argp))))
150		*err += 1;
151	    }
152	  else
153	    res = (TypeArgument *)argp;
154	}
155    }
156  return res;
157}
158
159/*---------------------------------------------------------------------------
160|   Facility      :  libnform
161|   Function      :  void _nc_Free_Argument(const FIELDTYPE *typ,
162|                                           TypeArgument * argp )
163|
164|   Description   :  Release memory associated with the argument structure
165|                    for the given fieldtype.
166|
167|   Return Values :  -
168+--------------------------------------------------------------------------*/
169void
170_nc_Free_Argument(const FIELDTYPE * typ, TypeArgument * argp)
171{
172  if (!typ || !(typ->status & _HAS_ARGS))
173    return;
174
175  if (typ->status & _LINKED_TYPE)
176    {
177      assert(argp);
178      _nc_Free_Argument(typ->left ,argp->left );
179      _nc_Free_Argument(typ->right,argp->right);
180      free(argp);
181    }
182  else
183    {
184      if (typ->freearg)
185	typ->freearg((void *)argp);
186    }
187}
188
189/*---------------------------------------------------------------------------
190|   Facility      :  libnform
191|   Function      :  bool _nc_Copy_Type( FIELD *dst, FIELD const *src )
192|
193|   Description   :  Copy argument structure of field src to field dst
194|
195|   Return Values :  TRUE       - copy worked
196|                    FALSE      - error occured
197+--------------------------------------------------------------------------*/
198bool
199_nc_Copy_Type(FIELD *dst, FIELD const *src)
200{
201  int err = 0;
202
203  assert(dst && src);
204
205  dst->type = src->type;
206  dst->arg  = (void *)_nc_Copy_Argument(src->type,(TypeArgument *)(src->arg),&err);
207
208  if (err)
209    {
210      _nc_Free_Argument(dst->type,(TypeArgument *)(dst->arg));
211      dst->type = (FIELDTYPE *)0;
212      dst->arg  = (void *)0;
213      return FALSE;
214    }
215  else
216    {
217      if (dst->type)
218	dst->type->ref++;
219      return TRUE;
220    }
221}
222
223/*---------------------------------------------------------------------------
224|   Facility      :  libnform
225|   Function      :  void _nc_Free_Type( FIELD *field )
226|
227|   Description   :  Release Argument structure for this field
228|
229|   Return Values :  -
230+--------------------------------------------------------------------------*/
231void
232_nc_Free_Type(FIELD *field)
233{
234  assert(field);
235  if (field->type)
236    field->type->ref--;
237  _nc_Free_Argument(field->type,(TypeArgument *)(field->arg));
238}
239
240/*---------------------------------------------------------------------------
241|   Facility      :  libnform
242|   Function      :  FIELD *new_field( int rows, int cols,
243|                                      int frow, int fcol,
244|                                      int nrow, int nbuf )
245|
246|   Description   :  Create a new field with this many 'rows' and 'cols',
247|                    starting at 'frow/fcol' in the subwindow of the form.
248|                    Allocate 'nrow' off-screen rows and 'nbuf' additional
249|                    buffers. If an error occurs, errno is set to
250|
251|                    E_BAD_ARGUMENT - invalid argument
252|                    E_SYSTEM_ERROR - system error
253|
254|   Return Values :  Pointer to the new field or NULL if failure.
255+--------------------------------------------------------------------------*/
256FIELD *new_field(int rows, int cols, int frow, int fcol, int nrow, int nbuf)
257{
258  FIELD *New_Field = (FIELD *)0;
259  int err = E_BAD_ARGUMENT;
260
261  if (rows>0  &&
262      cols>0  &&
263      frow>=0 &&
264      fcol>=0 &&
265      nrow>=0 &&
266      nbuf>=0 &&
267      ((err = E_SYSTEM_ERROR) != 0) && /* trick: this resets the default error */
268      (New_Field=(FIELD *)malloc(sizeof(FIELD))) )
269    {
270      *New_Field       = default_field;
271      New_Field->rows  = rows;
272      New_Field->cols  = cols;
273      New_Field->drows = rows + nrow;
274      New_Field->dcols = cols;
275      New_Field->frow  = frow;
276      New_Field->fcol  = fcol;
277      New_Field->nrow  = nrow;
278      New_Field->nbuf  = nbuf;
279      New_Field->link  = New_Field;
280
281      if (_nc_Copy_Type(New_Field,&default_field))
282	{
283	  size_t len;
284
285	  len = Total_Buffer_Size(New_Field);
286	  if ((New_Field->buf = (char *)malloc(len)))
287	    {
288	      /* Prefill buffers with blanks and insert terminating zeroes
289		 between buffers */
290	      int i;
291
292	      memset(New_Field->buf,' ',len);
293	      for(i=0;i<=New_Field->nbuf;i++)
294		{
295		  New_Field->buf[(New_Field->drows*New_Field->cols+1)*(i+1)-1]
296		    = '\0';
297		}
298	      return New_Field;
299	    }
300	}
301    }
302
303  if (New_Field)
304    free_field(New_Field);
305
306  SET_ERROR( err );
307  return (FIELD *)0;
308}
309
310/*---------------------------------------------------------------------------
311|   Facility      :  libnform
312|   Function      :  int free_field( FIELD *field )
313|
314|   Description   :  Frees the storage allocated for the field.
315|
316|   Return Values :  E_OK           - success
317|                    E_BAD_ARGUMENT - invalid field pointer
318|                    E_CONNECTED    - field is connected
319+--------------------------------------------------------------------------*/
320int free_field(FIELD * field)
321{
322  if (!field)
323    RETURN(E_BAD_ARGUMENT);
324
325  if (field->form)
326    RETURN(E_CONNECTED);
327
328  if (field == field->link)
329    {
330      if (field->buf)
331	free(field->buf);
332    }
333  else
334    {
335      FIELD *f;
336
337      for(f=field;f->link != field;f = f->link)
338	{}
339      f->link = field->link;
340    }
341  _nc_Free_Type(field);
342  free(field);
343  RETURN(E_OK);
344}
345
346/* fld_def.c ends here */
347