/****************************************************************************1* Copyright (c) 1998 Free Software Foundation, Inc. *2* *3* Permission is hereby granted, free of charge, to any person obtaining a *4* copy of this software and associated documentation files (the *5* "Software"), to deal in the Software without restriction, including *6* without limitation the rights to use, copy, modify, merge, publish, *7* distribute, distribute with modifications, sublicense, and/or sell *8* copies of the Software, and to permit persons to whom the Software is *9* furnished to do so, subject to the following conditions: *10* *11* The above copyright notice and this permission notice shall be included *12* in all copies or substantial portions of the Software. *13* *14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *15* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *16* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *17* IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *18* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *19* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *20* THE USE OR OTHER DEALINGS IN THE SOFTWARE. *21* *22* Except as contained in this notice, the name(s) of the above copyright *23* holders shall not be used in advertising or otherwise to promote the *24* sale, use or other dealings in this Software without prior written *25* authorization. *26****************************************************************************/2728/****************************************************************************29* Author: Juergen Pfeifer <[email protected]> 1995,1997 *30****************************************************************************/3132#include "form.priv.h"3334MODULE_ID("$Id$")3536/* this can't be readonly */37static FIELD default_field = {380, /* status */390, /* rows */400, /* cols */410, /* frow */420, /* fcol */430, /* drows */440, /* dcols */450, /* maxgrow*/460, /* nrow */470, /* nbuf */48NO_JUSTIFICATION, /* just */490, /* page */500, /* index */51(int)' ', /* pad */52A_NORMAL, /* fore */53A_NORMAL, /* back */54ALL_FIELD_OPTS, /* opts */55(FIELD *)0, /* snext */56(FIELD *)0, /* sprev */57(FIELD *)0, /* link */58(FORM *)0, /* form */59(FIELDTYPE *)0, /* type */60(char *)0, /* arg */61(char *)0, /* buf */62(char *)0 /* usrptr */63};6465FIELD *_nc_Default_Field = &default_field;6667/*---------------------------------------------------------------------------68| Facility : libnform69| Function : TypeArgument *_nc_Make_Argument(70| const FIELDTYPE *typ,71| va_list *ap,72| int *err )73|74| Description : Create an argument structure for the specified type.75| Use the type-dependent argument list to construct76| it.77|78| Return Values : Pointer to argument structure. Maybe NULL.79| In case of an error in *err an errorcounter is increased.80+--------------------------------------------------------------------------*/81TypeArgument*82_nc_Make_Argument(const FIELDTYPE *typ, va_list *ap, int *err)83{84TypeArgument *res = (TypeArgument *)0;85TypeArgument *p;8687if (typ && (typ->status & _HAS_ARGS))88{89assert(err && ap);90if (typ->status & _LINKED_TYPE)91{92p = (TypeArgument *)malloc(sizeof(TypeArgument));93if (p)94{95p->left = _nc_Make_Argument(typ->left ,ap,err);96p->right = _nc_Make_Argument(typ->right,ap,err);97return p;98}99else100*err += 1;101} else102{103assert(typ->makearg != 0);104if ( !(res=(TypeArgument *)typ->makearg(ap)) )105*err += 1;106}107}108return res;109}110111/*---------------------------------------------------------------------------112| Facility : libnform113| Function : TypeArgument *_nc_Copy_Argument(const FIELDTYPE *typ,114| const TypeArgument *argp,115| int *err )116|117| Description : Create a copy of an argument structure for the specified118| type.119|120| Return Values : Pointer to argument structure. Maybe NULL.121| In case of an error in *err an errorcounter is increased.122+--------------------------------------------------------------------------*/123TypeArgument*124_nc_Copy_Argument(const FIELDTYPE *typ,125const TypeArgument *argp, int *err)126{127TypeArgument *res = (TypeArgument *)0;128TypeArgument *p;129130if ( typ && (typ->status & _HAS_ARGS) )131{132assert(err && argp);133if (typ->status & _LINKED_TYPE)134{135p = (TypeArgument *)malloc(sizeof(TypeArgument));136if (p)137{138p->left = _nc_Copy_Argument(typ,argp->left ,err);139p->right = _nc_Copy_Argument(typ,argp->right,err);140return p;141}142*err += 1;143}144else145{146if (typ->copyarg)147{148if (!(res = (TypeArgument *)(typ->copyarg((const void *)argp))))149*err += 1;150}151else152res = (TypeArgument *)argp;153}154}155return res;156}157158/*---------------------------------------------------------------------------159| Facility : libnform160| Function : void _nc_Free_Argument(const FIELDTYPE *typ,161| TypeArgument * argp )162|163| Description : Release memory associated with the argument structure164| for the given fieldtype.165|166| Return Values : -167+--------------------------------------------------------------------------*/168void169_nc_Free_Argument(const FIELDTYPE * typ, TypeArgument * argp)170{171if (!typ || !(typ->status & _HAS_ARGS))172return;173174if (typ->status & _LINKED_TYPE)175{176assert(argp != 0);177_nc_Free_Argument(typ->left ,argp->left );178_nc_Free_Argument(typ->right,argp->right);179free(argp);180}181else182{183if (typ->freearg)184typ->freearg((void *)argp);185}186}187188/*---------------------------------------------------------------------------189| Facility : libnform190| Function : bool _nc_Copy_Type( FIELD *dst, FIELD const *src )191|192| Description : Copy argument structure of field src to field dst193|194| Return Values : TRUE - copy worked195| FALSE - error occurred196+--------------------------------------------------------------------------*/197bool198_nc_Copy_Type(FIELD *dst, FIELD const *src)199{200int err = 0;201202assert(dst && src);203204dst->type = src->type;205dst->arg = (void *)_nc_Copy_Argument(src->type,(TypeArgument *)(src->arg),&err);206207if (err)208{209_nc_Free_Argument(dst->type,(TypeArgument *)(dst->arg));210dst->type = (FIELDTYPE *)0;211dst->arg = (void *)0;212return FALSE;213}214else215{216if (dst->type)217dst->type->ref++;218return TRUE;219}220}221222/*---------------------------------------------------------------------------223| Facility : libnform224| Function : void _nc_Free_Type( FIELD *field )225|226| Description : Release Argument structure for this field227|228| Return Values : -229+--------------------------------------------------------------------------*/230void231_nc_Free_Type(FIELD *field)232{233assert(field != 0);234if (field->type)235field->type->ref--;236_nc_Free_Argument(field->type,(TypeArgument *)(field->arg));237}238239/*---------------------------------------------------------------------------240| Facility : libnform241| Function : FIELD *new_field( int rows, int cols,242| int frow, int fcol,243| int nrow, int nbuf )244|245| Description : Create a new field with this many 'rows' and 'cols',246| starting at 'frow/fcol' in the subwindow of the form.247| Allocate 'nrow' off-screen rows and 'nbuf' additional248| buffers. If an error occurs, errno is set to249|250| E_BAD_ARGUMENT - invalid argument251| E_SYSTEM_ERROR - system error252|253| Return Values : Pointer to the new field or NULL if failure.254+--------------------------------------------------------------------------*/255FIELD *new_field(int rows, int cols, int frow, int fcol, int nrow, int nbuf)256{257FIELD *New_Field = (FIELD *)0;258int err = E_BAD_ARGUMENT;259260if (rows>0 &&261cols>0 &&262frow>=0 &&263fcol>=0 &&264nrow>=0 &&265nbuf>=0 &&266((err = E_SYSTEM_ERROR) != 0) && /* trick: this resets the default error */267(New_Field=(FIELD *)malloc(sizeof(FIELD))) )268{269*New_Field = default_field;270New_Field->rows = rows;271New_Field->cols = cols;272New_Field->drows = rows + nrow;273New_Field->dcols = cols;274New_Field->frow = frow;275New_Field->fcol = fcol;276New_Field->nrow = nrow;277New_Field->nbuf = nbuf;278New_Field->link = New_Field;279280if (_nc_Copy_Type(New_Field,&default_field))281{282size_t len;283284len = Total_Buffer_Size(New_Field);285if ((New_Field->buf = (char *)malloc(len)))286{287/* Prefill buffers with blanks and insert terminating zeroes288between buffers */289int i;290291memset(New_Field->buf,' ',len);292for(i=0;i<=New_Field->nbuf;i++)293{294New_Field->buf[(New_Field->drows*New_Field->cols+1)*(i+1)-1]295= '\0';296}297return New_Field;298}299}300}301302if (New_Field)303free_field(New_Field);304305SET_ERROR( err );306return (FIELD *)0;307}308309/*---------------------------------------------------------------------------310| Facility : libnform311| Function : int free_field( FIELD *field )312|313| Description : Frees the storage allocated for the field.314|315| Return Values : E_OK - success316| E_BAD_ARGUMENT - invalid field pointer317| E_CONNECTED - field is connected318+--------------------------------------------------------------------------*/319int free_field(FIELD * field)320{321if (!field)322RETURN(E_BAD_ARGUMENT);323324if (field->form)325RETURN(E_CONNECTED);326327if (field == field->link)328{329if (field->buf)330free(field->buf);331}332else333{334FIELD *f;335336for(f=field;f->link != field;f = f->link)337{}338f->link = field->link;339}340_nc_Free_Type(field);341free(field);342RETURN(E_OK);343}344345/* fld_def.c ends here */346347348