<commit_before>//IBM_PROLOG_BEGIN_TAG
/* 
 * Copyright 2003,2016 IBM International Business Machines Corp.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
//IBM_PROLOG_END_TAG


//----------------------------------------------------------------------
//  Includes
//----------------------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <fstream>
#include <algorithm>

#include <ecmdCommandUtils.H>
#include <ecmdReturnCodes.H>
#include <ecmdClientCapi.H>
#include <ecmdUtils.H>
#include <ecmdDataBuffer.H>
#include <ecmdInterpreter.H>
#include <ecmdSharedUtils.H>

//----------------------------------------------------------------------
//  User Types
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Constants
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Macros
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Internal Function Prototypes
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Global Variables
//----------------------------------------------------------------------

//---------------------------------------------------------------------
// Member Function Specifications
//---------------------------------------------------------------------
#ifndef ECMD_REMOVE_MEMORY_FUNCTIONS

uint32_t ecmdGetMemUser(int argc, char * argv[], ECMD_DA_TYPE memMode) {
  uint32_t rc = ECMD_SUCCESS, coeRc = ECMD_SUCCESS;

  ecmdLooperData looperdata;            ///< Store internal Looper data
  std::string outputformat = "mem";     ///< Output format - default to 'mem'
  ecmdDataBuffer returnData;            ///< Buffer to hold return data from memory
  bool validPosFound = false;           ///< Did the looper find anything?
  ecmdChipTarget target;                ///< Current target being operated on
  uint32_t channel = ECMD_UNSET;        ///< Channel to use for getsram
  uint32_t pcietop = ECMD_UNSET;        ///< PCIe Top to use for getsram
  uint32_t pciephy = ECMD_UNSET;        ///< PCIe Phy to use for getsram
  uint32_t sramMode = 0x0;              ///< Mode value that contains data to send to the API
  uint64_t address;                     ///< The address from the command line
  uint32_t numBytes = ECMD_UNSET;       ///< Number of bytes from the command line
  std::string cmdlineName;              ///< Stores the name of what the command line function would be.
  int match;                            ///< For sscanf
  std::string printLine;                ///< Output data

  bool expectFlag = false;              ///< Are we doing an expect?
  bool maskFlag = false;                ///< Are we masking our expect data?
  char* expectPtr = NULL;               ///< Pointer to expected data in arg list
  char* maskPtr = NULL;                 ///< Pointer to mask data in arg list
  ecmdDataBuffer expected;                      ///< Buffer to store expected data
  ecmdDataBuffer mask;                          ///< Buffer for mask of expected data
  std::string inputformat = "x";                ///< Input format of data
  uint32_t mode = 0x0;                  ///< Extra options to pass to getMemProc


  /************************************************************************/
  /* Setup the cmdlineName variable                                       */
  /************************************************************************/
  if (memMode == ECMD_MEM_DMA) {
    cmdlineName = "getmemdma";
  } else if (memMode == ECMD_MEM_MEMCTRL) {
    cmdlineName = "getmemmemctrl";
  } else if (memMode == ECMD_MEM_PROC) {
    cmdlineName = "getmemproc";
  } else if (memMode == ECMD_SRAM) {
    cmdlineName = "getsram";
  }

  /************************************************************************/
  /* Parse Local FLAGS here!                                              */
  /************************************************************************/

  /* get format flag, if it's there */
  char * outputFormatPtr = ecmdParseOptionWithArgs(&argc, &argv, "-o");
  if (outputFormatPtr != NULL) {
    outputformat = outputFormatPtr;
  }  
  char * inputFormatPtr = ecmdParseOptionWithArgs(&argc, &argv, "-i");
  if (inputFormatPtr != NULL) {
    inputformat = inputFormatPtr;
  }

  /* Get the channel for getsram */
  if (memMode == ECMD_SRAM) {
    char * channelPtr = ecmdParseOptionWithArgs(&argc, &argv, "-ch");
    if (channelPtr != NULL) {
      if (!ecmdIsAllDecimal(channelPtr)) {
        printLine = cmdlineName + " - Non-dec characters detected in channel option\n";
        ecmdOutputError(printLine.c_str());
        return ECMD_INVALID_ARGS;
      }
      channel = (uint32_t)atoi(channelPtr);
      sramMode |= (channel & (ECMD_SRAM_MODE_CHANNEL_MASK >> ECMD_SRAM_MODE_CHANNEL_SHIFT)) << ECMD_SRAM_MODE_CHANNEL_SHIFT;
    } 

    char * pectopPtr = ecmdParseOptionWithArgs(&argc, &argv, "-top");
    if (pectopPtr != NULL) {
      if (!ecmdIsAllDecimal(pectopPtr)) {
        printLine = cmdlineName + " - Non-dec characters detected in top option\n";
        ecmdOutputError(printLine.c_str());
        return ECMD_INVALID_ARGS;
      }
      pcietop = (uint32_t)atoi(pectopPtr);
      sramMode |= (pcietop & (ECMD_SRAM_MODE_PECTOP_MASK >> ECMD_SRAM_MODE_PECTOP_SHIFT)) << ECMD_SRAM_MODE_PECTOP_SHIFT;
    }

    char * pecphyPtr = ecmdParseOptionWithArgs(&argc, &argv, "-phy");
    if (pecphyPtr != NULL) {
      if (!ecmdIsAllDecimal(pecphyPtr)) {
        printLine = cmdlineName + " - Non-dec characters detected in phy option\n";
        ecmdOutputError(printLine.c_str());
        return ECMD_INVALID_ARGS;
      }
      pciephy = (uint32_t)atoi(pecphyPtr);
      sramMode |= (pciephy & (ECMD_SRAM_MODE_PECPHY_MASK >> ECMD_SRAM_MODE_PECPHY_SHIFT)) << ECMD_SRAM_MODE_PECPHY_SHIFT;
    }

    char * modePtr = ecmdParseOptionWithArgs(&argc, &argv, "-mode");
    if (modePtr != NULL) {
      if (!ecmdIsAllHex(modePtr)) {
        printLine = cmdlineName + " - Non-hex characters detected in mode option\n";
        ecmdOutputError(printLine.c_str());
        return ECMD_INVALID_ARGS;
      }
      match = sscanf(modePtr, "%x", &sramMode);
      if (match != 1) {
        ecmdOutputError("Error occurred processing mode value!\n");
        return ECMD_INVALID_ARGS;
      }
      channel = (sramMode & ECMD_SRAM_MODE_CHANNEL_MASK) >> ECMD_SRAM_MODE_CHANNEL_SHIFT;
    }

    if ( (modePtr != NULL) && ((channelPtr != NULL) || (pectopPtr != NULL) || (pecphyPtr != NULL) ) ) {
      printLine = cmdlineName + " - mode cannot be specified along with channel, top or phy\n";
      ecmdOutputError(printLine.c_str());
      return ECMD_INVALID_ARGS;
    } else if ((channelPtr != NULL) && ((pectopPtr != NULL) || (pecphyPtr != NULL))) {
      printLine = cmdlineName + " - channel cannot be specified along with top or phy\n";
      ecmdOutputError(printLine.c_str());
      return ECMD_INVALID_ARGS;
    } else if ((pectopPtr != NULL) && (pecphyPtr == NULL)) {
      printLine = cmdlineName + " - top and phy must be specified together\n";
      ecmdOutputError(printLine.c_str());
      return ECMD_INVALID_ARGS;
    } else if ((pectopPtr == NULL) && (pecphyPtr != NULL)) {
      printLine = cmdlineName + " - top and phy must be specified together\n";
      ecmdOutputError(printLine.c_str());
      return ECMD_INVALID_ARGS;
    } 
  }

  /* Get the filename if -fb is specified */
  char * filename = ecmdParseOptionWithArgs(&argc, &argv, "-fb");
  
  /* Get the filename if -fd is specified */
  char * dcardfilename = ecmdParseOptionWithArgs(&argc, &argv, "-fd");

  if(((filename != NULL) || (dcardfilename != NULL)) && 
     ((outputFormatPtr != NULL) || (inputFormatPtr != NULL))) {
    printLine = cmdlineName + " - Options -f and -o/-i can't be specified together for format. Specify either one.\n";
    ecmdOutputError(printLine.c_str());
    return ECMD_INVALID_ARGS;
  } 
  if((dcardfilename != NULL) && (filename != NULL)) {
    printLine = cmdlineName + "Options -fb and -fd can't be specified together for format. Specify either one.\n";
    ecmdOutputError(printLine.c_str());
    return ECMD_INVALID_ARGS;
  }

  //expect and mask flags check
  if (filename == NULL && dcardfilename == NULL) {
    if ((expectPtr = ecmdParseOptionWithArgs(&argc, &argv, "-exp")) != NULL) {
      expectFlag = true;
      
      if ((maskPtr = ecmdParseOptionWithArgs(&argc, &argv, "-mask")) != NULL) {
	maskFlag = true;
      }
    }
  } else {
    // If we are passing in data with a file, just look for -exp
    expectFlag = ecmdParseOption(&argc, &argv, "-exp");
  }

  if (memMode == ECMD_MEM_PROC) {
    //Check cache inhit option
    bool cacheInhibit = ecmdParseOption(&argc, &argv, "-ci");
    if (cacheInhibit) {
      mode |= MEMPROC_CACHE_INHIBIT;
    }
  }

  /************************************************************************/
  /* Parse Common Cmdline Args                                            */
  /************************************************************************/
  rc = ecmdCommandArgs(&argc, &argv);
  if (rc) return rc;

  /* Global args have been parsed, we can read if -coe was given */
  bool coeMode = ecmdGetGlobalVar(ECMD_GLOBALVAR_COEMODE); ///< Are we in continue on error mode

  // Read in the expect data
  if (expectFlag) {
    if ((filename == NULL) && (dcardfilename == NULL)) {

      rc = ecmdReadDataFormatted(expected, expectPtr, inputformat);
      if (rc) {
	ecmdOutputError((cmdlineName + " - Problems occurred parsing expected data, must be an invalid format\n").c_str());
	return rc;
      }

      if (maskFlag) {
	rc = ecmdReadDataFormatted(mask, maskPtr, inputformat);
	if (rc) {
	  ecmdOutputError((cmdlineName + " - Problems occurred parsing mask data, must be an invalid format\n").c_str());
	  return rc;
	}
	
      }

    } else {
      // Read from a file 
      if (filename != NULL) {
	rc = expected.readFile(filename, ECMD_SAVE_FORMAT_BINARY_DATA);
	if (rc) {
	  ecmdOutputError((cmdlineName + " - Problems occurred parsing expected data from file " + filename + " , must be an invalid format\n").c_str());
	  return rc;
	}
      } else {
	// Dcard
	// Pulled support for this as it is a pain, could be added if needed, 
	//   ecmdReadDcard returns a list of memory entries because there could 
	//   be holes, so would have to loop down below
	ecmdOutputError((cmdlineName + " - Currently Dcard support is not supported with -exp\n").c_str());
	return ECMD_INVALID_ARGS;
	//	rc = ecmdReadDcard(dcardfilename, expected);
	//	if (rc) {
	//	  printLine = cmdlineName + " - Problems occurred parsing input data from file " + dcardfilename +", must be an invalid format\n";
	//	  ecmdOutputError(printLine.c_str());
	//	  return rc;
	//	}

      }
      // Let's pull the length from the file
      numBytes = expected.getByteLength();
    }
	
  }

  /************************************************************************/
  /* Parse Local ARGS here!                                               */
  /************************************************************************/
  std::string chipType, chipUnitType;
  int legacyModeArgOffset = 1;
  if ( argc == 0 )
  {
    legacyModeArgOffset = 0;
  }
  else
  {
    rc = ecmdParseChipField(argv[0], chipType, chipUnitType, true /* supports wildcard usage */);
    if (rc || ecmdIsAllHex(chipType.c_str())) {
      legacyModeArgOffset = 0;
    }
  }

  if ((memMode == ECMD_SRAM) && (channel == 1)) {
    // channel 1 for sram commands is access to a circular buffer and does not require an address
    if ((numBytes == ECMD_UNSET) && (argc != (1 + legacyModeArgOffset)) ) {  // size, optional chip
      printLine = cmdlineName + " - Incorrect arguments specified for channel 1; only number of bytes needed with optional chip.\n";
      ecmdOutputError(printLine.c_str());
      printLine = cmdlineName + " - Type '" + cmdlineName + " -h' for usage.\n";
      ecmdOutputError(printLine.c_str());
      return ECMD_INVALID_ARGS;
    } else if ((argc > (2 + legacyModeArgOffset)) ) {
      printLine = cmdlineName + " - Too many arguments specified for channel 1.\n";
      ecmdOutputError(printLine.c_str());
      printLine = cmdlineName + " - Type '" + cmdlineName + " -h' for usage.\n";
      ecmdOutputError(printLine.c_str());
      return ECMD_INVALID_ARGS;
    }
  } else if ((numBytes == ECMD_UNSET) && (argc < (2 + legacyModeArgOffset)) ) {  //address + size, optional chip
    printLine = cmdlineName + " - Too few arguments specified; you need at least an address and number of bytes with optional chip.\n";
    ecmdOutputError(printLine.c_str());
    printLine = cmdlineName + " - Type '" + cmdlineName + " -h' for usage.\n";
    ecmdOutputError(printLine.c_str());
    return ECMD_INVALID_ARGS;
  } else if ((argc < (1 + legacyModeArgOffset))) { 
    printLine = cmdlineName + " - Too few arguments specified; you need at least an address with optional chip.\n";
    ecmdOutputError(printLine.c_str());
    printLine = cmdlineName + " - Type '" + cmdlineName + " -h' for usage.\n";
    ecmdOutputError(printLine.c_str());
    return ECMD_INVALID_ARGS;
  }

  if ((memMode == ECMD_SRAM) && (channel == 1)) {
    // Set a default address
    address = 0;
    // Get the number of bytes
    if (numBytes == ECMD_UNSET) {
      numBytes = (uint32_t)atoi(argv[0 + legacyModeArgOffset]);
    }
  } else {
    // Get the address
    if (!ecmdIsAllHex(argv[0 + legacyModeArgOffset])) {
      printLine = cmdlineName + " - Non-hex characters detected in address field\n";
      ecmdOutputError(printLine.c_str());
      return ECMD_INVALID_ARGS;
    }
#ifdef _LP64
    match = sscanf(argv[0 + legacyModeArgOffset], "%lx", &address);
#else
    match = sscanf(argv[0 + legacyModeArgOffset], "%llx", &address);
#endif
    if (match != 1) {
      ecmdOutputError("Error occurred processing address!\n");
      return ECMD_INVALID_ARGS;
    }

    // Get the number of bytes
    if (numBytes == ECMD_UNSET) {
      numBytes = (uint32_t)atoi(argv[1 + legacyModeArgOffset]);
    }
  }


  // do not allow numBytes >= 512MB
  if (numBytes >= 0x20000000) {
    printLine = cmdlineName + " - Number of bytes must be < 512MB\n";
    ecmdOutputError(printLine.c_str());
    return ECMD_INVALID_ARGS;
  }

  //Setup the target that will be used to query the system config
  // Memctrl DA is on the cage depth and proc/dma are on the processor pos depth
  if (memMode == ECMD_MEM_MEMCTRL) {
    target.cageState = ECMD_TARGET_FIELD_WILDCARD;
    target.nodeState = target.chipTypeState = target.slotState = 
      target.posState = target.chipUnitTypeState = target.chipUnitNumState = target.threadState = ECMD_TARGET_FIELD_UNUSED;
  } else if ((memMode == ECMD_MEM_PROC) || (memMode == ECMD_MEM_DMA) || ((legacyModeArgOffset == 0) && (memMode == ECMD_SRAM)) ) {
    target.chipType = ECMD_CHIPT_PROCESSOR;
    target.chipTypeState = ECMD_TARGET_FIELD_VALID;
    target.cageState = target.nodeState = target.slotState = 
      target.posState = ECMD_TARGET_FIELD_WILDCARD;
    target.chipUnitTypeState = target.chipUnitNumState = target.threadState = ECMD_TARGET_FIELD_UNUSED;
  } else if ((memMode == ECMD_SRAM)) {
    target.chipType = chipType;
    target.chipTypeState = ECMD_TARGET_FIELD_VALID;
    target.cageState = target.nodeState = target.slotState = 
      target.posState = ECMD_TARGET_FIELD_WILDCARD;
    if (chipUnitType != "") {
      target.chipUnitType = chipUnitType;
      target.chipUnitTypeState = ECMD_TARGET_FIELD_VALID;
      target.chipUnitNumState = ECMD_TARGET_FIELD_WILDCARD;
    } else {
      target.chipUnitTypeState = target.chipUnitNumState = ECMD_TARGET_FIELD_UNUSED;
    }
    target.threadState = ECMD_TARGET_FIELD_UNUSED;
  }

  rc = ecmdLooperInit(target, ECMD_SELECTED_TARGETS_LOOP, looperdata);
  if (rc) return rc;

  while (ecmdLooperNext(target, looperdata) && (!coeRc || coeMode)) {

    if (memMode == ECMD_MEM_DMA) {
      rc = getMemDma(target, address, numBytes, returnData);
    } else if (memMode == ECMD_MEM_MEMCTRL) {
      rc = getMemMemCtrl(target, address, numBytes, returnData);
    } else if (memMode == ECMD_MEM_PROC) {
      rc = getMemProc(target, address, numBytes, returnData, mode);
    } else if (memMode == ECMD_SRAM) {
      rc = getSram(target, sramMode, address, numBytes, returnData);
    }

    if (rc) {
      printLine = cmdlineName + " - Error occured performing " + cmdlineName + " on ";
      printLine += ecmdWriteTarget(target) + "\n";
      ecmdOutputError( printLine.c_str() );
      coeRc = rc;
      continue;
    }
    else {
      validPosFound = true;     
    }
    
    printLine = ecmdWriteTarget(target);
    if (expectFlag) {
      uint32_t mismatchBit = 0;

      if (maskFlag) {
        returnData.setAnd(mask, 0, returnData.getBitLength());
      }

      if (!ecmdCheckExpected(returnData, expected, mismatchBit)) {

        //@ make this stuff sprintf'd
        char outstr[300];
        printLine = ecmdWriteTarget(target) + "\n";
        ecmdOutputError( printLine.c_str() );
        if (mismatchBit != ECMD_UNSET) {
          sprintf(outstr, "%s - Data miscompare occured at (address %llX) (bit %d) (byte %d:0x%X bit %d)\n", 
                  cmdlineName.c_str(), (unsigned long long)address, mismatchBit, mismatchBit/8,
                  mismatchBit/8, mismatchBit%8);
          ecmdOutputError( outstr );
        }
        coeRc = ECMD_EXPECT_FAILURE;
        continue;
      }
    } else {
      if (filename != NULL) {
	rc = returnData.writeFile(filename, ECMD_SAVE_FORMAT_BINARY_DATA);
       
	if (rc) {
	  printLine += cmdlineName + " - Problems occurred writing data into file" + filename +"\n";
	  ecmdOutputError(printLine.c_str());
          break;
	}
	ecmdOutput( printLine.c_str() );
      } else if (dcardfilename != NULL) {
	std::string dataStr = ecmdWriteDataFormatted(returnData, "memd", address);
	std::ofstream ops;
	ops.open(dcardfilename);
	if (ops.fail()) {
	  char mesg[1000];
	  sprintf(mesg, "Unable to open file : %s for write", dcardfilename);
	  ecmdOutputError(mesg);
	  return ECMD_DBUF_FOPEN_FAIL;
	}
	if (dataStr[0] != '\n') {
	  printLine += "\n";
	}
	printLine += dataStr;
	ops << printLine.c_str();
	ops.close();

      } else  {
     
	std::string dataStr = ecmdWriteDataFormatted(returnData, outputformat, address);
	if (dataStr[0] != '\n') {
	  printLine += "\n";
	}
	printLine += dataStr;
	ecmdOutput( printLine.c_str() );
      }
    }  
  }
  // coeRc will be the return code from in the loop, coe mode or not.
  if (coeRc) return coeRc;

  // This is an error common across all UI functions
  if (!validPosFound) {
    printLine = cmdlineName + " - Unable to find a valid chip to execute command on\n";
    ecmdOutputError(printLine.c_str());
    return ECMD_TARGET_NOT_CONFIGURED;
  }

  return rc;
}

