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

cmd_sizeof.c

/*
 * $Id: cmd_sizeof.c,v 1.2 2005/01/13 09:18:37 holzheu 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>

#define C_OFLAG (1 << C_LFLG_SHFT)

void sizeof_usage(command_t*);

/*
 * sizeof_cmd() -- Find an item in the symbol table that is either
 *                 a struct, field, etc.
 */
int
sizeof_cmd(command_t *cmd)
{
      int i, size, offset;
      char *ptr0, *ptr1, *ptr2;
      char *typestring;

        if (!strcmp(cmd->command, "offset")) {
                cmd->flags |= C_OFLAG;
      }
      for (i = 0; i < cmd->nargs; i++) {
            offset = -1;
            typestring = ptr0 = kl_str_to_block(cmd->args[i], K_TEMP);
            if ((ptr1 = strtok(cmd->args[i], "."))) {
                  if ((ptr2 = strtok(NULL, "."))) {
                        size = kl_member_size(ptr1, ptr2);
                        if(cmd->flags & C_OFLAG) {
                              offset = kl_member_offset(ptr1, ptr2);
                        }
                        if(strtok(NULL,".")) {
                              fprintf(cmd->efp,
                                    "Invalid command line.\n");
                              sizeof_usage(cmd);
                              return(1);
                        }
                  } else {
                        /* catch case of multiterm types */
                        if((ptr2 = strtok(ptr1, "\""))) {
                              typestring = ptr2;
                              size = kl_struct_len(ptr2);
                        } else {
                              size = kl_struct_len(ptr1);
                        }
                  }
            } else {
                  size = kl_struct_len(ptr1);
            }
            if (size || (kl_is_member(ptr1, ptr2) && (cmd->flags & C_OFLAG))) {
                  if(cmd->flags & C_OFLAG) {
                        if(offset > -1){
                              fprintf(cmd->ofp, "Offset: %d bytes.\n",
                                    offset);
                        } else {
                              fprintf(cmd->efp, "ERROR: Could not "
                                    "determine offset for %s.\n",
                                    typestring);
                        }
                  } else {
                        fprintf(cmd->ofp, "Size of \"%s\": %d bytes\n", 
                              typestring, size);
                  }
            } else if (ptr2) {
                  if (kl_is_member(ptr1, ptr2)) {
                        fprintf(cmd->ofp, "Size of \"%s\": %d bytes\n", 
                              typestring, size);
                  } else {
                        fprintf(cmd->efp, "%s: structure/field not "
                              "found.\n", typestring);
                  }
            } else {
                  fprintf(cmd->efp, "%s: type info not found.\n",
                        typestring);
            }
            kl_free_block(ptr0);
      }
      return(0);
}

#define _SIZEOF_USAGE \
"\n        type | structure.field [...]"\
"\n        -o structure.field [...]"\
"\n        [-w outfile]"

#define _OFFSET_USAGE \
"\n        structure.field [...]"\
"\n        [-w outfile]"


#define _SIZEOF_HELP \
"Display size of data types in bytes. Additionally display offsets for\n"\
"members of structs.\n"\
"\nOPTIONS:"\
"\n type | structure.field [...]"\
"\n       Print size of types (basic types, structs, typedefs) or"\
"\n       member of structures in bytes."\
"\n -o structure.field [...]"\
"\n       Determine the member offset. Only arguments of the form"\
"\n       'structure.field' are allowed.\n"\
"\nTo request size for multi-worded types (e.g. \"short int\") specify the"\
"\ntype within \"\".\n"\
"\nNote: An alias \"offset\" exists for the calling sequence \"sizeof -o\"."

/*
 * sizeof_usage() -- Print the usage string for the 'sizeof' command.
 */
void
sizeof_usage(command_t *cmd)
{
      if(!strcmp(cmd->command,"offset")){
            CMD_USAGE(cmd, _OFFSET_USAGE);
      } else {
            CMD_USAGE(cmd, _SIZEOF_USAGE);
      }
}

/*
 * sizeof_help() -- Print the help information for the 'sizeof' command.
 */
void
sizeof_help(command_t *cmd)
{
      CMD_HELP(cmd, _SIZEOF_USAGE, _SIZEOF_HELP);
}

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

      if (set_cmd_flags(cmd, (C_WRITE|C_TRUE|C_NEXT), "o")) {
            return(1);
      }
      op = cmd->options;
      while (op) {
            switch(op->op_char) {
                  case 'o':
                        cmd->flags |= C_OFLAG;
            }
            op = op->op_next;
      }

      return(0);
}

/*
 * sizeof_complete() -- Complete arguments of 'sizeof' command.
 */
char *
sizeof_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");
      sizeof_usage(cmd);
      return(DRAW_NEW_ENTIRE_LINE);
}

Generated by  Doxygen 1.6.0   Back to index