[BACK]Return to db_expr.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / ddb

File: [cvs.NetBSD.org] / src / sys / ddb / db_expr.c (download)

Revision 1.15, Thu Feb 22 06:41:01 2007 UTC (13 years, 8 months ago) by thorpej
Branch: MAIN
CVS Tags: yamt-x86pmap-base4, yamt-x86pmap-base3, yamt-x86pmap-base2, yamt-x86pmap-base, yamt-x86pmap, yamt-pf42-baseX, yamt-pf42-base4, yamt-pf42-base3, yamt-pf42-base2, yamt-pf42-base, yamt-pf42, yamt-nfs-mp-base2, yamt-nfs-mp-base, yamt-lazymbuf-base15, yamt-lazymbuf-base14, yamt-kmem-base3, yamt-kmem-base2, yamt-kmem-base, yamt-kmem, yamt-idlelwp-base8, wrstuden-revivesa-base-4, wrstuden-revivesa-base-3, wrstuden-revivesa-base-2, wrstuden-revivesa-base-1, wrstuden-revivesa-base, wrstuden-revivesa, vmlocking2-base3, vmlocking2-base2, vmlocking2-base1, vmlocking2, vmlocking-nbase, vmlocking-base, vmlocking, thorpej-atomic-base, thorpej-atomic, simonb-wapbl-nbase, simonb-wapbl-base, simonb-wapbl, reinoud-bufcleanup-nbase, reinoud-bufcleanup-base, reinoud-bufcleanup, nick-net80211-sync-base, nick-net80211-sync, nick-hppapmap-base2, nick-csl-alignment-base5, nick-csl-alignment-base, nick-csl-alignment, netbsd-5-base, netbsd-5-2-RELEASE, netbsd-5-2-RC1, netbsd-5-2-3-RELEASE, netbsd-5-2-2-RELEASE, netbsd-5-2-1-RELEASE, netbsd-5-2, netbsd-5-1-RELEASE, netbsd-5-1-RC4, netbsd-5-1-RC3, netbsd-5-1-RC2, netbsd-5-1-RC1, netbsd-5-1-5-RELEASE, netbsd-5-1-4-RELEASE, netbsd-5-1-3-RELEASE, netbsd-5-1-2-RELEASE, netbsd-5-1-1-RELEASE, netbsd-5-1, netbsd-5-0-RELEASE, netbsd-5-0-RC4, netbsd-5-0-RC3, netbsd-5-0-RC2, netbsd-5-0-RC1, netbsd-5-0-2-RELEASE, netbsd-5-0-1-RELEASE, netbsd-5-0, netbsd-5, mjf-ufs-trans-base, mjf-ufs-trans, mjf-devfs2-base, mjf-devfs2, mjf-devfs-base, mjf-devfs, matt-nb5-pq3-base, matt-nb5-pq3, matt-nb5-mips64-u2-k2-k4-k7-k8-k9, matt-nb5-mips64-u1-k1-k5, matt-nb5-mips64-premerge-20101231, matt-nb5-mips64-premerge-20091211, matt-nb5-mips64-k15, matt-nb5-mips64, matt-nb4-mips64-k7-u2a-k9b, matt-mips64-base2, matt-mips64-base, matt-mips64, matt-armv6-prevmlocking, matt-armv6-nbase, matt-armv6-base, matt-armv6, keiichi-mipv6-nbase, keiichi-mipv6-base, keiichi-mipv6, jmcneill-pm-base, jmcneill-pm, jmcneill-base, hpcarm-cleanup-nbase, hpcarm-cleanup-base, hpcarm-cleanup, haad-nbase2, haad-dm-base2, haad-dm-base1, haad-dm-base, haad-dm, cube-autoconf-base, cube-autoconf, bouyer-xeni386-nbase, bouyer-xeni386-merge1, bouyer-xeni386-base, bouyer-xeni386, bouyer-xenamd64-base2, bouyer-xenamd64-base, bouyer-xenamd64, ad-socklock-base1, ad-audiomp2-base, ad-audiomp2, ad-audiomp-base, ad-audiomp
Branch point for: yamt-nfs-mp, nick-hppapmap, jym-xensuspend
Changes since 1.14: +21 -21 lines

TRUE -> true, FALSE -> false

/*	$NetBSD: db_expr.c,v 1.15 2007/02/22 06:41:01 thorpej Exp $	*/

/*
 * Mach Operating System
 * Copyright (c) 1991,1990 Carnegie Mellon University
 * All Rights Reserved.
 *
 * Permission to use, copy, modify and distribute this software and its
 * documentation is hereby granted, provided that both the copyright
 * notice and this permission notice appear in all copies of the
 * software, derivative works or modified versions, and any portions
 * thereof, and that both notices appear in supporting documentation.
 *
 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
 * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
 *
 * Carnegie Mellon requests users of this software to return to
 *
 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
 *  School of Computer Science
 *  Carnegie Mellon University
 *  Pittsburgh PA 15213-3890
 *
 * any improvements or extensions that they make and grant Carnegie the
 * rights to redistribute these changes.
 *
 *	Author: David B. Golub, Carnegie Mellon University
 *	Date:	7/90
 */

#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: db_expr.c,v 1.15 2007/02/22 06:41:01 thorpej Exp $");

#include <sys/param.h>
#include <sys/proc.h>

#include <machine/db_machdep.h>

