X-Git-Url: https://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=form%2Ffty_enum.c;h=d3351644ef1849f2aa9de6dfd7ab31674cc08e8c;hp=054cc4dc862d6f69d0b2b618c873e851cc5b9a76;hb=17d9459c7aecedecbfc59b8ba5d29279a01e9003;hpb=027ae42953e3186daed8f3882da73de48291b606 diff --git a/form/fty_enum.c b/form/fty_enum.c index 054cc4dc..d3351644 100644 --- a/form/fty_enum.c +++ b/form/fty_enum.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2004,2006 Free Software Foundation, Inc. * + * Copyright (c) 1998-2009,2010 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 * @@ -34,7 +34,7 @@ #include "form.priv.h" -MODULE_ID("$Id: fty_enum.c,v 1.20 2006/04/22 21:33:05 tom Exp $") +MODULE_ID("$Id: fty_enum.c,v 1.26 2010/05/01 21:11:07 tom Exp $") typedef struct { @@ -45,40 +45,97 @@ typedef struct } enumARG; +typedef struct + { + char **kwds; + int ccase; + int cunique; + } +enumParams; + /*--------------------------------------------------------------------------- | Facility : libnform -| Function : static void *Make_Enum_Type( va_list * ap ) +| Function : static void *Generic_Enum_Type(void * arg) | | Description : Allocate structure for enumeration type argument. | | Return Values : Pointer to argument structure or NULL on error +--------------------------------------------------------------------------*/ static void * -Make_Enum_Type(va_list *ap) +Generic_Enum_Type(void *arg) { - enumARG *argp = (enumARG *)malloc(sizeof(enumARG)); + enumARG *argp = (enumARG *)0; + enumParams *params = (enumParams *) arg; - if (argp) + if (params) { - int cnt = 0; - char **kp = (char **)0; - int ccase, cunique; + argp = typeMalloc(enumARG, 1); + + if (argp) + { + int cnt = 0; + char **kp = (char **)0; + char **kwds = (char **)0; + char **kptarget; + int ccase, cunique; + + T((T_CREATE("enumARG %p"), (void *)argp)); + kwds = params->kwds; + ccase = params->ccase; + cunique = params->cunique; - argp->kwds = va_arg(*ap, char **); - ccase = va_arg(*ap, int); - cunique = va_arg(*ap, int); + argp->checkcase = ccase ? TRUE : FALSE; + argp->checkunique = cunique ? TRUE : FALSE; + argp->kwds = (char **)0; - argp->checkcase = ccase ? TRUE : FALSE; - argp->checkunique = cunique ? TRUE : FALSE; + kp = kwds; + while (kp && (*kp++)) + cnt++; + argp->count = cnt; - kp = argp->kwds; - while (kp && (*kp++)) - cnt++; - argp->count = cnt; + if (cnt > 0) + { + /* We copy the keywords, because we can't rely on the fact + that the caller doesn't relocate or free the memory used + for the keywords (maybe he has GC) + */ + argp->kwds = typeMalloc(char *, cnt + 1); + + kp = kwds; + if ((kptarget = argp->kwds) != 0) + { + while (kp && (*kp)) + { + (*kptarget++) = strdup(*kp++); + } + *kptarget = (char *)0; + } + } + } } return (void *)argp; } +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static void *Make_Enum_Type( va_list * ap ) +| +| Description : Allocate structure for enumeration type argument. +| +| Return Values : Pointer to argument structure or NULL on error ++--------------------------------------------------------------------------*/ +static void * +Make_Enum_Type(va_list *ap) +{ + enumParams params; + + params.kwds = va_arg(*ap, char **); + params.ccase = va_arg(*ap, int); + params.cunique = va_arg(*ap, int); + + return Generic_Enum_Type((void *)¶ms); +} + /*--------------------------------------------------------------------------- | Facility : libnform | Function : static void *Copy_Enum_Type( const void * argp ) @@ -96,10 +153,29 @@ Copy_Enum_Type(const void *argp) { const enumARG *ap = (const enumARG *)argp; - result = (enumARG *)malloc(sizeof(enumARG)); + result = typeMalloc(enumARG, 1); if (result) - *result = *ap; + { + T((T_CREATE("enumARG %p"), (void *)result)); + *result = *ap; + + if (ap->count > 0) + { + char **kptarget; + char **kp = ap->kwds; + result->kwds = typeMalloc(char *, 1 + ap->count); + + if ((kptarget = result->kwds) != 0) + { + while (kp && (*kp)) + { + (*kptarget++) = strdup(*kp++); + } + *kptarget = (char *)0; + } + } + } } return (void *)result; } @@ -116,7 +192,24 @@ static void Free_Enum_Type(void *argp) { if (argp) - free(argp); + { + const enumARG *ap = (const enumARG *)argp; + + if (ap->kwds && ap->count > 0) + { + char **kp = ap->kwds; + int cnt = 0; + + while (kp && (*kp)) + { + free(*kp++); + cnt++; + } + assert(cnt == ap->count); + free(ap->kwds); + } + free(argp); + } } #define SKIP_SPACE(x) while(((*(x))!='\0') && (is_blank(*(x)))) (x)++ @@ -322,13 +415,28 @@ static FIELDTYPE typeENUM = Make_Enum_Type, Copy_Enum_Type, Free_Enum_Type, - Check_Enum_Field, - NULL, - Next_Enum, - Previous_Enum + INIT_FT_FUNC(Check_Enum_Field), + INIT_FT_FUNC(NULL), + INIT_FT_FUNC(Next_Enum), + INIT_FT_FUNC(Previous_Enum), +#if NCURSES_INTEROP_FUNCS + Generic_Enum_Type +#endif }; NCURSES_EXPORT_VAR(FIELDTYPE *) TYPE_ENUM = &typeENUM; +#if NCURSES_INTEROP_FUNCS +/* The next routines are to simplify the use of ncurses from + programming languages with restictions on interop with C level + constructs (e.g. variable access or va_list + ellipsis constructs) +*/ +NCURSES_EXPORT(FIELDTYPE *) +_nc_TYPE_ENUM(void) +{ + return TYPE_ENUM; +} +#endif + /* fty_enum.c ends here */