OpenSolaris_b135/lib/libeti/form/common/fieldtype.c

Compare this file to the similar file:
Show the results in this format:

/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*	Copyright (c) 1988 AT&T	*/
/*	  All Rights Reserved  	*/


/*
 *      Copyright (c) 1997, by Sun Microsystems, Inc.
 *      All rights reserved.
 */

#pragma ident	"%Z%%M%	%I%	%E% SMI"

/*LINTLIBRARY*/

#include <sys/types.h>
#include <stdlib.h>
#include "utility.h"

typedef struct {
	char *leftarg;
	char *rightarg;
}
	LINK;

#define	ArgL(n)		(((LINK *)(n))->leftarg)
#define	ArgR(n)		(((LINK *)(n))->rightarg)

#define	Ref(t)		((t)->ref)
#define	TypeL(t)	((t)->left)
#define	TypeR(t)	((t)->right)
#define	MakeA(t)	((t)->makearg)
#define	CopyA(t)	((t)->copyarg)
#define	FreeA(t)	((t)->freearg)
#define	Fcheck(t)	((t)->fcheck)
#define	Ccheck(t)	((t)->ccheck)
#define	Next(t)		((t)->next)
#define	Prev(t)		((t)->prev)

	/*
	 *  default fieldtype
	 */

static FIELDTYPE default_fieldtype =
{
			0,			/* status	*/
			0,			/* ref		*/
			(FIELDTYPE *) 0,	/* left		*/
			(FIELDTYPE *) 0,	/* right	*/
			(PTF_charP) 0,		/* makearg	*/
			(PTF_charP) 0,		/* copyarg	*/
			(PTF_void) 0,		/* freearg	*/
			(PTF_int) 0,		/* fcheck	*/
			(PTF_int) 0,		/* ccheck	*/
			(PTF_int) 0,		/* next		*/
			(PTF_int) 0,		/* prev		*/
};

FIELDTYPE * _DEFAULT_FIELDTYPE	= &default_fieldtype;

/* new_fieldtype - field & character validation function */
FIELDTYPE *
new_fieldtype(PTF_int fcheck, PTF_int ccheck)
{
	FIELDTYPE *t = (FIELDTYPE *) 0;

	if ((fcheck || ccheck) && Alloc(t, FIELDTYPE)) {
		*t = *_DEFAULT_FIELDTYPE;

		Fcheck(t) = fcheck;
		Ccheck(t) = ccheck;
	}
	return (t);
}

FIELDTYPE *
link_fieldtype(FIELDTYPE *left, FIELDTYPE *right)
{
	FIELDTYPE *t = (FIELDTYPE *) 0;

	if ((left || right) && Alloc(t, FIELDTYPE)) {
		*t = *_DEFAULT_FIELDTYPE;

		Set(t, LINKED);

		if (Status(left, ARGS) || Status(right, ARGS))
			Set(t, ARGS);

		if (Status(left, CHOICE) || Status(right, CHOICE))
			Set(t, CHOICE);

		TypeL(t) = left;
		TypeR(t) = right;
		IncrType(left);	/* increment reference count */
		IncrType(right);	/* increment reference count */
	}
	return (t);
}

int
free_fieldtype(FIELDTYPE *t)
{
	if (!t)
		return (E_BAD_ARGUMENT);

	if (Ref(t))
		return (E_CONNECTED);

	if (Status(t, LINKED)) {
		DecrType(TypeL(t));	/* decrement reference count */
		DecrType(TypeR(t));	/* decrement reference count */
	}
	Free(t);
	return (E_OK);
}

int
set_fieldtype_arg(FIELDTYPE *t, PTF_charP makearg,
	PTF_charP copyarg, PTF_void freearg)
{
	if (t && makearg && copyarg && freearg) {
		Set(t, ARGS);
		MakeA(t) = makearg;
		CopyA(t) = copyarg;
		FreeA(t) = freearg;
		return (E_OK);
	}
	return (E_BAD_ARGUMENT);
}

/* set_fieldtype_choice next & prev choice function */
int
set_fieldtype_choice(FIELDTYPE *t, PTF_int next, PTF_int prev)
{
	if (t && next && prev) {
		Set(t, CHOICE);
		Next(t) = next;
		Prev(t) = prev;
		return (E_OK);
	}
	return (E_BAD_ARGUMENT);
}

