1 /* $OpenBSD: fld_def.c,v 1.7 2003/11/08 19:17:27 jmc Exp $ */ 2 3 /**************************************************************************** 4 * Copyright (c) 1998,2000 Free Software Foundation, Inc. * 5 * * 6 * Permission is hereby granted, free of charge, to any person obtaining a * 7 * copy of this software and associated documentation files (the * 8 * "Software"), to deal in the Software without restriction, including * 9 * without limitation the rights to use, copy, modify, merge, publish, * 10 * distribute, distribute with modifications, sublicense, and/or sell * 11 * copies of the Software, and to permit persons to whom the Software is * 12 * furnished to do so, subject to the following conditions: * 13 * * 14 * The above copyright notice and this permission notice shall be included * 15 * in all copies or substantial portions of the Software. * 16 * * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 20 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 23 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 24 * * 25 * Except as contained in this notice, the name(s) of the above copyright * 26 * holders shall not be used in advertising or otherwise to promote the * 27 * sale, use or other dealings in this Software without prior written * 28 * authorization. * 29 ****************************************************************************/ 30 31 /**************************************************************************** 32 * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 * 33 ****************************************************************************/ 34 35 #include "form.priv.h" 36 37 MODULE_ID("$From: fld_def.c,v 1.13 2000/12/10 02:09:38 tom Exp $") 38 39 /* this can't be readonly */ 40 static FIELD default_field = { 41 0, /* status */ 42 0, /* rows */ 43 0, /* cols */ 44 0, /* frow */ 45 0, /* fcol */ 46 0, /* drows */ 47 0, /* dcols */ 48 0, /* maxgrow*/ 49 0, /* nrow */ 50 0, /* nbuf */ 51 NO_JUSTIFICATION, /* just */ 52 0, /* page */ 53 0, /* index */ 54 (int)' ', /* pad */ 55 A_NORMAL, /* fore */ 56 A_NORMAL, /* back */ 57 ALL_FIELD_OPTS, /* opts */ 58 (FIELD *)0, /* snext */ 59 (FIELD *)0, /* sprev */ 60 (FIELD *)0, /* link */ 61 (FORM *)0, /* form */ 62 (FIELDTYPE *)0, /* type */ 63 (char *)0, /* arg */ 64 (char *)0, /* buf */ 65 (char *)0 /* usrptr */ 66 }; 67 68 NCURSES_EXPORT_VAR(FIELD *) _nc_Default_Field = &default_field; 69 70 /*--------------------------------------------------------------------------- 71 | Facility : libnform 72 | Function : TypeArgument *_nc_Make_Argument( 73 | const FIELDTYPE *typ, 74 | va_list *ap, 75 | int *err ) 76 | 77 | Description : Create an argument structure for the specified type. 78 | Use the type-dependent argument list to construct 79 | it. 80 | 81 | Return Values : Pointer to argument structure. Maybe NULL. 82 | In case of an error in *err an errorcounter is increased. 83 +--------------------------------------------------------------------------*/ 84 NCURSES_EXPORT(TypeArgument*) 85 _nc_Make_Argument 86 (const FIELDTYPE *typ, va_list *ap, int *err) 87 { 88 TypeArgument *res = (TypeArgument *)0; 89 TypeArgument *p; 90 91 if (typ && (typ->status & _HAS_ARGS)) 92 { 93 assert(err && ap); 94 if (typ->status & _LINKED_TYPE) 95 { 96 p = (TypeArgument *)malloc(sizeof(TypeArgument)); 97 if (p) 98 { 99 p->left = _nc_Make_Argument(typ->left ,ap,err); 100 p->right = _nc_Make_Argument(typ->right,ap,err); 101 return p; 102 } 103 else 104 *err += 1; 105 } else 106 { 107 assert(typ->makearg); 108 if ( !(res=(TypeArgument *)typ->makearg(ap)) ) 109 *err += 1; 110 } 111 } 112 return res; 113 } 114 115 /*--------------------------------------------------------------------------- 116 | Facility : libnform 117 | Function : TypeArgument *_nc_Copy_Argument(const FIELDTYPE *typ, 118 | const TypeArgument *argp, 119 | int *err ) 120 | 121 | Description : Create a copy of an argument structure for the specified 122 | type. 123 | 124 | Return Values : Pointer to argument structure. Maybe NULL. 125 | In case of an error in *err an errorcounter is increased. 126 +--------------------------------------------------------------------------*/ 127 NCURSES_EXPORT(TypeArgument*) 128 _nc_Copy_Argument 129 (const FIELDTYPE *typ, 130 const TypeArgument *argp, int *err) 131 { 132 TypeArgument *res = (TypeArgument *)0; 133 TypeArgument *p; 134 135 if ( typ && (typ->status & _HAS_ARGS) ) 136 { 137 assert(err && argp); 138 if (typ->status & _LINKED_TYPE) 139 { 140 p = (TypeArgument *)malloc(sizeof(TypeArgument)); 141 if (p) 142 { 143 p->left = _nc_Copy_Argument(typ,argp->left ,err); 144 p->right = _nc_Copy_Argument(typ,argp->right,err); 145 return p; 146 } 147 *err += 1; 148 } 149 else 150 { 151 if (typ->copyarg) 152 { 153 if (!(res = (TypeArgument *)(typ->copyarg((const void *)argp)))) 154 *err += 1; 155 } 156 else 157 res = (TypeArgument *)argp; 158 } 159 } 160 return res; 161 } 162 163 /*--------------------------------------------------------------------------- 164 | Facility : libnform 165 | Function : void _nc_Free_Argument(const FIELDTYPE *typ, 166 | TypeArgument * argp ) 167 | 168 | Description : Release memory associated with the argument structure 169 | for the given fieldtype. 170 | 171 | Return Values : - 172 +--------------------------------------------------------------------------*/ 173 NCURSES_EXPORT(void) 174 _nc_Free_Argument 175 (const FIELDTYPE * typ, TypeArgument * argp) 176 { 177 if (!typ || !(typ->status & _HAS_ARGS)) 178 return; 179 180 if (typ->status & _LINKED_TYPE) 181 { 182 assert(argp); 183 _nc_Free_Argument(typ->left ,argp->left ); 184 _nc_Free_Argument(typ->right,argp->right); 185 free(argp); 186 } 187 else 188 { 189 if (typ->freearg) 190 typ->freearg((void *)argp); 191 } 192 } 193 194 /*--------------------------------------------------------------------------- 195 | Facility : libnform 196 | Function : bool _nc_Copy_Type( FIELD *dst, FIELD const *src ) 197 | 198 | Description : Copy argument structure of field src to field dst 199 | 200 | Return Values : TRUE - copy worked 201 | FALSE - error occured 202 +--------------------------------------------------------------------------*/ 203 NCURSES_EXPORT(bool) 204 _nc_Copy_Type 205 (FIELD *dst, FIELD const *src) 206 { 207 int err = 0; 208 209 assert(dst && src); 210 211 dst->type = src->type; 212 dst->arg = (void *)_nc_Copy_Argument(src->type,(TypeArgument *)(src->arg),&err); 213 214 if (err) 215 { 216 _nc_Free_Argument(dst->type,(TypeArgument *)(dst->arg)); 217 dst->type = (FIELDTYPE *)0; 218 dst->arg = (void *)0; 219 return FALSE; 220 } 221 else 222 { 223 if (dst->type) 224 dst->type->ref++; 225 return TRUE; 226 } 227 } 228 229 /*--------------------------------------------------------------------------- 230 | Facility : libnform 231 | Function : void _nc_Free_Type( FIELD *field ) 232 | 233 | Description : Release Argument structure for this field 234 | 235 | Return Values : - 236 +--------------------------------------------------------------------------*/ 237 NCURSES_EXPORT(void) 238 _nc_Free_Type (FIELD *field) 239 { 240 assert(field); 241 if (field->type) 242 field->type->ref--; 243 _nc_Free_Argument(field->type,(TypeArgument *)(field->arg)); 244 } 245 246 /*--------------------------------------------------------------------------- 247 | Facility : libnform 248 | Function : FIELD *new_field( int rows, int cols, 249 | int frow, int fcol, 250 | int nrow, int nbuf ) 251 | 252 | Description : Create a new field with this many 'rows' and 'cols', 253 | starting at 'frow/fcol' in the subwindow of the form. 254 | Allocate 'nrow' off-screen rows and 'nbuf' additional 255 | buffers. If an error occurs, errno is set to 256 | 257 | E_BAD_ARGUMENT - invalid argument 258 | E_SYSTEM_ERROR - system error 259 | 260 | Return Values : Pointer to the new field or NULL if failure. 261 +--------------------------------------------------------------------------*/ 262 NCURSES_EXPORT(FIELD *) 263 new_field 264 (int rows, int cols, int frow, int fcol, int nrow, int nbuf) 265 { 266 FIELD *New_Field = (FIELD *)0; 267 int err = E_BAD_ARGUMENT; 268 269 if (rows>0 && 270 cols>0 && 271 frow>=0 && 272 fcol>=0 && 273 nrow>=0 && 274 nbuf>=0 && 275 ((err = E_SYSTEM_ERROR) != 0) && /* trick: this resets the default error */ 276 (New_Field=(FIELD *)malloc(sizeof(FIELD))) ) 277 { 278 *New_Field = default_field; 279 New_Field->rows = rows; 280 New_Field->cols = cols; 281 New_Field->drows = rows + nrow; 282 New_Field->dcols = cols; 283 New_Field->frow = frow; 284 New_Field->fcol = fcol; 285 New_Field->nrow = nrow; 286 New_Field->nbuf = nbuf; 287 New_Field->link = New_Field; 288 289 if (_nc_Copy_Type(New_Field,&default_field)) 290 { 291 size_t len; 292 293 len = Total_Buffer_Size(New_Field); 294 if ((New_Field->buf = (char *)malloc(len))) 295 { 296 /* Prefill buffers with blanks and insert terminating zeroes 297 between buffers */ 298 int i; 299 300 memset(New_Field->buf,' ',len); 301 for(i=0;i<=New_Field->nbuf;i++) 302 { 303 New_Field->buf[(New_Field->drows*New_Field->cols+1)*(i+1)-1] 304 = '\0'; 305 } 306 return New_Field; 307 } 308 } 309 } 310 311 if (New_Field) 312 free_field(New_Field); 313 314 SET_ERROR( err ); 315 return (FIELD *)0; 316 } 317 318 /*--------------------------------------------------------------------------- 319 | Facility : libnform 320 | Function : int free_field( FIELD *field ) 321 | 322 | Description : Frees the storage allocated for the field. 323 | 324 | Return Values : E_OK - success 325 | E_BAD_ARGUMENT - invalid field pointer 326 | E_CONNECTED - field is connected 327 +--------------------------------------------------------------------------*/ 328 NCURSES_EXPORT(int) 329 free_field (FIELD * field) 330 { 331 if (!field) 332 RETURN(E_BAD_ARGUMENT); 333 334 if (field->form) 335 RETURN(E_CONNECTED); 336 337 if (field == field->link) 338 { 339 if (field->buf) 340 free(field->buf); 341 } 342 else 343 { 344 FIELD *f; 345 346 for(f=field;f->link != field;f = f->link) 347 {} 348 f->link = field->link; 349 } 350 _nc_Free_Type(field); 351 free(field); 352 RETURN(E_OK); 353 } 354 355 /* fld_def.c ends here */ 356