ncurses 5.4
[ncurses.git] / form / fld_def.c
1 /****************************************************************************
2  * Copyright (c) 1998-2002,2003 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  ****************************************************************************/
32
33 #include "form.priv.h"
34
35 MODULE_ID("$Id: fld_def.c,v 1.17 2003/11/08 21:15:02 Jonathon.Gray 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 \f
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-dependent 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 error counter 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 error counter 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 occurred
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 */