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