OS/2, eCS & ArcaOS - Technical > Programming

List path to ObjectID's in plain rexx

(1/2) > >>

Jan-Erik Lärka:
This script take the object ID that point to a program object such as '<WP_CLIPV>' or a folder such as '<MMPM2_FOLDER>' and return path information.

* It can list the file path to the object, path to the application (for WPProgram) and the path to the object with names as seen visually on the desktop.
* The code use rexx and rexxutils without the need for wptools.
* Haven't tried, but it's possible to add information about startup folder and parameters for WPProgram objects.
* The script cache information during the first call so that consecutive calls return faster.
* Use fastini to shorten the initial startup delay more.
You may want to optimize/shorten the script  ;)


--- Code: ---/*
 * Filename: WPSObj.cmd
 *   Author: JanErik
 *  Created: Sat Aug  3 2019
 *  Purpose: Script to list Paths and Object names of Object ID's with rexx
 *  Changes:
 */
CALL rxFuncAdd "SysIni", "REXXUTIL", "SysIni"

objids = 'WP_NOWHERE NOOBJECT WP_CHESS WP_GAMES WP_TOOLS WP_SEEK XWP_FONTFOLDER WP_3DCAD MAH_FOLDER MAH_EXE'
DO i = 1 TO WORDS( objids )
   hID = RxObjIDPath( '<'||SUBWORD( objids, i, 1 )||'>' )
   SAY hID '"'!_PWH_!.hID.appPath'" ->' !_PWH_!.hID.fPath '"'!_PWH_!.hID.fName'"' '<-'||!_PWH_!.hID.isDir||'->' !_PWH_!.hID.oPath '"'!_PWH_!.hID.oName'"'
END
RETURN 0

RxObjIDPath: PROCEDURE EXPOSE !_PWH_!.
   PARSE ARG objID, refresh
   IF \DATATYPE( !_PWH_!.0, 'W' ) | refresh = 1 THEN
   DO
      /* Determine the currently active handles */
      hApp = SysIni( 'SYSTEM', 'PM_Workplace:ActiveHandles', 'HandlesAppName' )
      IF hApp = 'ERROR:' THEN
         hApp = 'PM_Workplace:Handles0'
      block = ''
      CALL SysIni 'SYSTEM', hApp, 'All:', 'blocks.'
      DO i = 1 To blocks.0
         block = block||SysIni( 'SYSTEM', hApp, blocks.i )
      END
      DROP blocks.
      DROP hApp
      !_PWH_!. = ''
      !_count_! = 0
      PARSE VALUE block WITH 5 block
      DO WHILE 0 < LENGTH( block )
         PARSE VALUE block WITH !_name_! 5 block
         SELECT
            WHEN !_name_! = 'DRIV' THEN
               PARSE VALUE block WITH 20 block
            WHEN !_name_! = 'NODE' THEN
            DO
               PARSE VALUE block WITH 3 !_oID_! 5 !_pID_! 7 25 !_isDir_! 27 !_fnSize_! 29 block
               !_oID_! = C2RX( !_oID_! )
               !_PWH_!.!_oID_!.isDir = C2X2D( !_isDir_! )
               !_PWH_!.!_oID_!.fID = C2RX( !_pID_! )
               !_PWH_!.!_oID_!.fPath = ''
               !_fnSize_! = C2X2D( !_fnSize_! )
               !_PWH_!.!_oID_!.fName = LEFT( block, !_fnSize_! )
               !_count_! = !_count_! + 1
               !_PWH_!.0 = !_count_!
               block = SUBSTR( block, !_fnSize_! + 2 )
            END
            OTHERWISE NOP
         END
      END
      IF SysIni( 'USER', 'PM_Abstract:FldrContent', 'All:', 'blocks.' ) <> 'ERROR:' THEN
      DO i = 1 TO blocks.0
         !_children_! = SysIni( 'USER', 'PM_Abstract:FldrContent', blocks.i )
         block = blocks.i
         IF !_PWH_!.block.isDir <> 1 THEN
            !_PWH_!.block.isDir = 1
         DO WHILE 0 < LENGTH( !_children_! )
            PARSE VALUE !_children_! WITH !_child_! 3 5 !_children_!
            !_child_! = C2RX( !_child_! )
            IF !_PWH_!.!_child_!.fID = '' THEN
               !_PWH_!.!_child_!.fID = block
         END
      END
      DROP blocks.
      DROP block
      DROP !_child_!
      DROP !_children_!
   END
   IF 0 < LENGTH( STRIP( objID ) ) THEN
   DO
      !_findID_! = C2RX( LEFT( SysIni( 'USER', 'PM_Workplace:Location', objID ), 2 ) )
      !_PWH_!.!_findID_!.oPath = RxObjPath( !_findID_! )
      RETURN !_findID_!
   END