#include <ddb/db_access.h>
#include <ddb/db_command.h>
#include <ddb/db_extern.h>
#include <ddb/db_lex.h>
#include <ddb/db_output.h>
#include <ddb/db_sym.h>
#include <ddb/db_variables.h>

static bool db_term(db_expr_t *);
static bool db_unary(db_expr_t *);
static bool db_mult_expr(db_expr_t *);
static bool db_add_expr(db_expr_t *);
static bool db_shift_expr(db_expr_t *);

static bool
db_term(db_expr_t *valuep)
{
	int	t;

	t = db_read_token();
	if (t == tIDENT) {
		if (!db_value_of_name(db_tok_string, valuep)) {
			db_expr_t v = 0;
			int	i, c, byte;

			/* See if we can make a number out of all of it */
			for (i = 0; (c = db_tok_string[i]) != '\0'; i++) {
				byte = 0;
				if (c >= '0' && c <= '9')
					byte = c - '0';
				else if (db_radix == 16 && c >= 'a' && c <= 'f')
					byte = c - 'a' + 10;
				else if (db_radix == 16 && c >= 'A' && c <= 'F')
					byte = c - 'A' + 10;
				else
					db_error("Symbol not found\n");
					/*NOTREACHED*/
				v = v * db_radix + byte;
			}
			*valuep = (db_expr_t)v;
		}
		return (true);
	}
	if (t == tNUMBER) {
		*valuep = (db_expr_t)db_tok_number;
		return (true);
	}
	if (t == tDOT) {
		*valuep = (db_expr_t)db_dot;
		return (true);
	}
	if (t == tDOTDOT) {
		*valuep = (db_expr_t)db_prev;
		return (true);
	}
	if (t == tPLUS) {
		*valuep = (db_expr_t) db_next;
		return (true);
	}
	if (t == tDITTO) {
		*valuep = (db_expr_t)db_last_addr;
		return (true);
	}
	if (t == tDOLLAR) {
		if (!db_get_variable(valuep))
		    return (false);
		return (true);
	}
	if (t == tLPAREN) {
		if (!db_expression(valuep)) {
			db_error("Syntax error\n");
			/*NOTREACHED*/
		}
		t = db_read_token();
		if (t != tRPAREN) {
			db_error("Syntax error\n");
			/*NOTREACHED*/
		}
		return (true);
	}
	db_unread_token(t);
	return (false);
}

static bool
db_unary(db_expr_t *valuep)
{
	int	t;

	t = db_read_token();
	if (t == tMINUS) {
		if (!db_unary(valuep)) {
			db_error("Syntax error\n");
			/*NOTREACHED*/
		}
		*valuep = -*valuep;
		return (true);
	}
	if (t == tSTAR) {
		/* indirection */
		if (!db_unary(valuep)) {
			db_error("Syntax error\n");
			/*NOTREACHED*/
		}
		*valuep = db_get_value((db_addr_t)*valuep, sizeof(db_expr_t),
		    false);
		return (true);
	}
	db_unread_token(t);
	return (db_term(valuep));
}

static bool
db_mult_expr(db_expr_t *valuep)
{
	db_expr_t	lhs, rhs;
	int		t;

	if (!db_unary(&lhs))
		return (false);

	t = db_read_token();
	while (t == tSTAR || t == tSLASH || t == tPCT || t == tHASH) {
		if (!db_term(&rhs)) {
			db_error("Syntax error\n");
			/*NOTREACHED*/
		}
		if (t == tSTAR)
			lhs *= rhs;
		else {
			if (rhs == 0) {
				db_error("Divide by 0\n");
				/*NOTREACHED*/
			}
			if (t == tSLASH)
				lhs /= rhs;
			else if (t == tPCT)
				lhs %= rhs;
			else
				lhs = ((lhs+rhs-1)/rhs)*rhs;
		}
		t = db_read_token();
	}
	db_unread_token(t);
	*valuep = lhs;
	return (true);
}

static bool
db_add_expr(db_expr_t *valuep)
{
	db_expr_t	lhs, rhs;
	int		t;

	if (!db_mult_expr(&lhs))
		return (false);

	t = db_read_token();
	while (t == tPLUS || t == tMINUS) {
		if (!db_mult_expr(&rhs)) {
			db_error("Syntax error\n");
			/*NOTREACHED*/
		}
		if (t == tPLUS)
			lhs += rhs;
		else
			lhs -= rhs;
		t = db_read_token();
	}
	db_unread_token(t);
	*valuep = lhs;
	return (true);
}

static bool
db_shift_expr(db_expr_t *valuep)
{
	db_expr_t	lhs, rhs;
	int		t;

	if (!db_add_expr(&lhs))
		return (false);

	t = db_read_token();
	while (t == tSHIFT_L || t == tSHIFT_R) {
		if (!db_add_expr(&rhs)) {
			db_error("Syntax error\n");
			/*NOTREACHED*/
		}
		if (rhs < 0) {
			db_error("Negative shift amount\n");
			/*NOTREACHED*/
		}
		if (t == tSHIFT_L)
			lhs <<= rhs;
		else {
			/* Shift right is unsigned */
			lhs = (unsigned long) lhs >> rhs;
		}
		t = db_read_token();
	}
	db_unread_token(t);
	*valuep = lhs;
	return (true);
}

int
db_expression(db_expr_t *valuep)
{

	return (db_shift_expr(valuep));
}