char *
_makearg(FIELDTYPE *t, va_list *ap, int *err)
{
/*
 * invoke make_arg function associated with field type t.
 * return pointer to argument information or null if none.
 * increment err if an error is encountered.
 */
	char *p = (char *)0;

	if (! t || ! Status(t, ARGS))
		return (p);

	if (Status(t, LINKED)) {
		LINK *n = (LINK *) 0;

		if (Alloc(n, LINK)) {
			ArgL(n) = _makearg(TypeL(t), ap, err);
			ArgR(n) = _makearg(TypeR(t), ap, err);
			p = (char *)n;
		} else
			++(*err);		/* out of space */
	} else
		if (!(p = (*MakeA(t)) (ap)))
			++(*err);		/* make_arg had problem */
	return (p);
}

char *
_copyarg(FIELDTYPE *t, char *arg, int *err)
{
/*
 * invoke copy_arg function associated with field type t.
 * return pointer to argument information or null if none.
 * increment err if an error is encountered.
 */
	char *p = (char *)0;

	if (!t || !Status(t, ARGS))
		return (p);

	if (Status(t, LINKED)) {
		LINK *n = (LINK *) 0;

		if (Alloc(n, LINK)) {
			ArgL(n) = _copyarg(TypeL(t), ArgL(arg), err);
			ArgR(n) = _copyarg(TypeR(t), ArgR(arg), err);
			p = (char *)n;
		} else
			++(*err);		/* out of space */
	} else
		if (!(p = (*CopyA(t)) (arg)))
			++(*err);		/* copy_arg had problem */
	return (p);
}

/* _freearg - invoke free_arg function associated with field type t.  */
void
_freearg(FIELDTYPE *t, char *arg)
{
	if (!t || !Status(t, ARGS))
		return;

	if (Status(t, LINKED)) {
		_freearg(TypeL(t), ArgL(arg));
		_freearg(TypeR(t), ArgR(arg));
		Free(arg);
	} else
		(*FreeA(t)) (arg);
}

/* _checkfield - invoke check_field function associated with field type t.  */
int
_checkfield(FIELDTYPE *t, FIELD *f, char *arg)
{
	if (!t)
		return (TRUE);

	if (Opt(f, O_NULLOK)) {
		char *v = Buf(f);

		while (*v && *v == ' ')
			++v;
		if (!*v)
			return (TRUE);	/* empty field */
	}
	if (Status(t, LINKED))
		return	(_checkfield(TypeL(t), f, ArgL(arg)) ||
		    _checkfield(TypeR(t), f, ArgR(arg)));
	else
		if (Fcheck(t))
			return ((*Fcheck(t)) (f, arg));
	return (TRUE);
}

/* _checkchar - invoke check_char function associated with field type t.  */
int
_checkchar(FIELDTYPE *t, int c, char *arg)
{
	if (!t)
		return (TRUE);

	if (Status(t, LINKED))
		return	(_checkchar(TypeL(t), c, ArgL(arg)) ||
		    _checkchar(TypeR(t), c, ArgR(arg)));
	else
		if (Ccheck(t))
			return ((*Ccheck(t)) (c, arg));
	return (TRUE);
}

/* _nextchoice - invoke next_choice function associated with field type t.  */
int
_nextchoice(FIELDTYPE *t, FIELD *f, char *arg)
{
	if (!t || !Status(t, CHOICE))
		return (FALSE);

	if (Status(t, LINKED))
		return	(_nextchoice(TypeL(t), f, ArgL(arg)) ||
		    _nextchoice(TypeR(t), f, ArgR(arg)));
	else
		return ((*Next(t)) (f, arg));
}

/* _prevchoice - invoke prev_choice function associated with field type t. */
int
_prevchoice(FIELDTYPE *t, FIELD *f, char *arg)
{
	if (!t || !Status(t, CHOICE))
		return (FALSE);

	if (Status(t, LINKED))
		return	(_prevchoice(TypeL(t), f, ArgL(arg)) ||
		    _prevchoice(TypeR(t), f, ArgR(arg)));
	else
		return ((*Prev(t)) (f, arg));
}