06-19-2013 08:20 PM
A site I look after has recently completed a migration of their application from OpenVMS Alpha 7.2-2 to OpenVMS IA64 V8.4.
One of the developers has presented me with a set of requirements for defining a search list logical name. He insists "it used to work this way" back on the old machine. He wants a search list logical that:
- points to a DEV and a PROD source directory tree, in that order
- be able to SET DEFAULT to any subdirectory, using the search list logical name
- edit a file that exists (only) in the PROD tree and have it automatically saved to the corresponding DEV tree on exit
- a PURGE command should not delete all versions of the file in the PROD tree.
The best I have been able to come up with is this:
$ define OC_ SYS$SYSDEVICE:[OPS_COM.]/trans=CONC
$ define OPS_COM DKA2:[ITDEV.OPS_COM.]/trans=CONC, OC_:
This satisfies criteria 1,2 and 4. But he wants to edit a production file, that doesn't exist in the DEV area, and have the resulting file written to the DEV area. For example, suppose the file X.COM exists in SYS$SYSDEVICE:[OPS_COM.TEST] but not in DKA2:[ITDEV.OPS_COM.TEST]. He wants to be able to say
$ SET DEFAULT OPS_COM:[TEST]
$ EDIT X.COM
and have the resulting output file written to DKA2:[ITDEV.OPS_COM.TEST] not SYS$SYSDEVICE:[OPS_COM.TEST].
He could easily change his edit command to
$ EDIT X.COM /OUT=OPS_COM:
but he says he didn't have to do that, and he observed the same behaviour using EVE, EDT and LSEDIT.
The only way I've been able to get the editor to automatically write the output file to the DEV directory is to make the logical name fully concealed, i.e.
$ define OPS_COM DKA2:[ITDEV.OPS_COM.]/trans=CONC, OC_:/trans=CONC
but this then gives undesireable results with PURGE. For example, suppose there is one copy of file X.COM in DKA2:[ITDEV.OPS_COM.TEST] and two copies in SYS$SYSDEVICE:[OPS_COM.TEST]. The command
$ PURGE OPS_COM:[TEST]X.COM
results in all copies of SYS$SYSDEVICE:[OPS_COM.TEST]X.COM being deleted!
I have tested various permutations of logical names on multiple VMS versions and have come up with only two explanations for his perceived change in behaviour:
- the logical names on the old machine were somewhat different
- they had used a TPU section file to change the way the editor determined the default output file directory
Both options are possible, even likely. I am going to try to go back to some old backups of the old system (from before this project started) to see how the logical names were defined.
In the meantime, can someone offer a better way of setting up these logical names?
06-19-2013 10:00 PM
Conditions 1 and 2 will be met regardless of how you define the search list.
I'm a bit puzzled by 4 - I think that will depend on which files exist across the two branches of the search list, and the version numbers. For example, if the file exists in PROD only, surely it will get purged?
As for 3, I'm fairly sure that is dependent on the way (and when) the editor editor resolves the given filespec. As I recall, TPU would always create the new version in the same directory as the old version. Effectively it would parse the filespec to the terminal device name, and use it to create the new file. The "real" EDT would use the text of the original filespec, which would result in the new file being created in the first search list translation. I seem to recall this as a behaviour difference between EDT and TPU with an EDT config file.
I'm thinking of the issue of editing a VMS$COMMON file. TPU "gets it right" and puts the new version back where it came from. EDT gives you a SYS$SPECIFIC file, which will often break things down the track, or for other nodes in the cluster (another reason why I always advocated against using EDT).
If my recollection is correct, you MIGHT be able to use
$ DEFINE SD physdev1:[root1.],physdev2:[root2.] /TRANS=(CONCEALED,TERMINAL)
$ DEFINE SD:[whereever]
by keeping the search list concealed and terminal, it should defer the resolution to a physical device. I haven't tested it, and could well be wrong!
Just remember that the device names used in a CONCEALED definition must be real physical device names
Here's a fragment of code I use to define concealed logical names. You need 3 symbols defined
lognam is the logical name string
dirspec is the root directory (as a valid directory specification, which may contain concealed devices)
quals is any other qualifiers you want on define, like /SYSTEM/EXEC
It deals with the RMS oddities of <> vs , eliminates nested concealed devices, and removes redundant root directories.
In your case you'd need to generate 2 translation strings to construct the search list.
$ Conc=F$TRNLNM(F$PARSE(dirspec,,,"DEVICE")-":") $ IF F$LOCATE("<",Conc).LT.F$LENGTH(Conc) $ THEN $ lbr="<" $ rbr=">" $ ELSE $ lbr="[" $ rbr="]" $ ENDIF $ trans=(F$PARSE(dirspec,,,"DEVICE","NO_CONCEAL")+- F$PARSE(dirspec,lbr+"000000"+rbr,,"DIRECTORY","NO_
CONCEAL"))-- (rbr+lbr)-("000000"+rbr)-("."+rbr)+"*"-".*"-"*"-rb r+("."+rbr) $ DEFINE/TRANSLATION_ATTRIBUTES=(TERMINAL,CONCEALED) 'quals' 'lognam' 'trans'
06-20-2013 03:22 PM
Ouch! Forget everything I said. The double concealed and terminal search list does exactly what you DON'T want!
The behaviour of PURGE is particularly ugly. In this example, the DEV side has 3 versions 1, 20 and 21. The PROD side has versions 1,2 & 3. Note that the PURGE takes out all the PROD files, leaving just the highest version in the DEV branch.
JG$ dir sd:[dir2.dir4]fileb Directory SD:[DIR2.DIR4] FILEB.TXT;21 0 21-JUN-2013 07:57:31.88 FILEB.TXT;20 0 21-JUN-2013 07:57:29.32 FILEB.TXT;1 0 21-JUN-2013 07:57:22.72 FILEB.TXT;3 0 21-JUN-2013 07:57:04.62 FILEB.TXT;2 0 21-JUN-2013 07:56:59.59 FILEB.TXT;1 0 21-JUN-2013 07:56:54.90 Total of 6 files, 0 blocks. JG$ purge/log sd:[dir2.dir4]fileb.txt %PURGE-I-FILPURG, SD:[DIR2.DIR4]FILEB.TXT;20 deleted (0 blocks) %PURGE-I-FILPURG, SD:[DIR2.DIR4]FILEB.TXT;1 deleted (0 blocks) %PURGE-I-FILPURG, SD:[DIR2.DIR4]FILEB.TXT;3 deleted (0 blocks) %PURGE-I-FILPURG, SD:[DIR2.DIR4]FILEB.TXT;2 deleted (0 blocks) %PURGE-I-FILPURG, SD:[DIR2.DIR4]FILEB.TXT;1 deleted (0 blocks) %PURGE-I-TOTAL, 5 files deleted (0 blocks) JG$ dir sd:[dir2.dir4]fileb Directory SD:[DIR2.DIR4] FILEB.TXT;21 0 21-JUN-2013 07:57:31.88 Total of 1 file, 0 blocks.
but it gets worse. Here the PROD files have higher version numbers than DEV, but still PURGE deletes all but the highest version number in the DEV branch.
JG$ dir SD:[DIR2.DIR4]FILEB.TXT Directory SD:[DIR2.DIR4] FILEB.TXT;21 0 21-JUN-2013 07:57:31.88 FILEB.TXT;23 0 21-JUN-2013 08:03:43.13 FILEB.TXT;22 0 21-JUN-2013 08:03:20.42 Total of 3 files, 0 blocks. JG$ purge/log sd:[dir2.dir4]fileb.txt %PURGE-I-FILPURG, SD:[DIR2.DIR4]FILEB.TXT;23 deleted (0 blocks) %PURGE-I-FILPURG, SD:[DIR2.DIR4]FILEB.TXT;22 deleted (0 blocks) %PURGE-I-TOTAL, 2 files deleted (0 blocks)
If I thought there was anyone left in VMS engineering who'd listen I'd submit this as a bug!
Editing a file results in the new file always being created in the DEV branch. That seems reasonable, since I'm forcing the translation of the logical name to be deferred until it's actually being used, so the only possible translation for creations is DEV, and that's what you want, yes?
Maybe the trick here would be to create a PROD branch which is read only? You'll get FILNOTPUR errors from PURGE, but you won't delete the files. Storage is cheap, and you can never have too many backup copies of your release source code.
07-03-2013 01:01 AM
It looks like you've replicated my findings - thanks for making the effort.
When the PURGE issue was first reported to me I went back to test the behaviour on various older versions of VMS across VAX and Alpha and found the same behaviour as on Integrity V8.4. So it's not a new problem. Which is why I hesitate to report it as a bug; maybe I should anyway.
(But I expect the response will be along the lines of "if we change this it will break long-standing behaviour", and I suppose there could be sites that might be affected. On the other hand it would leave at worst one version of a file in a directory where previously it would leave 0.)