Logo Search packages:      
Sourcecode: lcrash version File versions  Download package

cmd_print.c

/*
 * $Id: cmd_print.c,v 1.1 2004/12/21 23:26:18 tjm Exp $
 *
 * This file is part of lcrash, an analysis tool for Linux memory dumps.
 *
 * Created by Silicon Graphics, Inc.
 * Contributions by IBM, and others
 *
 * Copyright (C) 1999 - 2002 Silicon Graphics, Inc. All rights reserved.
 * Copyright (C) 2001, 2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version. See the file COPYING for more
 * information.
 */

#include <lcrash.h>
#include <lc_eval.h>

void print_usage(command_t *);

/*
 * print_cmd() -- Dump out type information.
 */
int
print_cmd(command_t *cmd)
{
      int i, j = 0;
      uint64_t flags = 0;
      char *buf, *next, *end, *exp;
      node_t *np;

      /* If there is nothing to evaluate, just return
       */
      if (cmd->nargs == 0) {
            return(0);
      }

      /* Set up the flags value. If this command was invoked via
       * pd, px, or po, then make sure the appropriate flag is set. 
       */
        if (!strcmp(cmd->command, "pd")) {
            cmd->flags &= ~(C_HEX|C_OCTAL);
                cmd->flags |= C_DECIMAL;
        } else if (!strcmp(cmd->command, "px")) {
            cmd->flags &= ~(C_OCTAL|C_BINARY);
                cmd->flags |= C_HEX;
        } else if (!strcmp(cmd->command, "po")) {
            cmd->flags &= ~(C_HEX|C_BINARY);
                cmd->flags |= C_OCTAL;
        } else if (!strcmp(cmd->command, "pb")) {
            cmd->flags &= ~(C_HEX|C_OCTAL);
                cmd->flags |= C_BINARY;
        }
      if (cmd->flags & C_HEX) {
            flags = K_HEX;
      } else if (cmd->flags & C_OCTAL) {
            flags = K_OCTAL;
      } else if (cmd->flags & C_BINARY) {
            flags = K_BINARY;
      }

      /* Count the number of bytes necessary to hold the entire expression
       * string.
       */
      for (i = 0; i < cmd->nargs; i++) {
            j += (strlen(cmd->args[i]) + 1);
      }

      /* Allocate space for the expression string and copy the individual
       * arguments into it.
       */
      buf = (char *)kl_alloc_block(j, K_TEMP);
      for (i = 0; i < cmd->nargs; i++) {
            strcat(buf, cmd->args[i]);
            if ((i + 1) < cmd->nargs) {
                  strcat(buf, " ");
            }
      }

      /* Walk through the expression string, expression by expression.
       * Note that a comma (',') is the delimiting character between
       * expressions.
       */
      next = buf;
      while (next) {
            if ((end = strchr(next, ','))) {
                  *end = (char)0;
            }

            /* Copy the next expression to a separate expression string.
             * A seperate expresison string is necessary because it is 
             * likely to get freed up in eval() when variables get expanded.
             */
            exp = (char *)kl_alloc_block(strlen(next) + 1, K_TEMP);
            strcpy(exp, next);

            /* Evaluate the expression
             */
            np = eval(&exp, 0);
            if (!np || eval_error) {
                  print_eval_error(cmd->command, exp,
                        (error_token ? error_token : (char*)NULL), 
                        eval_error, CMD_NAME_FLG);
                  if (np) {
                        free_nodes(np);
                  }
                  kl_free_block((void *)buf);
                  kl_free_block((void *)exp);
                  free_eval_memory();
                  return(1);
            }
            if (print_eval_results(np, cmd->ofp, flags)) {
                  free_nodes(np);
                  kl_free_block((void *)buf);
                  free_eval_memory();
                  return(1);
            }
            kl_free_block((void *)exp);

            if (end) {
                  next = end + 1;
                  fprintf(cmd->ofp, " ");
            } else {
                  next = (char*)NULL;
                  fprintf(cmd->ofp, "\n");
            }
            free_nodes(np);
      }
      kl_free_block((void *)buf);
      free_eval_memory();
      return(1);
}

#define _PRINT_USAGE "[-d] [-o] [-x] [-b] [-w outfile] expression"
#define _PD_USAGE "[-w outfile] expression"
#define _PX_USAGE "[-w outfile] expression"
#define _PO_USAGE "[-w outfile] expression"
#define _PB_USAGE "[-w outfile] expression"

/*
 * print_usage() -- Print the usage string for the 'print' command.
 */
void
print_usage(command_t *cmd)
{
      if (!strcmp(cmd->command, "pd")) {
            CMD_USAGE(cmd, _PD_USAGE);
      } else if (!strcmp(cmd->command, "px")) {
            CMD_USAGE(cmd, _PX_USAGE);
      } else if (!strcmp(cmd->command, "po")) {
            CMD_USAGE(cmd, _PO_USAGE);
      } else if (!strcmp(cmd->command, "pb")) {
            CMD_USAGE(cmd, _PB_USAGE);
      } else {
            CMD_USAGE(cmd, _PRINT_USAGE);
      }
}

/*
 * print_help() -- Print the help information for the 'print' command.
 */
void
print_help(command_t *cmd)
{
      CMD_HELP(cmd, _PRINT_USAGE,
            "Evaluate an expression and print the result. An "
            "expression can consist of numeric values, operators, "
            "typedefs, struct/union members, symbols, or a "
            "combination of the above. Following are some examples "
            "of valid expressions:\n\n"
            "    (((2*3+4/2)*2+(2/6))/2)"
            "\n\n"
            "    ((struct task_struct *)0xc5c14000)->comm"
            "\n\n"
            "    (*((struct task_struct *)0xc5c14000)->files.fd)."
            "f_flags & 0x8000"
            "\n\n"
            "The pd command is the same as the print command "
            "except that it forces all integers to be displayed as "
            "decimal values."
            "\n\n"
            "The px command is the same as the print command "
            "except that it forces all integers to be displayed as "
            "hexadecimal values."
            "\n\n"
            "The po command is the same as the print command "
            "except that it forces all integers to be displayed as "
            "octal values."
            "\n\n"
            "The pb command is the same as the print command "
            "except that it forces all integer values to be "
            "displayed as binary values. Note that only single "
            "values (numbers, members of structures, etc.) will "
            "be displayed in binary form. Integer values in "
            "complex data types such as structures will be "
            "displayed as decimal values.");
}

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

      if ((cmd->command[1] == 'd') || (cmd->command[1] == 'x') || 
                  (cmd->command[1] == 'o') || (cmd->command[1] == 'b')) {
            return(set_cmd_flags(cmd, (C_TRUE|C_WRITE|C_NO_OPCHECK), ""));
      } 
        if (set_cmd_flags(cmd, (C_TRUE|C_WRITE|C_NO_OPCHECK), "doxb")) {
                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 'b':
                                cmd->flags |= C_BINARY;
                                break;
                }
                op = op->op_next;
      }
      return(0);
}

/*
 * print_complete() -- Complete arguments of 'print' command.
 */
char *
print_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");
      print_usage(cmd);
      return(DRAW_NEW_ENTIRE_LINE);
}

Generated by  Doxygen 1.6.0   Back to index