#!/usr/bin/perl
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 1999,2019 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
# sccsid = "@(#)50   1.31.1.17   src/rsct/rmc/cli/bin/lsrsrcdef.perl, rmccli, rsct_rady, rady2035a 11/12/15 16:30:08"
######################################################################
#                                                                    #
# Module: lsrsrcdef                                                  #
#                                                                    #
# Purpose:                                                           #
#   lsrsrcdef - Lists a resource or resource class definition.       #
#                                                                    #
# Syntax:                                                            #
#   lsrsrcdef [-h] [-c] [-A p|d] [-p Property] [-s] [-e] [-v]        #
#             [-l|-i|-t|-d|-D Delimiter] [-x] [-T] [-V]              #
#             [Resource_class [Attr...]                              #
#                                                                    #
# Flags:                                                             #
#   -h      Help. Writes this command's usage statement to stdout.   #
#   -c      Class. Displays the resource class definition. By        #
#           default, the resource definition is displayed. Combine   #
#           with the -A p|d flag to display the resource class       #
#           definition for persistent or dynamic attributes.         #
#           Use the -c flag alone, without the -A p|d flag, to see   #
#           the resource class definition.                           #
#   -A      Attribute type. Specifies the attribute type. Either     #
#           persistent or dynamic attribute definitions may be       #
#           displayed. Use this flag with the -c flag for the        #
#           persistent or dynamic attribute definitions of the       #
#           resource class.                                          #
#           p - Displays only persistent attributes                  #
#           d - Displays only dynamic attributes                     #
#   -p Property Displays attributes with the specified Property. By  #
#           default, only public attributes are displayed. To        #
#           display all attribute definitions regardless of the      #
#           property, use the -p 0 flag. Refer to ct_mc.h for        #
#           persistent and dynamic property values. An or-ing of the #
#           properties will be accepted to display only attributes   #
#           that have any of the specified properties.               #
#   -s      Structured Data. Displays the structured data definition.#
#           Specify this flag for the structured data definition to  #
#           be expanded so that each element definition of the       #
#           structured data attributes is displayed.                 #
#   -e      Expands the descriptions. By default the definitions are #
#           displayed, but the textual descriptions are not          #
#           displayed because they may be lengthy. Specify this flag #
#           to see both the definitions and descriptions.            #
#   -v      Display attribute valid values. The -s flag must be      #
#           given in conjunction with the -v flag in order to view   #
#           valid values of structured data elements (if present).   #
#   -l      Specifies long formatted output, one entry per line.     #
#           This is the default display format. If the lsrsrcdef     #
#           command is issued with the -l flag, but without a        #
#           resource class name, the -l flag is ignored when the     #
#           command returns the list of defined resource class names.#
#   -i      Input format. Generates a template of the Resource Data  #
#           Input File which can then, after appropriate editing, be #
#           used as input to the mkrsrc command. The output is       #
#           displayed in long (stanza) format. All required and      #
#           optional attributes that can be used to define a         #
#           resource are displayed. The attribute data type is       #
#           displayed as the value in the Attr=value pairs. It is    #
#           suggested that when you use this flag, the output of the #
#           lsrsrcdef command be directed to a file.                 #
#           The -i flag overrides the -Ad, -s, and -v flags.         #
#   -t      Specifies tabular formatted output. Each attribute is    #
#           displayed in a separate column, one resource per line.   #
#   -d      Specifies delimiter-formatted output. The default        #
#           delimiter is a colon (:). Use the -D flag to change the  #
#           default delimiter.                                       #
#   -D Delimiter    Specifies delimiter-formatted output that uses   #
#           the specified delimiter. Use this flag to specify        #
#           something other than the default colon (:). An example   #
#           is when the data to be displayed contains colons. Use    #
#           this flag to specify a delimiter of one or more          #
#           characters.                                              #
#   -x      Exclude header. Suppress header printing.                #
#   -T      Trace. Writes the command's trace messages to standard   #
#           error. For your software-service organization's use only.#
#   -V      Verbose. Writes this command's verbose messages to       #
#           standard out.                                            #
#                                                                    # 
# Operands:                                                          #
#   Resource_class  Resource class name. The name of the resource    #
#                   class whose attribute definitions are to be      #
#                   displayed. If no Resource_class operand is       #
#                   specified, a list of all of the resource class   #
#                   names is displayed.                              #
#                                                                    #
#   Attr            If a Resource_class operand is specified, zero   #
#                   or more attribute names can be specified. If no  #
#                   Attr operand is specified, the definition for    #
#                   all the attributes for the Resource_class are    #
#                   listed. Specific attribute names may be          #
#                   specified to control which attributes are        #
#                   displayed and their order. Specify only          #
#                   persistent attribute names when the -A p flag is #
#                   used. Specify only dynamic attribute names when  #
#                   the -A d flag is used. Attributes must be        #
#                   separated by spaces.                             #
#                                                                    #
# Description:                                                       #
#   The lsrsrcdef command lists the definition of a resource class,  #
#   or the persistent or dynamic attributes of a resource instance   #
#   or a resource class.                                             #
#                                                                    #
#   Use lsrsrcdef with no operands specified to get a list of all    #
#   resource class names.                                            #
#                                                                    #
#   To see just the resource class definition, specify the -c flag   #
#   and a Resource_class operand without specifying the -A flag.     #
#                                                                    #
#   To see the persistent or dynamic attribute definitions of the    #
#   resource class, specify a Resource_class operand and the -c flag #
#   with the appropriate -A flag (-A d for dynamic attribute or -A p #
#   for persistent attribute definitions). To see the persistent or  #
#   dynamic attribute definitions for a resource, specify the        #
#   appropriate -A p|d flag without the -c flag.                     #
#                                                                    #
#   By default, when no Attr operands are specified on the command   #
#   line, only the definitions for public attributes are displayed.  #
#   To override this default, use the -p flag or specify the name of #
#   the attribute you wish to display.                               #
#                                                                    #
#   By default, for the attributes that contain descriptions, the    #
#   descriptions are not displayed. Specify the -e flag to display   #
#   the descriptions. Because some of the descriptions are very      #
#   long, the default is not to display them. If descriptions for    #
#   members of the valid_vals list are available, they are displayed #
#   with the -e flag as well.                                        #
#                                                                    #
#   By default, for attributes that have defined valid values, the   #
#   valid values are not displayed.  Specify the -v flag to display  # 
#   the valid values. Specify the -s flag with the -v flag to view   #
#   the structured data elements' valid values. Valid_vals and       #
#   valid_vals_label fields are blank for pointer data types. Fields #
#   are also blank if the attribute is an SD or SD array and the -s  #
#   flag was not given. Because valid values are not returned as     #
#   part of the base definition of the resource or resource class,   #
#   and extra calls to RMC must be made to retrieve the valid values,#
#   the default is not to display them.                              #
#                                                                    #
# Exit Values:                                                       #
#   0  MC_CLI_SUCCESS        Command completed successfully.         #
#   1  MC_CLI_RMC_ERROR      Command terminated due to an underlying #
#                            RMC error.                              #
#   2  MC_CLI_ERROR          Command terminated due to an underlying #
#                            error in the command script.            #
#   3  MC_CLI_BAD_FLAG       Command terminated due to user          #
#                            specifying an invalid flag.             #
#   4  MC_CLI_BAD_OPERAND    Command terminated due to user          #
#                            specifying a bad operand.               #
#   5  MC_CLI_USER_ERROR     Command terminated due to a user error. #
#                            For example specifying an undefined     #
#                            Resource name as the Resource operand.  #
#                                                                    #
# Examples:                                                          #
#   lsrsrcdef                    (lists all resource class names     #
#   lsrsrcdef -c IBM.Processor   (lists resource class definition)   #
#   lsrsrcdef -c -Ap IBM.Condition (lists resouce class pers at defs)#
#   lsrsrcdef IBM.Host           (lists resource persistent attr def)#
#   lsrsrcdef -Ad IBM.Host       (lists resouce dynamic attr defs)   #
#   lsrsrcdef -c -e IBM.Hostt    (lists resource class def with desc)#
#   lsrsrcdef -Ap IBM.FileSystem Name Vfs                            #
#   lsrsrcdef -s -Ap IBM.EventResponse Actions (list the expanded    #
#                                 SD def for SD attr Actions.)       #
#   lsrsrcdef -v -Ap IBM.FileSystem (list resource persistent attr   #
#                                    defs with attr valid values)    #
#                                                                    #
# Man Page:                                                          #
#   For the most current detailed description of this command see    #
#   the lsrsrcdef man page in /opt/rsct/man.                    #
#                                                                    #
#--------------------------------------------------------------------#
# Inputs:                                                            #
#   /opt/rsct/msgmaps/mccli.lsrsrcdef.map - message mapping     #
#   /opt/rsct/msgmaps/mccli.mccli.map - message mapping         #
#                                                                    #
# Outputs:                                                           #
#   stdout - display of the resource class definitions.              #
#   stderr - any error message.                                      #
#                                                                    #
# External Ref:                                                      #
#   Commands: ctdspmsg                                               #
#   Modules:  MC_cli_utils.pm, MC_cli_display_utils.pm, MC_cli_rc.pm #
#             CT_cli_utils.pm, CT_cli_data_type_utils                #
#   Extensions:  CT::MC, CT::MCerr, CT::CT                           #
#   Perl library routines: Getopt::Std                               #
#                                                                    #
# Tab Settings:                                                      #
#   4 and tabs should be expanded to spaces before saving this file. #
#   in vi:  (:set ts=4  and   :%!expand -4)                          #
#                                                                    #
# Change Activity:                                                   #
#   990528 SAB 48419: Initial design & write.                        #
#   010311 SAB 63852: Prepared for GA.                               #
#   010806 YSK 75111: Added -v, valid values support.                #
#   020307 JAC 80687: Remove -v and go back to old usage.            #
#   020726 JAC 84819: Change -a to -A for cmd consistency.           #
#   020801 JAC 85417: Update usage message.                          #
#   021208 JAC 88086: Use lsrsrcdef-api instead of perl extensions.  #
#   030105 JAC 88088: Update new lsrsrcdef-api flags.                #
#   030124 JAC 91171: Fix required attr list processing.             #
#   030129 JAC 91258: Fix required attr list processing for real.    #
#   030205 JAC 91176: Change data type display for none to ct_none.  #
#   030206 JAC 91302: Fix default value display for bin and rh.      #
#   030214 JAC 90033: Add code to quote BIN/RH in SDs.               #
#   030305 JAC 92311: Copy quoting code from lsrsrc.                 #
#   030709 JAC 96745: Add delimiter to call to remove_api_error.     #
#   080122 JAC 145056: translate "attribute" title.                  #
#   080715 JAC 152303: make sure -c with attr gets attr defn         #
######################################################################

#--------------------------------------------------------------------#
# General Program Flow/Logic:                                        #
#                                                                    #
# A. Parse command line flags and operands, determine which flavor   #
#    of this command we are actually invoking.                       #
#    This command allows a user to see the Resource Definitions.     #
#    They can select to see one of:                                  #
#       * The Resource Class Definition                              #
#       * The Resource Class Persistent Attributes Definitions       #
#       * The Resource Class Dynamic Attributes Definitions          #
#       * The Resource Persistent Attributes Definitions             #
#       * The Resource Dynamic Attributes Definitions                #
#       * Structured Data Definitions for Resource Class P & D Attr  #
#       * Structured Data Definitions for Resource P & D Attr Defs.  #
#       * Resource Data Input File format for mkrsrc or chrsrc.      #
# B. Initialize a session with RMC.                                  #
# C. Query the definition of the specified resource class using RMC. #
# D. Display the results.                                            #
# E. Cleanup.                                                        #
#--------------------------------------------------------------------#

#--------------------------------------------------------------------#
# Included Libraries and Extensions                                  #
#--------------------------------------------------------------------#
use lib "/opt/rsct/pm";
use locale;
use Getopt::Std; 

use autouse CT_cli_utils => qw(
    printIMsg
    printEMsg
);
use autouse CT_cli_data_type_utils => qw(
    data_type_to_string
);

use MC_cli_rc qw(:return_codes);
use MC_cli_utils qw(
    get_p_attr_defs_api
    get_d_attr_defs_api
    translate_lsAOpt
    qdef_resource_class_api
    build_HoAttr
    process_exit_code
    process_api_error
    remove_api_error
    format_value_for_display
    $RMC_RSRC_PATTR_REQD_FOR_DEFINE
    $RMC_RSRC_PATTR_OPTION_FOR_DEFINE
    $RMC_RSRC_PATTR_PUBLIC
    printCEMsg
);
use autouse MC_cli_display_utils => qw(
    display_resource_data_api
    display_resource_data_api2
    convert_valid_values
    convert_sd_valid_values
    convert_valid_values_label
    convert_sd_valid_values_label
    getIMsg
);


#--------------------------------------------------------------------#
# Global Variables                                                   #
#--------------------------------------------------------------------#
$TRUE = 1;
$FALSE = 0;

$Verbose = $FALSE;                      # default - verbose turned off

