OpenSolaris_b135/lib/libtnfprobe/tnf_args.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) 1994, by Sun Microsytems, Inc.
 */

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

#ifndef DEBUG
#define	NDEBUG	1
#endif

#include "tnf_trace.h"
#include "tnf_types.h"
#include "tnf_args.h"
#include <string.h>
#include <assert.h>

/*
 * tnf_probe_get_num_args: returns the number of arguments at probe site
 * probe_p.  This includes the first 2 args (tag and time delta) in the return
 * value.
 */
int
tnf_probe_get_num_args(tnf_probe_control_t *probe_p)
{
	int count = 0;
	tnf_tag_data_t ***tag_p;

	tag_p = probe_p->slot_types;
	while (*tag_p) {
		count++;
		tag_p++;
	}
	return (count);
}

/*
 * tnf_probe_get_arg_indexed: returns a pointer into the buffer where
 * argument i is stored.  Returns NULL on error.  Argument numbering is
 * zero based i.e. to get the 3rd argument, the input value should be 2.
 */

/* ALIGN_ROUNDUP: y has to be one less than a power of 2 eg. 3, 7, 15, etc. */
#define	ALIGN_ROUNDUP(x, y) (((x) + (y)) & ~(y))

void *
tnf_probe_get_arg_indexed(tnf_probe_control_t *probe_p, int index, void *buffer)
{
	int count = 0;
	size_t align;
	size_t elem_size = 0;
	tnf_tag_data_t ***tag_ppp;
	tnf_tag_data_t   *tag_p;
	unsigned long offset = 0;

	tag_ppp = probe_p->slot_types;
	if (!tag_ppp)
		return (NULL);

	while (count <= index) {
		/* error checking. REMIND: Do we need it ? */
		if (!(*tag_ppp))
			return (NULL);
		tag_p = **tag_ppp;
		if (!tag_p)
			return (NULL);

		offset = offset + elem_size;
		align = tag_p->tag_align - 1;
		assert(align != 0);
		offset = ALIGN_ROUNDUP(offset, align);
		/* get size of current element */
		elem_size = tag_p->tag_ref_size;
		tag_ppp++;
		count++;
	}

	return ((void *)((char *)buffer + offset));
}

/*
 * tnf_probe_get_type_indexed: returns the type of the ith argument.
 * returns TNF_UNKNOWN on error.  Argument numbering is zero based
 * i.e. to get the 3rd argument, the input value should be 2.
 */

tnf_arg_kind_t
tnf_probe_get_type_indexed(tnf_probe_control_t *probe_p, int index)
{
	tnf_tag_data_t ***tag_ppp;
	tnf_tag_data_t   *tag_p;

	tag_ppp = probe_p->slot_types + index;
	if (!tag_ppp)
		return (TNF_UNKNOWN);
	if (!(*tag_ppp))
		return (TNF_UNKNOWN);
	tag_p = **tag_ppp;
	if (!tag_p)
		return (TNF_UNKNOWN);
	return (tag_p->tag_kind);
}


/*
 * tnf_probe_get_value: returns the start of the value string that is
 * associated with the input attribute.  The number of characters in the
 * value is also returned as the final argument.  The size return value
 * indicates the length of the string that is valid.  Returns NULL on no
 * match or error.
 */

const char *
tnf_probe_get_value(tnf_probe_control_t *probe_p, char *attribute,
ulong_t *size)
{

	const char 	*attr_start, *attr_end, *str_end;
	const char	*val_start;
	int 		separator;
	uint_t		attr_len;
	size_t		input_len;

	input_len = strlen(attribute);
	attr_start = probe_p->attrs;
	assert(attr_start);
	str_end = attr_start + strlen(attr_start);
	separator = ATTR_SEPARATOR;
	while (attr_start < str_end) {
		attr_end = strchr(attr_start, separator);
		if (!attr_end) {
			/* last attribute */
			attr_end = str_end;
		}
		/* LINTED - result <= string length */
		attr_len = attr_end - attr_start;

		/* skip over leading white space */
		while (*attr_start && ((*attr_start == ' ') ||
						(*attr_start == '\t'))) {
			attr_start++;
		}
		/* search for match on attribute */
		if (strncmp(attr_start, attribute, input_len) == 0) {
			/* make sure next char is a space or semicolon */
			val_start = attr_start + input_len;
			if (*val_start == ATTR_SEPARATOR) {
				*size = 0;
				return (val_start);
			} else if (*val_start == VAL_SEPARATOR) {
				/* +1 for val separator */
				*size = attr_len - (input_len + 1);
				return (val_start + 1);
			}
			/* a false match - just continue */
		}
		/* skip to next attribute */
		attr_start = attr_end + 1;
	}

	/* no match */
	return (NULL);
}

/* used by in-process argument reader */
char *
tnf_probe_get_chars(void *slot)
{
	tnf_reference_t	ref;
	char		*str_p;

	ref = *((tnf_reference_t *)slot);
	assert(TNF_REF32_IS_FWD(ref));
	str_p = (char *)slot + TNF_REF32_VALUE(ref);
	str_p += ARRAY_HDR_SIZE;
	return (str_p);
}