xref: /openbsd-src/lib/libform/fld_def.c (revision c7ef0cfc17afcba97172c25e1e3a943e893bc632)
1*c7ef0cfcSnicm /*	$OpenBSD: fld_def.c,v 1.10 2023/10/17 09:52:10 nicm Exp $	*/
202f2426aSmillert /****************************************************************************
3*c7ef0cfcSnicm  * Copyright 2020,2021 Thomas E. Dickey                                     *
4*c7ef0cfcSnicm  * Copyright 1998-2012,2014 Free Software Foundation, Inc.                  *
502f2426aSmillert  *                                                                          *
602f2426aSmillert  * Permission is hereby granted, free of charge, to any person obtaining a  *
702f2426aSmillert  * copy of this software and associated documentation files (the            *
802f2426aSmillert  * "Software"), to deal in the Software without restriction, including      *
902f2426aSmillert  * without limitation the rights to use, copy, modify, merge, publish,      *
1002f2426aSmillert  * distribute, distribute with modifications, sublicense, and/or sell       *
1102f2426aSmillert  * copies of the Software, and to permit persons to whom the Software is    *
1202f2426aSmillert  * furnished to do so, subject to the following conditions:                 *
1302f2426aSmillert  *                                                                          *
1402f2426aSmillert  * The above copyright notice and this permission notice shall be included  *
1502f2426aSmillert  * in all copies or substantial portions of the Software.                   *
1602f2426aSmillert  *                                                                          *
1702f2426aSmillert  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
1802f2426aSmillert  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
1902f2426aSmillert  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
2002f2426aSmillert  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
2102f2426aSmillert  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
2202f2426aSmillert  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
2302f2426aSmillert  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
2402f2426aSmillert  *                                                                          *
2502f2426aSmillert  * Except as contained in this notice, the name(s) of the above copyright   *
2602f2426aSmillert  * holders shall not be used in advertising or otherwise to promote the     *
2702f2426aSmillert  * sale, use or other dealings in this Software without prior written       *
2802f2426aSmillert  * authorization.                                                           *
2902f2426aSmillert  ****************************************************************************/
3002f2426aSmillert 
3102f2426aSmillert /****************************************************************************
3281d8c4e1Snicm  *   Author:  Juergen Pfeifer, 1995,1997                                    *
3302f2426aSmillert  ****************************************************************************/
34ae611fdaStholo 
35ae611fdaStholo #include "form.priv.h"
36ae611fdaStholo 
37*c7ef0cfcSnicm MODULE_ID("$Id: fld_def.c,v 1.10 2023/10/17 09:52:10 nicm Exp $")
386cd90de4Smillert 
39ae611fdaStholo /* this can't be readonly */
4081d8c4e1Snicm static FIELD default_field =
4181d8c4e1Snicm {
42ae611fdaStholo   0,				/* status  */
43ae611fdaStholo   0,				/* rows    */
44ae611fdaStholo   0,				/* cols    */
45ae611fdaStholo   0,				/* frow    */
46ae611fdaStholo   0,				/* fcol    */
47ae611fdaStholo   0,				/* drows   */
48ae611fdaStholo   0,				/* dcols   */
49ae611fdaStholo   0,				/* maxgrow */
50ae611fdaStholo   0,				/* nrow    */
51ae611fdaStholo   0,				/* nbuf    */
52ae611fdaStholo   NO_JUSTIFICATION,		/* just    */
53ae611fdaStholo   0,				/* page    */
54ae611fdaStholo   0,				/* index   */
55ae611fdaStholo   (int)' ',			/* pad     */
56ae611fdaStholo   A_NORMAL,			/* fore    */
57ae611fdaStholo   A_NORMAL,			/* back    */
58*c7ef0cfcSnicm   STD_FIELD_OPTS,		/* opts    */
59ae611fdaStholo   (FIELD *)0,			/* snext   */
60ae611fdaStholo   (FIELD *)0,			/* sprev   */
61ae611fdaStholo   (FIELD *)0,			/* link    */
62ae611fdaStholo   (FORM *)0,			/* form    */
63ae611fdaStholo   (FIELDTYPE *)0,		/* type    */
64ae611fdaStholo   (char *)0,			/* arg     */
6581d8c4e1Snicm   (FIELD_CELL *)0,		/* buf     */
66ae611fdaStholo   (char *)0			/* usrptr  */
6781d8c4e1Snicm   NCURSES_FIELD_EXTENSION
68ae611fdaStholo };
69ae611fdaStholo 
70*c7ef0cfcSnicm FORM_EXPORT_VAR(FIELD *) _nc_Default_Field = &default_field;
7181d8c4e1Snicm 
72ae611fdaStholo /*---------------------------------------------------------------------------
73ae611fdaStholo |   Facility      :  libnform
748d0fca71Smillert |   Function      :  TypeArgument *_nc_Make_Argument(
75ae611fdaStholo |                              const FIELDTYPE *typ,
76ae611fdaStholo |                              va_list *ap,
77ae611fdaStholo |                              int *err )
78ae611fdaStholo |
79ae611fdaStholo |   Description   :  Create an argument structure for the specified type.
806957a4a4Sjmc |                    Use the type-dependent argument list to construct
81ae611fdaStholo |                    it.
82ae611fdaStholo |
83ae611fdaStholo |   Return Values :  Pointer to argument structure. Maybe NULL.
84ae611fdaStholo |                    In case of an error in *err an error counter is increased.
85ae611fdaStholo +--------------------------------------------------------------------------*/
86*c7ef0cfcSnicm FORM_EXPORT(TypeArgument *)
_nc_Make_Argument(const FIELDTYPE * typ,va_list * ap,int * err)8781d8c4e1Snicm _nc_Make_Argument(const FIELDTYPE *typ, va_list *ap, int *err)
88ae611fdaStholo {
89ae611fdaStholo   TypeArgument *res = (TypeArgument *)0;
90ae611fdaStholo 
9181d8c4e1Snicm   if (typ != 0 && (typ->status & _HAS_ARGS) != 0)
92ae611fdaStholo     {
9381d8c4e1Snicm       assert(err != 0 && ap != (va_list *)0);
9481d8c4e1Snicm       if ((typ->status & _LINKED_TYPE) != 0)
95ae611fdaStholo 	{
96*c7ef0cfcSnicm 	  TypeArgument *p = typeMalloc(TypeArgument, 1);
9781d8c4e1Snicm 
9881d8c4e1Snicm 	  if (p != 0)
99ae611fdaStholo 	    {
1008d0fca71Smillert 	      p->left = _nc_Make_Argument(typ->left, ap, err);
1018d0fca71Smillert 	      p->right = _nc_Make_Argument(typ->right, ap, err);
102ae611fdaStholo 	      return p;
103ae611fdaStholo 	    }
104ae611fdaStholo 	  else
105ae611fdaStholo 	    {
106ae611fdaStholo 	      *err += 1;
107ae611fdaStholo 	    }
108ae611fdaStholo 	}
10981d8c4e1Snicm       else
11081d8c4e1Snicm 	{
11181d8c4e1Snicm 	  assert(typ->makearg != (void *)0);
11281d8c4e1Snicm 	  if (!(res = (TypeArgument *)typ->makearg(ap)))
11381d8c4e1Snicm 	    {
11481d8c4e1Snicm 	      *err += 1;
11581d8c4e1Snicm 	    }
11681d8c4e1Snicm 	}
11781d8c4e1Snicm     }
118ae611fdaStholo   return res;
119ae611fdaStholo }
120ae611fdaStholo 
121ae611fdaStholo /*---------------------------------------------------------------------------
122ae611fdaStholo |   Facility      :  libnform
1238d0fca71Smillert |   Function      :  TypeArgument *_nc_Copy_Argument(const FIELDTYPE *typ,
124ae611fdaStholo |                                                    const TypeArgument *argp,
125ae611fdaStholo |                                                    int *err )
126ae611fdaStholo |
127ae611fdaStholo |   Description   :  Create a copy of an argument structure for the specified
128ae611fdaStholo |                    type.
129ae611fdaStholo |
130ae611fdaStholo |   Return Values :  Pointer to argument structure. Maybe NULL.
131ae611fdaStholo |                    In case of an error in *err an error counter is increased.
132ae611fdaStholo +--------------------------------------------------------------------------*/
133*c7ef0cfcSnicm FORM_EXPORT(TypeArgument *)
_nc_Copy_Argument(const FIELDTYPE * typ,const TypeArgument * argp,int * err)13481d8c4e1Snicm _nc_Copy_Argument(const FIELDTYPE *typ, const TypeArgument *argp, int *err)
135ae611fdaStholo {
136ae611fdaStholo   TypeArgument *res = (TypeArgument *)0;
137ae611fdaStholo 
13881d8c4e1Snicm   if (typ != 0 && (typ->status & _HAS_ARGS) != 0)
139ae611fdaStholo     {
14081d8c4e1Snicm       assert(err != 0 && argp != 0);
14181d8c4e1Snicm       if ((typ->status & _LINKED_TYPE) != 0)
142ae611fdaStholo 	{
143*c7ef0cfcSnicm 	  TypeArgument *p = typeMalloc(TypeArgument, 1);
14481d8c4e1Snicm 
14581d8c4e1Snicm 	  if (p != 0)
146ae611fdaStholo 	    {
1478d0fca71Smillert 	      p->left = _nc_Copy_Argument(typ, argp->left, err);
1488d0fca71Smillert 	      p->right = _nc_Copy_Argument(typ, argp->right, err);
149ae611fdaStholo 	      return p;
150ae611fdaStholo 	    }
151ae611fdaStholo 	  *err += 1;
152ae611fdaStholo 	}
153ae611fdaStholo       else
154ae611fdaStholo 	{
15581d8c4e1Snicm 	  if (typ->copyarg != (void *)0)
1568d0fca71Smillert 	    {
1576cd90de4Smillert 	      if (!(res = (TypeArgument *)(typ->copyarg((const void *)argp))))
15881d8c4e1Snicm 		{
159ae611fdaStholo 		  *err += 1;
160ae611fdaStholo 		}
16181d8c4e1Snicm 	    }
1628d0fca71Smillert 	  else
16381d8c4e1Snicm 	    {
1648d0fca71Smillert 	      res = (TypeArgument *)argp;
1658d0fca71Smillert 	    }
166ae611fdaStholo 	}
16781d8c4e1Snicm     }
168ae611fdaStholo   return res;
169ae611fdaStholo }
170ae611fdaStholo 
171ae611fdaStholo /*---------------------------------------------------------------------------
172ae611fdaStholo |   Facility      :  libnform
1738d0fca71Smillert |   Function      :  void _nc_Free_Argument(const FIELDTYPE *typ,
174ae611fdaStholo |                                           TypeArgument * argp )
175ae611fdaStholo |
176ae611fdaStholo |   Description   :  Release memory associated with the argument structure
177ae611fdaStholo |                    for the given fieldtype.
178ae611fdaStholo |
179ae611fdaStholo |   Return Values :  -
180ae611fdaStholo +--------------------------------------------------------------------------*/
181*c7ef0cfcSnicm FORM_EXPORT(void)
_nc_Free_Argument(const FIELDTYPE * typ,TypeArgument * argp)18281d8c4e1Snicm _nc_Free_Argument(const FIELDTYPE *typ, TypeArgument *argp)
183ae611fdaStholo {
18481d8c4e1Snicm   if (typ != 0 && (typ->status & _HAS_ARGS) != 0)
185ae611fdaStholo     {
18681d8c4e1Snicm       if ((typ->status & _LINKED_TYPE) != 0)
18781d8c4e1Snicm 	{
188*c7ef0cfcSnicm 	  if (argp != 0)
189*c7ef0cfcSnicm 	    {
1908d0fca71Smillert 	      _nc_Free_Argument(typ->left, argp->left);
1918d0fca71Smillert 	      _nc_Free_Argument(typ->right, argp->right);
192ae611fdaStholo 	      free(argp);
193ae611fdaStholo 	    }
194*c7ef0cfcSnicm 	}
195ae611fdaStholo       else
196ae611fdaStholo 	{
19781d8c4e1Snicm 	  if (typ->freearg != (void *)0)
19881d8c4e1Snicm 	    {
199ae611fdaStholo 	      typ->freearg((void *)argp);
200ae611fdaStholo 	    }
201ae611fdaStholo 	}
20281d8c4e1Snicm     }
20381d8c4e1Snicm }
204ae611fdaStholo 
205ae611fdaStholo /*---------------------------------------------------------------------------
206ae611fdaStholo |   Facility      :  libnform
2078d0fca71Smillert |   Function      :  bool _nc_Copy_Type( FIELD *dst, FIELD const *src )
208ae611fdaStholo |
2098d0fca71Smillert |   Description   :  Copy argument structure of field src to field dst
210ae611fdaStholo |
211ae611fdaStholo |   Return Values :  TRUE       - copy worked
21281d8c4e1Snicm |                    FALSE      - error occurred
213ae611fdaStholo +--------------------------------------------------------------------------*/
214*c7ef0cfcSnicm FORM_EXPORT(bool)
_nc_Copy_Type(FIELD * dst,FIELD const * src)21581d8c4e1Snicm _nc_Copy_Type(FIELD *dst, FIELD const *src)
216ae611fdaStholo {
217ae611fdaStholo   int err = 0;
218ae611fdaStholo 
21981d8c4e1Snicm   assert(dst != 0 && src != 0);
220ae611fdaStholo 
2218d0fca71Smillert   dst->type = src->type;
2228d0fca71Smillert   dst->arg = (void *)_nc_Copy_Argument(src->type, (TypeArgument *)(src->arg), &err);
223ae611fdaStholo 
22481d8c4e1Snicm   if (err != 0)
225ae611fdaStholo     {
2268d0fca71Smillert       _nc_Free_Argument(dst->type, (TypeArgument *)(dst->arg));
2278d0fca71Smillert       dst->type = (FIELDTYPE *)0;
2288d0fca71Smillert       dst->arg = (void *)0;
229ae611fdaStholo       return FALSE;
230ae611fdaStholo     }
231ae611fdaStholo   else
232ae611fdaStholo     {
23381d8c4e1Snicm       if (dst->type != 0)
23481d8c4e1Snicm 	{
2358d0fca71Smillert 	  dst->type->ref++;
23681d8c4e1Snicm 	}
237ae611fdaStholo       return TRUE;
238ae611fdaStholo     }
239ae611fdaStholo }
240ae611fdaStholo 
241ae611fdaStholo /*---------------------------------------------------------------------------
242ae611fdaStholo |   Facility      :  libnform
2438d0fca71Smillert |   Function      :  void _nc_Free_Type( FIELD *field )
244ae611fdaStholo |
245ae611fdaStholo |   Description   :  Release Argument structure for this field
246ae611fdaStholo |
247ae611fdaStholo |   Return Values :  -
248ae611fdaStholo +--------------------------------------------------------------------------*/
249*c7ef0cfcSnicm FORM_EXPORT(void)
_nc_Free_Type(FIELD * field)2508d0fca71Smillert _nc_Free_Type(FIELD *field)
251ae611fdaStholo {
25281d8c4e1Snicm   assert(field != 0);
25381d8c4e1Snicm   if (field->type != 0)
25481d8c4e1Snicm     {
255ae611fdaStholo       field->type->ref--;
2568d0fca71Smillert       _nc_Free_Argument(field->type, (TypeArgument *)(field->arg));
257ae611fdaStholo     }
258*c7ef0cfcSnicm }
259ae611fdaStholo 
260ae611fdaStholo /*---------------------------------------------------------------------------
261ae611fdaStholo |   Facility      :  libnform
262ae611fdaStholo |   Function      :  FIELD *new_field( int rows, int cols,
263ae611fdaStholo |                                      int frow, int fcol,
264ae611fdaStholo |                                      int nrow, int nbuf )
265ae611fdaStholo |
266ae611fdaStholo |   Description   :  Create a new field with this many 'rows' and 'cols',
267ae611fdaStholo |                    starting at 'frow/fcol' in the subwindow of the form.
268ae611fdaStholo |                    Allocate 'nrow' off-screen rows and 'nbuf' additional
269ae611fdaStholo |                    buffers. If an error occurs, errno is set to
270ae611fdaStholo |
271ae611fdaStholo |                    E_BAD_ARGUMENT - invalid argument
272ae611fdaStholo |                    E_SYSTEM_ERROR - system error
273ae611fdaStholo |
274ae611fdaStholo |   Return Values :  Pointer to the new field or NULL if failure.
275ae611fdaStholo +--------------------------------------------------------------------------*/
276*c7ef0cfcSnicm FORM_EXPORT(FIELD *)
new_field(int rows,int cols,int frow,int fcol,int nrow,int nbuf)27781d8c4e1Snicm new_field(int rows, int cols, int frow, int fcol, int nrow, int nbuf)
278ae611fdaStholo {
27981d8c4e1Snicm   static const FIELD_CELL blank = BLANK;
28081d8c4e1Snicm   static const FIELD_CELL zeros = ZEROS;
28181d8c4e1Snicm 
282ae611fdaStholo   FIELD *New_Field = (FIELD *)0;
283ae611fdaStholo   int err = E_BAD_ARGUMENT;
284ae611fdaStholo 
28581d8c4e1Snicm   T((T_CALLED("new_field(%d,%d,%d,%d,%d,%d)"), rows, cols, frow, fcol, nrow, nbuf));
286ae611fdaStholo   if (rows > 0 &&
287ae611fdaStholo       cols > 0 &&
288ae611fdaStholo       frow >= 0 &&
289ae611fdaStholo       fcol >= 0 &&
290ae611fdaStholo       nrow >= 0 &&
291ae611fdaStholo       nbuf >= 0 &&
292ae611fdaStholo       ((err = E_SYSTEM_ERROR) != 0) &&	/* trick: this resets the default error */
29381d8c4e1Snicm       (New_Field = typeMalloc(FIELD, 1)) != 0)
294ae611fdaStholo     {
295*c7ef0cfcSnicm       T((T_CREATE("field %p"), (void *)New_Field));
296ae611fdaStholo       *New_Field = default_field;
297*c7ef0cfcSnicm       New_Field->rows = (short)rows;
298*c7ef0cfcSnicm       New_Field->cols = (short)cols;
299ae611fdaStholo       New_Field->drows = rows + nrow;
300ae611fdaStholo       New_Field->dcols = cols;
301*c7ef0cfcSnicm       New_Field->frow = (short)frow;
302*c7ef0cfcSnicm       New_Field->fcol = (short)fcol;
303ae611fdaStholo       New_Field->nrow = nrow;
304*c7ef0cfcSnicm       New_Field->nbuf = (short)nbuf;
305ae611fdaStholo       New_Field->link = New_Field;
306ae611fdaStholo 
30781d8c4e1Snicm #if USE_WIDEC_SUPPORT
30881d8c4e1Snicm       New_Field->working = newpad(1, Buffer_Length(New_Field) + 1);
30981d8c4e1Snicm       New_Field->expanded = typeCalloc(char *, 1 + (unsigned)nbuf);
31081d8c4e1Snicm #endif
31181d8c4e1Snicm 
3128d0fca71Smillert       if (_nc_Copy_Type(New_Field, &default_field))
313ae611fdaStholo 	{
314ae611fdaStholo 	  size_t len;
315ae611fdaStholo 
316ae611fdaStholo 	  len = Total_Buffer_Size(New_Field);
31781d8c4e1Snicm 	  if ((New_Field->buf = (FIELD_CELL *)malloc(len)))
318ae611fdaStholo 	    {
319ae611fdaStholo 	      /* Prefill buffers with blanks and insert terminating zeroes
320ae611fdaStholo 	         between buffers */
32181d8c4e1Snicm 	      int i, j;
32281d8c4e1Snicm 	      int cells = Buffer_Length(New_Field);
323ae611fdaStholo 
324ae611fdaStholo 	      for (i = 0; i <= New_Field->nbuf; i++)
325ae611fdaStholo 		{
32681d8c4e1Snicm 		  FIELD_CELL *buffer = &(New_Field->buf[(cells + 1) * i]);
32781d8c4e1Snicm 
32881d8c4e1Snicm 		  for (j = 0; j < cells; ++j)
32981d8c4e1Snicm 		    {
33081d8c4e1Snicm 		      buffer[j] = blank;
331ae611fdaStholo 		    }
33281d8c4e1Snicm 		  buffer[j] = zeros;
33381d8c4e1Snicm 		}
33481d8c4e1Snicm 	      returnField(New_Field);
335ae611fdaStholo 	    }
336ae611fdaStholo 	}
337ae611fdaStholo     }
338ae611fdaStholo 
339ae611fdaStholo   if (New_Field)
340ae611fdaStholo     free_field(New_Field);
341ae611fdaStholo 
342ae611fdaStholo   SET_ERROR(err);
34381d8c4e1Snicm   returnField((FIELD *)0);
344ae611fdaStholo }
345ae611fdaStholo 
346ae611fdaStholo /*---------------------------------------------------------------------------
347ae611fdaStholo |   Facility      :  libnform
348ae611fdaStholo |   Function      :  int free_field( FIELD *field )
349ae611fdaStholo |
350ae611fdaStholo |   Description   :  Frees the storage allocated for the field.
351ae611fdaStholo |
352ae611fdaStholo |   Return Values :  E_OK           - success
353ae611fdaStholo |                    E_BAD_ARGUMENT - invalid field pointer
354ae611fdaStholo |                    E_CONNECTED    - field is connected
355ae611fdaStholo +--------------------------------------------------------------------------*/
356*c7ef0cfcSnicm FORM_EXPORT(int)
free_field(FIELD * field)35784af20ceSmillert free_field(FIELD *field)
358ae611fdaStholo {
359*c7ef0cfcSnicm   T((T_CALLED("free_field(%p)"), (void *)field));
360ae611fdaStholo   if (!field)
361ae611fdaStholo     {
36281d8c4e1Snicm       RETURN(E_BAD_ARGUMENT);
36381d8c4e1Snicm     }
36481d8c4e1Snicm   else if (field->form != 0)
36581d8c4e1Snicm     {
36681d8c4e1Snicm       RETURN(E_CONNECTED);
36781d8c4e1Snicm     }
36881d8c4e1Snicm   else if (field == field->link)
36981d8c4e1Snicm     {
37081d8c4e1Snicm       if (field->buf != 0)
371ae611fdaStholo 	free(field->buf);
372ae611fdaStholo     }
373ae611fdaStholo   else
374ae611fdaStholo     {
375ae611fdaStholo       FIELD *f;
376ae611fdaStholo 
377ae611fdaStholo       for (f = field; f->link != field; f = f->link)
37881d8c4e1Snicm 	{
37981d8c4e1Snicm 	}
380ae611fdaStholo       f->link = field->link;
381ae611fdaStholo     }
3828d0fca71Smillert   _nc_Free_Type(field);
38381d8c4e1Snicm #if USE_WIDEC_SUPPORT
38481d8c4e1Snicm   if (field->expanded != 0)
38581d8c4e1Snicm     {
38681d8c4e1Snicm       int n;
38781d8c4e1Snicm 
38881d8c4e1Snicm       for (n = 0; n <= field->nbuf; ++n)
38981d8c4e1Snicm 	{
39081d8c4e1Snicm 	  FreeIfNeeded(field->expanded[n]);
39181d8c4e1Snicm 	}
39281d8c4e1Snicm       free(field->expanded);
39381d8c4e1Snicm       (void)delwin(field->working);
39481d8c4e1Snicm     }
39581d8c4e1Snicm #endif
396ae611fdaStholo   free(field);
397ae611fdaStholo   RETURN(E_OK);
398ae611fdaStholo }
399ae611fdaStholo 
400ae611fdaStholo /* fld_def.c ends here */
401