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