/****************************************************************************
- * Copyright (c) 2008 Free Software Foundation, Inc. *
+ * Copyright 2018-2020,2021 Thomas E. Dickey *
+ * Copyright 2008-2012,2016 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
#include "form.priv.h"
-MODULE_ID("$Id: fty_generic.c,v 1.1 2008/11/18 08:50:04 juergen Exp $")
+MODULE_ID("$Id: fty_generic.c,v 1.15 2021/03/27 23:49:53 tom Exp $")
/*
* This is not a full implementation of a field type, but adds some
* support for higher level languages with some restrictions to interop
- * with C language. Especially the collection of arguments for the
+ * with C language. In particular, the collection of arguments for the
* various fieldtypes is not based on the vararg C mechanism, but on a
- * iterator based callback mechanism that allowes the high level language
+ * iterator based callback mechanism that allows the high level language
* to provide the arguments as a structure. Most languages have mechanisms
* to layout structures so that they can be passed to C.
+ *
* The languages can register a new generic fieldtype dynamically and store
* a handle (key) to the calling object as an argument. Together with that
* it can register a freearg callback, so that the high level language
* remains in control of the memory management of the arguments they pass.
* The design idea is, that the high-level language - typically a OO
- * language like C# or Java, uses it's own dispatching mechanisms
+ * language like C# or Java, uses its own dispatching mechanisms
* (polymorphism) to call the proper check routines responsible for the
* argument type. So these language implement typically only one generic
* fieldtype they register with the forms library using this call.
*
- * For that purpose we have extended the fieldtype struc by a new element
- * that gets the arguments from a single struct passed by the caller.
- *
+ * For that purpose we have extended the fieldtype structure by a new element
+ * that gets the arguments from a single struct passed by the caller.
+ *
*/
-
+#if NCURSES_INTEROP_FUNCS
/*---------------------------------------------------------------------------
-| Facility : libnform
+| Facility : libnform
| Function : static void *Generic_This_Type( void * arg )
-|
+|
| Description : We interpret the passed arg just as a handle the
| calling language uses to keep track of its allocated
| argument structures. We can simply copy it back.
| write a field_check and a char_check function and give
| them as input to this call. A callback to allow the
| release of the allocated memory must also be provided.
-| For generic field types, we provide some more
+| For generic field types, we provide some more
| information about the field as parameters.
|
| If an error occurs, errno is set to
|
| Return Values : Fieldtype pointer or NULL if error occurred
+--------------------------------------------------------------------------*/
-NCURSES_EXPORT(FIELDTYPE *)
-_nc_generic_fieldtype(bool (*const field_check) (FORM*, FIELD *, const void *),
- bool (*const char_check) (int, FORM*, FIELD*, const void *),
- bool (*const next)(FORM*, FIELD*,const void*),
- bool (*const prev)(FORM*, FIELD*,const void*),
- void (*freecallback)(void*))
+FORM_EXPORT(FIELDTYPE *)
+_nc_generic_fieldtype(bool (*const field_check) (FORM *, FIELD *, const void *),
+ bool (*const char_check) (int, FORM *, FIELD *, const
+ void *),
+ bool (*const next) (FORM *, FIELD *, const void *),
+ bool (*const prev) (FORM *, FIELD *, const void *),
+ void (*freecallback) (void *))
{
- int code = E_SYSTEM_ERROR;
- FIELDTYPE* res = (FIELDTYPE*)0;
+ int code = E_SYSTEM_ERROR;
+ FIELDTYPE *res = (FIELDTYPE *)0;
+
+ TR_FUNC_BFR(5);
- T((T_CALLED("_nc_generic_fieldtype(%p,%p,%p,%p,%p)"),
- field_check, char_check, next, prev, freecallback));
+ T((T_CALLED("_nc_generic_fieldtype(%s,%s,%s,%s,%s)"),
+ TR_FUNC_ARG(0, field_check),
+ TR_FUNC_ARG(1, char_check),
+ TR_FUNC_ARG(2, next),
+ TR_FUNC_ARG(3, prev),
+ TR_FUNC_ARG(4, freecallback)));
- if (field_check || char_check)
+ if (field_check || char_check)
{
- res = typeMalloc(FIELDTYPE,1);
+ res = typeMalloc(FIELDTYPE, 1);
+
if (res)
- {
- *res = *_nc_Default_FieldType;
- res->status |= (_HAS_ARGS | _GENERIC);
- res->fieldcheck.gfcheck = field_check;
- res->charcheck.gccheck = char_check;
- res->genericarg = Generic_This_Type;
- res->freearg = freecallback;
- res->enum_next.gnext = next;
- res->enum_prev.gprev = prev;
- code = E_OK;
- }
+ {
+ *res = *_nc_Default_FieldType;
+ SetStatus(res, (_HAS_ARGS | _GENERIC));
+ res->fieldcheck.gfcheck = field_check;
+ res->charcheck.gccheck = char_check;
+ res->genericarg = Generic_This_Type;
+ res->freearg = freecallback;
+ res->enum_next.gnext = next;
+ res->enum_prev.gprev = prev;
+ code = E_OK;
+ }
}
- else
- code = E_BAD_ARGUMENT;
+ else
+ code = E_BAD_ARGUMENT;
- if (E_OK != code)
- SET_ERROR(code);
+ if (E_OK != code)
+ SET_ERROR(code);
- returnFieldType(res);
+ returnFieldType(res);
}
-
/*---------------------------------------------------------------------------
-| Facility : libnform
+| Facility : libnform
| Function : static TypeArgument *GenericArgument(
| const FIELDTYPE* typ,
| int (*argiterator)(void**),
| int* err)
-|
+|
| Description : The iterator callback must browse through all fieldtype
| parameters that have an argument associated with the
| type. The iterator returns 1 if the operation to get
-| the next element was successfull, 0 otherwise. If the
+| the next element was successful, 0 otherwise. If the
| iterator could move to the next argument, it fills
| the void* pointer representing the argument into the
| location provided as argument to the iterator.
|
| Return Values : Pointer to argument structure
+--------------------------------------------------------------------------*/
-static TypeArgument*
-GenericArgument(const FIELDTYPE *typ,
- int (*argiterator)(void**), int *err)
+static TypeArgument *
+GenericArgument(const FIELDTYPE *typ,
+ int (*argiterator) (void **), int *err)
{
TypeArgument *res = (TypeArgument *)0;
- if (typ!=0 && (typ->status & _HAS_ARGS) != 0 && err!=0 && argiterator != 0)
- {
- if (typ->status & _LINKED_TYPE)
- {
- /* Composite fieldtypes keep track internally of their own memory */
- TypeArgument* p = typeMalloc(TypeArgument,1);
- if (p)
- {
- p->left = GenericArgument(typ->left, argiterator, err);
- p->right = GenericArgument(typ->right, argiterator, err);
- return p;
- }
- else
- *err += 1;
- }
- else
+ if (typ != 0 && (typ->status & _HAS_ARGS) != 0 && err != 0 && argiterator != 0)
{
- assert(typ->genericarg != (void*)0);
- if (typ->genericarg == 0)
- *err += 1;
+ if (typ->status & _LINKED_TYPE)
+ {
+ /* Composite fieldtypes keep track internally of their own memory */
+ TypeArgument *p = typeMalloc(TypeArgument, 1);
+
+ if (p)
+ {
+ p->left = GenericArgument(typ->left, argiterator, err);
+ p->right = GenericArgument(typ->right, argiterator, err);
+ return p;
+ }
+ else
+ *err += 1;
+ }
else
{
- void* argp;
- int valid = argiterator(&argp);
- if (valid==0 || argp==0 ||
- !(res = (TypeArgument*)typ->genericarg(argp)))
+ assert(typ->genericarg != (void *)0);
+ if (typ->genericarg == 0)
+ *err += 1;
+ else
{
- *err += 1;
+ void *argp;
+ int valid = argiterator(&argp);
+
+ if (valid == 0 || argp == 0 ||
+ !(res = (TypeArgument *)typ->genericarg(argp)))
+ {
+ *err += 1;
+ }
}
}
}
- }
return res;
}
/*---------------------------------------------------------------------------
-| Facility : libnform
+| Facility : libnform
| Function : int _nc_set_generic_fieldtype(
| FIELD* field,
| FIELDTYPE* ftyp,
| int (*argiterator)(void**))
-|
+|
| Description : Assign the fieldtype to the field and use the iterator
-| mechanism to get the arguments when a check is
+| mechanism to get the arguments when a check is
| performed.
|
| Return Values : E_OK if all went well
| E_SYSTEM_ERROR if an error occurred
+--------------------------------------------------------------------------*/
-NCURSES_EXPORT(int)
+FORM_EXPORT(int)
_nc_set_generic_fieldtype(FIELD *field,
- FIELDTYPE* ftyp,
- int (*argiterator)(void**))
+ FIELDTYPE *ftyp,
+ int (*argiterator) (void **))
{
int code = E_SYSTEM_ERROR;
int err = 0;
if (field)
- {
+ {
if (field && field->type)
_nc_Free_Type(field);
field->type = ftyp;
if (ftyp)
- {
- if (argiterator)
{
- /* The precondition is that the iterator is reset */
- field->arg = (void*)GenericArgument(field->type,argiterator,&err);
-
- if (err)
- {
- _nc_Free_Argument(field->type, (TypeArgument*)(field->arg));
- field->type = (FIELDTYPE*)0;
- field->arg = (void*)0;
- }
- else
+ if (argiterator)
{
- code = E_OK;
- if (field->type)
- field->type->ref++;
+ /* The precondition is that the iterator is reset */
+ field->arg = (void *)GenericArgument(field->type, argiterator, &err);
+
+ if (err)
+ {
+ _nc_Free_Argument(field->type, (TypeArgument *)(field->arg));
+ field->type = (FIELDTYPE *)0;
+ field->arg = (void *)0;
+ }
+ else
+ {
+ code = E_OK;
+ if (field->type)
+ field->type->ref++;
+ }
}
}
- }
else
- {
- field->arg = (void*)0;
- code = E_OK;
- }
+ {
+ field->arg = (void *)0;
+ code = E_OK;
+ }
}
- return code;
+ return code;
}
/*---------------------------------------------------------------------------
-| Facility : libnform
+| Facility : libnform
| Function : WINDOW* _nc_form_cursor(
| FORM* form,
| int *pRow, int *pCol)
-|
+|
| Description : Get the current position of the form cursor position
| We also return the field window
|
-| Return Values : The fields Window or NULL on error
+| Return Values : The field's Window or NULL on error
+--------------------------------------------------------------------------*/
-NCURSES_EXPORT(WINDOW*)
-_nc_form_cursor(const FORM* form, int* pRow, int* pCol)
+FORM_EXPORT(WINDOW *)
+_nc_form_cursor(const FORM *form, int *pRow, int *pCol)
{
int code = E_SYSTEM_ERROR;
- WINDOW* res = (WINDOW*)0;
+ WINDOW *res = (WINDOW *)0;
- if (!(form==0 || pRow==0 || pCol==0))
- {
+ if (form != 0 && pRow != 0 && pCol != 0)
+ {
*pRow = form->currow;
*pCol = form->curcol;
- res = form->w;
- code = E_OK;
- }
+ res = form->w;
+ code = E_OK;
+ }
if (code != E_OK)
SET_ERROR(code);
return res;
}
+#else
+extern void _nc_fty_generic(void);
+void
+_nc_fty_generic(void)
+{
+}
+#endif
/* fty_generic.c ends here */