xref: /freebsd/contrib/ncurses/form/fld_def.c (revision ae83180158c4c937f170e31eff311b18c0286a93)
1 /****************************************************************************
2  * Copyright (c) 1998,2000 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 
35 MODULE_ID("$Id: fld_def.c,v 1.13 2000/12/10 02:09:38 tom Exp $")
36 
37 /* this can't be readonly */
38 static 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 
66 NCURSES_EXPORT_VAR(FIELD *) _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 +--------------------------------------------------------------------------*/
82 NCURSES_EXPORT(TypeArgument*)
83 _nc_Make_Argument
84 (const FIELDTYPE *typ, va_list *ap, int *err)
85 {
86   TypeArgument *res = (TypeArgument *)0;
87   TypeArgument *p;
88 
89   if (typ && (typ->status & _HAS_ARGS))
90     {
91       assert(err && ap);
92       if (typ->status & _LINKED_TYPE)
93 	{
94 	  p = (TypeArgument *)malloc(sizeof(TypeArgument));
95 	  if (p)
96 	    {
97 	      p->left  = _nc_Make_Argument(typ->left ,ap,err);
98 	      p->right = _nc_Make_Argument(typ->right,ap,err);
99 	      return p;
100 	    }
101 	  else
102 	    *err += 1;
103       } else
104 	{
105 	  assert(typ->makearg);
106 	  if ( !(res=(TypeArgument *)typ->makearg(ap)) )
107 	    *err += 1;
108 	}
109     }
110   return res;
111 }
112 
113 /*---------------------------------------------------------------------------
114 |   Facility      :  libnform
115 |   Function      :  TypeArgument *_nc_Copy_Argument(const FIELDTYPE *typ,
116 |                                                    const TypeArgument *argp,
117 |                                                    int *err )
118 |
119 |   Description   :  Create a copy of an argument structure for the specified
120 |                    type.
121 |
122 |   Return Values :  Pointer to argument structure. Maybe NULL.
123 |                    In case of an error in *err an errorcounter is increased.
124 +--------------------------------------------------------------------------*/
125 NCURSES_EXPORT(TypeArgument*)
126 _nc_Copy_Argument
127     (const FIELDTYPE *typ,
128      const TypeArgument *argp, int *err)
129 {
130   TypeArgument *res = (TypeArgument *)0;
131   TypeArgument *p;
132 
133   if ( typ && (typ->status & _HAS_ARGS) )
134     {
135       assert(err && argp);
136       if (typ->status & _LINKED_TYPE)
137 	{
138 	  p = (TypeArgument *)malloc(sizeof(TypeArgument));
139 	  if (p)
140 	    {
141 	      p->left  = _nc_Copy_Argument(typ,argp->left ,err);
142 	      p->right = _nc_Copy_Argument(typ,argp->right,err);
143 	      return p;
144 	    }
145 	  *err += 1;
146       }
147       else
148 	{
149 	  if (typ->copyarg)
150 	    {
151 	      if (!(res = (TypeArgument *)(typ->copyarg((const void *)argp))))
152 		*err += 1;
153 	    }
154 	  else
155 	    res = (TypeArgument *)argp;
156 	}
157     }
158   return res;
159 }
160 
161 /*---------------------------------------------------------------------------
162 |   Facility      :  libnform
163 |   Function      :  void _nc_Free_Argument(const FIELDTYPE *typ,
164 |                                           TypeArgument * argp )
165 |
166 |   Description   :  Release memory associated with the argument structure
167 |                    for the given fieldtype.
168 |
169 |   Return Values :  -
170 +--------------------------------------------------------------------------*/
171 NCURSES_EXPORT(void)
172 _nc_Free_Argument
173 (const FIELDTYPE * typ, TypeArgument * argp)
174 {
175   if (!typ || !(typ->status & _HAS_ARGS))
176     return;
177 
178   if (typ->status & _LINKED_TYPE)
179     {
180       assert(argp);
181       _nc_Free_Argument(typ->left ,argp->left );
182       _nc_Free_Argument(typ->right,argp->right);
183       free(argp);
184     }
185   else
186     {
187       if (typ->freearg)
188 	typ->freearg((void *)argp);
189     }
190 }
191 
192 /*---------------------------------------------------------------------------
193 |   Facility      :  libnform
194 |   Function      :  bool _nc_Copy_Type( FIELD *dst, FIELD const *src )
195 |
196 |   Description   :  Copy argument structure of field src to field dst
197 |
198 |   Return Values :  TRUE       - copy worked
199 |                    FALSE      - error occured
200 +--------------------------------------------------------------------------*/
201 NCURSES_EXPORT(bool)
202 _nc_Copy_Type
203 (FIELD *dst, FIELD const *src)
204 {
205   int err = 0;
206 
207   assert(dst && src);
208 
209   dst->type = src->type;
210   dst->arg  = (void *)_nc_Copy_Argument(src->type,(TypeArgument *)(src->arg),&err);
211 
212   if (err)
213     {
214       _nc_Free_Argument(dst->type,(TypeArgument *)(dst->arg));
215       dst->type = (FIELDTYPE *)0;
216       dst->arg  = (void *)0;
217       return FALSE;
218     }
219   else
220     {
221       if (dst->type)
222 	dst->type->ref++;
223       return TRUE;
224     }
225 }
226 
227 /*---------------------------------------------------------------------------
228 |   Facility      :  libnform
229 |   Function      :  void _nc_Free_Type( FIELD *field )
230 |
231 |   Description   :  Release Argument structure for this field
232 |
233 |   Return Values :  -
234 +--------------------------------------------------------------------------*/
235 NCURSES_EXPORT(void)
236 _nc_Free_Type (FIELD *field)
237 {
238   assert(field);
239   if (field->type)
240     field->type->ref--;
241   _nc_Free_Argument(field->type,(TypeArgument *)(field->arg));
242 }
243 
244 /*---------------------------------------------------------------------------
245 |   Facility      :  libnform
246 |   Function      :  FIELD *new_field( int rows, int cols,
247 |                                      int frow, int fcol,
248 |                                      int nrow, int nbuf )
249 |
250 |   Description   :  Create a new field with this many 'rows' and 'cols',
251 |                    starting at 'frow/fcol' in the subwindow of the form.
252 |                    Allocate 'nrow' off-screen rows and 'nbuf' additional
253 |                    buffers. If an error occurs, errno is set to
254 |
255 |                    E_BAD_ARGUMENT - invalid argument
256 |                    E_SYSTEM_ERROR - system error
257 |
258 |   Return Values :  Pointer to the new field or NULL if failure.
259 +--------------------------------------------------------------------------*/
260 NCURSES_EXPORT(FIELD *)
261 new_field
262 (int rows, int cols, int frow, int fcol, int nrow, int nbuf)
263 {
264   FIELD *New_Field = (FIELD *)0;
265   int err = E_BAD_ARGUMENT;
266 
267   if (rows>0  &&
268       cols>0  &&
269       frow>=0 &&
270       fcol>=0 &&
271       nrow>=0 &&
272       nbuf>=0 &&
273       ((err = E_SYSTEM_ERROR) != 0) && /* trick: this resets the default error */
274       (New_Field=(FIELD *)malloc(sizeof(FIELD))) )
275     {
276       *New_Field       = default_field;
277       New_Field->rows  = rows;
278       New_Field->cols  = cols;
279       New_Field->drows = rows + nrow;
280       New_Field->dcols = cols;
281       New_Field->frow  = frow;
282       New_Field->fcol  = fcol;
283       New_Field->nrow  = nrow;
284       New_Field->nbuf  = nbuf;
285       New_Field->link  = New_Field;
286 
287       if (_nc_Copy_Type(New_Field,&default_field))
288 	{
289 	  size_t len;
290 
291 	  len = Total_Buffer_Size(New_Field);
292 	  if ((New_Field->buf = (char *)malloc(len)))
293 	    {
294 	      /* Prefill buffers with blanks and insert terminating zeroes
295 		 between buffers */
296 	      int i;
297 
298 	      memset(New_Field->buf,' ',len);
299 	      for(i=0;i<=New_Field->nbuf;i++)
300 		{
301 		  New_Field->buf[(New_Field->drows*New_Field->cols+1)*(i+1)-1]
302 		    = '\0';
303 		}
304 	      return New_Field;
305 	    }
306 	}
307     }
308 
309   if (New_Field)
310     free_field(New_Field);
311 
312   SET_ERROR( err );
313   return (FIELD *)0;
314 }
315 
316 /*---------------------------------------------------------------------------
317 |   Facility      :  libnform
318 |   Function      :  int free_field( FIELD *field )
319 |
320 |   Description   :  Frees the storage allocated for the field.
321 |
322 |   Return Values :  E_OK           - success
323 |                    E_BAD_ARGUMENT - invalid field pointer
324 |                    E_CONNECTED    - field is connected
325 +--------------------------------------------------------------------------*/
326 NCURSES_EXPORT(int)
327 free_field (FIELD * field)
328 {
329   if (!field)
330     RETURN(E_BAD_ARGUMENT);
331 
332   if (field->form)
333     RETURN(E_CONNECTED);
334 
335   if (field == field->link)
336     {
337       if (field->buf)
338 	free(field->buf);
339     }
340   else
341     {
342       FIELD *f;
343 
344       for(f=field;f->link != field;f = f->link)
345 	{}
346       f->link = field->link;
347     }
348   _nc_Free_Type(field);
349   free(field);
350   RETURN(E_OK);
351 }
352 
353 /* fld_def.c ends here */
354