docs: def parseCmdline(rh, posOpsList, keyOpsList):
      """
      Parse the request command input.
  
      Input:
         Request Handle
         Positional Operands List.  This is a dictionary that contains
         an array for each subfunction.  The array contains a entry
         (itself an array) for each positional operand.
         That array contains:
            - Human readable name of the operand,
            - Property in the parms dictionary to hold the value,
            - Is it required (True) or optional (False),
            - Type of data (1: int, 2: string).
         Keyword Operands List.  This is a dictionary that contains
         an item for each subfunction.  The value for the subfunction is a
         dictionary that contains a key for each recognized operand.
         The value associated with the key is an array that contains
         the following:
            - the related ReqHandle.parms item that stores the value,
            - how many values follow the keyword, and
            - the type of data for those values (1: int, 2: string)
  
      Output:
         Request Handle updated with parsed input.
         Return code - 0: ok, non-zero: error
      """
  
      rh.printSysLog("Enter generalUtils.parseCmdline")
  
      # Handle any positional operands on the line.
      if rh.results['overallRC'] == 0 and rh.subfunction in posOpsList:
          ops = posOpsList[rh.subfunction]
          currOp = 0
          # While we have operands on the command line AND
          # we have more operands in the positional operand list.
          while rh.argPos < rh.totalParms and currOp < len(ops):
              key = ops[currOp][1]       # key for rh.parms[]
              opType = ops[currOp][3]    # data type
              if opType == 1:
                  # Handle an integer data type
                  try:
                      rh.parms[key] = int(rh.request[rh.argPos])
                  except ValueError:
                      # keyword is not an integer
                      msg = msgs.msg['0001'][1] % (modId, rh.function,
                          rh.subfunction, (currOp + 1),
                          ops[currOp][0], rh.request[rh.argPos])
                      rh.printLn("ES", msg)
                      rh.updateResults(msgs.msg['0001'][0])
                      break
              else:
                  rh.parms[key] = rh.request[rh.argPos]
              currOp += 1
              rh.argPos += 1
  
          if (rh.argPos >= rh.totalParms and currOp < len(ops) and
              ops[currOp][2] is True):
              # Check for missing required operands.
              msg = msgs.msg['0002'][1] % (modId, rh.function,
                  rh.subfunction, ops[currOp][0], (currOp + 1))
              rh.printLn("ES", msg)
              rh.updateResults(msgs.msg['0002'][0])
  
      # Handle any keyword operands on the line.
      if rh.results['overallRC'] == 0 and rh.subfunction in keyOpsList:
          while rh.argPos < rh.totalParms:
              if rh.request[rh.argPos] in keyOpsList[rh.subfunction]:
                  keyword = rh.request[rh.argPos]
                  rh.argPos += 1
                  ops = keyOpsList[rh.subfunction]
                  if keyword in ops:
                      key = ops[keyword][0]
                      opCnt = ops[keyword][1]
                      opType = ops[keyword][2]
                      if opCnt == 0:
                          # Keyword has no additional value
                          rh.parms[key] = True
                      else:
                          # Keyword has values following it.
                          storeIntoArray = False    # Assume single word
                          if opCnt < 0:
                              storeIntoArray = True
                              # Property is a list all of the rest of the parms.
                              opCnt = rh.totalParms - rh.argPos
                              if opCnt == 0:
                                  # Need at least 1 operand value
                                  opCnt = 1
                          elif opCnt > 1:
                              storeIntoArray = True
                          if opCnt + rh.argPos > rh.totalParms:
                              # keyword is missing its related value operand
                              msg = msgs.msg['0003'][1] % (modId, rh.function,
                                  rh.subfunction, keyword)
                              rh.printLn("ES", msg)
                              rh.updateResults(msgs.msg['0003'][0])
                              break
  
                          """
                          Add the expected value to the property.
                          Take into account if there are more than 1.
                          """
                          if storeIntoArray:
                              # Initialize the list.
                              rh.parms[key] = []
                          for i in range(0, opCnt):
                              if opType == 1:
                                  # convert from string to int and save it.
                                  try:
                                      if not storeIntoArray:
                                          rh.parms[key] = (
                                              int(rh.request[rh.argPos]))
                                      else:
                                          rh.parms[key].append(int(
                                              rh.request[rh.argPos]))
                                  except ValueError:
                                      # keyword is not an integer
                                      msg = (msgs.msg['0004'][1] %
                                          (modId, rh.function, rh.subfunction,
                                          keyword, rh.request[rh.argPos]))
                                      rh.printLn("ES", msg)
                                      rh.updateResults(msgs.msg['0004'][0])
                                      break
                              else:
                                  # Value is a string, save it.
                                  if not storeIntoArray:
                                      rh.parms[key] = rh.request[rh.argPos]
                                  else:
                                      rh.parms[key].append(rh.request[rh.argPos])
                              rh.argPos += 1
                          if rh.results['overallRC'] != 0:
                              # Upper loop had an error break from loops.
                              break
                  else:
                      # keyword is not in the subfunction's keyword list
                      msg = msgs.msg['0005'][1] % (modId, rh.function,
                          rh.subfunction, keyword)
                      rh.printLn("ES", msg)
                      rh.updateResults(msgs.msg['0005'][0])
                      break
              else:
                  # Subfunction does not support keywords
                  msg = (msgs.msg['0006'][1] % (modId, rh.function,
                      rh.subfunction, rh.request[rh.argPos]))
                  rh.printLn("ES", msg)
                  rh.updateResults(msgs.msg['0006'][0])
                  break
  
      rh.printSysLog("Exit generalUtils.parseCmdLine, rc: " +
          str(rh.results['overallRC']))
      return rh.results['overallRC']