Article
· Sep 11 3m read

Code Scanner

This story has followed me for more than 20 years.

In the early days of ObjectScript, the volume of $Functions was limited.
You had to write it as part of your program.
But the functionality was often implemented. It just had no name.
To use it, you had "system" calls using $ZU() functions. See Reference

Over time most $ZU() became deprecated and replaced by "official" $Functions.
But how to find then over a thousand lines of code written over decades
by an uncounted number of programmers that were gone with the wind.
Studio was something fresh and not so performant.

So I created a Search Utility to Scan all corners of possible Objectscript 
It is written in pure ObjectScript avoiding all System Methods.
This made it independent and was very useful in preparing migration to IRIS

It looks like this;

USER>do ^rcc.find
----------------
 
enter search string [$ZU] <blank> to exit: RCC
          Verbose? (0,1) [0]:
          Force UpperCase? (1,0) [1]:
 
enter code type (CLS,MAC,INT,INC,ALL) [ALL]: CLS
 
select namespace (ALL,%SYS,DOCBOOK,ENSDEMO,ENSEMBLE,SAMPLES,USER) [USER]:
 
** Scan Namespace: USER **
 
** CLS **
** 2      User.ConLoad
** 15     User.Main
** 3      csp.form
** 3      csp.winner
** 2      dc.rcc.Contest
** 37     dc.rcc.Main
** 1      dc.rcc.Prize
** 63 CLS **
----------------
 
enter search string [$ZU] <blank> to exit: RCC
          Verbose? (0,1) [0]:
          Force UpperCase? (1,0) [1]:
 
enter code type (CLS,MAC,INT,INC,ALL) [ALL]: mac
 
select namespace (%SYS,DOCBOOK,ENSDEMO,ENSEMBLE,SAMPLES,USER) [USER]:
 
** Scan Namespace: USER **
 
** MAC **
** 9      zpmshow
** 9 MAC **
----------------
 
enter search string [$ZU] <blank> to exit: RCC
          Verbose? (0,1) [0]: 1
          Force UpperCase? (1,0) [1]:
 
enter code type (CLS,MAC,INT,INC,ALL) [ALL]: MAC
 
select namespace (%SYS,DOCBOOK,ENSDEMO,ENSEMBLE,SAMPLES,USER) [USER]:
 
** Scan Namespace: USER **
 
** MAC **
 
** zpmshow **
#define rcc ^||rcc
        kill $$$rcc
                ,$$$rcc($i($$$rcc))=lin
        else { zw  zw $$$rcc b }
        for i=1:1:$$$rcc {
                if $d($$$rcc(+nb)) {
                set cmd=$s(ac="u":"un",1:"")_"install "_$li($$$rcc(nb))
        set lin=$g($$$rcc(ln))
                    ,$$$rcc(ln)=lin_$lb(desc)
** 9      zpmshow
** 9 MAC **
----------------
  • First enter some string to be searched
  • Verbose allows you to see matches in detail
  • Force UpperCase is useful to make scan case insensitive
  • Code type allows splitting scan into several steps
  • Namespace defines where the scan is executed
    • %-routines and %-classes are always excluded for namespaces other than %SYS

Practical hint

  • run a scan over ALL non-verbose to find affected code types
  • next run over INC and apply the required changes
  • then run CLS and apply the required changes
  • then run over MAC and apply the required changes
  • most likely there is no need for any fix in INT

GitHub

Video

Demo Server SMP
Demo Server WebTerminal
 

Discussion (4)2
Log in or sign up to continue

Hi Robert, I had to write something similar myself about 20 years ago when we moved from DSM to Caché to deal with all those pesky &$ZLIB functions. On top of that there was the problem of variable names that exceeded 8 characters. DSM was quite happy to truncate a variable to 8 characters and work with it. For example, a variable named LONGVAR was the same variable as one named LONGVARIABLE just because the first 8 were the same. Under DSM if you SET one of them the other was also SET, but not under Caché. All of these had to be found and corrected.