1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22/* Copyright (c) 1988 AT&T */ 23/* All Rights Reserved */ 24 25 26/* 27 * Copyright (c) 1997, by Sun Microsystems, Inc. 28 * All rights reserved. 29 */ 30 31#pragma ident "%Z%%M% %I% %E% SMI" 32 33/*LINTLIBRARY*/ 34 35#include <sys/types.h> 36#include <stdlib.h> 37#include "utility.h" 38 39typedef struct { 40 char *leftarg; 41 char *rightarg; 42} 43 LINK; 44 45#define ArgL(n) (((LINK *)(n))->leftarg) 46#define ArgR(n) (((LINK *)(n))->rightarg) 47 48#define Ref(t) ((t)->ref) 49#define TypeL(t) ((t)->left) 50#define TypeR(t) ((t)->right) 51#define MakeA(t) ((t)->makearg) 52#define CopyA(t) ((t)->copyarg) 53#define FreeA(t) ((t)->freearg) 54#define Fcheck(t) ((t)->fcheck) 55#define Ccheck(t) ((t)->ccheck) 56#define Next(t) ((t)->next) 57#define Prev(t) ((t)->prev) 58 59 /* 60 * default fieldtype 61 */ 62 63static FIELDTYPE default_fieldtype = 64{ 65 0, /* status */ 66 0, /* ref */ 67 (FIELDTYPE *) 0, /* left */ 68 (FIELDTYPE *) 0, /* right */ 69 (PTF_charP) 0, /* makearg */ 70 (PTF_charP) 0, /* copyarg */ 71 (PTF_void) 0, /* freearg */ 72 (PTF_int) 0, /* fcheck */ 73 (PTF_int) 0, /* ccheck */ 74 (PTF_int) 0, /* next */ 75 (PTF_int) 0, /* prev */ 76}; 77 78FIELDTYPE * _DEFAULT_FIELDTYPE = &default_fieldtype; 79 80/* new_fieldtype - field & character validation function */ 81FIELDTYPE * 82new_fieldtype(PTF_int fcheck, PTF_int ccheck) 83{ 84 FIELDTYPE *t = (FIELDTYPE *) 0; 85 86 if ((fcheck || ccheck) && Alloc(t, FIELDTYPE)) { 87 *t = *_DEFAULT_FIELDTYPE; 88 89 Fcheck(t) = fcheck; 90 Ccheck(t) = ccheck; 91 } 92 return (t); 93} 94 95FIELDTYPE * 96link_fieldtype(FIELDTYPE *left, FIELDTYPE *right) 97{ 98 FIELDTYPE *t = (FIELDTYPE *) 0; 99 100 if ((left || right) && Alloc(t, FIELDTYPE)) { 101 *t = *_DEFAULT_FIELDTYPE; 102 103 Set(t, LINKED); 104 105 if (Status(left, ARGS) || Status(right, ARGS)) 106 Set(t, ARGS); 107 108 if (Status(left, CHOICE) || Status(right, CHOICE)) 109 Set(t, CHOICE); 110 111 TypeL(t) = left; 112 TypeR(t) = right; 113 IncrType(left); /* increment reference count */ 114 IncrType(right); /* increment reference count */ 115 } 116 return (t); 117} 118 119int 120free_fieldtype(FIELDTYPE *t) 121{ 122 if (!t) 123 return (E_BAD_ARGUMENT); 124 125 if (Ref(t)) 126 return (E_CONNECTED); 127 128 if (Status(t, LINKED)) { 129 DecrType(TypeL(t)); /* decrement reference count */ 130 DecrType(TypeR(t)); /* decrement reference count */ 131 } 132 Free(t); 133 return (E_OK); 134} 135 136int 137set_fieldtype_arg(FIELDTYPE *t, PTF_charP makearg, 138 PTF_charP copyarg, PTF_void freearg) 139{ 140 if (t && makearg && copyarg && freearg) { 141 Set(t, ARGS); 142 MakeA(t) = makearg; 143 CopyA(t) = copyarg; 144 FreeA(t) = freearg; 145 return (E_OK); 146 } 147 return (E_BAD_ARGUMENT); 148} 149 150/* set_fieldtype_choice next & prev choice function */ 151int 152set_fieldtype_choice(FIELDTYPE *t, PTF_int next, PTF_int prev) 153{ 154 if (t && next && prev) { 155 Set(t, CHOICE); 156 Next(t) = next; 157 Prev(t) = prev; 158 return (E_OK); 159 } 160 return (E_BAD_ARGUMENT); 161} 162 163char * 164_makearg(FIELDTYPE *t, va_list *ap, int *err) 165{ 166/* 167 * invoke make_arg function associated with field type t. 168 * return pointer to argument information or null if none. 169 * increment err if an error is encountered. 170 */ 171 char *p = (char *)0; 172 173 if (! t || ! Status(t, ARGS)) 174 return (p); 175 176 if (Status(t, LINKED)) { 177 LINK *n = (LINK *) 0; 178 179 if (Alloc(n, LINK)) { 180 ArgL(n) = _makearg(TypeL(t), ap, err); 181 ArgR(n) = _makearg(TypeR(t), ap, err); 182 p = (char *)n; 183 } else 184 ++(*err); /* out of space */ 185 } else 186 if (!(p = (*MakeA(t)) (ap))) 187 ++(*err); /* make_arg had problem */ 188 return (p); 189} 190 191char * 192_copyarg(FIELDTYPE *t, char *arg, int *err) 193{ 194/* 195 * invoke copy_arg function associated with field type t. 196 * return pointer to argument information or null if none. 197 * increment err if an error is encountered. 198 */ 199 char *p = (char *)0; 200 201 if (!t || !Status(t, ARGS)) 202 return (p); 203 204 if (Status(t, LINKED)) { 205 LINK *n = (LINK *) 0; 206 207 if (Alloc(n, LINK)) { 208 ArgL(n) = _copyarg(TypeL(t), ArgL(arg), err); 209 ArgR(n) = _copyarg(TypeR(t), ArgR(arg), err); 210 p = (char *)n; 211 } else 212 ++(*err); /* out of space */ 213 } else 214 if (!(p = (*CopyA(t)) (arg))) 215 ++(*err); /* copy_arg had problem */ 216 return (p); 217} 218 219/* _freearg - invoke free_arg function associated with field type t. */ 220void 221_freearg(FIELDTYPE *t, char *arg) 222{ 223 if (!t || !Status(t, ARGS)) 224 return; 225 226 if (Status(t, LINKED)) { 227 _freearg(TypeL(t), ArgL(arg)); 228 _freearg(TypeR(t), ArgR(arg)); 229 Free(arg); 230 } else 231 (*FreeA(t)) (arg); 232} 233 234/* _checkfield - invoke check_field function associated with field type t. */ 235int 236_checkfield(FIELDTYPE *t, FIELD *f, char *arg) 237{ 238 if (!t) 239 return (TRUE); 240 241 if (Opt(f, O_NULLOK)) { 242 char *v = Buf(f); 243 244 while (*v && *v == ' ') 245 ++v; 246 if (!*v) 247 return (TRUE); /* empty field */ 248 } 249 if (Status(t, LINKED)) 250 return (_checkfield(TypeL(t), f, ArgL(arg)) || 251 _checkfield(TypeR(t), f, ArgR(arg))); 252 else 253 if (Fcheck(t)) 254 return ((*Fcheck(t)) (f, arg)); 255 return (TRUE); 256} 257 258/* _checkchar - invoke check_char function associated with field type t. */ 259int 260_checkchar(FIELDTYPE *t, int c, char *arg) 261{ 262 if (!t) 263 return (TRUE); 264 265 if (Status(t, LINKED)) 266 return (_checkchar(TypeL(t), c, ArgL(arg)) || 267 _checkchar(TypeR(t), c, ArgR(arg))); 268 else 269 if (Ccheck(t)) 270 return ((*Ccheck(t)) (c, arg)); 271 return (TRUE); 272} 273 274/* _nextchoice - invoke next_choice function associated with field type t. */ 275int 276_nextchoice(FIELDTYPE *t, FIELD *f, char *arg) 277{ 278 if (!t || !Status(t, CHOICE)) 279 return (FALSE); 280 281 if (Status(t, LINKED)) 282 return (_nextchoice(TypeL(t), f, ArgL(arg)) || 283 _nextchoice(TypeR(t), f, ArgR(arg))); 284 else 285 return ((*Next(t)) (f, arg)); 286} 287 288/* _prevchoice - invoke prev_choice function associated with field type t. */ 289int 290_prevchoice(FIELDTYPE *t, FIELD *f, char *arg) 291{ 292 if (!t || !Status(t, CHOICE)) 293 return (FALSE); 294 295 if (Status(t, LINKED)) 296 return (_prevchoice(TypeL(t), f, ArgL(arg)) || 297 _prevchoice(TypeR(t), f, ArgR(arg))); 298 else 299 return ((*Prev(t)) (f, arg)); 300} 301