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 39 typedef 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 63 static 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 78 FIELDTYPE * _DEFAULT_FIELDTYPE = &default_fieldtype; 79 80 /* new_fieldtype - field & character validation function */ 81 FIELDTYPE * 82 new_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 95 FIELDTYPE * 96 link_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 119 int 120 free_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 136 int 137 set_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 */ 151 int 152 set_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 163 char * 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 191 char * 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. */ 220 void 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. */ 235 int 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. */ 259 int 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. */ 275 int 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. */ 289 int 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