MSM to Caché Conversion Guide
Converting Your MSM Application
[Back] [Next]
Go to:

It is strongly recommended that you convert any MSM-specific language features to native Caché code, even though the Caché MSM language compatibility mode may allow you to run your MSM application with fewer changes. Conversion will be the first step in taking advantage of Caché-specific features such as Caché ObjectScript.

This chapter discusses the following topics:
How Routines Differ
Working with routines is slightly different in Caché than in MSM.
The MSM approach:
The Caché approach:
Porting MSM Routines
Use the following procedure to migrate MSM routines that are less than 64KB in size:
Although MSM can support as large a routine as the current stack and partitions sizes will allow (tested as high as 200 KB), Caché routines must compile to less than 64KB in size. You can use MSM’s ^%RSIZE utility to check your routine’s size before importing into Caché. To figure out how large a routine is, multiply the number of Text Blocks, as reported by ^%RSIZE, by 1 KB.
Any MSM routines larger than 64KB can be addressed in one of two ways:
You cannot migrate an MSM routine that is only stored as p-code (known as object code in Caché). If you need to migrate a routine that was only supplied as p-code, you will need to contact your application supplier to get the routine’s source code before proceeding.
MSM Language Compatibility Mode
Caché operates in MSM language mode when working with a MSM routine that has been ported. A language mode can be set individually for each routine, and a routine compiled in one language mode can call or be called by a routine compiled in another mode. Thus, for instance, an MSM mode routine could call a Caché mode routine which could in turn call another MSM mode routine.
Use $ZU(55, mode) to switch language modes, where mode is the number of the language mode. The relevant settings are:
After an MSM application is compiled in the correct language mode, it can be installed and run on any Caché system, no matter what other applications or language modes are used on that system. Almost all language mode processing occurs at compile time, not runtime. As a result, using a language mode such as MSM will generally deliver the same high performance as the Caché native language mode.
Native Caché mode is the default for each process. To change this default for specific process types, you will need to modify the appropriate line tag within the ^%ZSTART routine.
From within any of these modes, you can add your own commands, functions, or special variables, allowing you to convert your MSM %ZZCMNDS, %ZZFUNCS, and %ZZSVARS MSM routines. Depending on the current language mode, corresponding Caché routines will be searched for these added features.
  Commands Functions Variables
Original (native MSM) routines %ZZCMNDS %ZZFUNCS %ZZSVARS
Native Caché mode routines ^%ZLANGC00 ^%ZLANGF00 ^%ZLANGV00
MSM mode routines ^%ZLANGC008 ^%ZLANGF008 ^%ZLANGV008
The line tags you enter in these routines will be the names of your new commands, functions, or special variables. The line tags entered must begin with a “Z” and must be all capital letters. Actual execution of the command, function, or special variable is not case-sensitive.
Here is an example of custom code that calls the routines defined above:
MyRtn   ; Call the code added to the ^%ZLANG* routines
   New pid,rtn,x
   Set x=$ZU(55,8)   ; Change to MSM mode
   Read !,"Enter a process ID: ",pid
   Set rtn=$ZRTN(pid)
   If rtn=""  Set rtn="no routine"
   Write !,"At "_$ZTIME_", process #"_pid_" was running "_rtn_"."
   Set x=$ZU(55,0)   ; Return to native mode