uint32_t ecmdPutMemUser(int argc, char * argv[], ECMD_DA_TYPE memMode) {
  uint32_t rc = ECMD_SUCCESS, coeRc = ECMD_SUCCESS;

  ecmdLooperData looperdata;            ///< Store internal Looper data
  std::string inputformat = "x";        ///< Output format - default to 'mem'
  ecmdDataBuffer inputData;             ///< Buffer to hold the data intended for memory
  std::list<ecmdMemoryEntry> memdata;   ///< Data from the D-Card format file 
  std::list<ecmdMemoryEntry>::iterator memdataIter; ///< to iterate on memdata list 
  ecmdMemoryEntry memEntry;             ///< to store data from the user
  bool validPosFound = false;           ///< Did the looper find anything?
  ecmdChipTarget target;                ///< Current target being operated on
  uint32_t channel = ECMD_UNSET;        ///< Channel to use for getsram
  uint32_t pcietop = ECMD_UNSET;        ///< PCIe Top to use for getsram
  uint32_t pciephy = ECMD_UNSET;        ///< PCIe Phy to use for getsram
  uint32_t sramMode = 0x0;              ///< Mode value that contains data to send to the API
  uint64_t address = 0;                 ///< The address from the command line
  std::string cmdlineName;              ///< Stores the name of what the command line function would be.
  int match;                            ///< For sscanf
  std::string printLine;                ///< Output data
  uint32_t mode = 0x0;                  ///< Extra options to pass to putMemProc

  /************************************************************************/
  /* Setup the cmdlineName variable                                       */
  /************************************************************************/
  if (memMode == ECMD_MEM_DMA) {
    cmdlineName = "putmemdma";
  } else if (memMode == ECMD_MEM_MEMCTRL) {
    cmdlineName = "putmemmemctrl";
  } else if (memMode == ECMD_MEM_PROC) {
    cmdlineName = "putmemproc";
  } else if (memMode == ECMD_SRAM) {
    cmdlineName = "putsram";
  }

  /************************************************************************/
  /* Parse Local FLAGS here!                                              */
  /************************************************************************/
  /* get format flag, if it's there */
  char * formatPtr = ecmdParseOptionWithArgs(&argc, &argv, "-i");
  if (formatPtr != NULL) {
    inputformat = formatPtr;
  }

  /* Get the channel for putsram */
  if (memMode == ECMD_SRAM) {
    char * channelPtr = ecmdParseOptionWithArgs(&argc, &argv, "-ch");
    if (channelPtr != NULL) {
      if (!ecmdIsAllDecimal(channelPtr)) {
        printLine = cmdlineName + " - Non-dec characters detected in channel option\n";
        ecmdOutputError(printLine.c_str());
        return ECMD_INVALID_ARGS;
      }
      channel = (uint32_t)atoi(channelPtr);
      sramMode |= (channel & (ECMD_SRAM_MODE_CHANNEL_MASK >> ECMD_SRAM_MODE_CHANNEL_SHIFT)) << ECMD_SRAM_MODE_CHANNEL_SHIFT;
    } 

    char * pectopPtr = ecmdParseOptionWithArgs(&argc, &argv, "-top");
    if (pectopPtr != NULL) {
      if (!ecmdIsAllDecimal(pectopPtr)) {
        printLine = cmdlineName + " - Non-dec characters detected in top option\n";
        ecmdOutputError(printLine.c_str());
        return ECMD_INVALID_ARGS;
      }
      pcietop = (uint32_t)atoi(pectopPtr);
      sramMode |= (pcietop & (ECMD_SRAM_MODE_PECTOP_MASK >> ECMD_SRAM_MODE_PECTOP_SHIFT)) << ECMD_SRAM_MODE_PECTOP_SHIFT;
    }

    char * pecphyPtr = ecmdParseOptionWithArgs(&argc, &argv, "-phy");
    if (pecphyPtr != NULL) {
      if (!ecmdIsAllDecimal(pecphyPtr)) {
        printLine = cmdlineName + " - Non-dec characters detected in phy option\n";
        ecmdOutputError(printLine.c_str());
        return ECMD_INVALID_ARGS;
      }
      pciephy = (uint32_t)atoi(pecphyPtr);
      sramMode |= (pciephy & (ECMD_SRAM_MODE_PECPHY_MASK >> ECMD_SRAM_MODE_PECPHY_SHIFT)) << ECMD_SRAM_MODE_PECPHY_SHIFT;
    }

    char * modePtr = ecmdParseOptionWithArgs(&argc, &argv, "-mode");
    if (modePtr != NULL) {
      if (!ecmdIsAllHex(modePtr)) {
        printLine = cmdlineName + " - Non-hex characters detected in mode option\n";
        ecmdOutputError(printLine.c_str());
        return ECMD_INVALID_ARGS;
      }
      match = sscanf(modePtr, "%x", &sramMode);
      if (match != 1) {
        ecmdOutputError("Error occurred processing mode value!\n");
        return ECMD_INVALID_ARGS;
      }
      channel = (sramMode & ECMD_SRAM_MODE_CHANNEL_MASK) >> ECMD_SRAM_MODE_CHANNEL_SHIFT;
      sramMode = (uint32_t)atoi(modePtr);
    }

    if ( (modePtr != NULL) && ((channelPtr != NULL) || (pectopPtr != NULL) || (pecphyPtr != NULL) ) ) {
      printLine = cmdlineName + " - mode cannot be specified along with channel, top or phy\n";
      ecmdOutputError(printLine.c_str());
      return ECMD_INVALID_ARGS;
    } else if ((channelPtr != NULL) && ((pectopPtr != NULL) || (pecphyPtr != NULL))) {
      printLine = cmdlineName + " - channel cannot be specified along with top or phy\n";
      ecmdOutputError(printLine.c_str());
      return ECMD_INVALID_ARGS;
    } else if ((pectopPtr != NULL) && (pecphyPtr == NULL)) {
      printLine = cmdlineName + " - top and phy must be specified together\n";
      ecmdOutputError(printLine.c_str());
      return ECMD_INVALID_ARGS;
    } else if ((pectopPtr == NULL) && (pecphyPtr != NULL)) {
      printLine = cmdlineName + " - top and phy must be specified together\n";
      ecmdOutputError(printLine.c_str());
      return ECMD_INVALID_ARGS;
    } 
  }

  /* Get the filename if -fb is specified */
  char * filename = ecmdParseOptionWithArgs(&argc, &argv, "-fb");
 
  /* Get the filename to file in D-Card format */ 
  char *dcardfilename = ecmdParseOptionWithArgs(&argc, &argv, "-fd");

  if(((filename != NULL) || (dcardfilename != NULL)) && (formatPtr != NULL) ) {
    printLine = cmdlineName + "Options -f and -i can't be specified together for format. Specify either one.\n";
    ecmdOutputError(printLine.c_str());
    return ECMD_INVALID_ARGS;
  } 

  if((dcardfilename != NULL) && (filename != NULL)) {
    printLine = cmdlineName + "Options -fb and -fd can't be specified together for format. Specify either one.\n";
    ecmdOutputError(printLine.c_str());
    return ECMD_INVALID_ARGS;
  }

  if (memMode == ECMD_MEM_PROC) {
    //Check cache inhit option
    bool cacheInhibit = ecmdParseOption(&argc, &argv, "-ci");
    if (cacheInhibit) {
      mode |= MEMPROC_CACHE_INHIBIT;
    }
  }

  /************************************************************************/
  /* Parse Common Cmdline Args                                            */
  /************************************************************************/
  rc = ecmdCommandArgs(&argc, &argv);
  if (rc) return rc;

  /* Global args have been parsed, we can read if -coe was given */
  bool coeMode = ecmdGetGlobalVar(ECMD_GLOBALVAR_COEMODE); ///< Are we in continue on error mode

  /************************************************************************/
  /* Parse Local ARGS here!                                               */
  /************************************************************************/
  std::string chipType, chipUnitType;
  int legacyModeArgOffset = 1;
  if ( argc == 0 )
  {
    legacyModeArgOffset = 0;
  }
  else
  {
    rc = ecmdParseChipField(argv[0], chipType, chipUnitType, true /* supports wildcard usage */);
    if (rc || ecmdIsAllHex(chipType.c_str())) {
      legacyModeArgOffset = 0;
    }
  }

  if ((memMode == ECMD_SRAM) && (channel == 1)) {
    // channel 1 for sram commands is access to a circular buffer and does not require an address
    // dcard not supported
    if (dcardfilename != NULL) {
      // ERROR
      printLine = cmdlineName + " - dcard file not supported for channel 1.\n";
      ecmdOutputError(printLine.c_str());
      printLine = cmdlineName + " - Type '" + cmdlineName + " -h' for usage.\n";
      ecmdOutputError(printLine.c_str());
      return ECMD_INVALID_ARGS;
    } else if ( ((argc >= (1 + legacyModeArgOffset)) && (filename != NULL)) ) {
      // Too many arguments
      printLine = cmdlineName + " - Too many arguments specified for channel 1.\n";
      ecmdOutputError(printLine.c_str());
      printLine = cmdlineName + " - Type '" + cmdlineName + " -h' for usage.\n";
      ecmdOutputError(printLine.c_str());
      return ECMD_INVALID_ARGS;
    } else if ( (argc > 1 + legacyModeArgOffset) ) {
      // Too many arguments
      printLine = cmdlineName + " - Too many arguments specified for channel 1; you only need input data|file.\n";
      ecmdOutputError(printLine.c_str());
      printLine = cmdlineName + " - Type '" + cmdlineName + " -h' for usage.\n";
      ecmdOutputError(printLine.c_str());
      return ECMD_INVALID_ARGS;
    } else if ( ((argc < (1 + legacyModeArgOffset)) && (filename == NULL)) ) {
      // Too few arguments, need data
      printLine = cmdlineName + " - Too few arguments specified for channel 1; you need at least input data.\n";
      ecmdOutputError(printLine.c_str());
      printLine = cmdlineName + " - Type '" + cmdlineName + " -h' for usage.\n";
      ecmdOutputError(printLine.c_str());
      return ECMD_INVALID_ARGS;
    }
  } else if ( (argc < (2 + legacyModeArgOffset)) && (filename == NULL) && (dcardfilename == NULL) ) {  //chip + address
    printLine = cmdlineName + " - Too few arguments specified; you need at least an address and data to write.\n";
    ecmdOutputError(printLine.c_str());
    printLine = cmdlineName + " - Type '" + cmdlineName + " -h' for usage.\n";
    ecmdOutputError(printLine.c_str());
    return ECMD_INVALID_ARGS;
  }else if( (argc < (1 + legacyModeArgOffset)) && (filename != NULL) ) { 
    printLine = cmdlineName + " - Too few arguments specified; you need at least an address and input data file.\n";
    ecmdOutputError(printLine.c_str());
    printLine = cmdlineName + " - Type '" + cmdlineName + " -h' for usage.\n";
    ecmdOutputError(printLine.c_str());
    return ECMD_INVALID_ARGS;
  } else if( ((argc > (2 + legacyModeArgOffset)) && (filename == NULL) && (dcardfilename == NULL)) || ((argc > (1 + legacyModeArgOffset)) && (filename != NULL)) ) {
    printLine = cmdlineName + " - Too many arguments specified; you only need an address and input data|file.\n";
    ecmdOutputError(printLine.c_str());
    printLine = cmdlineName + " - Type '" + cmdlineName + " -h' for usage.\n";
    ecmdOutputError(printLine.c_str());
    return ECMD_INVALID_ARGS;
  } else if( (argc > (1 + legacyModeArgOffset)) && (dcardfilename != NULL) ) {
    printLine = cmdlineName + " - Too many arguments specified; you only need an optional address offset and a dcard file.\n";
    ecmdOutputError(printLine.c_str());
    printLine = cmdlineName + " - Type '" + cmdlineName + " -h' for usage.\n";
    ecmdOutputError(printLine.c_str());
    return ECMD_INVALID_ARGS;
  }
  //Setup the target that will be used to query the system config 
  // Memctrl DA is on the cage depth and proc/dma are on the processor pos depth
  if (memMode == ECMD_MEM_MEMCTRL) {
    target.cageState = ECMD_TARGET_FIELD_WILDCARD;
    target.nodeState = target.chipTypeState = target.slotState = target.posState = target.chipUnitTypeState = target.chipUnitNumState = target.threadState = ECMD_TARGET_FIELD_UNUSED;
  } else if ((memMode == ECMD_MEM_PROC) || (memMode == ECMD_MEM_DMA) || ((legacyModeArgOffset == 1) && (memMode == ECMD_SRAM)) ) {
    target.chipType = ECMD_CHIPT_PROCESSOR;
    target.chipTypeState =   ECMD_TARGET_FIELD_VALID;
    target.cageState = target.nodeState = target.slotState = target.posState = ECMD_TARGET_FIELD_WILDCARD;
    target.chipUnitTypeState = target.chipUnitNumState = target.threadState = ECMD_TARGET_FIELD_UNUSED;
  } else if ((memMode == ECMD_SRAM)) {
    target.chipType = chipType;
    target.chipTypeState = ECMD_TARGET_FIELD_VALID;
    target.cageState = target.nodeState = target.slotState = 
      target.posState = ECMD_TARGET_FIELD_WILDCARD;
    if (chipUnitType != "") {
      target.chipUnitType = chipUnitType;
      target.chipUnitTypeState = ECMD_TARGET_FIELD_VALID;
      target.chipUnitNumState = ECMD_TARGET_FIELD_WILDCARD;
    } else {
      target.chipUnitTypeState = target.chipUnitNumState = ECMD_TARGET_FIELD_UNUSED;
    }
    target.threadState = ECMD_TARGET_FIELD_UNUSED;
  }

  // Get the address
  if ((memMode == ECMD_SRAM) && (channel == 1)) {
    address = 0;
  } else if ((dcardfilename == NULL) || (dcardfilename != NULL && argv[0] != NULL)) {<commit_msg>fix a typo for command line processing<commit_after>//IBM_PROLOG_BEGIN_TAG
/* 
 * Copyright 2003,2016 IBM International Business Machines Corp.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
//IBM_PROLOG_END_TAG


//----------------------------------------------------------------------
//  Includes
//----------------------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <fstream>
#include <algorithm>

#include <ecmdCommandUtils.H>
#include <ecmdReturnCodes.H>
#include <ecmdClientCapi.H>
#include <ecmdUtils.H>
#include <ecmdDataBuffer.H>
#include <ecmdInterpreter.H>
#include <ecmdSharedUtils.H>

//----------------------------------------------------------------------
//  User Types
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Constants
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Macros
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Internal Function Prototypes
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Global Variables
//----------------------------------------------------------------------

//---------------------------------------------------------------------
// Member Function Specifications
//---------------------------------------------------------------------
#ifndef ECMD_REMOVE_MEMORY_FUNCTIONS

uint32_t ecmdGetMemUser(int argc, char * argv[], ECMD_DA_TYPE memMode) {
  uint32_t rc = ECMD_SUCCESS, coeRc = ECMD_SUCCESS;

  ecmdLooperData looperdata;            ///< Store internal Looper data
  std::string outputformat = "mem";     ///< Output format - default to 'mem'
  ecmdDataBuffer returnData;            ///< Buffer to hold return data from memory
  bool validPosFound = false;           ///< Did the looper find anything?
  ecmdChipTarget target;                ///< Current target being operated on
  uint32_t channel = ECMD_UNSET;        ///< Channel to use for getsram
  uint32_t pcietop = ECMD_UNSET;        ///< PCIe Top to use for getsram
  uint32_t pciephy = ECMD_UNSET;        ///< PCIe Phy to use for getsram
  uint32_t sramMode = 0x0;              ///< Mode value that contains data to send to the API
  uint64_t address;                     ///< The address from the command line
  uint32_t numBytes = ECMD_UNSET;       ///< Number of bytes from the command line
  std::string cmdlineName;              ///< Stores the name of what the command line function would be.
  int match;                            ///< For sscanf
  std::string printLine;                ///< Output data

  bool expectFlag = false;              ///< Are we doing an expect?
  bool maskFlag = false;                ///< Are we masking our expect data?
  char* expectPtr = NULL;               ///< Pointer to expected data in arg list
  char* maskPtr = NULL;                 ///< Pointer to mask data in arg list
  ecmdDataBuffer expected;                      ///< Buffer to store expected data
  ecmdDataBuffer mask;                          ///< Buffer for mask of expected data
  std::string inputformat = "x";                ///< Input format of data
  uint32_t mode = 0x0;                  ///< Extra options to pass to getMemProc


  /************************************************************************/
  /* Setup the cmdlineName variable                                       */
  /************************************************************************/
  if (memMode == ECMD_MEM_DMA) {
    cmdlineName = "getmemdma";
  } else if (memMode == ECMD_MEM_MEMCTRL) {
    cmdlineName = "getmemmemctrl";
  } else if (memMode == ECMD_MEM_PROC) {
    cmdlineName = "getmemproc";
  } else if (memMode == ECMD_SRAM) {
    cmdlineName = "getsram";
  }

  /************************************************************************/
  /* Parse Local FLAGS here!                                              */
  /************************************************************************/

  /* get format flag, if it's there */
  char * outputFormatPtr = ecmdParseOptionWithArgs(&argc, &argv, "-o");
  if (outputFormatPtr != NULL) {
    outputformat = outputFormatPtr;
  }  
  char * inputFormatPtr = ecmdParseOptionWithArgs(&argc, &argv, "-i");
  if (inputFormatPtr != NULL) {
    inputformat = inputFormatPtr;
  }

  /* Get the channel for getsram */
  if (memMode == ECMD_SRAM) {
    char * channelPtr = ecmdParseOptionWithArgs(&argc, &argv, "-ch");
    if (channelPtr != NULL) {
      if (!ecmdIsAllDecimal(channelPtr)) {
        printLine = cmdlineName + " - Non-dec characters detected in channel option\n";
        ecmdOutputError(printLine.c_str());
        return ECMD_INVALID_ARGS;
      }
      channel = (uint32_t)atoi(channelPtr);
      sramMode |= (channel & (ECMD_SRAM_MODE_CHANNEL_MASK >> ECMD_SRAM_MODE_CHANNEL_SHIFT)) << ECMD_SRAM_MODE_CHANNEL_SHIFT;
    } 

    char * pectopPtr = ecmdParseOptionWithArgs(&argc, &argv, "-top");
    if (pectopPtr != NULL) {
      if (!ecmdIsAllDecimal(pectopPtr)) {
        printLine = cmdlineName + " - Non-dec characters detected in top option\n";
        ecmdOutputError(printLine.c_str());
        return ECMD_INVALID_ARGS;
      }
      pcietop = (uint32_t)atoi(pectopPtr);
      sramMode |= (pcietop & (ECMD_SRAM_MODE_PECTOP_MASK >> ECMD_SRAM_MODE_PECTOP_SHIFT)) << ECMD_SRAM_MODE_PECTOP_SHIFT;
    }

    char * pecphyPtr = ecmdParseOptionWithArgs(&argc, &argv, "-phy");
    if (pecphyPtr != NULL) {
      if (!ecmdIsAllDecimal(pecphyPtr)) {
        printLine = cmdlineName + " - Non-dec characters detected in phy option\n";
        ecmdOutputError(printLine.c_str());
        return ECMD_INVALID_ARGS;
      }
      pciephy = (uint32_t)atoi(pecphyPtr);
      sramMode |= (pciephy & (ECMD_SRAM_MODE_PECPHY_MASK >> ECMD_SRAM_MODE_PECPHY_SHIFT)) << ECMD_SRAM_MODE_PECPHY_SHIFT;
    }

    char * modePtr = ecmdParseOptionWithArgs(&argc, &argv, "-mode");
    if (modePtr != NULL) {
      if (!ecmdIsAllHex(modePtr)) {
        printLine = cmdlineName + " - Non-hex characters detected in mode option\n";
        ecmdOutputError(printLine.c_str());
        return ECMD_INVALID_ARGS;
      }
      match = sscanf(modePtr, "%x", &sramMode);
      if (match != 1) {
        ecmdOutputError("Error occurred processing mode value!\n");
        return ECMD_INVALID_ARGS;
      }
      channel = (sramMode & ECMD_SRAM_MODE_CHANNEL_MASK) >> ECMD_SRAM_MODE_CHANNEL_SHIFT;
    }

    if ( (modePtr != NULL) && ((channelPtr != NULL) || (pectopPtr != NULL) || (pecphyPtr != NULL) ) ) {
      printLine = cmdlineName + " - mode cannot be specified along with channel, top or phy\n";
      ecmdOutputError(printLine.c_str());
      return ECMD_INVALID_ARGS;
    } else if ((channelPtr != NULL) && ((pectopPtr != NULL) || (pecphyPtr != NULL))) {
      printLine = cmdlineName + " - channel cannot be specified along with top or phy\n";
      ecmdOutputError(printLine.c_str());
      return ECMD_INVALID_ARGS;
    } else if ((pectopPtr != NULL) && (pecphyPtr == NULL)) {
      printLine = cmdlineName + " - top and phy must be specified together\n";
      ecmdOutputError(printLine.c_str());
      return ECMD_INVALID_ARGS;
    } else if ((pectopPtr == NULL) && (pecphyPtr != NULL)) {
      printLine = cmdlineName + " - top and phy must be specified together\n";
      ecmdOutputError(printLine.c_str());
      return ECMD_INVALID_ARGS;
    } 
  }

  /* Get the filename if -fb is specified */
  char * filename = ecmdParseOptionWithArgs(&argc, &argv, "-fb");
  
  /* Get the filename if -fd is specified */
  char * dcardfilename = ecmdParseOptionWithArgs(&argc, &argv, "-fd");

  if(((filename != NULL) || (dcardfilename != NULL)) && 
     ((outputFormatPtr != NULL) || (inputFormatPtr != NULL))) {
    printLine = cmdlineName + " - Options -f and -o/-i can't be specified together for format. Specify either one.\n";
    ecmdOutputError(printLine.c_str());
    return ECMD_INVALID_ARGS;
  } 
  if((dcardfilename != NULL) && (filename != NULL)) {
    printLine = cmdlineName + "Options -fb and -fd can't be specified together for format. Specify either one.\n";
    ecmdOutputError(printLine.c_str());
    return ECMD_INVALID_ARGS;
  }

  //expect and mask flags check
  if (filename == NULL && dcardfilename == NULL) {
    if ((expectPtr = ecmdParseOptionWithArgs(&argc, &argv, "-exp")) != NULL) {
      expectFlag = true;
      
      if ((maskPtr = ecmdParseOptionWithArgs(&argc, &argv, "-mask")) != NULL) {
	maskFlag = true;
      }
    }
  } else {
    // If we are passing in data with a file, just look for -exp
    expectFlag = ecmdParseOption(&argc, &argv, "-exp");
  }

  if (memMode == ECMD_MEM_PROC) {
    //Check cache inhit option
    bool cacheInhibit = ecmdParseOption(&argc, &argv, "-ci");
    if (cacheInhibit) {
      mode |= MEMPROC_CACHE_INHIBIT;
    }
  }

  /************************************************************************/
  /* Parse Common Cmdline Args                                            */
  /************************************************************************/
  rc = ecmdCommandArgs(&argc, &argv);
  if (rc) return rc;

  /* Global args have been parsed, we can read if -coe was given */
  bool coeMode = ecmdGetGlobalVar(ECMD_GLOBALVAR_COEMODE); ///< Are we in continue on error mode

  // Read in the expect data
  if (expectFlag) {
    if ((filename == NULL) && (dcardfilename == NULL)) {

      rc = ecmdReadDataFormatted(expected, expectPtr, inputformat);
      if (rc) {
	ecmdOutputError((cmdlineName + " - Problems occurred parsing expected data, must be an invalid format\n").c_str());
	return rc;
      }

      if (maskFlag) {
	rc = ecmdReadDataFormatted(mask, maskPtr, inputformat);
	if (rc) {
	  ecmdOutputError((cmdlineName + " - Problems occurred parsing mask data, must be an invalid format\n").c_str());
	  return rc;
	}
	
      }

    } else {
      // Read from a file 
      if (filename != NULL) {
	rc = expected.readFile(filename, ECMD_SAVE_FORMAT_BINARY_DATA);
	if (rc) {
	  ecmdOutputError((cmdlineName + " - Problems occurred parsing expected data from file " + filename + " , must be an invalid format\n").c_str());
	  return rc;
	}
      } else {
	// Dcard
	// Pulled support for this as it is a pain, could be added if needed, 
	//   ecmdReadDcard returns a list of memory entries because there could 
	//   be holes, so would have to loop down below
	ecmdOutputError((cmdlineName + " - Currently Dcard support is not supported with -exp\n").c_str());
	return ECMD_INVALID_ARGS;
	//	rc = ecmdReadDcard(dcardfilename, expected);
	//	if (rc) {
	//	  printLine = cmdlineName + " - Problems occurred parsing input data from file " + dcardfilename +", must be an invalid format\n";
	//	  ecmdOutputError(printLine.c_str());
	//	  return rc;
	//	}

      }
      // Let's pull the length from the file
      numBytes = expected.getByteLength();
    }
	
  }

  /************************************************************************/
  /* Parse Local ARGS here!                                               */
  /************************************************************************/
  std::string chipType, chipUnitType;
  int legacyModeArgOffset = 1;
  if ( argc == 0 )
  {
    legacyModeArgOffset = 0;
  }
  else
  {
    rc = ecmdParseChipField(argv[0], chipType, chipUnitType, true /* supports wildcard usage */);
    if (rc || ecmdIsAllHex(chipType.c_str())) {
      legacyModeArgOffset = 0;
    }
  }

  if ((memMode == ECMD_SRAM) && (channel == 1)) {
    // channel 1 for sram commands is access to a circular buffer and does not require an address
    if ((numBytes == ECMD_UNSET) && (argc != (1 + legacyModeArgOffset)) ) {  // size, optional chip
      printLine = cmdlineName + " - Incorrect arguments specified for channel 1; only number of bytes needed with optional chip.\n";
      ecmdOutputError(printLine.c_str());
      printLine = cmdlineName + " - Type '" + cmdlineName + " -h' for usage.\n";
      ecmdOutputError(printLine.c_str());
      return ECMD_INVALID_ARGS;
    } else if ((argc > (2 + legacyModeArgOffset)) ) {
      printLine = cmdlineName + " - Too many arguments specified for channel 1.\n";
      ecmdOutputError(printLine.c_str());
      printLine = cmdlineName + " - Type '" + cmdlineName + " -h' for usage.\n";
      ecmdOutputError(printLine.c_str());
      return ECMD_INVALID_ARGS;
    }
  } else if ((numBytes == ECMD_UNSET) && (argc < (2 + legacyModeArgOffset)) ) {  //address + size, optional chip
    printLine = cmdlineName + " - Too few arguments specified; you need at least an address and number of bytes with optional chip.\n";
    ecmdOutputError(printLine.c_str());
    printLine = cmdlineName + " - Type '" + cmdlineName + " -h' for usage.\n";
    ecmdOutputError(printLine.c_str());
    return ECMD_INVALID_ARGS;
  } else if ((argc < (1 + legacyModeArgOffset))) { 
    printLine = cmdlineName + " - Too few arguments specified; you need at least an address with optional chip.\n";
    ecmdOutputError(printLine.c_str());
    printLine = cmdlineName + " - Type '" + cmdlineName + " -h' for usage.\n";
    ecmdOutputError(printLine.c_str());
    return ECMD_INVALID_ARGS;
  }

  if ((memMode == ECMD_SRAM) && (channel == 1)) {
    // Set a default address
    address = 0;
    // Get the number of bytes
    if (numBytes == ECMD_UNSET) {
      numBytes = (uint32_t)atoi(argv[0 + legacyModeArgOffset]);
    }
  } else {
    // Get the address
    if (!ecmdIsAllHex(argv[0 + legacyModeArgOffset])) {
      printLine = cmdlineName + " - Non-hex characters detected in address field\n";
      ecmdOutputError(printLine.c_str());
      return ECMD_INVALID_ARGS;
    }
#ifdef _LP64
    match = sscanf(argv[0 + legacyModeArgOffset], "%lx", &address);
#else
    match = sscanf(argv[0 + legacyModeArgOffset], "%llx", &address);
#endif
    if (match != 1) {
      ecmdOutputError("Error occurred processing address!\n");
      return ECMD_INVALID_ARGS;
    }

    // Get the number of bytes
    if (numBytes == ECMD_UNSET) {
      numBytes = (uint32_t)atoi(argv[1 + legacyModeArgOffset]);
    }
  }


  // do not allow numBytes >= 512MB
  if (numBytes >= 0x20000000) {
    printLine = cmdlineName + " - Number of bytes must be < 512MB\n";
    ecmdOutputError(printLine.c_str());
    return ECMD_INVALID_ARGS;
  }

  //Setup the target that will be used to query the system config
  // Memctrl DA is on the cage depth and proc/dma are on the processor pos depth
  if (memMode == ECMD_MEM_MEMCTRL) {
    target.cageState = ECMD_TARGET_FIELD_WILDCARD;
    target.nodeState = target.chipTypeState = target.slotState = 
      target.posState = target.chipUnitTypeState = target.chipUnitNumState = target.threadState = ECMD_TARGET_FIELD_UNUSED;
  } else if ((memMode == ECMD_MEM_PROC) || (memMode == ECMD_MEM_DMA) || ((legacyModeArgOffset == 0) && (memMode == ECMD_SRAM)) ) {
    target.chipType = ECMD_CHIPT_PROCESSOR;
    target.chipTypeState = ECMD_TARGET_FIELD_VALID;
    target.cageState = target.nodeState = target.slotState = 
      target.posState = ECMD_TARGET_FIELD_WILDCARD;
    target.chipUnitTypeState = target.chipUnitNumState = target.threadState = ECMD_TARGET_FIELD_UNUSED;
  } else if ((memMode == ECMD_SRAM)) {
    target.chipType = chipType;
    target.chipTypeState = ECMD_TARGET_FIELD_VALID;
    target.cageState = target.nodeState = target.slotState = 
      target.posState = ECMD_TARGET_FIELD_WILDCARD;
    if (chipUnitType != "") {
      target.chipUnitType = chipUnitType;
      target.chipUnitTypeState = ECMD_TARGET_FIELD_VALID;
      target.chipUnitNumState = ECMD_TARGET_FIELD_WILDCARD;
    } else {
      target.chipUnitTypeState = target.chipUnitNumState = ECMD_TARGET_FIELD_UNUSED;
    }
    target.threadState = ECMD_TARGET_FIELD_UNUSED;
  }

  rc = ecmdLooperInit(target, ECMD_SELECTED_TARGETS_LOOP, looperdata);
  if (rc) return rc;

  while (ecmdLooperNext(target, looperdata) && (!coeRc || coeMode)) {

    if (memMode == ECMD_MEM_DMA) {
      rc = getMemDma(target, address, numBytes, returnData);
    } else if (memMode == ECMD_MEM_MEMCTRL) {
      rc = getMemMemCtrl(target, address, numBytes, returnData);
    } else if (memMode == ECMD_MEM_PROC) {
      rc = getMemProc(target, address, numBytes, returnData, mode);
    } else if (memMode == ECMD_SRAM) {
      rc = getSram(target, sramMode, address, numBytes, returnData);
    }

    if (rc) {
      printLine = cmdlineName + " - Error occured performing " + cmdlineName + " on ";
      printLine += ecmdWriteTarget(target) + "\n";
      ecmdOutputError( printLine.c_str() );
      coeRc = rc;
      continue;
    }
    else {
      validPosFound = true;     
    }
    
    printLine = ecmdWriteTarget(target);
    if (expectFlag) {
      uint32_t mismatchBit = 0;

      if (maskFlag) {
        returnData.setAnd(mask, 0, returnData.getBitLength());
      }

      if (!ecmdCheckExpected(returnData, expected, mismatchBit)) {

        //@ make this stuff sprintf'd
        char outstr[300];
        printLine = ecmdWriteTarget(target) + "\n";
        ecmdOutputError( printLine.c_str() );
        if (mismatchBit != ECMD_UNSET) {
          sprintf(outstr, "%s - Data miscompare occured at (address %llX) (bit %d) (byte %d:0x%X bit %d)\n", 
                  cmdlineName.c_str(), (unsigned long long)address, mismatchBit, mismatchBit/8,
                  mismatchBit/8, mismatchBit%8);
          ecmdOutputError( outstr );
        }
        coeRc = ECMD_EXPECT_FAILURE;
        continue;
      }
    } else {
      if (filename != NULL) {
	rc = returnData.writeFile(filename, ECMD_SAVE_FORMAT_BINARY_DATA);
       
	if (rc) {
	  printLine += cmdlineName + " - Problems occurred writing data into file" + filename +"\n";
	  ecmdOutputError(printLine.c_str());
          break;
	}
	ecmdOutput( printLine.c_str() );
      } else if (dcardfilename != NULL) {
	std::string dataStr = ecmdWriteDataFormatted(returnData, "memd", address);
	std::ofstream ops;
	ops.open(dcardfilename);
	if (ops.fail()) {
	  char mesg[1000];
	  sprintf(mesg, "Unable to open file : %s for write", dcardfilename);
	  ecmdOutputError(mesg);
	  return ECMD_DBUF_FOPEN_FAIL;
	}
	if (dataStr[0] != '\n') {
	  printLine += "\n";
	}
	printLine += dataStr;
	ops << printLine.c_str();
	ops.close();

      } else  {
     
	std::string dataStr = ecmdWriteDataFormatted(returnData, outputformat, address);
	if (dataStr[0] != '\n') {
	  printLine += "\n";
	}
	printLine += dataStr;
	ecmdOutput( printLine.c_str() );
      }
    }  
  }
  // coeRc will be the return code from in the loop, coe mode or not.
  if (coeRc) return coeRc;

  // This is an error common across all UI functions
  if (!validPosFound) {
    printLine = cmdlineName + " - Unable to find a valid chip to execute command on\n";
    ecmdOutputError(printLine.c_str());
    return ECMD_TARGET_NOT_CONFIGURED;
  }

  return rc;
}

uint32_t ecmdPutMemUser(int argc, char * argv[], ECMD_DA_TYPE memMode) {
  uint32_t rc = ECMD_SUCCESS, coeRc = ECMD_SUCCESS;

  ecmdLooperData looperdata;            ///< Store internal Looper data
  std::string inputformat = "x";        ///< Output format - default to 'mem'
  ecmdDataBuffer inputData;             ///< Buffer to hold the data intended for memory
  std::list<ecmdMemoryEntry> memdata;   ///< Data from the D-Card format file 
  std::list<ecmdMemoryEntry>::iterator memdataIter; ///< to iterate on memdata list 
  ecmdMemoryEntry memEntry;             ///< to store data from the user
  bool validPosFound = false;           ///< Did the looper find anything?
  ecmdChipTarget target;                ///< Current target being operated on
  uint32_t channel = ECMD_UNSET;        ///< Channel to use for getsram
  uint32_t pcietop = ECMD_UNSET;        ///< PCIe Top to use for getsram
  uint32_t pciephy = ECMD_UNSET;        ///< PCIe Phy to use for getsram
  uint32_t sramMode = 0x0;              ///< Mode value that contains data to send to the API
  uint64_t address = 0;                 ///< The address from the command line
  std::string cmdlineName;              ///< Stores the name of what the command line function would be.
  int match;                            ///< For sscanf
  std::string printLine;                ///< Output data
  uint32_t mode = 0x0;                  ///< Extra options to pass to putMemProc

  /************************************************************************/
  /* Setup the cmdlineName variable                                       */
  /************************************************************************/
  if (memMode == ECMD_MEM_DMA) {
    cmdlineName = "putmemdma";
  } else if (memMode == ECMD_MEM_MEMCTRL) {
    cmdlineName = "putmemmemctrl";
  } else if (memMode == ECMD_MEM_PROC) {
    cmdlineName = "putmemproc";
  } else if (memMode == ECMD_SRAM) {
    cmdlineName = "putsram";
  }

  /************************************************************************/
  /* Parse Local FLAGS here!                                              */
  /************************************************************************/
  /* get format flag, if it's there */
  char * formatPtr = ecmdParseOptionWithArgs(&argc, &argv, "-i");
  if (formatPtr != NULL) {
    inputformat = formatPtr;
  }

  /* Get the channel for putsram */
  if (memMode == ECMD_SRAM) {
    char * channelPtr = ecmdParseOptionWithArgs(&argc, &argv, "-ch");
    if (channelPtr != NULL) {
      if (!ecmdIsAllDecimal(channelPtr)) {
        printLine = cmdlineName + " - Non-dec characters detected in channel option\n";
        ecmdOutputError(printLine.c_str());
        return ECMD_INVALID_ARGS;
      }
      channel = (uint32_t)atoi(channelPtr);
      sramMode |= (channel & (ECMD_SRAM_MODE_CHANNEL_MASK >> ECMD_SRAM_MODE_CHANNEL_SHIFT)) << ECMD_SRAM_MODE_CHANNEL_SHIFT;
    } 

    char * pectopPtr = ecmdParseOptionWithArgs(&argc, &argv, "-top");
    if (pectopPtr != NULL) {
      if (!ecmdIsAllDecimal(pectopPtr)) {
        printLine = cmdlineName + " - Non-dec characters detected in top option\n";
        ecmdOutputError(printLine.c_str());
        return ECMD_INVALID_ARGS;
      }
      pcietop = (uint32_t)atoi(pectopPtr);
      sramMode |= (pcietop & (ECMD_SRAM_MODE_PECTOP_MASK >> ECMD_SRAM_MODE_PECTOP_SHIFT)) << ECMD_SRAM_MODE_PECTOP_SHIFT;
    }

    char * pecphyPtr = ecmdParseOptionWithArgs(&argc, &argv, "-phy");
    if (pecphyPtr != NULL) {
      if (!ecmdIsAllDecimal(pecphyPtr)) {
        printLine = cmdlineName + " - Non-dec characters detected in phy option\n";
        ecmdOutputError(printLine.c_str());
        return ECMD_INVALID_ARGS;
      }
      pciephy = (uint32_t)atoi(pecphyPtr);
      sramMode |= (pciephy & (ECMD_SRAM_MODE_PECPHY_MASK >> ECMD_SRAM_MODE_PECPHY_SHIFT)) << ECMD_SRAM_MODE_PECPHY_SHIFT;
    }

    char * modePtr = ecmdParseOptionWithArgs(&argc, &argv, "-mode");
    if (modePtr != NULL) {
      if (!ecmdIsAllHex(modePtr)) {
        printLine = cmdlineName + " - Non-hex characters detected in mode option\n";
        ecmdOutputError(printLine.c_str());
        return ECMD_INVALID_ARGS;
      }
      match = sscanf(modePtr, "%x", &sramMode);
      if (match != 1) {
        ecmdOutputError("Error occurred processing mode value!\n");
        return ECMD_INVALID_ARGS;
      }
      channel = (sramMode & ECMD_SRAM_MODE_CHANNEL_MASK) >> ECMD_SRAM_MODE_CHANNEL_SHIFT;
      sramMode = (uint32_t)atoi(modePtr);
    }

    if ( (modePtr != NULL) && ((channelPtr != NULL) || (pectopPtr != NULL) || (pecphyPtr != NULL) ) ) {
      printLine = cmdlineName + " - mode cannot be specified along with channel, top or phy\n";
      ecmdOutputError(printLine.c_str());
      return ECMD_INVALID_ARGS;
    } else if ((channelPtr != NULL) && ((pectopPtr != NULL) || (pecphyPtr != NULL))) {
      printLine = cmdlineName + " - channel cannot be specified along with top or phy\n";
      ecmdOutputError(printLine.c_str());
      return ECMD_INVALID_ARGS;
    } else if ((pectopPtr != NULL) && (pecphyPtr == NULL)) {
      printLine = cmdlineName + " - top and phy must be specified together\n";
      ecmdOutputError(printLine.c_str());
      return ECMD_INVALID_ARGS;
    } else if ((pectopPtr == NULL) && (pecphyPtr != NULL)) {
      printLine = cmdlineName + " - top and phy must be specified together\n";
      ecmdOutputError(printLine.c_str());
      return ECMD_INVALID_ARGS;
    } 
  }

  /* Get the filename if -fb is specified */
  char * filename = ecmdParseOptionWithArgs(&argc, &argv, "-fb");
 
  /* Get the filename to file in D-Card format */ 
  char *dcardfilename = ecmdParseOptionWithArgs(&argc, &argv, "-fd");

  if(((filename != NULL) || (dcardfilename != NULL)) && (formatPtr != NULL) ) {
    printLine = cmdlineName + "Options -f and -i can't be specified together for format. Specify either one.\n";
    ecmdOutputError(printLine.c_str());
    return ECMD_INVALID_ARGS;
  } 

  if((dcardfilename != NULL) && (filename != NULL)) {
    printLine = cmdlineName + "Options -fb and -fd can't be specified together for format. Specify either one.\n";
    ecmdOutputError(printLine.c_str());
    return ECMD_INVALID_ARGS;
  }

  if (memMode == ECMD_MEM_PROC) {
    //Check cache inhit option
    bool cacheInhibit = ecmdParseOption(&argc, &argv, "-ci");
    if (cacheInhibit) {
      mode |= MEMPROC_CACHE_INHIBIT;
    }
  }

  /************************************************************************/
  /* Parse Common Cmdline Args                                            */
  /************************************************************************/
  rc = ecmdCommandArgs(&argc, &argv);
  if (rc) return rc;

  /* Global args have been parsed, we can read if -coe was given */
  bool coeMode = ecmdGetGlobalVar(ECMD_GLOBALVAR_COEMODE); ///< Are we in continue on error mode

  /************************************************************************/
  /* Parse Local ARGS here!                                               */
  /************************************************************************/
  std::string chipType, chipUnitType;
  int legacyModeArgOffset = 1;
  if ( argc == 0 )
  {
    legacyModeArgOffset = 0;
  }
  else
  {
    rc = ecmdParseChipField(argv[0], chipType, chipUnitType, true /* supports wildcard usage */);
    if (rc || ecmdIsAllHex(chipType.c_str())) {
      legacyModeArgOffset = 0;
    }
  }

  if ((memMode == ECMD_SRAM) && (channel == 1)) {
    // channel 1 for sram commands is access to a circular buffer and does not require an address
    // dcard not supported
    if (dcardfilename != NULL) {
      // ERROR
      printLine = cmdlineName + " - dcard file not supported for channel 1.\n";
      ecmdOutputError(printLine.c_str());
      printLine = cmdlineName + " - Type '" + cmdlineName + " -h' for usage.\n";
      ecmdOutputError(printLine.c_str());
      return ECMD_INVALID_ARGS;
    } else if ( ((argc >= (1 + legacyModeArgOffset)) && (filename != NULL)) ) {
      // Too many arguments
      printLine = cmdlineName + " - Too many arguments specified for channel 1.\n";
      ecmdOutputError(printLine.c_str());
      printLine = cmdlineName + " - Type '" + cmdlineName + " -h' for usage.\n";
      ecmdOutputError(printLine.c_str());
      return ECMD_INVALID_ARGS;
    } else if ( (argc > 1 + legacyModeArgOffset) ) {
      // Too many arguments
      printLine = cmdlineName + " - Too many arguments specified for channel 1; you only need input data|file.\n";
      ecmdOutputError(printLine.c_str());
      printLine = cmdlineName + " - Type '" + cmdlineName + " -h' for usage.\n";
      ecmdOutputError(printLine.c_str());
      return ECMD_INVALID_ARGS;
    } else if ( ((argc < (1 + legacyModeArgOffset)) && (filename == NULL)) ) {
      // Too few arguments, need data
      printLine = cmdlineName + " - Too few arguments specified for channel 1; you need at least input data.\n";
      ecmdOutputError(printLine.c_str());
      printLine = cmdlineName + " - Type '" + cmdlineName + " -h' for usage.\n";
      ecmdOutputError(printLine.c_str());
      return ECMD_INVALID_ARGS;
    }
  } else if ( (argc < (2 + legacyModeArgOffset)) && (filename == NULL) && (dcardfilename == NULL) ) {  //chip + address
    printLine = cmdlineName + " - Too few arguments specified; you need at least an address and data to write.\n";
    ecmdOutputError(printLine.c_str());
    printLine = cmdlineName + " - Type '" + cmdlineName + " -h' for usage.\n";
    ecmdOutputError(printLine.c_str());
    return ECMD_INVALID_ARGS;
  }else if( (argc < (1 + legacyModeArgOffset)) && (filename != NULL) ) { 
    printLine = cmdlineName + " - Too few arguments specified; you need at least an address and input data file.\n";
    ecmdOutputError(printLine.c_str());
    printLine = cmdlineName + " - Type '" + cmdlineName + " -h' for usage.\n";
    ecmdOutputError(printLine.c_str());
    return ECMD_INVALID_ARGS;
  } else if( ((argc > (2 + legacyModeArgOffset)) && (filename == NULL) && (dcardfilename == NULL)) || ((argc > (1 + legacyModeArgOffset)) && (filename != NULL)) ) {
    printLine = cmdlineName + " - Too many arguments specified; you only need an address and input data|file.\n";
    ecmdOutputError(printLine.c_str());
    printLine = cmdlineName + " - Type '" + cmdlineName + " -h' for usage.\n";
    ecmdOutputError(printLine.c_str());
    return ECMD_INVALID_ARGS;
  } else if( (argc > (1 + legacyModeArgOffset)) && (dcardfilename != NULL) ) {
    printLine = cmdlineName + " - Too many arguments specified; you only need an optional address offset and a dcard file.\n";
    ecmdOutputError(printLine.c_str());
    printLine = cmdlineName + " - Type '" + cmdlineName + " -h' for usage.\n";
    ecmdOutputError(printLine.c_str());
    return ECMD_INVALID_ARGS;
  }
  //Setup the target that will be used to query the system config 
  // Memctrl DA is on the cage depth and proc/dma are on the processor pos depth
  if (memMode == ECMD_MEM_MEMCTRL) {
    target.cageState = ECMD_TARGET_FIELD_WILDCARD;
    target.nodeState = target.chipTypeState = target.slotState = target.posState = target.chipUnitTypeState = target.chipUnitNumState = target.threadState = ECMD_TARGET_FIELD_UNUSED;
  } else if ((memMode == ECMD_MEM_PROC) || (memMode == ECMD_MEM_DMA) || ((legacyModeArgOffset == 0) && (memMode == ECMD_SRAM)) ) {
    target.chipType = ECMD_CHIPT_PROCESSOR;
    target.chipTypeState =   ECMD_TARGET_FIELD_VALID;
    target.cageState = target.nodeState = target.slotState = target.posState = ECMD_TARGET_FIELD_WILDCARD;
    target.chipUnitTypeState = target.chipUnitNumState = target.threadState = ECMD_TARGET_FIELD_UNUSED;
  } else if ((memMode == ECMD_SRAM)) {
    target.chipType = chipType;
    target.chipTypeState = ECMD_TARGET_FIELD_VALID;
    target.cageState = target.nodeState = target.slotState = 
      target.posState = ECMD_TARGET_FIELD_WILDCARD;
    if (chipUnitType != "") {
      target.chipUnitType = chipUnitType;
      target.chipUnitTypeState = ECMD_TARGET_FIELD_VALID;
      target.chipUnitNumState = ECMD_TARGET_FIELD_WILDCARD;
    } else {
      target.chipUnitTypeState = target.chipUnitNumState = ECMD_TARGET_FIELD_UNUSED;
    }
    target.threadState = ECMD_TARGET_FIELD_UNUSED;
  }

  // Get the address
  if ((memMode == ECMD_SRAM) && (channel == 1)) {
    address = 0;
  } else if ((dcardfilename == NULL) || (dcardfilename != NULL && argv[0] != NULL)) {
{'fraction_non_alphanumeric': 0.17970029159974427, 'fraction_numerical': 0.00480281931731354, 'mean_word_length': 2.662687760580273, 'pattern_counts': {'":': 0, '<': 153, '<?xml version=': 0, '>': 79, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 28, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7120447', 'n_tokens_mistral': 19728, 'n_tokens_neox': 19153, 'n_words': 5012}