/*
 * Copyright 1999 Silicon Graphics, Inc. All rights reserved.
 */
#include <lcrash.h>

/*
 * dump_cmd() -- Run the 'dump' command.
 */
int
dump_cmd(command_t *cmd)
{
        int mode;
        uint64_t size, value;
        kaddr_t start_addr;
        syment_t *sp;

        sp = kl_lkup_symname(cmd->args[0]);
        if (!KL_ERROR) {
                start_addr = sp->s_addr;
        }
        else {
                kl_get_value(cmd->args[0], &mode, 0, &value);
                if (KL_ERROR) {
			fprintf(KL_ERRORFP, "Invalid value: %s\n", 
				cmd->args[0]); 
                        return(1);
                }
		start_addr = (kaddr_t)value;

                /* If entered as a PFN, convert to physical address
                 */
                if (mode == 1) {
                        start_addr = start_addr << KL_PAGE_SHIFT;
                }
        }

        if (cmd->nargs > 1) {
                GET_VALUE(cmd->args[1], &size);
                if (KL_ERROR) {
			fprintf(KL_ERRORFP, "Invalid size: %s\n", 
				cmd->args[1]);
                        return(1);
                }
        }
        else {
                size = 1;
        }

        if ((start_addr == 0) &&
                ((cmd->args[0][0] != '0') && (cmd->args[0][0] != '#'))) {
                        fprintf(cmd->efp, "%s not found in symbol table.\n", 
				cmd->args[0]);
        }

        dump_memory(start_addr, size, cmd->flags, cmd->ofp);
        if (KL_ERROR) {
                return(1);
        }
        return(0);
}

#define _DUMP_USAGE \
        "[-d] [-o] [-x] [-B] [-D] [-H] [-W] [-w outfile] addr [count]"
/*
 * dump_usage() -- Print the usage string for the 'dump' command.
 */
void
dump_usage(command_t *cmd)
{
        CMD_USAGE(cmd, _DUMP_USAGE);
}

/*
 * dump_help() -- Print the help information for the 'dump' command.
 */
void
dump_help(command_t *cmd)
{
        CMD_HELP(cmd, _DUMP_USAGE,
                "Display count values starting at kernel virtual (or "
		"physical) address. "
                "addr in one of the following formats: decimal (-d), "
                "octal (-o), or hexadecimal (-x). addr is considered to be "
	        "a physical address if -p option is specified. The default "
		"format is hexadecimal, and the default count is 1. If addr is "
		"preceeded by a pound sign ('#'), it will be treated as a "
		"page number (PFN).");
}

/*
 * dump_parse() -- Parse the command line arguments for the 'dump' command.
 */
int
dump_parse(command_t *cmd)
{
	option_t *op;

	if (set_cmd_flags(cmd, (C_TRUE|C_WRITE), "doxipBDHW")) {
		return(1);
	}
	op = cmd->options;
	while (op) {
		switch(op->op_char) {
			case 'd':
				cmd->flags |= C_DECIMAL;
				break;

			case 'o':
				cmd->flags |= C_OCTAL;
				break;

			case 'x':
				cmd->flags |= C_HEX;
				break;

			case 'i':
				cmd->flags |= C_INSTR;
				break;

			case 'p':
				cmd->flags |= C_PADDR;
				break;

			case 'B':
				cmd->flags |= C_BYTE;
				break;

			case 'D':
				cmd->flags |= C_DWORD;
				break;

			case 'H':
				cmd->flags |= C_HWORD;
				break;

			case 'W':
				cmd->flags |= C_WORD;
				break;
		}
		op = op->op_next;
	}
	return(0);
}

/*
 * dump_complete() -- Complete arguments of 'dump' command.
 */
char *
dump_complete(command_t *cmd)
{
	char *ret;

	/* complete standard options (for example, -w option) arguments
	 */
	if ((ret = complete_standard_options(cmd)) != NOT_COMPLETED) {
		return(ret);
	}
	fprintf(cmd->ofp, "\n");
	dump_usage(cmd);
	return(DRAW_NEW_ENTIRE_LINE);
}
