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 *
new_fieldtype(PTF_int fcheck,PTF_int ccheck)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 *
link_fieldtype(FIELDTYPE * left,FIELDTYPE * right)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
free_fieldtype(FIELDTYPE * t)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
set_fieldtype_arg(FIELDTYPE * t,PTF_charP makearg,PTF_charP copyarg,PTF_void freearg)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
set_fieldtype_choice(FIELDTYPE * t,PTF_int next,PTF_int prev)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 *
_makearg(FIELDTYPE * t,va_list * ap,int * err)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 *
_copyarg(FIELDTYPE * t,char * arg,int * err)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
_freearg(FIELDTYPE * t,char * arg)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
_checkfield(FIELDTYPE * t,FIELD * f,char * arg)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
_checkchar(FIELDTYPE * t,int c,char * arg)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
_nextchoice(FIELDTYPE * t,FIELD * f,char * arg)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
_prevchoice(FIELDTYPE * t,FIELD * f,char * arg)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