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