RETURN 0
   
RxObjPath: PROCEDURE EXPOSE !_PWH_!.
   PARSE ARG findID
   !_path_! = ''
   !_PWH_!.findID.appPath = ''
   PARSE VALUE SysIni( 'USER', 'PM_Abstract:Objects', STRIP( findID, 'L', '0' ) ) WITH . 'WPProgramRef' +19 !_findID_! +2 'WPAbstract' +15 !_objSize_! +2 !_objName_! 'WPObject'
   IF !_findID_! <> '' THEN
   DO
      !_findID_! = C2RX( !_findID_! )
      IF 0 < LENGTH( !_objSize_! ) THEN
         !_PWH_!.findID.oName = LEFT( !_objName_!, C2X2D( !_objSize_! ) - 1 )
      IF !_PWH_!.!_findID_!.isDir <> 1 THEN
      DO
         !_PWH_!.findID.fName = !_PWH_!.findID.oName
         DO WHILE 0 < !_PWH_!.!_findID_!.fID
            !_path_! = '\'||!_PWH_!.!_findID_!.fName||!_path_!
            !_findID_! = !_PWH_!.!_findID_!.fID
         END
         !_path_! = !_PWH_!.!_findID_!.fName||!_path_!
         !_PWH_!.findID.appPath = !_path_!
      END
      !_findID_! = !_PWH_!.findID.fID
   END
   ELSE IF !_PWH_!.!_findID_!.isDir <> 1 THEN
      !_findID_! = !_PWH_!.findID.fID
   ELSE
      !_findID_! = findID
   !_path_! = ''
   DO WHILE 0 < !_PWH_!.!_findID_!.fID
      !_path_! = '\'||!_PWH_!.!_findID_!.fName||!_path_!
      !_findID_! = !_PWH_!.!_findID_!.fID
   END
   !_path_! = !_PWH_!.!_findID_!.fName||!_path_!
   !_PWH_!.findID.fPath = !_path_!
   !_path_! = !_path_!||'\'||!_PWH_!.findID.fName
   !_findID_! = findID
   DO WHILE 0 < !_PWH_!.!_findID_!.fID
      PARSE VALUE REVERSE( !_path_! ) WITH !_name_!'\'!_path_!
      !_name_! = REVERSE( !_name_! )
      !_path_! = REVERSE( !_path_! )
      IF SysGetEA( !_path_!||'\'||!_name_!, '.LONGNAME', 'EAValue' ) = 0 & EAValue <> '' THEN
      DO
         PARSE VAR EAValue EAType +2 EALength +2 EAValue
         IF EAType = 'FDFF'x THEN
            !_PWH_!.!_findID_!.oName = STRIP( EAValue, 'T', '00'x )
      END
      ELSE
         !_PWH_!.!_findID_!.oName = !_name_!
      !_findID_! = !_PWH_!.!_findID_!.fID
   END
   !_path_! = ''
   !_findID_! = !_PWH_!.findID.fID
   DO WHILE 0 < !_PWH_!.!_findID_!.fID
      !_path_! = '\'||!_PWH_!.!_findID_!.oName||!_path_!
      !_findID_! = !_PWH_!.!_findID_!.fID
   END
   !_path_! = !_PWH_!.!_findID_!.fName||!_path_!
RETURN !_path_!

XREV: PROCEDURE
   !_hex_! = STRIP( ARG( 1 ) )
   !_exp_! = ''
   IF \DATATYPE( !_hex_!, 'X' ) THEN RETURN !_exp_!
   DO i = 1 TO LENGTH( !_hex_! ) BY 4
      !_exp_! = STRIP( TRANSLATE( '1234', RIGHT( '0000'||STRIP( SUBSTR( !_hex_!, i, 4 ) ), 4 ), '3412' ) )||!_exp_!
   END
RETURN !_exp_!

C2RX: PROCEDURE
RETURN XREV( C2X( ARG(1) ) )

C2X2D: PROCEDURE
   chrs = ARG(1)
   retval = ''
   DO i = 1 TO LENGTH( chrs ) BY 2
      retval = retval||X2D( C2RX( SUBSTR( chrs, i, 2 ) ) )
   END
RETURN retval
--- End code ---

//Jan-Erik

xynixme:
An impressive but slow part of WPTOOOLS.DLL in Rexx. A possible bug, depending on an unknown goal, is appending the assumed, recommended and usual <> characters, which aren't required.


--- Quote from: Jan-Erik Lärka on September 11, 2019, 10:50:05 pm ---
* The script cache information during the first call so that consecutive calls return faster.
--- End quote ---

It may be possible to reduce the total number of SysIni()-calls with 'All:' to one, instead of once per sample object.

Besides that, after having inserted a CALL Time 'R' and SAY Time('E'):

First call of the whole script, all sample objects, Object Rexx interpreter: 86.74 seconds.
Second call of the whole script, only <WP_GAMES>: 95.32 seconds.
Third call of the whole script, only <WP_GAMES>: 102.43 seconds.
Fourth call of the whole script, only <WP_GAMES>: 313.86 seconds (executed in the background).

IIRC a possible improvement w.r.t. WPTOOLS.DLL, without introducing new functionalities, is that is does display some default settings as if those settings were customized. IIRC/2 mainly the German OS/2 community tends to copy code to set the program type of, for example, a PM program with program type PM to PM, probably because WPTOOLS.DLL returned that (default) setting. If someone is going to add (displaying) the EXENAME, PARAMETERS, and so on, then please consider an option to unhide such a modern default setting. Typically "PROGTYPE=PM" is not required in a WPS setup string of a PM app, albeit WPTOOLS.DLL may display this as if it's set intentionally. A reason to display it may be that WPTOOLS.EXE doesn't check the type of the app itself, but typically that type will be right for a fully functional PM app.

Jan-Erik Lärka:
Retrieval of the values for object id's in the users ini-file require < and >
Measure the time to retrieve the first object compared to the second, third etc. not the script itself.
It has to load and build entries from the ini-files the first time.
Object Rexx use built in functionality, so this is intended for Classic Rexx.
External libraries are seldom a part of the base OS and call for something as this.


--- Code: ---IF \DATATYPE( !_PWH_!.0, 'W' ) | refresh = 1 THEN
--- End code ---
restrict the number of times the script has to fill the stem to only the first time while it retrieve the entry once for each <objectid> with
--- Code: ---PARSE VALUE SysIni( 'USER', 'PM_Abstract:Objects', STRIP( findID, 'L', '0' ) ) WITH . 'WPProgramRef' +19 !_findID_! +2 'WPAbstract' +15 !_objSize_! +2 !_objName_! 'WPObject'
--- End code ---

xynixme:

--- Quote from: Jan-Erik Lärka on September 12, 2019, 12:40:03 pm ---Retrieval of the values for object id's in the users ini-file require < and >."
 
Measure the time to retrieve the first object compared to the second, third etc. not the script itself.

External libraries are seldom a part of the base OS and call for something as this.
--- End quote ---

No, the characters are a part of the object ID. First you have left out those characters, and next you always append then. Like changing your first name to an-Erik, next always use a J prefix, and hope Erik-Jan will never use the app (an-Erik -> Jan-Erik, Erik-Jan -> JErik-Jan). The name of the object ID of the desktop is "<WP_DESKTOP>", including the <> characters. The OS, or apps, don't have to append it. You actually may end up with <<WP_DESKTOP>>, if the users types a correct name and you won't check the name. HELP REXX SYSCREATEOBJECT is an example, which shows that the object ID isn't "WP_DESKTOP". It's "<WP_DESKTOP>". IIRC I've seen at least one app which didn't use the <> characters.

I've measured what I wanted to measure, which was the script itself. It slows down too. Different measurement, different subject.

So is your script. But AFAICT, I don't have ArcaOS, is there an OS file called WPTOOLS.DLL in the DLL directory of that OS, and it would be easy to release WPTools as an informal "User's FixPak" for OS/2s and eCSes, if you can find the same full set of WPTools files. Unfortunately people have added "stuff" to OSes without thinking about the rest of the small community (7-zip, WPTools, OO.EXE, ...), so you may have missed the fact that this external module actually is a part of the base OS by now. Nevertheless the dive into the INI files remains impressive, and may have some use on its own.

Dave Yeo:

--- Quote from: André Heldoorn on September 12, 2019, 02:57:32 pm --- But AFAICT, I don't have ArcaOS, is there an OS file called WPTOOLS.DLL in the DLL directory of that OS, and it would be easy to release WPTools as an informal "User's FixPak" for OS/2s and eCSes, if you can find the same full set of WPTools files. Unfortunately people have added "stuff" to OSes without thinking about the rest of the small community (7-zip, WPTools, OO.EXE, ...), so you may have missed the fact that this external module actually is a part of the base OS by now. Nevertheless the dive into the INI files remains impressive, and may have some use on its own.

--- End quote ---

WPTools is in the DLL directory on ArcaOS (sys\dll) and eCS 2.1+ (ecs\dll).
While oo.exe is in both ArcaOS and eCS2.1+, 7z is not installed as part of ArcaOS, just eCS 2.1+

Navigation

[0] Message Index

[#] Next page

Go to full version