Converting Nonstandard Functions and Features
Converting MSM’s implementation-specific functions and features will be the most intricate part of your conversion. Issues to keep in mind include:
Here are a few suggested actions that you can take to get a rough idea of how much effort will be involved in an MSM to Caché conversion.
See the appendix MSM and Caché Utilities Catalog for a list of MSM commands, functions, operators, preprocessor directives, special variables, and structured system variables, and their Caché equivalents.
MSM-XCALL Functions
XCALL functions allow the use of external programs, such as C or Assembler, to be called from within M. For backward compatibility support, MSM also supports a ZCALL interface. Both XCALLs and ZCALLs are similar in concept and in implementation to Caché’s $ZF() Callout interface (see Using the Caché Callout Gateway). XCALL and ZCALL functions must be converted to Caché $ZF() functions.
OS Functions via %OS and $ZOS
MSM’s %OS utility and $ZOS function allow many OS-related functions to be performed from within M. There are no direct equivalents to %OS or $ZOS in Caché, although through the use of $ZF(-1), $ZF(-2), or a pipe to an OS command (using the "Q" parameter to the OPEN command), you can easily execute any OS functions you wish.
Generally speaking, any file related operations (as used in $ZOS for example) should be replaced with method calls to the %Library.File class. For example, to delete a file:
Set status=##class(%Library.File).Delete("filename")
Caché’s $ZF(-1) function allows you to run OS commands from a Caché programmer’s prompt. On Windows platforms, these commands will hang if they expect user input. For more details see Issuing Operating System Commands in Using the Caché Callout Gateway.
Converting ZWINTERM Calls
MSM allows you to use pop-up windows to display messages via the ZWINTERM interface. With Caché, you have several options to gain this same character-based windowing functionality.
MSM Preprocessor Directives
Both MSM and Caché provide mechanisms by which you can use preprocessor directives to perform tasks such as defining macros, defining macro libraries, and including source code from another routine.
Caché stores its directives in .MAC and .INC code. The MSM globals ^ZMSMMAC and ^ZMSMSRC, which store the preprocessor directives and source code respectively, have conceptual equivalents in Caché’s ^rMAC and ^ROUTINE globals.
While MSM and Caché have similar facilities conceptually, the syntax varies between the two systems. For example, in MSM you can use one of two mechanisms to build formal parameter lists for your macros:
Caché does not support the use of enumerated variables for macro preprocessing. Instead, you will need to adopt Caché’s method of referencing alphanumeric names. The MSM examples above would look like this in Caché:
#define copyright(%var1,%var2) "Copyright ",%var1,"-",%var2
Arguments of the formal parameter list in Caché must begin with a % sign. Caché does not support MSM’s $0 variable, which stores the number of arguments passed to a given macro.
MSM and Caché also differ in the way that macros are referenced from within the application. Using the above macro definition, in MSM you could reference the copyright macro using one of two methods:
In Caché, the %% and #% syntax for referencing macros is not supported. You would call the copyright macro using this syntax:
Extended References for Globals and Routines
As mentioned earlier, Caché relies on namespaces to access data from the actual physical database volumes. It is strongly recommended that you adopt Caché’s namespaces from within your application. In some cases however, changing every hard-coded extended reference in the application will be a difficult short-term goal.
Caché supports several forms of extended references:
For globals:
         (this is useful if piecing apart an MSM UVI/VOL string)
For routines:
DO ^|"namespace"|routine
DO ^|"^system^directory"|routine
JOB ^routine["namespace"]
JOB ^routine["namespace",""]
JOB ^routine["directory","system"]
JOB ^routine["^system^directory"]
You might want to create a Caché namespace called MGR that uses the CACHESYS database as the default location for globals and routines. Extended references that expect MGR to contain system globals and routines will not need modification.
Handling End-of-file Situations in Caché
MSM uses the special variable $ZC to store status information from the last device access. In particular, MSM applications made wide use of $ZC to check if the READ command reached the end of a sequential file ($ZC returns -1 in this case). Caché, unlike MSM, triggers an <ENDOFFILE> error in this situation. To handle an End-Of-File situation in Caché, you will need to create a custom error trap in your application using $ZTRAP.
Caché also supports the $ZC (if used in MSM language compatibility mode) as well as the $ZEOF (native Caché language mode) special variables.
MSM and Cache Database Networking (DDP)
There are a number of differences between MSM database networking (DDP) and Caché database networking (DSM-DDP/DCP/ECP).