# By default output is written in long format 
$Opt_Long_Format = $TRUE;               # default - see -l (long form)
$Opt_Table_Format = $FALSE;             # default - see -t (table)
$Opt_Delm_Format = $FALSE;              # default - see -d (delimiter)
$Opt_Delm_Str = ":";                    # default - see -D (colon :) 
$Opt_No_HDR = $FALSE;                   # default - see -x
$Opt_Exp_Desc = $FALSE;                 # default - see -e
$Opt_LS_Class_Def = $FALSE;             # default - see -c
$Opt_SD_Def = $FALSE;                   # default - see -s 
$Opt_LS_Input_File = $FALSE;            # default - see -i
$Opt_LS_Class = $FALSE;                 # default (no -A flag) 
$Opt_LS_DAttr = $FALSE;                 # default - see -A 
$Opt_LS_PAttr = $TRUE;                  # default - see -A 
$Opt_Valid_Vals = $FALSE;               # default - see -v 

$PROGNAME = "lsrsrcdef";                # Program Name for messages
$MSGCAT = "mccli.cat";                  # msg catalogue for this cmd

$CTDIR = "/opt/rsct";              # RSCT root directory
$CTBINDIR = "$CTDIR/bin";               # Cluster Bin directory path
$LSMSG = "$CTBINDIR/ctdspmsg";          # display message rtn.
$ENV{'MSGMAPPATH'} = "$CTDIR/msgmaps";  # msg maps used by $LSMSG

#--------------------------------------------------------------------#
# Variables                                                          #
#--------------------------------------------------------------------#
@LoSDAttr = ();
%HoSDDefs = ();
@LoCAttr = ();
%HoCAttr = ();
@LoCMgrAttr = ();
%HoCMgrAttr = ();
@LoPAttr = ();
%HoPAttr = ();
@LoDAttr = ();
%HoDAttr = ();
@out_title = ();

@lsr_out = ();
@lsr_out2 = ();
@temp_line = ();
$j = 0;
$rc = 0;
$rc2 = 0;
$DELIMITER = "tvrtvrtvr";
@rresponse = ();


#--------------------------------------------------------------------#
# Main Code                                                          #
#--------------------------------------------------------------------#

# look for the old -a option for attributes and change it to -A
@ARGV = translate_lsAOpt(@ARGV);

# parse the command line, exit if there are errors 
my ($rc, $resource, $req_properties, @attributes) = &parse_cmd_line;
($rc == 0) || exit($rc);

# set the quote string environment variable, if necessary
if (!defined $ENV{CT_CLI_QUOTE_STRING}){
   $ENV{CT_CLI_QUOTE_STRING} = 1;
}

