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 /*LINTLIBRARY*/ 32 33 #include <sys/types.h> 34 #include <stdlib.h> 35 #include "utility.h" 36 37 typedef struct { 38 char *leftarg; 39 char *rightarg; 40 } 41 LINK; 42 43 #define ArgL(n) (((LINK *)(n))->leftarg) 44 #define ArgR(n) (((LINK *)(n))->rightarg) 45 46 #define Ref(t) ((t)->ref) 47 #define TypeL(t) ((t)->left) 48 #define TypeR(t) ((t)->right) 49 #define MakeA(t) ((t)->makearg) 50 #define CopyA(t) ((t)->copyarg) 51 #define FreeA(t) ((t)->freearg) 52 #define Fcheck(t) ((t)->fcheck) 53 #define Ccheck(t) ((t)->ccheck) 54 #define Next(t) ((t)->next) 55 #define Prev(t) ((t)->prev) 56 57 /* 58 * default fieldtype 59 */ 60 61 static FIELDTYPE default_fieldtype = 62 { 63 0, /* status */ 64 0, /* ref */ 65 (FIELDTYPE *) 0, /* left */ 66 (FIELDTYPE *) 0, /* right */ 67 (PTF_charP) 0, /* makearg */ 68 (PTF_charP) 0, /* copyarg */ 69 (PTF_void) 0, /* freearg */ 70 (PTF_int) 0, /* fcheck */ 71 (PTF_int) 0, /* ccheck */ 72 (PTF_int) 0, /* next */ 73 (PTF_int) 0, /* prev */ 74 }; 75 76 FIELDTYPE * _DEFAULT_FIELDTYPE = &default_fieldtype; 77 78 /* new_fieldtype - field & character validation function */ 79 FIELDTYPE * 80 new_fieldtype(PTF_int fcheck, PTF_int ccheck) 81 { 82 FIELDTYPE *t = (FIELDTYPE *) 0; 83 84 if ((fcheck || ccheck) && Alloc(t, FIELDTYPE)) { 85 *t = *_DEFAULT_FIELDTYPE; 86 87 Fcheck(t) = fcheck; 88 Ccheck(t) = ccheck; 89 } 90 return (t); 91 } 92 93 FIELDTYPE * 94 link_fieldtype(FIELDTYPE *left, FIELDTYPE *right) 95 { 96 FIELDTYPE *t = (FIELDTYPE *) 0; 97 98 if ((left || right) && Alloc(t, FIELDTYPE)) { 99 *t = *_DEFAULT_FIELDTYPE; 100 101 Set(t, LINKED); 102 103 if (Status(left, ARGS) || Status(right, ARGS)) 104 Set(t, ARGS); 105 106 if (Status(left, CHOICE) || Status(right, CHOICE)) 107 Set(t, CHOICE); 108 109 TypeL(t) = left; 110 TypeR(t) = right; 111 IncrType(left); /* increment reference count */ 112 IncrType(right); /* increment reference count */ 113 } 114 return (t); 115 } 116 117 int 118 free_fieldtype(FIELDTYPE *t) 119 { 120 if (!t) 121 return (E_BAD_ARGUMENT); 122 123 if (Ref(t)) 124 return (E_CONNECTED); 125 126 if (Status(t, LINKED)) { 127 DecrType(TypeL(t)); /* decrement reference count */ 128 DecrType(TypeR(t)); /* decrement reference count */ 129 } 130 Free(t); 131 return (E_OK); 132 } 133 134 int 135 set_fieldtype_arg(FIELDTYPE *t, PTF_charP makearg, 136 PTF_charP copyarg, PTF_void freearg) 137 { 138 if (t && makearg && copyarg && freearg) { 139 Set(t, ARGS); 140 MakeA(t) = makearg; 141 CopyA(t) = copyarg; 142 FreeA(t) = freearg; 143 return (E_OK); 144 } 145 return (E_BAD_ARGUMENT); 146 } 147 148 /* set_fieldtype_choice next & prev choice function */ 149 int 150 set_fieldtype_choice(FIELDTYPE *t, PTF_int next, PTF_int prev) 151 { 152 if (t && next && prev) { 153 Set(t, CHOICE); 154 Next(t) = next; 155 Prev(t) = prev; 156 return (E_OK); 157 } 158 return (E_BAD_ARGUMENT); 159 } 160 161 char * 162 _makearg(FIELDTYPE *t, va_list *ap, int *err) 163 { 164 /* 165 * invoke make_arg function associated with field type t. 166 * return pointer to argument information or null if none. 167 * increment err if an error is encountered. 168 */ 169 char *p = (char *)0; 170 171 if (! t || ! Status(t, ARGS)) 172 return (p); 173 174 if (Status(t, LINKED)) { 175 LINK *n = (LINK *) 0; 176 177 if (Alloc(n, LINK)) { 178 ArgL(n) = _makearg(TypeL(t), ap, err); 179 ArgR(n) = _makearg(TypeR(t), ap, err); 180 p = (char *)n; 181 } else 182 ++(*err); /* out of space */ 183 } else 184 if (!(p = (*MakeA(t)) (ap))) 185 ++(*err); /* make_arg had problem */ 186 return (p); 187 } 188 189 char * 190 _copyarg(FIELDTYPE *t, char *arg, int *err) 191 { 192 /* 193 * invoke copy_arg function associated with field type t. 194 * return pointer to argument information or null if none. 195 * increment err if an error is encountered. 196 */ 197 char *p = (char *)0; 198 199 if (!t || !Status(t, ARGS)) 200 return (p); 201 202 if (Status(t, LINKED)) { 203 LINK *n = (LINK *) 0; 204 205 if (Alloc(n, LINK)) { 206 ArgL(n) = _copyarg(TypeL(t), ArgL(arg), err); 207 ArgR(n) = _copyarg(TypeR(t), ArgR(arg), err); 208 p = (char *)n; 209 } else 210 ++(*err); /* out of space */ 211 } else 212 if (!(p = (*CopyA(t)) (arg))) 213 ++(*err); /* copy_arg had problem */ 214 return (p); 215 } 216 217 /* _freearg - invoke free_arg function associated with field type t. */ 218 void 219 _freearg(FIELDTYPE *t, char *arg) 220 { 221 if (!t || !Status(t, ARGS)) 222 return; 223 224 if (Status(t, LINKED)) { 225 _freearg(TypeL(t), ArgL(arg)); 226 _freearg(TypeR(t), ArgR(arg)); 227 Free(arg); 228 } else 229 (*FreeA(t)) (arg); 230 } 231 232 /* _checkfield - invoke check_field function associated with field type t. */ 233 int 234 _checkfield(FIELDTYPE *t, FIELD *f, char *arg) 235 { 236 if (!t) 237 return (TRUE); 238 239 if (Opt(f, O_NULLOK)) { 240 char *v = Buf(f); 241 242 while (*v && *v == ' ') 243 ++v; 244 if (!*v) 245 return (TRUE); /* empty field */ 246 } 247 if (Status(t, LINKED)) 248 return (_checkfield(TypeL(t), f, ArgL(arg)) || 249 _checkfield(TypeR(t), f, ArgR(arg))); 250 else 251 if (Fcheck(t)) 252 return ((*Fcheck(t)) (f, arg)); 253 return (TRUE); 254 } 255 256 /* _checkchar - invoke check_char function associated with field type t. */ 257 int 258 _checkchar(FIELDTYPE *t, int c, char *arg) 259 { 260 if (!t) 261 return (TRUE); 262 263 if (Status(t, LINKED)) 264 return (_checkchar(TypeL(t), c, ArgL(arg)) || 265 _checkchar(TypeR(t), c, ArgR(arg))); 266 else 267 if (Ccheck(t)) 268 return ((*Ccheck(t)) (c, arg)); 269 return (TRUE); 270 } 271 272 /* _nextchoice - invoke next_choice function associated with field type t. */ 273 int 274 _nextchoice(FIELDTYPE *t, FIELD *f, char *arg) 275 { 276 if (!t || !Status(t, CHOICE)) 277 return (FALSE); 278 279 if (Status(t, LINKED)) 280 return (_nextchoice(TypeL(t), f, ArgL(arg)) || 281 _nextchoice(TypeR(t), f, ArgR(arg))); 282 else 283 return ((*Next(t)) (f, arg)); 284 } 285 286 /* _prevchoice - invoke prev_choice function associated with field type t. */ 287 int 288 _prevchoice(FIELDTYPE *t, FIELD *f, char *arg) 289 { 290 if (!t || !Status(t, CHOICE)) 291 return (FALSE); 292 293 if (Status(t, LINKED)) 294 return (_prevchoice(TypeL(t), f, ArgL(arg)) || 295 _prevchoice(TypeR(t), f, ArgR(arg))); 296 else 297 return ((*Prev(t)) (f, arg)); 298 } 299