VFPUtils Article By: M. Asherman

  | Bottom | Unframe | Help |

Commander Development Tasks

Locate in Contents | (framed)

Locate in Discussion | (framed) 

Date Done
(not done)
add an optional abort-to-depth argument to CMDRM_AddFuncStep
Support a new numeric 4th argument to the Commander.CMDRM_AddFuncStep method (defaulting to 0), which would specify the relative stack depth to return to if an error occurs.  E.g. specifying a value of -1 for this abort_to_depth argument would cause CMDRM_AddFuncStep to fail (RETURN .F.) directly to the caller one level deeper than its direct caller in the stack.

The main purpose of this extension is to simplify state-saving logic in Saver-based applications, by providing a more concise alternative to a frequently used construct.  Note the equivalence of this:

IF NOT oCmdr.CMDRM_AddFuncStep(funcid, seq, cmdline)
    RETURN .F.

to the following single command line, which uses the new abort_to_depth argument (-1):

oCmdr.CMDRM_AddFuncStep(funcid, seq, cmdline, -1)

The reason that we can't simply substitute this command:

oCmdr.CMDRM_AddFuncStep(funcid, seq, cmdline)

i.e. omitting the last argument will not do, because the point is to fail cleanly as soon as an error has been detected.  The new argument avoids clumsy in-line error checking, but it still provides the same rigorous level of clean, modular error handling.

(not done)
cleaner handling of cases without explicit DBF extension
The Commander.Init argument for specifying a metafile path requires an explicit extension, which would typically (but not necessarily) be DBF.  If one specifies an existing metafile without an explicit DBF extension, however, the Init logic fails to detect the previous metafile and attempts to overwrite it with an empty copy of the template metafile.  If the SAFETY setting happens to be OFF, the old metafile is effectively zapped without warning.  This is a bug that should be fixed by revising the specs to follow the more usual convention of assuming a default DBF extension if no explicit extension was supplied.

Nadya mentioned noticing this problem (in connection with BTCrit) in her email of 5/20/01.  This also applies to any other Saver-based apps, e.g. XFormDBF.

support a GOTO mechanism for jumping directly to a given sequence #
Introduce a new PRIVATE memory variable, m.cmdr_next, declared in method Commander.CMDRM_DoFunc.  At the top of the main processing loop, check for a numeric value of m.cmdr_next.  If specified, locate the desired record for the same functionid with the given sequence # and continue processing from there (after resetting m.cmdr_next to .F.).  Generate an error if the specified seq # is not found (supply new error code/msg macros in commandr.h).  Also update help documentation regarding this new global memory variable.