# if no resource names specified display the list of resource
# names.
if (!$resource) {               # No resource operand

    # List the Resource Class Names
    # call lsrsrcdef-api to get the list of classes
    if ($Trace) { print STDERR "$PROGNAME: calling lsrsrcdef-api\n";}

    @lsr_out = `$CTBINDIR/lsrsrcdef-api -I $DELIMITER -D $DELIMITER -c "*" 2>&1`;

    # capture the return code from lsrsrcdef-api
    $rc = $?;
    $rc = process_exit_code($rc);

    if ($Trace) { print STDERR "lsrsrcdef-api results:\n";
              print STDERR "@lsr_out";
              print STDERR "$PROGNAME: lsrsrcdef-api returned $rc\n";}

    # show any errors if there was a bad rc
    if ($rc != 0) {
       process_api_error($DELIMITER,$rc,@lsr_out);
    }

    # remove any error messages from the output to display
    @lsr_out = remove_api_error($DELIMITER,@lsr_out);

    # extract only the class names
    for ($j=0;$j<=$#lsr_out;$j=$j+2) {
       @temp_line = split(/$DELIMITER/, $lsr_out[$j]);
       push @lsr_out2, $temp_line[0];
    }

    # save the attribute name to display
    push @LoPAttr, "class_name";

    # use table output format
    $Opt_Table_Format = $TRUE;
    $Opt_Long_Format = $FALSE;
    $Opt_LS_DAttr = $FALSE;
    $Opt_LS_PAttr = $FALSE;

    my $row_title = "resource";

    # check for delimited output
    if ($Opt_Delm_Format) { $Opt_Table_Format = $FALSE; }

    # print output if lsrsrcdef-api command worked or there's
    # something to print
    if ($rc ==0 || $#lsr_out2 >=0 )
       {
          # Display the Resource Class Persistent Attributes
          $rc2 = display_attributes_api("", $row_title, \@attributes, \@LoPAttr, \@lsr_out2);
          if ($rc == 0) { $rc = $rc2; }
       }

    ($rc == 0) || exit($rc);

}

elsif ($Opt_SD_Def) {
    # List the Structured Data Definition

    # Select the attributes that are SDs and that at least one of the
    # requested properties or were in the list of attributes 
    # specified on the command line.    
    $rc = select_SD_attr($resource, $req_properties, \@attributes);
    ($rc == 0) || exit($rc);

    # If there are any SD attributes to be displayed 
    # let the subroutine make the call to the extension, and 
    # handle all the assorted potential errors.
    if (scalar(@attributes) > 0) {
        $rc = qdef_sd($resource, \@attributes, \@rresponse);
        ($rc == 0) || exit($rc);

        # Get response for valid values if they were requested by user.
        # Call subroutine to handle valid values extension.
        if ($Opt_Valid_Vals) {
            
            my $usage = $Opt_LS_PAttr ? MC_VV_USAGE_PATTR_RESOURCE
                                      : MC_VV_USAGE_DATTR_RESOURCE;

            if ($Opt_LS_Class) {
                $usage = $Opt_LS_PAttr ? MC_VV_USAGE_PATTR_RSRC_CLASS
                                       : MC_VV_USAGE_DATTR_RSRC_CLASS;
            }

            $response_vv = CT::MC::qdef_valid_vals_rsp_t->new;
            $rc = qdef_valid_vals($session, $resource, \@attributes,
                                  $response_vv, $usage);
            ($rc == 0) || exit($rc);
        }
        # Format the Class Query Definition Attributes into
        # a form suitable for display.
        format_sd_defs($resource, \@rresponse, \@attributes, 
            \@LoSDAttr, \%HoSDDefs, $response_vv);
    }

    # Display the Resource Persistent Attributes Defs & Desc
    $rc = display_sd_defs($resource, \@LoSDAttr, \%HoSDDefs);
    ($rc == 0) || exit($rc);
}

elsif ($Opt_LS_Class_Def) {
    # List the Resource Class Definition

    # Let the subroutine make the call to the extension, and
    # handle all the assorted potential errors.
    ($rc, $rLoCInfo) = qdef_resource_class_api($resource, $Opt_Exp_Desc);
    ($rc == 0) || exit($rc); 

    # Format the Class Query Definition Attributes into
    # a form suitable for display.
    format_class_attributes($resource, $rLoCInfo, \@LoCAttr, 
        \%HoCAttr, \@LoCMgrAttr, \%HoCMgrAttr);

    # Display the Resource Persistent Attributes Defs & Desc
    ($Opt_No_HDR) || 
        printIMsg("IMsglsrsrcdefLsRsrcClassDefHdr", $resource);
    my $row_title = "resource class";
    @attributes = ();
    $rc = display_attributes("", $row_title, \@attributes,
        \@LoCAttr, \%HoCAttr); 
    ($rc == 0) || exit($rc);

    $row_title = "rsrc_mgrs";
    @attributes = ();
    $rc = display_attributes("", $row_title, \@attributes, 
        \@LoCMgrAttr, \%HoCMgrAttr);
    ($rc == 0) || exit($rc);
} 

elsif ($Opt_LS_Input_File) {
    # Listing Input File for mkrsrc or chrsrc 

    # Get the persistent attribute definitions.
    $rc = qdef_p_attribute($resource, \@attributes, \@rresponse, $req_properties);
    ($rc == 0) || exit($rc);

    # Format the Query Definition Persistent Attributes into
    # a form suitable for display. Filter out any attributes
    # that don't have one of the specified properties.
    # Attributes listed on command lide override property filtering.
    format_p_attr_for_input($resource, \@rresponse, $req_properties,
        \@attributes, \@LoPAttr, \%HoPAttr);

    # Display the Resource Persistent Attributes Defs & Desc
    (!$Opt_No_HDR && $Opt_LS_Class) &&
        print "PersistentResourceClassAttributes::\n"; 
    (!$Opt_No_HDR && !$Opt_LS_Class) &&
        print "PersistentResourceAttributes::\n";
    my $row_title = "resource";
    @attributes = ();
    $rc = display_attributes("", $row_title, \@attributes,
         \@LoPAttr, \%HoPAttr);
    ($rc == 0) || exit($rc);
}

elsif ($Opt_LS_PAttr) {
    # Listing Resource Class or Resource Persistent Attribute Defs

    # Let the subroutine make the call to the extension, and
    # handle all the assorted potential errors.
    $rc = qdef_p_attribute($resource, \@attributes, \@rresponse, $req_properties);
    ($rc == 0) || exit($rc);

    # Format the Query Definition Persistent Attributes into
    # a form suitable for display. Filter out any attributes
    # that don't have one of the specified properties. 
    # Attributes listed on command lide override property filtering.
    format_p_attributes($resource, \@rresponse, $req_properties, 
        \@attributes, \@LoPAttr, \%HoPAttr, $response_vv);

    # Display the Resource Persistent Attributes Defs & Desc
    (!$Opt_No_HDR && $Opt_LS_Class) &&   
        printIMsg("IMsglsrsrcdefLsRsrcClassPAttrDefHdr", $resource);
    (!$Opt_No_HDR && !$Opt_LS_Class) &&
        printIMsg("IMsglsrsrcdefLsRsrcPAttrDefHdr", $resource);

    #my $row_title = "attribute";
    @out_title = getIMsg("IMsglsrsrcdefAttributeTitle");
    $row_title = $out_title[0];

    @attributes = ();
    $rc = display_attributes("", $row_title, \@attributes,
         \@LoPAttr, \%HoPAttr); 
    ($rc == 0) || exit($rc);
}

elsif ($Opt_LS_DAttr) {
    # Listing Resource Dynamic Attribute Definitions

    # Let the subroutine make the call to the extension, and
    # handle all the assorted potential errors.
    $rc = qdef_d_attribute($resource, \@attributes, \@rresponse, $req_properties);
    ($rc == 0) || exit($rc);

    # Format the Query Definition Dynamic Attributes into
    # a form suitable for display. Filter out any attributes
    # that don't have one of the specified properties. 
    # Attributes listed on command lide override property filtering.
    format_d_attributes($resource, \@rresponse, $req_properties,
        \@attributes, \@LoDAttr, \%HoDAttr, $response_vv);

    # Display the Resource Dynamic Attributes Defs & Desc
    (!$Opt_No_HDR && $Opt_LS_Class) &&
        printIMsg("IMsglsrsrcdefLsRsrcClassDAttrDefHdr", $resource);
    (!$Opt_No_HDR && !$Opt_LS_Class) &&
        printIMsg("IMsglsrsrcdefLsRsrcDAttrDefHdr", $resource);

    #my $row_title = "attribute";
    @out_title = getIMsg("IMsglsrsrcdefAttributeTitle");
    $row_title = $out_title[0];

    @attributes = ();
    $rc = display_attributes("", $row_title, \@attributes,
         \@LoDAttr, \%HoDAttr);
    ($rc == 0) || exit($rc);
}

exit $rc;


#--------------------------------------------------------------------#
# End Main Code                                                      #
#--------------------------------------------------------------------#


#--------------------------------------------------------------------#
# parse_cmd_line - Parse the command line for options and operands.  #
#   Set appropriate global variables as outlined below, make sure we #
#   have a valid combination of arguments / options.                 #
#                                                                    #
# Return:                                                            #
#   $rc   0                  Command line parsed fine, no problem.   #
#         SR_CLI_BAD_FLAG    Command line contained a bad flag.      #
#   $resource                Resource Class Name.                    #
#   $properties              Attributes having these properties      #
#                            should be displayed.                    #
#   @attributes              Array of attribute names.               #
#                                                                    #
# Global Variables Modified:                                         #
#   $Opt_Current       output   True (-c) print current cluster info #
#   $Opt_Exp_Desc      output   True (-e) print both definition      #
#                               and description (print all).         #
#   $Opt_LS_Class_Def  output   True (-c) display the resource class #
#                               definition this is not the same as   #
#                               combining -Ap and -c.                #
#   $Opt_SD_Def        output   True (-s) display the detailed       #
#                               structured data definition for a     #
#                               attr defined as an SD.               #
#   $Opt_LS_Input_File output   True (-i) create/list an input file  #
#                               suitable for mkrsrc or chrsrc.       #
#   $Opt_LS_Class      output   True (c) display the resource        #
#                               class pers or dynamic definition.    #
#   $Opt_LS_DAttr      ouptput  True (-A d) display the resource     #
#                               dynamic attributes.                  #
#   $Opt_LS_PAttr      output   True (-A p) display the resource     #
#                               persistent attributes.               #
#   $Opt_Valid_Vals    output   True (-v) display valid values.      #
#   $Opt_Long_Format   output   True (-l) print one entry per line   #
#   $Opt_Table_Format  output   True (-t) table format.              #
#   $Opt_Delm_Format   output   True (-d|-D) print delimiter         #
#                               separated output.                    #
#   $Opt_Delm_Str      output   the string to use as the delimiter,  #
#                               default is colon (:).                #
#   $Opt_No_HDR        output   True (-x) print without header       #
#   $Verbose           output   True (-V) turn Verbose mode on.      #
#   $Trace             output   True (-T) turn Trace mode on.        #
#--------------------------------------------------------------------#
sub parse_cmd_line 
{
my(@original_argv) = @ARGV;
my @attributes = ();
my %opts = ();

# Process the command line...
#if (!&getopts('ha:ceip:sdD:ltxvVT', \%opts)) { # Gather options/flags
if (!&getopts('hA:ceip:sdD:ltxVT', \%opts)) { # Gather options/flags
    &print_usage;                       # display proper usage
    return MC_CLI_BAD_FLAG;             # return bad rc - bad flag 
}

# Always accept the -h help flag regardless of other flags or operands
if (defined $opts{h}) {                 # -h, help request  
    &print_usage;                       # print usage statement
    exit(0);                            # all done with good return!
}

# If no operands in lsrsrcdef that is OK, it just means display
# a list of all Resource Class Names

# Get the arguments (operands)
if ($#ARGV >= 0) { 
    $resource = shift @ARGV;            # user specified resource
    @attributes = @ARGV;                # array of attribute names
}

# See which options/flags were used...

if (defined $opts{A}) {                 # -A, attribute type
    if ($opts{A} eq "d") {              # -A d, dynamic attributes
        $Opt_LS_DAttr = $TRUE;
        $Opt_LS_PAttr = $FALSE;
    }
    elsif ($opts{A} eq "p") {           # -A p, persistent attributes
        $Opt_LS_PAttr = $TRUE;
    }
    else {
        # -A flag requires d dynamic | p persistent
        printCEMsg("EMsgMCcliImproperUsageFlag", "-A $opts{A}");
        $rc = MC_CLI_BAD_FLAG;
        return($rc, $resource);
    }
}

# The resource class definition is a separate definition,
# it is not the same as the resource class persistent or dynamic 
# attribute definition
if (defined $opts{c}) {                 # -c, rsrc class definitions
    if (defined $opts{A}  || defined $opts{s} || ($#attributes >= 0)) {
        $Opt_LS_Class = $TRUE;
    }
    else {
        $Opt_LS_Class_Def = $TRUE;
        $Opt_LS_PAttr = $FALSE;
    }
}

if (defined $opts{e}) {                 # -e, display all desc & def
    $Opt_Exp_Desc = $TRUE;
}

if (defined $opts{i}) {
    $Opt_LS_Input_File = $TRUE;
    # Default to displaying only required for define and optional for 
    # define attributes. User should enter -p <property> if they want
    # other properties.
    $properties = $RMC_RSRC_PATTR_REQD_FOR_DEFINE | 
        $RMC_RSRC_PATTR_OPTION_FOR_DEFINE;    
    # -i overrides -Ad (-i only makes sense with persistent attrs)
    if (defined $opts{A} && $opts{A} eq "d") {
        $Opt_LS_DAttr = $FALSE;
        $Opt_LS_PAttr = $TRUE;
    }
    if (defined $opts{c}) {
        $Opt_LS_Class_Def = $FALSE;
        $Opt_LS_Class = $TRUE;
    }
}

if (defined $opts{p}) {                 # -p Property
    $properties = $opts{p};
    # Make sure properties is a number (hex, octal or decimal)
    if ($properties !~ /^(0x|\d+)\d*/) {
        printCEMsg("EMsgMCcliImproperUsageFlag", "-p $opts{p}");
        &print_usage;
        return MC_CLI_USER_ERROR;
    }
    # Convert properties specified in hex or octal to decimal
    $properties = oct $properties if $properties =~ /^0/;

    # Just some mininmal range checking - valid property values only
    # range between 0x0001 to 0x0020 but allow for growth here
    # -p 0 means display attributes with any property
    if ($properties < hex("0x0000") || $properties > hex("0xFFFF")) {
        printCEMsg("EMsgMCcliImproperUsageFlag", "-p $opts{p}");
        &print_usage;
        return MC_CLI_USER_ERROR;
    }
    if ($properties == 0) {
        $properties = hex("0xFFFF");
    }
}
elsif (!defined $opts{i}) {
    # Default to display only public attributes
    # Dynamic and Persistent Public properties are both 0x0020
    $properties = $RMC_RSRC_PATTR_PUBLIC;   # Default to Public 
}

# The -i flag overrides -s
if (defined $opts{s} && !defined $opts{i}) { # -s, sd definitions
    $Opt_SD_Def = $TRUE;
}

# The -i flag overrides -v
if (defined $opts{v} && !defined $opts{i}) { # -v valid values 
    $Opt_Valid_Vals = $TRUE;
}

# The -l flag overrides -t which overrides -d which overrides -D flag
# When -i flag always display in long format
if (defined $opts{l} || defined $opts{i}) { # -l long format, 
    $Opt_Long_Format = $TRUE;          #    1 entry/line
}
elsif (defined $opts{t}) {             # -t tabular format
    $Opt_Table_Format = $TRUE;
    $Opt_Long_Format = $FALSE;
}
elsif (defined $opts{d}) {             # -d delimiter format
    $Opt_Delm_Format = $TRUE;
    $Opt_Long_Format = $FALSE; 
}
elsif (defined $opts{D}) {             # -D <delimiter> format
    $Opt_Delm_Format = $TRUE;
    $Opt_Long_Format = $FALSE;
    $Opt_Delm_Str = $opts{D};
}

if (defined $opts{x}) {                # -x do not print header
    $Opt_No_HDR = $TRUE;
}

if (defined $opts{T}) {                # -T trace
    $Trace = $TRUE; 
}

if (defined $opts{V}) {                # -V verbose 
    $Verbose = $TRUE;
}

return(0, $resource, $properties, @attributes); # success
}   # end parse_cmd_line


#--------------------------------------------------------------------#
# print_usage : print the usage statement (syntax) to stdout.        #
#   See this command's prologue syntax section for current usage.    #
#--------------------------------------------------------------------#
sub print_usage
{
printIMsg("IMsglsrsrcdefUsage25");
}   # end print_usage


#--------------------------------------------------------------------#
# qdef_p_attribute - function to call lsrsrcdef-api to get           #
#   persistent attribute information for attributes or class         #
#   attributes.                                                      # 
#                                                                    #
# Parameters:                                                        #
#   $resource         input   Name of the resource class whose attr  #
#                             definitions we want.                   #
#   @$r_attributes    input   Reference to array of attribute names. #
#   @$response        in/out  Result from lsrsrcdef-api.             #
#                                                                    #
# Return:                                                            #
#   $rc                       return code.                           #
#                                                                    #
# Global References:                                                 #
#   $Opt_Exp_Desc     input  TRUE if display def & description.      #
#   $Opt_LS_Class     input  TRUE if display resource class pers def #
#                            versus the resource pers def.           #
#--------------------------------------------------------------------#
sub qdef_p_attribute 
{
my ($resource, $r_attributes, $response, $properties) = @_;
my $rc = 0;
my @lsr_out = ();
my $cmd_flg = "";
my $attr_list = "";
my $attr_name = "";
 
# are descriptions needed?
if ($Opt_Exp_Desc) { $cmd_flg = "-q";}

my $attr_count = scalar(@$r_attributes); 

# decide which attrs to list, class or resource
if ($Opt_LS_Class) { $cmd_flg .= " -c";}
else { $cmd_flg .= " -r";}

# build attr list for lsrsrcdef
if ($#$r_attributes >= 0) {
   foreach $attr_name (@$r_attributes) {
      $attr_list .= $DELIMITER . $attr_name;
   }
}

# call lsrsrcdef-api to get the attribute information
if ($Trace) { print STDERR "$PROGNAME: calling lsrsrcdef-api\n";}

@lsr_out = `$CTBINDIR/lsrsrcdef-api -I $DELIMITER -D $DELIMITER -d $cmd_flg "${resource}${attr_list}${DELIMITER}*p${properties}" 2>&1`;

# capture the return code from lsrsrcdef-api
$rc = $?;
$rc = process_exit_code($rc);

if ($Trace) { print STDERR "lsrsrcdef-api results:\n";
          print STDERR "@lsr_out";
          print STDERR "$PROGNAME: lsrsrcdef-api returned $rc\n";}

# show any errors if there was a bad rc
if ($rc != 0) {
   process_api_error($DELIMITER,$rc,@lsr_out);
}

# remove any error messages from the output to display
@lsr_out = remove_api_error($DELIMITER,@lsr_out);

@$response = @lsr_out;

return $rc;
}   # end qdef_p_attribute


#--------------------------------------------------------------------#
# qdef_valid_vals - function to call the CT::MC::qdef_valid_         #
#   values_bp extension.                                             #
#                                                                    #
# Parameters:                                                        #
#   $session          input   RMC session handle.                    #
#   $resource         input   Name of the resource class whose attr  #
#                             definitions we want.                   #
#   @$r_attributes    input   Reference to array of attribute names. #
#   $response         in/out  Response data structure, on output     #
#                             this will point to the real resposne.  #
#   $usage            input   One of mc_vv_usage_t enum types.       #
#                                                                    #
# Return:                                                            #
#   $rc                       return code.                           #
#                                                                    #
# Global References:                                                 #
#   $Opt_Exp_Desc     input   TRUE if display def & description.     #
#                                                                    #
#TODO: While support for retrieving valid values through action      #
#      invokation is documented in the API, as of 8/6/01, it has not # 
#      yet been implemented. Once it is implemented in the RMC C API,# 
#      support for retrieving valid values using actions should be   # 
#      added to this command.                                        # 
#--------------------------------------------------------------------#
sub qdef_valid_vals
{
my ($session, $resource, $r_attributes, $response, $usage) = @_;
my $rc = 0;
 
my $error = CT::MC::errnum_t->new;

my $options = $Opt_Exp_Desc ? MC_QDEF_OPTS_NONE : MC_QDEF_OPTS_NODSCRP;

my $attr_count = scalar(@$r_attributes); 

$Trace && print STDERR "Calling CT::MC::qdef_valid_values_bp\n";

$rc = CT::MC::qdef_valid_values_bp($session, $response, $error,
                                   $options, $resource, $usage,
                                   $r_attributes, $attr_count);

$Trace && print STDERR "Return  CT::MC::qdef_valid_values_bp\n";

$rc = error_check("mc_qdef_valid_values_bp", $resource, $response, 
    $rc, $error);

return $rc;
}   # end qdef_valid_vals


#--------------------------------------------------------------------#
# qdef_d_attribute - function to call lsrsrcdef-api to get           #
#   dynamic attribute information for attributes or class            #
#   attributes.                                                      #
#                                                                    #
# Parameters:                                                        #
#   $resource         input   Name of the resource class whose attr  #
#                             definitions we want.                   #
#   @$r_attributes    input   Reference to array of attribute names. #
#   @$response        in/out  Result from lsrsrcdef-api.             #
#                                                                    #
# Return:                                                            #
#   $rc                       return code.                           #
#                                                                    #
# Global References:                                                 #
#   $Opt_Exp_Desc     input   TRUE if display def & description.     #
#   $Opt_LS_Class     input   TRUE if display resource class dyna    #
#                             def versus the resource dyna def.      #
#--------------------------------------------------------------------#
sub qdef_d_attribute 
{
my ($resource, $r_attributes, $response, $properties) = @_;
my $rc = 0;
my @lsr_out = ();
my $cmd_flg = "";
my $attr_list = "";
my $attr_name = "";

# are descriptions needed?
if ($Opt_Exp_Desc) { $cmd_flg = "-q";}

my $attr_count = scalar(@$r_attributes);

# decide which attrs to list, class or resource
if ($Opt_LS_Class) { $cmd_flg .= " -c";}
else { $cmd_flg .= " -r";}

# build attr list for lsrsrcdef
if ($#$r_attributes >= 0) {
   foreach $attr_name (@$r_attributes) {
      $attr_list .= $DELIMITER . $attr_name;
   }
}

# call lsrsrcdef-api to get the attribute information
if ($Trace) { print STDERR "$PROGNAME: calling lsrsrcdef-api\n";}

@lsr_out = `$CTBINDIR/lsrsrcdef-api -I $DELIMITER -D $DELIMITER -d $cmd_flg "${resource}${attr_list}${DELIMITER}*d${properties}" 2>&1`;

# capture the return code from lsrsrcdef-api
$rc = $?;
$rc = process_exit_code($rc);

if ($Trace) { print STDERR "lsrsrcdef-api results:\n";
          print STDERR "@lsr_out";
          print STDERR "$PROGNAME: lsrsrcdef-api returned $rc\n";}

# show any errors if there was a bad rc
if ($rc != 0) {
   process_api_error($DELIMITER,$rc,@lsr_out);
}

# remove any error messages from the output to display
@lsr_out = remove_api_error($DELIMITER,@lsr_out);

@$response = @lsr_out;

return $rc;
}   # end qdef_d_attribute


#--------------------------------------------------------------------#
# qdef_sd - function to call lsrsrcdep-api to get SD data.           #
#                                                                    #
# Parameters:                                                        #
#   $resource         input   Name of the resource class whose SD    #
#                             definitions we want.                   #
#   @$r_attributes    input   Reference to array of attribute names. #
#   @$response        in/out  lsrsrcdef-api output.                  #
#                                                                    #
# Return:                                                            #
#   $rc                       return code.                           #
#                                                                    #
# Global References:                                                 #
#   $Opt_Exp_Desc     input   TRUE if display def & description.     #
#   $Opt_LS_Class     input   TRUE if display resource class SD def  #
#                             versus the resource SD def.            #
#   $Opt_LS_PAttr     input   TRUE if display persistent attr.       #
#   $Opt_LS_DAttr     input   TRUE if display dynamic attributes.    #
#--------------------------------------------------------------------#
sub qdef_sd
{
my ($resource, $r_attributes, $response) = @_;
my $rc = 0;
my $cmd_flg = "";
my $attr_name = "";
my $attr_list = "";
my @lsr_out = ();
 
# are descriptions needed?
if ($Opt_Exp_Desc) { $cmd_flg = "-q";}

my $attr_count = scalar(@$r_attributes);

# decide which attrs to list, class or resource
if ($Opt_LS_Class) { $cmd_flg .= " -S";}
else { $cmd_flg .= " -s";}

# build attr list for lsrsrcdef-api
if ($#$r_attributes >= 0) {
   foreach $attr_name (@$r_attributes) {
      $attr_list .= $DELIMITER . $attr_name;
   }
}

# call lsrsrcdef-api to get the attribute information
if ($Trace) { print STDERR "calling lsrsrcdef-api\n";}

@lsr_out = `$CTBINDIR/lsrsrcdef-api -I $DELIMITER -D $DELIMITER $cmd_flg "${resource}${attr_list}" 2>&1`;

# capture the return code from lsrsrcdef-api
$rc = $?;
$rc = process_exit_code($rc);

if ($Trace) { print STDERR "lsrsrcdef-api results:\n";
          print STDERR "@lsr_out";
          print STDERR "$PROGNAME: lsrsrcdef-api returned $rc\n";}

# show any errors if there was a bad rc
if ($rc != 0) {
   process_api_error($DELIMITER,$rc,@lsr_out);
}

# remove any error messages from the output to display
@lsr_out = remove_api_error($DELIMITER,@lsr_out);

@$response = @lsr_out;

return $rc;
}   # end qdef_sd


#--------------------------------------------------------------------#
# select_SD_attr - function to determine which attributes are        #
#   structured data type (ct_sd_ptr or ct_sd_ptr_array). Also        #
#   determines which SD attributes have at least one of the          #
#   specified properties or was listed on the command line.          #
#                                                                    #
# Parameters:                                                        #
#   $resource         in      Resource class name.                   #
#   $req_properties   in      Return attributes with these props.    #
#   @$r_attr_names    in/out  Reference to list of attributes        #
#                             On input attributes from command line  #
#                             (if any).                              #
#                             On output filtered list of attr names. #
#                                                                    #
# Return:                                                            #
#   $rc                       return code.                           #
#                                                                    #
# Global References:                                                 #
#   $Opt_LS_Class     input   TRUE if display resource class versus  #
#                             the resource.                          #
#   $Opt_LS_PAttr     input   TRUE if display persistent attributes. #
#   $Opt_LS_DAttr     input   TRUE if display dynamic attributes.    #
#--------------------------------------------------------------------#
sub select_SD_attr
{
my ($resource, $req_properties, $r_attr_names) = @_;

my @LoAttrDefs = ();                   # Attr Names, the key
                                       # in HoAttrDefs in rsp order
my %HoAttrDefs = ();                   # Complex Hash of 
                                       # attr names and definitions

my @req_attributes = ();               # Required / filtered attrs
my $attribute;
my $rc = 0;

# Get the attribute definitions filtering out any attribute that 
# does not have one of the specified properties unless it is in the
# list of required attributes. Also verifies the attr names are valid.
if ($Opt_LS_PAttr) {
#   $req_properties = "";
    $rc = get_p_attr_defs_api($resource, $Opt_LS_Class,
        $req_properties, $r_attr_names, \@LoAttrDefs, \%HoAttrDefs);
    ($rc == 0) || return($rc);
}

if ($Opt_LS_DAttr) {
#   $req_properties = "";
    $rc = get_d_attr_defs_api($resource, $Opt_LS_Class,
        $req_properties, $r_attr_names, \@LoAttrDefs, \%HoAttrDefs);
    ($rc == 0) || return($rc);
}

# Filter out any attribute with a data type other than 
# ct_sd_ptr or ct_sd_ptr_array.
foreach $attribute (@LoAttrDefs) {
    if (($HoAttrDefs{$attribute}{at_dtype} =~ /^CT_SD_PTR$/) ||
        ($HoAttrDefs{$attribute}{at_dtype} =~ /^CT_SD_PTR_ARRAY$/)) {
        push @req_attributes, $attribute;
    }           
    else {
        delete $HoAttrDefs{$attribute};
    }
}   

# Push the list of required attributes after filtering onto 
# the list of attributes that will be displayed
# If any attributes were specified on the command line they 
# override the filtered list of required attributes
if (scalar(@$r_attr_names) == 0) {
    foreach $attribute (@req_attributes) {
        push @$r_attr_names, $attribute;
    }   
}

return $rc;
}   # end select_SD_attr


#--------------------------------------------------------------------#
# format_class_attributes - formats the resource class attributes    #
#   into a complex hash of attribute elements %rHoAttr) which can    #
#   then be easily displayed using utility display_resource_data.    #
#                                                                    #
# Parameters:                                                        #
#   $resource         input   Resource Name                          #
#   $response         input   output from lsrsrcdef-api.             #
#   @$rLoCAttr        in/out  Reference to the list of class defn    #
#                             attributes that are also in HoCAttr.   #
#   %$rHoCAttr        in/out  Reference to the hash of class defn    #
#                             attributes.                            #
#                                                                    #
# Global References:                                                 #
#   None.                                                            #
#--------------------------------------------------------------------#
sub format_class_attributes 
{
my($resource, $response, $rLoCAttr, $rHoCAttr, 
    $rLoCMgrAttr, $rHoCMgrAttr) = @_;

my($name, $r, $j);

# format each of the attribute in the response structure so 
# can use more generic printing....
my %HoRspAttr = ( 
    "class_name"            => 1,
    "class_id"              => 1,
    "properties"            => 1,
    "display_name"          => 1,
    "description"           => 1,
    "locator"               => 1,
    "class_pattr_count"     => 1,
    "class_dattr_count"     => 1,
    "class_action_count"    => 1,
    "pattr_count"           => 1,
    "dattr_count"           => 1,
    "action_count"          => 1,
    "error_count"           => 1,
    "rsrc_mgrs"             => 1,
    "rsrc_mgr_count"        => 1
);  

# Hash of Hash of mc_rsrc_mgr_t attributes 
my %HoMgrAttr = (
    "mgr_name"              => 1, 
    "first_key"             => 1,
    "last_key"              => 1
);

my %elements = ();
my @class_info = ();

# go through the lsrsrcdef-api out and assign the values in order
chomp($$response[0]);
@class_info = split (/$DELIMITER/, $$response[0]);
$r = 0;

%elements = ();
$elements{at_name} = "class_name";
$elements{at_dtype} = "CT_CHAR_PTR";
$elements{at_value} = $class_info[0];
build_HoAttr($elements{at_name}, $rLoCAttr, $rHoCAttr, \%elements, $r);

%elements = ();
$elements{at_name} = "class_id";
$elements{at_dtype} = "CT_UINT32";
$elements{at_value} = $class_info[1];
build_HoAttr($elements{at_name}, $rLoCAttr, $rHoCAttr, \%elements, $r);

%elements = ();
$elements{at_name} = "properties";
$elements{at_dtype} = "CT_CHAR_PTR_ARRAY";
$elements{at_value} = $class_info[2];
build_HoAttr($elements{at_name}, $rLoCAttr, $rHoCAttr, \%elements, $r);

%elements = ();
$elements{at_name} = "display_name";
$elements{at_dtype} = "CT_CHAR_PTR";
$elements{at_value} = $class_info[3];
build_HoAttr($elements{at_name}, $rLoCAttr, $rHoCAttr, \%elements, $r);

%elements = ();
$elements{at_name} = "description";
$elements{at_dtype} = "CT_CHAR_PTR";
$elements{at_value} = $class_info[4];
build_HoAttr($elements{at_name}, $rLoCAttr, $rHoCAttr, \%elements, $r);

%elements = ();
$elements{at_name} = "locator";
$elements{at_dtype} = "CT_CHAR_PTR";
$elements{at_value} = $class_info[5];
build_HoAttr($elements{at_name}, $rLoCAttr, $rHoCAttr, \%elements, $r);

%elements = ();
$elements{at_name} = "class_pattr_count";
$elements{at_dtype} = "CT_UINT32";
$elements{at_value} = $class_info[6];
build_HoAttr($elements{at_name}, $rLoCAttr, $rHoCAttr, \%elements, $r);

%elements = ();
$elements{at_name} = "class_dattr_count";
$elements{at_dtype} = "CT_UINT32";
$elements{at_value} = $class_info[7];
build_HoAttr($elements{at_name}, $rLoCAttr, $rHoCAttr, \%elements, $r);

%elements = ();
$elements{at_name} = "class_action_count";
$elements{at_dtype} = "CT_UINT32";
$elements{at_value} = $class_info[8];
build_HoAttr($elements{at_name}, $rLoCAttr, $rHoCAttr, \%elements, $r);

%elements = ();
$elements{at_name} = "pattr_count";
$elements{at_dtype} = "CT_UINT32";
$elements{at_value} = $class_info[9];
build_HoAttr($elements{at_name}, $rLoCAttr, $rHoCAttr, \%elements, $r);

%elements = ();
$elements{at_name} = "dattr_count";
$elements{at_dtype} = "CT_UINT32";
$elements{at_value} = $class_info[10];
build_HoAttr($elements{at_name}, $rLoCAttr, $rHoCAttr, \%elements, $r);

%elements = ();
$elements{at_name} = "action_count";
$elements{at_dtype} = "CT_UINT32";
$elements{at_value} = $class_info[11];
build_HoAttr($elements{at_name}, $rLoCAttr, $rHoCAttr, \%elements, $r);

%elements = ();
$elements{at_name} = "error_count";
$elements{at_dtype} = "CT_UINT32";
$elements{at_value} = $class_info[12];
build_HoAttr($elements{at_name}, $rLoCAttr, $rHoCAttr, \%elements, $r);

%elements = ();
$elements{at_name} = "rsrc_mgr_count";
$elements{at_dtype} = "CT_UINT32";
$elements{at_value} = $class_info[13];
my $rsrc_mgr_count = $class_info[13];
build_HoAttr($elements{at_name}, $rLoCAttr, $rHoCAttr, \%elements, $r);

chomp($$response[1]);
@class_info = split (/$DELIMITER/, $$response[1]);

for ($j = 0; $j < $rsrc_mgr_count; $j++) {
     %elements = ();
     $elements{at_name} = "mgr_name";
     $elements{at_dtype} = "CT_CHAR_PTR";
     $elements{at_value} = $class_info[$j*3];
     build_HoAttr($elements{at_name}, $rLoCMgrAttr, $rHoCMgrAttr, \%elements, $j);

      %elements = ();
      $elements{at_name} = "first_key";
      $elements{at_dtype} = "CT_UINT32";
      $elements{at_value} = $class_info[$j*3+1];   
      build_HoAttr($elements{at_name}, $rLoCMgrAttr, $rHoCMgrAttr, \%elements, $j);

      %elements = ();
      $elements{at_name} = "last_key";
      $elements{at_dtype} = "CT_UINT32";
      $elements{at_value} = $class_info[$j*3+2];   
      build_HoAttr($elements{at_name}, $rLoCMgrAttr, $rHoCMgrAttr, \%elements, $j);
}

return;
}   # end of format_class_attributes


#--------------------------------------------------------------------#
# format_p_attr_for_input - formats the persistent attributes into   #
#   an input format suitable for mkrsrc or chrsrc. Formats the       #
#   persistent attributes into a complex hash of attribute elements  #
#   which can then be easily displayed using utility                 #
#   dislay_resouce_data.                                             #
#                                                                    #
# Parameters:                                                        #
#   $resource         input   Resource Name                          #
#   $response         input   Response data structure.               #
#   $req_properties   input   Requested properties - only put the    #
#                             attributes in the hash that have these #
#                             requested properties.                  #
#   @$r_attributes    input   Reference to the list of attributes    #
#                             to be displayed, if empty display all  #
#                             attributes.                            #
#   @$rLoPAttr        in/out  Reference to the list of persistent    #
#                             attributes that are also in HoPAttr.   #
#   %$rHoPAttr        in/out  Reference to the hash of persistent    #
#                             attributes.                            #
#                                                                    #
# Global References:                                                 #
#   None.                                                            #
#--------------------------------------------------------------------#
sub format_p_attr_for_input
{
my($resource, $response, $req_properties, $r_attributes,
    $rLoPAttr, $rHoPAttr) = @_;

my($attr_name, $r);

# format each of the attribute in the response structure so
# can use more generic printing....

my %elements = ();
my @r_info = ();
my $at_data_type = "";
my $response_cnt = $#$response;

# go through the lsrsrcdef-api out and assign the values in order
for ($r = 0; $r <= $response_cnt; $r++) {

    chomp($$response[$r]);
    @r_info = split (/$DELIMITER/, $$response[$r]);

    # Filter out the attributes that should not be displayed
    # Attributes requested as operand to this command always get
    # displayed ($r_attributes), otherwise display any attribute
    # that has one of the requested properties.
#   (required_attr($response->program_name($r),
#       $response->properties($r), $r_attributes, $req_properties)) ||
#       next;
    $attr_name = $r_info[0];
    $attr_name =~ s/^\"//;
    $attr_name =~ s/\"$//;

    (required_attr2($attr_name, $r_attributes)) || next;

    # Filter out attributes that have already been processed
    (exists $rHoPAttr->{$attr_name}) && next;

    %elements = ();
    $elements{at_name}  = $attr_name; 
    $elements{at_id}    = $r_info[5];
    $elements{at_dtype} = "CT_CHAR_PTR";
    $at_data_type = $r_info[7];
    $at_data_type =~ s/^CT_//;
    $at_data_type = lc $at_data_type;
    $at_data_type =~ s/^none$/ct_none/;
    $elements{at_value} = "\"".$at_data_type."\"";
    build_HoAttr($elements{at_name}, $rLoPAttr, $rHoPAttr, \%elements, 0);

}   # end for responses

return;
}   # end of format_p_attr_for_input



#--------------------------------------------------------------------#
# format_p_attributes - formats the persistent attributes into a     #
#   complex hash of attribute elements (%rHoAttr) which can then     #
#   be easily displayed using utility dislay_resouce_data.           #
#                                                                    #
# Parameters:                                                        #
#   $resource         input   Resource Name                          #
#   @$response        input   output from lsrsrcdef-api.             #
#   $req_properties   input   Requested properties - only put the    #
#                             attributes in the hash that have these #
#                             requested properties.                  #
#   @$r_attributes    input   Reference to the list of attributes    #
#                             to be displayed, if empty display all  #
#                             attributes.                            #
#   @$rLoPAttr        in/out  Reference to the list of persistent    #
#                             attributes that are also in HoPAttr.   #
#   %$rHoPAttr        in/out  Reference to the hash of persistent    #
#                             attributes.                            #
#   $response_vv      input   Valid values response structure.       #
#                                                                    #
# Global References:                                                 #
#   $Opt_Valid_Vals   input   True if valid values are being         #
#                             displayed.                             #
#--------------------------------------------------------------------#
sub format_p_attributes
{
my($resource, $response, $req_properties, $r_attributes, 
    $rLoPAttr, $rHoPAttr, $response_vv) = @_;

my($name, $r, $attr_defn, $attr_msg_nm, $deflt_val);

# format each of the attribute in the response structure so
# can use more generic printing....

# List of field names in the qdef_pattr_rsp_t
my %HoRspAttr = (
    "program_name"      => 1,
    "display_name"      => 1,
    "group_name"        => 1,
    "properties"        => 1,
    "description"       => 1,
    "attribute_id"      => 1,
    "group_id"          => 1,
    "data_type"         => 1,
    "variety_list"      => 1,
    "variety_count"     => 1,
    "default_value"     => 1,
    "valid_vals"        => $Opt_Valid_Vals,
    "valid_vals_label"  => $Opt_Valid_Vals
);

my %elements = ();
my @r_info = ();
my $at_data_type = "";
my $SDdef_retr = $FALSE;                # indicate if SD infor available
my %SDdefs = ();                        # SD definitions
my @out_attrs = ();                     # list of attrs
my $z = 0;
my $tmp_name = "";
my $tmp_attr_name = "";
my @junk = ();

my $response_cnt = $#$response;
my $a = 0;

# go through the lsrsrcdef-api out and assign the values in order
for ($r = 0; $r <= $response_cnt; $r++) {

    chomp($$response[$r]);
    @r_info = split (/$DELIMITER/, $$response[$r]);

    # Filter out the attributes that should not be displayed
    # Attributes requested as operand to this command always get
    # displayed ($r_attributes), otherwise display any attribute
    # that has one of the requested properties.
#   (required_attr($response->program_name($r), 
#       $response->properties($r), $r_attributes, $req_properties)) ||  
#       next;   
    (required_attr2($r_info[0], $r_attributes)) || next;

    # find whether the attribute is persistent or dynamic
    # if it's dynamic, show error and exit. it should be persistent
    # (this is how the manpage says it should work)
    $attr_defn = $r_info[$#r_info];
    if ($attr_defn =~ /d/) {
       $attr_msg_nm = $r_info[0];
       $attr_msg_nm =~ s/\"//g;
       printCEMsg("EMsgMCcliInvalidAttrName", $attr_msg_nm);
       exit MC_CLI_USER_ERROR;
    }

    %elements = ();
    $elements{at_name} = "program_name";
    $elements{at_dtype} = "CT_CHAR_PTR";
    $elements{at_value} = $r_info[0];
    build_HoAttr($elements{at_name}, $rLoPAttr, $rHoPAttr, \%elements, $a);
    
    %elements = ();
    $elements{at_name}  = "display_name";
    $elements{at_dtype} = "CT_CHAR_PTR";
    $elements{at_value} = $r_info[1];
    build_HoAttr($elements{at_name}, $rLoPAttr, $rHoPAttr, \%elements, $a);

    %elements = ();
    $elements{at_name} = "group_name";
    $elements{at_dtype} = "CT_CHAR_PTR";    
    $elements{at_value} = $r_info[2];
    build_HoAttr($elements{at_name}, $rLoPAttr, $rHoPAttr, \%elements, $a);

    %elements = ();
    $elements{at_name} = "properties";
    $elements{at_dtype} = "CT_CHAR_PTR_ARRAY";
    $elements{at_value} = $r_info[3];
    build_HoAttr($elements{at_name}, $rLoPAttr, $rHoPAttr, \%elements, $a);

    %elements = ();
    $elements{at_name} = "description";
    $elements{at_dtype} = "CT_CHAR_PTR";
    $elements{at_value} = $r_info[4];
    build_HoAttr($elements{at_name}, $rLoPAttr, $rHoPAttr, \%elements, $a);
    
    %elements = ();
    $elements{at_name} = "attribute_id";
    $elements{at_dtype} = "CT_INT32";
    $elements{at_value} = $r_info[5];
    build_HoAttr($elements{at_name}, $rLoPAttr, $rHoPAttr, \%elements, $a);

    %elements = ();
    $elements{at_name} = "group_id";
    $elements{at_dtype} = "CT_UINT32";
    $elements{at_value} = $r_info[6];
    build_HoAttr($elements{at_name}, $rLoPAttr, $rHoPAttr, \%elements, $a);

    %elements = ();
    $elements{at_name} = "data_type";
    $elements{at_dtype} = "CT_CHAR_PTR";
    $at_data_type = $r_info[7];
    $at_data_type =~ s/^CT_//;
    $at_data_type = lc $at_data_type;
    $at_data_type =~ s/^none$/ct_none/;
    $elements{at_value} = "\"".$at_data_type."\"";
    build_HoAttr($elements{at_name}, $rLoPAttr, $rHoPAttr, \%elements, $a);

    %elements = ();
    $elements{at_name} = "variety_list";
    $elements{at_dtype} = "CT_SD_PTR_ARRAY";
    $elements{at_value} = $r_info[8];
    build_HoAttr($elements{at_name}, $rLoPAttr, $rHoPAttr, \%elements, $a);

    %elements = ();
    $elements{at_name} = "variety_count";
    $elements{at_dtype} = "CT_UINT32";
    $elements{at_value} = $r_info[9];
    build_HoAttr($elements{at_name}, $rLoPAttr, $rHoPAttr, \%elements, $a);

    %elements = ();
    $elements{at_name} = "default_value";
    $elements{at_dtype} = $r_info[7];
    $deflt_val = $r_info[10];

    # format the default value if binary, handle or SD
    if ( ($r_info[7] =~ /^CT_BINARY_PTR/) ||
         ($r_info[7] =~ /^CT_RSRC_HANDLE_PTR/) ||
         ($r_info[7] =~ /^CT_SD_PTR/) ) {

       $tmp_attr_name = $r_info[0];
       $tmp_attr_name =~ s/^\"//;
       $tmp_attr_name =~ s/\"$//;

       if (!$SDdef_retr) {
          # create list of attribute names
          for ($z=0; $z<= $#$response; $z++) {
              ($tmp_name, @junk) =  split (/$DELIMITER/, $$response[$z]);
              $tmp_name =~ s/\"//g;
              push @out_attrs, $tmp_name;
          }
       }

       # function call format is value, name, type, class, class_flg,
       #   SDdef_retr, attributes, SDdefs
       ($deflt_val, $SDdef_retr) =
           format_value_for_display($deflt_val,$tmp_attr_name,
               $r_info[7], $resource, $Opt_LS_Class, $SDdef_retr,
               \@out_attrs, \%SDdefs);
    }

    $elements{at_value} = $deflt_val;
    build_HoAttr($elements{at_name}, $rLoPAttr, $rHoPAttr, \%elements, $a);
 
    #  TODO: Do we want a valid values field present at all times? 
    #        (Or just there when "-v" flag is given, as is the case now?)

    if ($HoRspAttr{"valid_vals"}) {
        %elements = ();
        $elements{at_name} = "valid_vals";
        ($elements{at_dtype}, $elements{at_value}) = 
            convert_valid_values($response_vv, $r, $response_vv->count($r),
                                 $data_type);
        build_HoAttr($elements{at_name}, $rLoPAttr, $rHoPAttr, \%elements, $a);
    }

    if ($HoRspAttr{"valid_vals_label"}) {
        %elements = ();
        $elements{at_name} = "valid_vals_label";
        ($elements{at_dtype}, $elements{at_value}) = 
            convert_valid_values_label($response_vv, $r,
                                       $response_vv->count($r), $data_type);
        build_HoAttr($elements{at_name}, $rLoPAttr, $rHoPAttr, \%elements, $a);
    }

    $a = $a + 1;
}   # end for responses

return;
}   # end of format_p_attributes


#--------------------------------------------------------------------#
# format_d_attributes - formats the dynamic attributes into a        #
#   complex hash of attribute elements (%rHoAttr) which can then     #
#   be easily displayed using utility display_resource_data.         #
#                                                                    #
# Parameters:                                                        #
#   $resource         input   Resource Name                          #
#   @$response        input   output from lsrsrcdef-api.             #
#   $req_properties   input   Requested properties - only put the    #
#                             attributes in the hash that have these #
#                             requested properties.                  #
#   @$r_attributes    input   Reference to the list of attributes    #
#                             to be displayed, if empty display all  #
#                             attributes.                            #
#   @$rLoDAttr        in/out  Reference to the list of dynamic       #
#                             attributes that are also in HoDAttr.   #
#   %$rHoDAttr        in/out  Reference to the hash of dynamic       #
#                             attributes.                            #
#   $response_vv      input   Valid values response structure.       #
#                                                                    #
# Global References:                                                 #
#   $Opt_Valid_Vals   input  TRUE if attr valid values are being     #
#                            displayed.                              #
#--------------------------------------------------------------------#
sub format_d_attributes
{
my($resource, $response, $req_properties, $r_attributes, 
    $rLoDAttr, $rHoDAttr, $response_vv) = @_;

my($name, $r, $attr_defn, $attr_msg_nm);

# format each of the attribute in the response structure so
# can use more generic printing....

# List of field names in the qdef_dattr_rsp_t
my %HoRspAttr = (
    "attribute"                 => 1,
    "program_name"              => 1,
    "display_name"              => 1,
    "group_name"                => 1,
    "properties"                => 1,
    "description"               => 1,
    "attribute_id"              => 1,
    "group_id"                  => 1,
    "data_type"                 => 1,
    "variable_type"             => 1,
    "variety_list"              => 1,
    "variety_count"             => 1,
    "init_value"                => 1,
    "min_value"                 => 1,
    "max_value"                 => 1,
    "expression"                => 1,
    "expression_description"    => 1,
    "rearm_expression"          => 1,
    "rearm_description"         => 1,
    "PTX_name"                  => 1,
    "reporting_interval"        => 1,
    "valid_vals"                => $Opt_Valid_Vals,
    "valid_vals_label"          => $Opt_Valid_Vals
);

my %elements = ();
my @r_info = ();
my $at_data_type = "";
my $response_cnt = $#$response;
my $a = 0;

my $SDdef_retr = $FALSE;                # indicate if SD infor available
my %SDdefs = ();                        # SD definitions
my @out_attrs = ();                     # list of attrs
my $z = 0;
my $tmp_name = "";
my @junk = ();

# go through the lsrsrcdef-api out and assign the values in order
for ($r = 0; $r <= $response_cnt; $r++) {

    chomp($$response[$r]);
    @r_info = split (/$DELIMITER/, $$response[$r]);

    # Filter out the attributes that should not be displayed
    # Attributes requested as operand to this command always get
    # displayed ($r_attributes), otherwise display any attribute
    # that has one of the requested properties.
#   (required_attr($response->program_name($r), 
#       $response->properties($r), $r_attributes, $req_properties)) ||
#       next;   
    (required_attr2($r_info[0], $r_attributes)) || next;

    # find whether the attribute is persistent or dynamic
    # if it's persistent, show error and exit. it should be dynamic
    # (this is how the manpage says it should work)
    $attr_defn = $r_info[$#r_info];
    if ($attr_defn =~ /p/) {
       $attr_msg_nm = $r_info[0];
       $attr_msg_nm =~ s/\"//g;
       printCEMsg("EMsgMCcliInvalidAttrName", $attr_msg_nm);
       exit MC_CLI_USER_ERROR;
    }

    %elements = ();
    $elements{at_name} = "program_name";
    $elements{at_dtype} = "CT_CHAR_PTR";
    $elements{at_value} = $r_info[0];
    build_HoAttr($elements{at_name}, $rLoDAttr, $rHoDAttr, \%elements, $a);

    %elements = ();
    $elements{at_name}  = "display_name";
    $elements{at_dtype} = "CT_CHAR_PTR";
    $elements{at_value} = $r_info[1];
    build_HoAttr($elements{at_name}, $rLoDAttr, $rHoDAttr, \%elements, $a);

    %elements = ();
    $elements{at_name} = "group_name";
    $elements{at_dtype} = "CT_CHAR_PTR";
    $elements{at_value} = $r_info[2];
    build_HoAttr($elements{at_name}, $rLoDAttr, $rHoDAttr, \%elements, $a);

    %elements = ();
    $elements{at_name} = "properties";
    $elements{at_dtype} = "CT_CHAR_PTR_ARRAY";
    $elements{at_value} = $r_info[3];
    build_HoAttr($elements{at_name}, $rLoDAttr, $rHoDAttr, \%elements, $a);

    %elements = ();
    $elements{at_name} = "description";
    $elements{at_dtype} = "CT_CHAR_PTR";
    $elements{at_value} = $r_info[4];
    build_HoAttr($elements{at_name}, $rLoDAttr, $rHoDAttr, \%elements, $a);

    %elements = ();
    $elements{at_name} = "attribute_id";
    $elements{at_dtype} = "CT_INT32";
    $elements{at_value} = $r_info[5];
    build_HoAttr($elements{at_name}, $rLoDAttr, $rHoDAttr, \%elements, $a);

    %elements = ();
    $elements{at_name} = "group_id";
    $elements{at_dtype} = "CT_UINT32";
    $elements{at_value} = $r_info[6];
    build_HoAttr($elements{at_name}, $rLoDAttr, $rHoDAttr, \%elements, $a);

    %elements = ();
    $elements{at_name} = "data_type";
    $elements{at_dtype} = "CT_CHAR_PTR";
    $at_data_type = $r_info[7];
    $at_data_type =~ s/^CT_//;
    $at_data_type = lc $at_data_type;
    $at_data_type =~ s/^none$/ct_none/;
    $elements{at_value} = "\"".$at_data_type."\"";
    build_HoAttr($elements{at_name}, $rLoDAttr, $rHoDAttr, \%elements, $a);

    %elements = ();
    $elements{at_name} = "variable_type";
    $elements{at_dtype} = "CT_CHAR_PTR";
    $elements{at_value} = "\"".$r_info[8]."\"";
    build_HoAttr($elements{at_name}, $rLoDAttr, $rHoDAttr, \%elements, $a);

    %elements = ();
    $elements{at_name} = "variety_list";
    $elements{at_dtype} = "CT_SD_PTR_ARRAY";
    $elements{at_value} = $r_info[9];
    build_HoAttr($elements{at_name}, $rLoDAttr, $rHoDAttr, \%elements, $a);

    %elements = ();
    $elements{at_name} = "variety_count";
    $elements{at_dtype} = "CT_UINT32";
    $elements{at_value} = $r_info[10];
    build_HoAttr($elements{at_name}, $rLoDAttr, $rHoDAttr, \%elements, $a);

    %elements = ();
    $elements{at_name} = "init_value";
    $elements{at_dtype} = $at_data_type;

    # format the init_value if binary, handle or SD
    if ( ($r_info[7] =~ /^CT_BINARY_PTR/) ||
         ($r_info[7] =~ /^CT_RSRC_HANDLE_PTR/) ||
         ($r_info[7] =~ /^CT_SD_PTR/) ) {

       $tmp_attr_name = $r_info[0];
       $tmp_attr_name =~ s/^\"//;
       $tmp_attr_name =~ s/\"$//;

       if (!$SDdef_retr) {
          # create list of attribute names
          for ($z=0; $z<= $#$response; $z++) {
              ($tmp_name, @junk) =  split (/$DELIMITER/, $$response[$z]);
              $tmp_name =~ s/\"//g;
              push @out_attrs, $tmp_name;
          }
       }

       # function call format is value, name, type, class, class_flg,
       #   SDdef_retr, attributes, SDdefs
       ($r_info[11], $SDdef_retr) =
           format_value_for_display($r_info[11],$tmp_attr_name,
               $r_info[7], $resource, $Opt_LS_Class, $SDdef_retr,
               \@out_attrs, \%SDdefs);
    }
    $elements{at_value} = $r_info[11];
    build_HoAttr($elements{at_name}, $rLoDAttr, $rHoDAttr, \%elements, $a);

    %elements = ();
    $elements{at_name} = "min_value";
    $elements{at_dtype} = $at_data_type;

    # format the min_value if binary, handle or SD
    if ( ($r_info[7] =~ /^CT_BINARY_PTR/) ||
         ($r_info[7] =~ /^CT_RSRC_HANDLE_PTR/) ||
         ($r_info[7] =~ /^CT_SD_PTR/) ) {

       $tmp_attr_name = $r_info[0];
       $tmp_attr_name =~ s/^\"//;
       $tmp_attr_name =~ s/\"$//;

       if (!$SDdef_retr) {
          # create list of attribute names
          for ($z=0; $z<= $#$response; $z++) {
              ($tmp_name, @junk) =  split (/$DELIMITER/, $$response[$z]);
              $tmp_name =~ s/\"//g;
              push @out_attrs, $tmp_name;
          }
       }

       # function call format is value, name, type, class, class_flg,
       #   SDdef_retr, attributes, SDdefs
       ($r_info[12], $SDdef_retr) =
           format_value_for_display($r_info[12],$tmp_attr_name,
               $r_info[7], $resource, $Opt_LS_Class, $SDdef_retr,
               \@out_attrs, \%SDdefs);
    }
    $elements{at_value} = $r_info[12];
    build_HoAttr($elements{at_name}, $rLoDAttr, $rHoDAttr, \%elements, $a);

    %elements = ();
    $elements{at_name} = "max_value";
    $elements{at_dtype} = $at_data_type;

    # format the max_value if binary, handle or SD
    if ( ($r_info[7] =~ /^CT_BINARY_PTR/) ||
         ($r_info[7] =~ /^CT_RSRC_HANDLE_PTR/) ||
         ($r_info[7] =~ /^CT_SD_PTR/) ) {

       $tmp_attr_name = $r_info[0];
       $tmp_attr_name =~ s/^\"//;
       $tmp_attr_name =~ s/\"$//;

       if (!$SDdef_retr) {
          # create list of attribute names
          for ($z=0; $z<= $#$response; $z++) {
              ($tmp_name, @junk) =  split (/$DELIMITER/, $$response[$z]);
              $tmp_name =~ s/\"//g;
              push @out_attrs, $tmp_name;
          }
       }

       # function call format is value, name, type, class, class_flg,
       #   SDdef_retr, attributes, SDdefs
       ($r_info[13], $SDdef_retr) =
           format_value_for_display($r_info[13],$tmp_attr_name,
               $r_info[7], $resource, $Opt_LS_Class, $SDdef_retr,
               \@out_attrs, \%SDdefs);
    }
    $elements{at_value} = $r_info[13];
    build_HoAttr($elements{at_name}, $rLoDAttr, $rHoDAttr, \%elements, $a);

    %elements = ();
    $elements{at_name} = "expression";
    $elements{at_dtype} = "CT_CHAR_PTR";
    $elements{at_value} = $r_info[14];
    build_HoAttr($elements{at_name}, $rLoDAttr, $rHoDAttr, \%elements, $a);

    %elements = ();
    $elements{at_name} = "expression_description";
    $elements{at_dtype} = "CT_CHAR_PTR";
    $elements{at_value} = $r_info[15];
    build_HoAttr($elements{at_name}, $rLoDAttr, $rHoDAttr, \%elements, $a);

    %elements = ();
    $elements{at_name} = "rearm_expression";
    $elements{at_dtype} = "CT_CHAR_PTR";
    $elements{at_value} = $r_info[16];
    build_HoAttr($elements{at_name}, $rLoDAttr, $rHoDAttr, \%elements, $a);

    %elements = ();
    $elements{at_name} = "rearm_description";
    $elements{at_dtype} = "CT_CHAR_PTR";
    $elements{at_value} = $r_info[17];
    build_HoAttr($elements{at_name}, $rLoDAttr, $rHoDAttr, \%elements, $a);

    %elements = ();
    $elements{at_name} = "PTX_name";
    $elements{at_dtype} = "CT_CHAR_PTR";
    $elements{at_value} = $r_info[18];
    build_HoAttr($elements{at_name}, $rLoDAttr, $rHoDAttr, \%elements, $a);

    %elements = ();
    $elements{at_name} = "reporting_interval";
    $elements{at_dtype} = "CT_UINT32";
    $elements{at_value} = $r_info[19];
    build_HoAttr($elements{at_name}, $rLoDAttr, $rHoDAttr, \%elements, $a);

    if ($HoRspAttr{"valid_vals"}) {
        %elements = ();
        $elements{at_name} = "valid_vals";
        ($elements{at_dtype}, $elements{at_value}) = 
            convert_valid_values($response_vv, $r, $response_vv->count($r),
                                 $data_type);
        build_HoAttr($elements{at_name}, $rLoDAttr, $rHoDAttr, \%elements, $a);
    }

    if ($HoRspAttr{"valid_vals_label"}) {
        %elements = ();
        $elements{at_name} = "valid_vals_label";
        ($elements{at_dtype}, $elements{at_value}) = 
            convert_valid_values_label($response_vv, $r,
                                       $response_vv->count($r), $data_type);
        build_HoAttr($elements{at_name}, $rLoDAttr, $rHoDAttr, \%elements, $a);
    }    

    $a = $a + 1;
}   # end for responses

return;
}   # end of format_d_attributes


#--------------------------------------------------------------------#
# format_sd_defs - formats the structured data definitions for       #
#   resource or resource class dynamic or persistent SD attributes.  #
#   0 or more SDs may have been defined. A complex hash is           #
#   constructed -                                                    #
#      level 1:  Complex hash                                        #
#                key is attribute name (see mc_sd_rsp_t in ct_mc.h)  #
#                data hash of definition data for an SD.             #
#      level 2:  Complex hash                                        #
#                key is field_name (see mc_sd_element_t in ct_mc.h)  #
#                data value                                          #
#      x $rHoSDDefs - to really see what is created.                 #
#      x $$rHoSDDefs{$response->program_name($r)} to see level 2.    #
#      The hash for each attribute (level 2) can be easily displayed #
#      using the MC_cli_display_utils::display_resource_data.        #
#                                                                    #
# Parameters:                                                        #
#   $resource         input   Resource Name                          #
#   $response         input   Response data structure.               #
#   @$r_attributes    input   Reference to the list of attributes    #
#                             to be displayed, if empty display all  #
#                             attributes.                            #
#   @$rLoSDAttr       in/out  Reference to the list of SD attributes #
#                             (elements) that are also in HoSDAttr.  #
#   %$rHoSDDefs       in/out  Reference to the hash of SD attributes #
#                             definitions (elements).                #
#   $response_vv      input   Valid values response structure.       #
#                                                                    #
# Global References:                                                 #
#   $Opt_Valid_Vals   input   TRUE if valid values are being         #
#                             displayed.                             #
#--------------------------------------------------------------------#
sub format_sd_defs
{
my($resource, $response, $r_attributes, $rLoSDAttr, $rHoSDDefs,
   $response_vv) = @_;

my %HoSDAttr = ();
my($name, $r);

# format each of the attribute in the response structure so
# can use more generic printing....

# List of field names in the qdef_sd_rsp_t (mc_sd_element_t)
my %HoRspAttr = (
    "element_name"          => 1,
    "display_name"          => 1,
    "description"           => 1,
    "element_data_type"     => 1,
    "element_index"         => 1,
    "valid_vals"            => $Opt_Valid_Vals,
    "valid_vals_label"      => $Opt_Valid_Vals
);

my %elements = ();
my @r_info = ();
my $at_data_type = "";
my $response_cnt = $#$response;
    %HoSDAttr = ();
    @$rLoSDAttr = ();

for ($r = 0; $r <= $response_cnt; $r++) {
    chomp($$response[$r]);
    @r_info = split (/$DELIMITER/, $$response[$r]);

#   %HoSDAttr = ();
#   @$rLoSDAttr = ();

        if ($HoRspAttr{"element_name"}) {
            %elements = ();
            $elements{at_name} = "element_name";
            $elements{at_dtype} = "CT_CHAR_PTR";
            $elements{at_value} = $r_info[1];
            build_HoAttr($elements{at_name}, $rLoSDAttr, \%HoSDAttr,
                \%elements, 0);
        }

        if ($HoRspAttr{"display_name"}) {
            %elements = ();
            $elements{at_name}  = "display_name";
            $elements{at_dtype} = "CT_CHAR_PTR";
            $elements{at_value} = $r_info[3];
            build_HoAttr($elements{at_name}, $rLoSDAttr, \%HoSDAttr,
                \%elements, 0);
        }

        if ($HoRspAttr{"description"}) {
            %elements = ();
            $elements{at_name} = "description";
            $elements{at_dtype} = "CT_CHAR_PTR";
            $elements{at_value} = $r_info[4];
            build_HoAttr($elements{at_name}, $rLoSDAttr, \%HoSDAttr, 
                \%elements, 0);
        }

        if ($HoRspAttr{"element_data_type"}) {
            %elements = ();
            $elements{at_name} = "element_data_type";
            $elements{at_dtype} = "CT_CHAR_PTR";
            $at_data_type = $r_info[2];
            $at_data_type =~ s/^CT_//;
            $at_data_type = lc $at_data_type;
            $at_data_type =~ s/^none$/ct_none/;
            $elements{at_value} = "\"".$at_data_type."\"";
            build_HoAttr($elements{at_name}, $rLoSDAttr, \%HoSDAttr,
                \%elements, 0);
        }

        if ($HoRspAttr{"element_index"}) {
            %elements = ();
            $elements{at_name}  = "element_index";
            $elements{at_dtype} = "CT_UINT32";
            $elements{at_value} = $r_info[5];
            build_HoAttr($elements{at_name}, $rLoSDAttr, \%HoSDAttr,
                \%elements, 0);
        } 

        if ( ($r == $response_cnt) || ($$response[$r+1] =~ /${DELIMITER}0\n$/) ) {

            # Put this SD Attribute definition in the hash with the rest of
            # the SD attributes definitions.
            $$rHoSDDefs{$r_info[0]} = { %HoSDAttr };
        }

        if ( ($r < $response_cnt) && ($$response[$r+1] =~ /${DELIMITER}0\n$/) ) {
            %HoSDAttr = ();
            @$rLoSDAttr = ();
        }
}   # end for each response

return;
}   # end of format_sd_defs


#--------------------------------------------------------------------#
# display_attributes - displays the attributes names and values for  #
#   each element stored in %$rHoAttr. Only the attributes that       #
#   are listed in the array $r_attributes are displayed using the    #
#   appropriate output format (long, delimitter, or tabular).        #
#   If $r_attributes is empty all attributes in %$rHoAttr are        #
#   displayed.                                                       #
#                                                                    #
# Parameters:                                                        #
#   $col_title        input   Title/Header that gets displayed       #
#                             before any attributes.                 #
#   $row_title        input   Title/Header that gets displayed       #
#                             before each new attribute.             #
#   @$r_attributes    input   Attribute names from command line.     #
#   @$rLoAttr         input   Reference to List of Attributes Names  #
#   %$rHoAttr         input   Reference to Hash of Attributes        #
#                                                                    #
# Returns:                                                           #
#   $rc                       Return code.                           #
#                                                                    #
# Global References:                                                 #
#   $Opt_Long_Format  input   TRUE if should display one per line.   #
#   $Opt_Table_Format input   TRUE if should display in table form.  #
#   $Opt_Delm_Format  input   TRUE if should display with delimiter. #
#   $Opt_Delm_Str     input   Actual delimiter to display with.      #
#   $Opt_No_HDR       input   TRUE if should not display header.     #
#--------------------------------------------------------------------#
sub display_attributes
{
my($col_title, $row_title, $r_attributes, $rLoAttr, $rHoAttr) = @_;

my $print_format = "long";
my $delim = "";

# Determine if displaying in long, delimiter or tabular/column format.
if ($Opt_Long_Format) {
    $print_format = "long";
}
elsif ($Opt_Table_Format) {
    $print_format = "column";
}
elsif ($Opt_Delm_Format) {
    $print_format = "delim";
    $delim = $Opt_Delm_Str;
}

# Display the attributes in the order that they were requested
# on the command line.  If no attribute names were specified on
# the command line display them in the order that RMC returned
# them.

if (scalar(@$r_attributes) == 0) {
    $r_attributes = $rLoAttr;
}

# For debugging to reference one element
# $rHoAttr->{$attr_name}[$row]{at_value}

my $rc = display_resource_data_api2($print_format, $Opt_No_HDR,
    $r_attributes, $row_title, $rHoAttr, $delim, $col_title);

return $rc;
}   # end display_attributes


#--------------------------------------------------------------------#
# display_attributes_api - displays the attributes names and values  #
#   for each element stored in %$rHoAttr. Only the attributes that   #
#   are listed in the array $r_attributes are displayed using the    #
#   appropriate output format (long, delimitter, or tabular).        #
#   If $r_attributes is empty all attributes in %$rHoAttr are        #
#   displayed.                                                       #
#                                                                    #
# Parameters:                                                        #
#   $col_title        input   Title/Header that gets displayed       #
#                             before any attributes.                 #
#   $row_title        input   Title/Header that gets displayed       #
#                             before each new attribute.             #
#   @$r_attributes    input   Attribute names from command line.     #
#   @$rLoAttr         input   Reference to List of Attributes Names  #
#   %$rHoAttr         input   Reference to Hash of Attributes        #
#                                                                    #
# Returns:                                                           #
#   $rc                       Return code.                           #
#                                                                    #
# Global References:                                                 #
#   $Opt_Long_Format  input   TRUE if should display one per line.   #
#   $Opt_Table_Format input   TRUE if should display in table form.  #
#   $Opt_Delm_Format  input   TRUE if should display with delimiter. #
#   $Opt_Delm_Str     input   Actual delimiter to display with.      #
#   $Opt_No_HDR       input   TRUE if should not display header.     #
#--------------------------------------------------------------------#
sub display_attributes_api
{
my($col_title, $row_title, $r_attributes, $rLoAttr, $rHoAttr) = @_;

my $print_format = "long";
my $delim = "";

# Determine if displaying in long, delimiter or tabular/column format.
if ($Opt_Long_Format) {
    $print_format = "long";
}
elsif ($Opt_Table_Format) {
    $print_format = "column";
}
elsif ($Opt_Delm_Format) {
    $print_format = "delim";
    $delim = $Opt_Delm_Str;
}

# Display the attributes in the order that they were requested
# on the command line.  If no attribute names were specified on
# the command line display them in the order that RMC returned
# them.

if (scalar(@$r_attributes) == 0) {
    $r_attributes = $rLoAttr;
}

# For debugging to reference one element
# $rHoAttr->{$attr_name}[$row]{at_value}

my $rc = display_resource_data_api($print_format, $Opt_No_HDR,
    $r_attributes, $row_title, $rHoAttr, $delim, $col_title);

return $rc;
}   # end display_attributes_api


#--------------------------------------------------------------------#
# display_sd_defs - displays the SD definition for the resource      #
#   or resource class persistent or dynamic SD attributes.           #
#   Zero or more SDs may have been formatted to be displayed.        #
#                                                                    #
# Parameters:                                                        #
#   $resource         input   Name of resource.                      #
#   @$rLoSDAttr       input   Reference to List of Attributes        #
#   %$rHoSDDefs       input   Reference to Hash of Attributes        #
#                                                                    #
# Returns:                                                           #
#   $rc                       return code.                           #
#                                                                    #
# Global References:                                                 #
#   $Opt_LS_Class     input   TRUE if listing resource class SD defs #
#   $Opt_LS_PAttr     input   TRUE if listing Persistent Attributes. #
#   $Opt_LS_DAttr     input   TRUE if listing Dynamic Attributes.    #
#   $Opt_No_HDR       input   TRUE if should not display header.     #
#--------------------------------------------------------------------#
sub display_sd_defs
{
my($resource, $rLoSDAttr, $rHoSDDefs) = @_;

my ($col_title, $row_title);

if (!$Opt_No_HDR) {
    if ($Opt_LS_Class) {
        if ($Opt_LS_PAttr) {
            printIMsg("IMsglsrsrcdefLsRsrcClassPSDDefHdr", $resource);
        }
        else {
            printIMsg("IMsglsrsrcdefLsRsrcClassDSDDefHdr", $resource);
        }
    }
    else {
        if ($Opt_LS_PAttr) {
            printIMsg("IMsglsrsrcdefLsRsrcPSDDefHdr", $resource);
        }
        else {
            printIMsg("IMsglsrsrcdefLsRsrcDSDDefHdr", $resource);
        }
    }
}
   
$row_title = "sd_element";          # use programmic name for NLS
my @fields = ();                    # display all fields in HoSDDefs
my @sd_keys = keys %$rHoSDDefs;
my $sd_def_cnt = scalar(@sd_keys);
my $badrc = 0;
for (my $s = 0; $s < $sd_def_cnt; $s++) {
    $col_title = "program_name $sd_keys[$s]:";
    $rc = display_attributes($col_title, $row_title, \@fields,
        $rLoSDAttr, $$rHoSDDefs{$sd_keys[$s]});
    if ($rc != 0 && $badrc == 0) {
        $badrc = $rc; 
    } 
}

return $badrc;
}   # end display_sd_defs


#--------------------------------------------------------------------#
# required_attr2 - checks to see if an attribute is in the required  #
#   list.  If no attributes are in the required list, then it is     #
#   required.                                                        #
#                                                                    #
# Parameters:                                                        #
#   $attr_name        input   Name of resource.                      #
#   @$rLoAttrs        input   Reference to List of Attributes        #
#                                                                    #
# Returns:                                                           #
#   $flag                     True or False.                         #
#                                                                    #
# Global References:                                                 #
#--------------------------------------------------------------------#
sub required_attr2 
{
my($attr_name, $rLoAttr) = @_;
my $flag = 0;

# get rid of any surrounding quotes in attr_name
$attr_name =~ s/^\"//;
$attr_name =~ s/\"$//;

# if there are attrs in the list, see if this is one of them
if ($#$rLoAttr >=0) {
   foreach $attr (@$rLoAttr) {
      # get rid of any surrounding quotes in attr
      $attr =~ s/^\"//;
      $attr =~ s/\"$//;

      if ($attr eq $attr_name) {
         $flag = 1;
      }
   }
}
else {
   # attr list is empty, get all attributes
   $flag = 1;
}

return $flag;

}   # end required_attr2 


#--------------------------------------------------------------------#
# error_check - checks the return code from the RMC function and     #
#   the error response return code.  If an error is detected         #
#   appropriate error messages will be displayed.                    #
#                                                                    #
# Parameters:                                                        #
#   $rmc_function     in      Name of the rmc function that was      #
#                             called and whose error code we are     #
#                             checking.                              #
#   $rmc_class        in      The rmc class name.                    #
#   $response         in      RMC response.                          #
#   $rmc_rc           in      The rmc function return code.          #
#   $error            in      The error response.                    #
#                                                                    #
# Return:                                                            #
#   $rc                       return code.                           #
#                                                                    #
# Global References:                                                 #
#   None.                                                            #
#--------------------------------------------------------------------#
sub error_check
{
my ($rmc_function, $rmc_class, $response, $rmc_rc, $error) = @_;

my $rc = 0;
my $err_rc = $error->errnum();

if ($rmc_rc != 0) {
    printEMsg("EMsglsrsrcdefLsRsrcDefError", $rmc_class);
    my $rmc_rc_hex = sprintf "0x%8.8lx", $rmc_rc;
    printCEMsg("EMsgMCcliMCFunctionFailure", $rmc_function,
        $rmc_rc, $rmc_rc_hex);
    $rc = MC_CLI_RMC_ERROR;
    return $rc;
}

# Check the errnum in each of the RMC responses
for (my $r = 0; $r < $response->array_count; $r++) {
    # get the error that goes with the specific response
    if ($r > 0) {
        $response->error($error, $r);
        $err_rc = $error->errnum();
    }
    if ($err_rc != 0) {
        if ($err_rc == RMC_ECLASSNOTDEFINED) {
            printCEMsg("EMsgMCcliClassNotDef", $rmc_class);
            $rc = MC_CLI_USER_ERROR;
        }
        elsif ($err_rc == RMC_ESDNOTDEFINED) {
            # Not having any SD Defs is not an error just don't
            # display anything
            $Verbose && print STDERR $error->error_msg;
            $rc = 0;
        }
        elsif ($err_rc == RMC_EBADATTRNAM) {
            print STDERR $error->error_msg;
            $rc = MC_CLI_USER_ERROR;
        }   
        elsif ($err_rc == RMC_EACCESS) {
            print STDERR $error->error_msg;
            $rc = MC_CLI_USER_ERROR;
        }
        else {
            printEMsg("EMsglsrsrcdefLsRsrcDefError", $rmc_class);
            my $err_rc_hex = sprintf "0x%8.8lx", $err_rc;
            printCEMsg("EMsgMCcliMCFunctionFailure", $rmc_function, 
                $err_rc, $err_rc_hex);
            print STDERR $error->error_msg; 
            $rc = MC_CLI_RMC_ERROR;
        }
    }   # end if
}   # end for

return $rc;
}   # end error_check


#--------------------------------------------------------------------#
# get_SD_types - obtain the SD definitions for attibutes of this     #
#   class and return a hash based on the attribute names that        #
#   contains the data types in the hash.                             #
#                                                                    #
# Parameters:                                                        #
#   $rattributes      input   Reference to the array of attr names.  #
#   $class_name       input   class name.                            #
#   $rSDdefs          in/out  Reference to hash for data types.      #
#                                                                    #
# Returns:                                                           #
#   $rc                       0 - if success, otherwise failure.     #
#                                                                    #
# Global References:                                                 #
#   $Opt_LS_Class     input   TRUE if displaying resource class.     #
#--------------------------------------------------------------------#
sub get_SD_types
{
my($rattributes, $class_name, $rSDdefs) = @_;

my $at_name = "";                    # attribute names
my $list_attrs = "";                 # list of attribute names
my @lsr_out = ();                    # lsrsrcdef-api output
my @SD_info = ();                    # SD info array
my @type_array = ();                 # arrays for data types
my $rc = 0;
my $r = 0;

# build list to use for lsrsrcdef-api
foreach $at_name (@$rattributes) {
      $list_attrs .= "::${at_name}";
}

# call lsrsrcdef-api to get the SD information
if ($Trace) { print STDERR "$PROGNAME: calling lsrsrcdef-api\n";}

# check if to get class or resource info
if (!$Opt_LS_Class) {
   @lsr_out = `$CTBINDIR/lsrsrcdef-api -s ${class_name}${list_attrs} 2>&1`;
}
else {
   @lsr_out = `$CTBINDIR/lsrsrcdef-api -S ${class_name}${list_attrs} 2>&1`;
}

# capture the return code from lsrsrcdef-api
$rc = $?;
$rc = process_exit_code($rc);

if ($Trace) { print STDERR "lsrsrcdef-api results:\n";
           print STDERR "@lsr_out";
           print STDERR "$PROGNAME: lsrsrcdef-api returned $rc\n";}

# show any errors if there was a bad rc
if ($rc != 0) {
   process_api_error("::",$rc,@lsr_out);
}

# remove any error messages from the output to display
@lsr_out = remove_api_error("::",@lsr_out);

# go through lsrsrcdef-api output making array of data types for each SD attr
# format of output is:  SDattrname::SDelementname::datatype::?::?::elementindex
@type_array = ();
for ($r = 0; $r <= $#lsr_out; $r++) {
    chomp($lsr_out[$r]);
    @SD_info = split (/::/, $lsr_out[$r]);

    # put data type for this element in array
    push @type_array, $SD_info[2]; 

    # if next one is new SD attr, save array in hash for this SD attr
    if ( ($r == $#lsr_out) || ($lsr_out[$r+1] =~ /::0\n$/) ) {
            $SD_info[0] =~ s/\"//g;
            $$rSDdefs{$SD_info[0]} = [ @type_array ];
            @type_array = ();
    }
}

return ($rc);

}   # end get_SD_types


#--------------------------------------------------------------------#
# add_SD_quotes - add quotes to binary and RH data in an SD if they  #
#   are present.                                                     #
#                                                                    #
# Parameters:                                                        #
#   $attr_name        input   Attribute name.                        #
#   $attr_value       input   Attribute value.                       #
#   $attr_type        input   Attribute type.                        #
#   $rSDdefs          input   Reference to hash for SD data types.   #
#                                                                    #
# Returns:                                                           #
#   $out_SD_value     output  Modified SD value.                     #
#                                                                    #
# Global References:                                                 #
#--------------------------------------------------------------------#
sub add_SD_quotes
{

use Text::ParseWords;
my($name, $value, $type, $rSDdefs) = @_;

my @sd_value_split = ();           # array of elements from SD
my @sd_array_split = ();           # array of elements from SD array
my $original_value = "";           # original SD value passed in
my $original_sd_value = "";        # original SD value (one SD)
my $tmp_value = "";                # intermediate SD value
my $tmp_array_val = "";            # used for splitting 
my $tmp_split_val = "";            # used for splitting 
my $out_value = "";                # output SD value
my $modified = 0;                  # set if change made to original
my $i = 0;                         # loop index
my $j = 0;                         # loop index
my $y = 0;                         # loop index
my $comma = "";                    # comma for delimiter in SD
my @temp_str_array = ();           # for reformatting values
my $temp_str = "";                 # for reformatting values
my $temp_str2 = "";                # for reformatting values
my @parse_split = ();              # for reformatting values
my $tmp_len = 0;                   # for reformatting values

# save the original value
$original_value = $value;

# see if it's an SD array (or just SD)
if ($type =~ /CT_SD_PTR_ARRAY$/) {
   # create array of SD's from the SD array
   # get rid of outside {}
   $value =~ s/^{//;
   $value =~ s/}$//;

   # split the SD array into an array of SDs (based on commas and brackets)
   @sd_array_split = split (/\],\[/, $value);
   # @sd_array_split now has array of SDs
}

# else it's an SD (not SD array)
else {
   # make this SD look like a SD array of 1 SD 
   push (@sd_array_split, $value);
   # @sd_array_split now has array of 1 SDs
}

# process each SD whether array or not
for ($j=0; $j<=$#sd_array_split; $j++) {

   # save original value
   $original_sd_value = $sd_array_split[$j];

   # get rid of outside []
   $sd_array_split[$j] =~ s/^\[//;
   $sd_array_split[$j] =~ s/\]$//;

   # split the SD into it's parts (based on commas)
   # [a,b,c,d,e,f,g,h]  or [a,b,c,{d,e,f},g,h]
   # keep in mind, may not have values for entire SD 
   #@sd_value_split = split (/,/, $sd_array_split[$j]);
   @sd_value_split = ();
   $tmp_array_val = $sd_array_split[$j];

   while ( (defined($tmp_array_val))  && ($tmp_array_val !~ /^$/) ) {

      # split either on an entry or an array
      if ( $tmp_array_val =~ /^{/ ) {
         ($tmp_split_val,$tmp_array_val) = split (/\},/, $tmp_array_val,2);
         if ($tmp_split_val !~ /\}$/) {
            $tmp_split_val .= "}";
         }
      }
      else {
         #($tmp_split_val,$tmp_array_val) = split (/,/, $tmp_array_val,2);
         @parse_split = parse_line(",",1,$tmp_array_val);
         $tmp_split_val = $parse_split[0];
         if ($tmp_array_val eq $tmp_split_val) {
            $tmp_array_val = "";
         }
         else {
            $tmp_len = length($tmp_split_val);
            $tmp_array_val = substr $tmp_array_val,$tmp_len;
            $tmp_array_val =~ s/^,//;
         }
      }

      push (@sd_value_split, $tmp_split_val);
   }

   # go through SD checking types for BINARYs and RHs
   for ($i=0; $i <= $#sd_value_split; $i++) {

      # check type
      #print ("type is ${$$rSDdefs{$name}}[$i]\n");
      # need to look for CT_BINARY_PTR, CT_BINARY_PTR_ARRAY, CT_RSRC_HANDLE_PTR,
      # CT_RSRC_HANDLE_PTR_ARRAY
      if ( (${$$rSDdefs{$name}}[$i] =~ /^CT_BINARY_PTR$/) || 
           (${$$rSDdefs{$name}}[$i] =~ /^CT_RSRC_HANDLE_PTR$/) ) {

          # split up binary values that are bigger than 8 chars
          if ( (${$$rSDdefs{$name}}[$i] =~ /^CT_BINARY_PTR$/)  && 
               (length($sd_value_split[$i])>10) ) {
                $sd_value_split[$i] = split_bin_8($sd_value_split[$i]);
          }

          # put quotes around the single value
          $sd_value_split[$i] = "\"".$sd_value_split[$i]."\"";
          $modified = 1;
      }

      if ( (${$$rSDdefs{$name}}[$i] =~ /^CT_BINARY_PTR_ARRAY$/) || 
           (${$$rSDdefs{$name}}[$i] =~ /^CT_RSRC_HANDLE_PTR_ARRAY$/) ) {

          # make binary strings into groups of 8's
          if (${$$rSDdefs{$name}}[$i] =~ /^CT_BINARY_PTR_ARRAY$/) {

              # get rid of beginning and ending {} and any 0x
              $sd_value_split[$i] =~ s/^\{//;
              $sd_value_split[$i] =~ s/\}$//;
              $sd_value_split[$i] =~ s/^0x//;
              $sd_value_split[$i] =~ s/,0x/,/g;

              # get the separate binary values by splitting on commas
              @temp_str_array = split (/,/, $sd_value_split[$i]);

              # process each binary value
              $temp_str = "";
              $comma = "";
              for ($y=0; $y<=$#temp_str_array; $y++) {

                   # format the binary string
                   $temp_str2 = split_bin_8($temp_str_array[$y]);

                   # build the array back
                   $temp_str .= $comma . $temp_str2;
                   $comma = ",";
                }

                # put {} back around it and assign back to original variable
                $sd_value_split[$i] = "{" . $temp_str . "}";
             }

          # put quotes at the beginning and end 
          $sd_value_split[$i] =~ s/^{/{\"/;
          $sd_value_split[$i] =~ s/}$/\"}/;

          # put quotes around beginning and end of each element in array 
          $sd_value_split[$i] =~ s/,/\",\"/g;
          $modified = 1;
      }

   }

   # if there was a change to the SD value, put it back together
   if ($modified) {
      # put beginning bracket on
      $tmp_value = "[";
      $comma = "";

      # put each split value on $out_value
      for ($i=0; $i <= $#sd_value_split; $i++) {
         $tmp_value .= $comma . $sd_value_split[$i];
         $comma = ",";
      }

      # put ending bracket on
      $tmp_value .= "]";

      # assign in back to the array of SDs
      $sd_array_split[$j] = $tmp_value;  
   }

   else {
      # use original value
      $sd_array_split[$j] = $original_sd_value;
   }

}  # end of for-loop for each SD array element 

# now check for overall changes to SD
# if the was a change to the SD value, put it back together
if ($modified) {

   # if an array, need to put the {} back on
   if ($type =~ /CT_SD_PTR_ARRAY$/) {

      # put beginning bracket on
      $out_value = "{";
      $comma = "";

      # put each SD value on $out_value
      for ($j=0; $j<=$#sd_array_split; $j++) {
         $out_value .= $comma . $sd_array_split[$j];
         $comma = ",";
      }

      # put ending bracket on
      $out_value .= "}";
   }  

   # else it's an SD (not array). there's only one
   else {
      $out_value = $sd_array_split[0];
   }  
}  

else {
   # use original value
   $out_value = $original_value;
}

return ($out_value);

}   # end add_SD_quotes


#--------------------------------------------------------------------#
# split_bin_8 - takes a binary type value and splits it up so it's   #
#   in strings of 8.  0x01234567890a becomes 0x01234567 0x890a.      #
#                                                                    #
# Parameters:                                                        #
#   $value            input   Binary type value.                     #
#                                                                    #
# Returns:                                                           #
#   $out_value        output  Modified value.                        #
#                                                                    #
# Global References:                                                 #
#--------------------------------------------------------------------#
sub split_bin_8
{
my $value = shift @_;
my $out_value = "";                    # result
my $temp_str = "";                     # temp place to play
my $z = 0;

# get rid of the original 0x at the beginning
$value =~ s/^0x//;

# breakup into groups of 8
$temp_str = "";

# loop through the string making groups of 8
for ($z=0; $z<length($value);$z+=8){
    $temp_str .= "0x" . substr($value,$z,8) . " ";
}

# get anything left over
#$temp_str .= substr($value,$z);

# get rid of any trailing blanks
$temp_str =~ s/ +$//;

# return new (maybe) value
$out_value = $temp_str;
return ($out_value);

}   # end split_bin_8