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