This idea was mentioned a long time ago, but suddenly its usefulness has become clear in the context of BTCrit.  (We can use this GOTO mechanism to support an optimized mode of Saver-based state restoration logic for BTCrit's non-interactive "Run" action.)

(not done)
new cmdrm_nextfid method for obtaining the next available serialized functionid
Introduce a new Commander method that returns the next available functionid beginning with a given prefix and ending with an automatically assigned sequence number portion.  This will be useful for a Saver extension to easily generate new configuration ids.

Some preliminary logic for this new method was implemented on 2/13/01, but I didn't quite finish with testing and error handling aspects.  Also the Commander Help documentation hasn't yet been updated to show this extension.  The latest version of Commander includes this preliminary logic, since it does no harm, but this feature is not yet ready.

(not done)
assimilate old commandr.txt task list into new HTML task list
Go through the old Commander task list and create updated entries in the new Commander task list (this table and its outline) for selected issues that are still of interest.  Some of these old tasks were disposed of in changes for support of error handling and assorted small Commander refinements already done, so the tasks that remain are not of immediate importance.
quiet Commander subclass for nested error handling requirements
Introduce a new Commander subclass, CommanderQuiet, with property settings initialized to suppress visible error messages, so that a caller (e.g. Saver) can wrap an additional layer of error information around the lower level error message.  This is needed for proper error handling in Saver's "nested" usage of a Commander object, where Saver calls Commander, and both are based on ErrHandler foundation classes.  In order to capture and preserve any Commander.Init error details, it will also be necessary to support a new Init argument for target indirection.

Also take this opportunity to allow for customized error reporting based on the pseudo-function logic itself.  Use a modified version of the factorial function example, demo07b, to test and demonstrate proper use such error reporting, e.g. for the logic that validates the required numeric argument.  This requires only a minor change in the Commander.CMDRM_DoFunc method logic.  (Instead of treating the failure of the &cmd expansion as a generic error, the non-zero value of ehp_apperrno indicates that the pseudo-function logic has already reported the error and assigned a failure return value.)

Documentation in Commander Help - Design Overview really should include sections for all native methods (e.g. Init) that have any logic, and this should be kept in synch with program changes.  Also include a section about the cmdrclon( ) utility function.

(not done)
catch-all error handling for remaining Commander error cases
While most common Commander error cases are now handled cleanly, there remains the need to provide coverage for other possible errors that can't be explicitly checked for.  For example, this applies to infinite looping explosions and too-many-argument errors, which may be encountered before any method code is executed.  This is a similar problem to that of supporting a flexible default form-level error handler, which should be addressed at the ErrHandler level and then applied to its subclasses, including Commander.
assorted small Commander refinements from the old task list
Take this opportunity to knock off some small, compatible Commander changes that can be delivered along with the more substantial error handling changes already completed.  It will be helpful to batch these changes to minimize disruption of Saver and its derivative applications (XFormDBF and BTCrit).  Specifically, make these previously mentioned changes now:
revise Commander property, method, & macro names for consistency
Change the names of Commander properties and methods to follow the same sort of prefixing conventions as other more recent VFPUtils applications.  These conventions will make it easier to understand relationships to the underlying class hierarchy.  Specifically, make the following substitutions:

Type Old Name New Name Used Externally In
Property metafilepath cmdrp_metafilepath
  • SaverForm.SVM_GetLaunchCmd (in Saver2.vcx)
  • SaverCmdCopy.click (in both old Saver.vcx andSaver2.vcx)
  • SaverCmdSwitch.click (in both old Saver.vcx andSaver2.vcx)
Property quietnofunc cmdrp_quietnofunc 
  • saver.prg (in old Saver.pjx)
  • savrinit.prg (in Saver2.pjx)
  • XFormDBF.Init (in XFormDBF.scx)
  • BTCrit.Init (in BTCrit.scx)
Method addfuncstep cmdrm_addfuncstep
  • Saver.StateSave (in old Saver.vcx)
  • savrsave.prg (in Saver2.pjx)
  • SaverXFormDBF.StateSave (in XFormDBF.vcx)
  • SaverBTCrit.StateSave, BTCC_MultiList.BTC_StateSave, etc. (in BTCrit.vcx)
Method deletefunc cmdrm_deletefunc
  • Saver.StateSave (in old Saver.vcx)
  • SaverCmdDelete.Click (in both old Saver.vcx andSaver2.vcx)
  • savrsave.prg (in Saver2.pjx)
Method dofunc cmdrm_dofunc
  • Saver.StateRestore (in old Saver.vcx)
  • savrrest.prg (in Saver2.pjx)
  • XFormDBF.DBF sample configurations

Since these are incompatible changes, review cross-references to these names in order to determine which other programs will need to be adjusted.  In order to minimize disruption of XFormDBF and BTCrit, make these temporary provisions for compatibility:

  • retain old method names, AddFuncStep and DoFunc
    I.e. let the methods just pass on the call to the corresponding new method name.
  • use an ASSIGN method for the QuietNoFunc property
    Since the only usage by XFormDBF or BTCrit is an assignment in the Init method, we only need to introduce an Assign method to propagate these settings to the corresponding renamed property.

Also revise the names of macros defined in commandr.h to avoid use of the same prefix as used for global memory variables.  Retain the convention that Commander's global memory variables start with "cmdr_".  Rename macros previously starting with "CMDR_" to use the prefix "CMDM_", which is not used for any other purpose (regardless of upper/lower case, which is not significant to VFP).  Temporarily retain selected old macro definitions for compatibility, until all obsolete references have been eradicated.  (Most of these macros are only used internally in Commander, but note that BTCrit.Init uses CMDR_CLASS and CMDR_CLIBQ, and BTCrit criteria classes may also contain references to CMDR_DLAS1 and CMDR_DLAS2.)

developer-oriented help for Commander facilities
Create HTML pages of help documentation for the Commander application, as done for ErrHandler.  Also compare with similar task for the Saver subsystem, and see SplitCon Help - Design Overview as another example of developer help.  Expand on previous preliminary documentation.
convert old commandr.txt document into a web page
As done for other applications, e.g. similar task for XFormDBF, take the old text-based task list and documentation for Commander (commandr.txt) and put it into more convenient HTML form.  This will make it easier to migrate tidbits into the newer web organization.
support standard error handling facilities in Commander 
Compare this with similar tasks done for Querier on 11/6/99 and XFormDBF on 11/27/99, Saver on 08/07/00, and still outstanding task for Reporter.  This task, noted previously, is a prerequisite for supplying error-handling logic for all methods of SaverForm.  Detailed changes required for this task:
  • redefine Commander as a subclass of ErrHCustom
    (See ErrHandler Help - Usage, Creating an ErrHandler-Based Application for more about the required adjustments.)  Start out with default ehp_... property settings (no target indirection, interactive error reporting).
  • add/adjust error handling logic in all methods
    • Init Event
      supply standard ErrHandler Init Event method logic, plus additional error checking as appropriate.
    • Destroy Event
      Seems OK as-is, at least for this pass.  Errors here are very unlikely, and would require dealing with the complication of preserving information about any prior error.
    • AddFuncStep
    • DeleteFunc
    • DoFunc
      This is the most important event for which to provide good error handling coverage.
    • CMDRM_SeekFunc
    • CMDRM_Open
  • phase out use of the obsolete errorcode property
    Substitute the generic ehp_apperrcode property in its place.  Also make this substitution in Saver programs, to maintain compatibility with these Commander changes.  The only external users of the Commander.errorcode property are Saver.StateRestore (in old Saver.vcx) and savrrest.prg (in Saver2.pjx), which should be adjusted.  (Also see cmma0004 about internal Commander naming changes that will require further Saver adjustments.)
  • revised definition of the Commander.quietnofunc property
    This property affects the way that the DoFunc( ) method treats cases where the specified functionid is not found.  Previously, setting this flag to .T. suppressed an error message, but returned a failure result (.F.).  Redefine the quietnofunc property to have DoFunc( ) return success (.T.) and set ehp_apperrcode = 0 in these cases.  This simplifies the logic required in Saver's usage of Commander.DoFunc( ), but note the corresponding Saver adjustments required for compatibility.
  • eliminate obsolete CMDR_E* macros in commandr.h
    Get rid of the old macros for Commander error codes and messages in the commandr.h include file, because these are superseded by new macros that follow the new Commander naming conventions.  The old CMDR_E... macros were used only internally in Commander and in Saver, which needs to be adjusted accordingly as for the errorcode change.
  • define new Commander error codes and messages in commandr.h
    (The commandr.h include file should be included in the developer help pages for Commander, for convenient reference.)  New macros for Commander error codes and messages have the prefixes "CMDM_EC" and "CMDM_EM", respectively, according to the new Commander naming conventions.

Further extensions to consider are a Commander subclass having ehp_quiet = .t. as its default property setting, and an additional optional Init argument for passing an explicit target errhandler (see cmma0007).  This may be helpful in dealing with nested error handling issues, as in Saver changes for improved error handling during Init.  Wait and see how this falls out in the course of making those Saver changes.

| Top | Unframe |


Copyright 2000- 2002, SpaceTime Systems