'set novalue on' /* force KEXX and its way of SIGNAL ON NOVALUE */ /* Usage: [MACRO] KEX [macroname] */ /* Examples: KEX PROFILE */ /* KEX C-PgUp */ /* Requires: Kedit 5.0 or Keditw 1.0 (Frank Ellermann, 1999) */ /* Used to edit a macro, e.g. KEX PROFILE. This makes sense if */ /* the MACROPATH is not part of your normal PATH. Look at this: */ /* SET PATH=C:\DOS;C:\KEDIT (maybe) */ /* SET KEDIT=WIDTH 2048 MACROPATH KHELP (maybe) */ /* SET KHELP=C:\KEDIT\KEXX;C:\KEDIT\SAMPLES (maybe) */ /* KEDIT WHATEVER.TXT (start a Kedit session) */ /* X MANYFILE.KEX (doesn't find MANYFILE) */ /* X C:\KEDIT\SAMPLES\MANYFILE.KEX (edit old MANYFILE.KEX) */ /* KEX MANYFILE (dito with less typing) */ /* Another feature of KEX is its interpretation of macro names: */ /* X C:\KEDIT\KEXX\STAR.KEX (normally no good idea) */ /* KEX STAR (STAR is a defined key) */ /* X C:\KEDIT\KEXX\HIGH.KEX (normally no good idea) */ /* KEX HIGH (HIGH is SET HIGHLIGHT) */ /* X C:\KEDIT\KEXX\1234.KEX (a really dubious idea) */ /* KEX 1234 (1234 is a LOCATE 1234) */ /* X C:\KEDIT\KEXX\INITIAL.KML (that's a special case) */ /* KEX (most often edited KML) */ /* X C:\KEDIT\KEXX\ANOTHER.KML (no other special case) */ /* KEX ANOTHER.KML (but still less typing) */ /* X "C:\KEDIT\KEXX\BAD NAME.KEX" (possible on OS/2 HPFS) */ /* KEX "BAD NAME" (you get what you want) */ /* X A:TEST.KEX (other paths or drives) */ /* KEX A:TEST (save 4 key strokes :-) */ /* MOD MACRO ! (this won't modify s-1) */ /* KEX ! (edit !.KEX or key s-1) */ /* - Please update the header template for new macros in the line */ /* marked by "MODIFY template HERE". [New feature added 2002] */ /* - KEX called without arguments edits INITIAL.KML, change this */ /* for your most often edited macro library (maybe MISC.KML or */ /* KEYS.KML ?) in the line marked by "MODIFY initial HERE", but */ /* don't add a path: KEX takes care of your MACROPATH setting. */ /* - If no old macro is found KEX edits any new macro either in */ /* the 1st directory of an explicitly set MACROPATH, or in the */ /* PATH directory where it found KEDIT.EXE. Both can fail if */ /* MACROPATH is simply ON (default) or OFF, and then KEX edits */ /* a new macro in the current directory as shown by QUERY DIR. */ /* - KEDITW only: if MACROPATH is ON and KEDITW found in PATH, */ /* then the USER subdirectory of KEDITW is treated as default. */ /* - Kedit looks for macros (as its last resort) in the directory */ /* of KEDIT.EXE. Unfortunately neither KEX nor Kedit can use */ /* this information in searching a macro to be edited, unless */ /* KEDIT.EXE is (as usual) located in a diretory of your PATH. */ /* - You can also use KEX to edit any defined macro (like a key), */ /* this is done in a scratch library KEX.KML in your MACROPATH */ /* if the macro isn't found in INITIAL.KML. KEX won't replace */ /* a currently edited KEX.KML without warning (unlike command */ /* MACROS). KEX supports only the classic style of keys, e.g. */ /* KEX ! automatically looks for key S-1 and doesn't find S+1. */ /* - KEX tests the plausibility of new macro names, e.g. KEX ARB */ /* gives you the warning that ARB is an (implicit) SET ARBCHAR. */ /* Macro ARB.KEX as in SYNONYM ARBCHAR 3 MACRO ARB is possible, */ /* but more likely it's a typo (or you don't want such macros). */ /* - A macro like 007.KEX even won't work as SYNONYM 007, but it */ /* can be used by MACRO 007 (bypassing an implicit LOCATE 007). */ /* On HPFS completely weird stuff like KEX ...KEX (file ...KEX) */ /* can be used as MACRO ...KEX (only MACRO .. doesn't work !?). */ /* - KEX tests new KeditW commands and SET options, e.g. KEX CLIP */ /* would show a warning 'explicit MACRO CLIP required to bypass */ /* KeditW CLIPboard'. Only KeditW 1.0 commands and SET options */ /* are recognized. Of course if you use KEX with KeditW 1.5 or */ /* later any new SET options are implicitly recognized by a SET */ /* test, but the list of commands is probably incomplete. */ /* - The test SET uses e.g. NOMSG SET SCR, and if this results in */ /* error 3 "too few operands" SCR is a valid SET option missing */ /* its value. KEX then determines the complete option name and */ /* its value by NOMSG QUERY SCR, eventually showing a warning */ /* like 'implicit SET operand as in [SET] SCReen size 12'. */ /* Unfortunately KeditW does not support QUERY SCReen (even if */ /* OFPW OFF would allow SET SCReen), and therefore KEX acts on */ /* the QUERY SCReen error. Other SET options work as expected. */ /* - Vice versa KEX tests old Kedit 5.0 SET options removed from */ /* KeditW, e.g. KEX MOUSE shows a warning 'explicit MACRO MOUSE */ /* required to bypass old Kedit 5.0 SET MOUSE'. In the case of */ /* KeditW 1.0 this is literally true, even if MOUSE.KEX exists. */ NAME = strip( arg( 1 )) if length( NAME ) <= 1 then exit KEX( NAME ) if left( NAME, 1 ) <> '"' then exit KEX( NAME ) if right( NAME, 1 ) <> '"' then exit KEX( NAME ) exit KEX( substr( NAME, 2, length( NAME ) - 2 )) /* proposed test(s) => expected result(s) */ /* KEX a-. KEX a-\ KEX . KEX \ => keys a-. a-\ . \ */ /* KEX : KEX " " KEX  => keys s-; space c-u */ /* KEX CURL KEX STAR KEX END => keys curl star end */ /* KEX NN KEX N.N KEX NN. => files NN.KEX N.N NN */ /* KEX \\ KEX " " KEX .. KEX ".." => invalid fileid.s */ /* KEX ME KEX FE KEX COL KEX EOF => warnings MErge FExt */ /* KEX 123 KEX -NEW KEX NEW KEX NOP => warnings 123 -NEW */ /* KEX ' ' KEX ..KEX KEX KEX KEX => warnings ' ' ..KEX */ KEX: procedure /* -------------------------------------- */ KEYS = 'initial.kml' /* MODIFY initial HERE (Kedit Macros Lib) */ LAST = lastpos( '\', arg( 1 )) /* split explicit PATH, */ if 0 < LAST & LAST < length( arg( 1 )) /* \ at end is no PATH: */ then parse arg PATH +(LAST) FILE else parse arg FILE , PATH /* drive handled later */ if FILE == '' then FILE = KEYS /* default KEYS library */ NAME = FILE /* split explicit type, */ LAST = lastpos( '.', FILE ) /* . at end is no type: */ if 0 < LAST & LAST < length( arg( 1 )) then do if \ abbrev( NAME, '.' ) then NAME = left( FILE, LAST - 1 ) end /* do not split .* NAME */ if 0 = LAST then FILE = NAME || '.kex' /* adding default type */ if pos( '\', PATH ) > 0 /* no search, use PATH */ then exit EDIT( PATH || FILE ) if pos( ':', FILE ) = 2 /* no search, use drive */ then exit EDIT( FILE ) /* else search old FILE */ PATH = dosenv( 'PATH' ) /* prepare macro search */ if PATH > '' & right( PATH, 1 ) <> ';' then PATH = PATH || ';' if version.1() == 'KEDIT' then do /* Kedit 5.0 MACROPATH: */ LAST = PATH( 'kedit.exe', PATH ) /* Kedit's LAST resort */ if macropath.1() = 'ON' then MACS = PATH /* incl. LAST */ if macropath.1() = 'OFF' then MACS = LAST /* OFF -> LAST */ end else do /* KEDITW not tested... */ LAST = PATH( 'keditw.exe', PATH ) /* Keditw's LAST resort */ if LAST > '' then do /* add \USER & \SAMPLES */ LAST = LAST || ';' || LAST || 'USER;' || LAST || 'SAMPLES' end if macropath.1() = 'ON' then MACS = PATH || LAST if macropath.1() = 'OFF' then MACS = '' /* OFF -> void */ end if wordpos( macropath.1(), 'OFF ON' ) = 0 then do MACS = dosenv( macropath.1()) /* use common MACROPATH */ if MACS > '' & right( MACS, 1 ) <> ';' then MACS = MACS || ';' MACS = MACS || LAST /* LAST is Kedit's home */ end PATH = PATH( FILE, directory.1( ) || ';' || MACS ) if PATH > '' then exit EDIT( PATH || FILE ) parse var MACS PATH ';' . /* first MACROPATH dir. */ if version.1() <> 'KEDIT' then parse var LAST . ';' LAST ';' . if macropath.1() = 'ON' then PATH = LAST /* LAST / USER */ if macropath.1() = 'OFF' then PATH = '' /* actual dir. */ if PATH = '' then PATH = directory.1() /* use actual directory */ if right( PATH, 1 ) <> '\' then PATH = PATH || '\' LAST = translate( NAME || '.kex' ) if FILE = NAME | translate( FILE ) = LAST then do MACS = PATH( KEYS, MACS ) /* search KEYS library */ if MACS > '' then KEYS = MACS || KEYS ; else KEYS = '' call KEY NAME, PATH, KEYS /* check DEFINEd macros */ end return EDIT( PATH || FILE ) /* kedit in MACROPATH */ KEY: procedure /* -------------------------------------- */ parse arg NAME, PATH, KEYS /* edit a defined macro */ X = NAME /* translate key macros */ 'nomsg query macro' X /* check DEFINEd macro: */ if rc <> 0 then do if length( X ) <> 1 then return /* possible macro name */ K = c2d( X ) if K > 127 then return /* key handled by ASCII */ if K = 127 then NAME = 'c-bksp' /* also known as ^? DEL */ if K < 32 then NAME = 'c-' || d2c( K + 64 ) if K = 0 then NAME = 'c-2' /* also known as ^@ NUL */ if K = 30 then NAME = 'c-6' /* also known as ^^ RS */ if K = 31 then NAME = 'c--' /* also known as ^_ US */ if K = 32 then NAME = 'space' /* supporting a KEX " " */ K = '!@#$%^&*()<>?{|}+_":~' K = translate( X, "1234567890,./[\]=-';`", K ) if K <> X then NAME = 's-' || K /* name of shifted key */ 'nomsg query macro' NAME /* try defined key name */ if rc <> 0 then 'query macro' X /* Kedit is screwed up: */ if rc <> 0 then exit rc /* a really fatal error */ end if pos( X, xrange( 'A', 'Z' )) > 0 then NAME = 's-' || X if KEYS > '' then do /* look up default KEYS */ 'kedit "' || KEYS || '"' ; if rc <> 0 then exit rc 'extract /CASE/' ; 'case mixed ignore' 'nomsg tfind' delimit( ':' || NAME || ' ' ) CASE.0 = rc ; 'case' CASE.1 CASE.2 if CASE.0 = 0 then do NAME = translate( NAME ) ; 'refresh' say NAME 'is a defined macro (located in' KEYS || '):' say 'edit, save, and define' KEYS 'to modify' NAME exit 0 /* found key, leave KEX */ end if ring.0() > 1 then 'quit' /* not found, quit KEYS */ end 'macros' NAME ; if rc <> 0 then exit rc 'fileid "' || PATH || 'KEX.KML"' ; if rc == 0 then 'refresh' NAME = translate( NAME ) /* KEX.KML in MACROPATH */ say NAME 'is a defined macro (default or in defined *.KML):' say 'edit, save, define, and delete KEX.KML to modify' NAME exit rc /* found key, leave KEX */ EDIT: procedure /* -------------------------------------- */ 'kedit "' || arg(1) || '"' ; if rc <> 0 then exit rc if size.1() <> 0 then return 0 /* okay, edit old macro */ if fext.1() <> 'KEX' then return 0 /* okay, edit whatever */ TXT = fname.1() /* uppercase macro name */ 'sos lineadd firstcol' /* add a default header */ "text 'set novalue on'" /* based on TABS INCR 3 */ TXT = TXT '...' copies( ' ', 34 - length( TXT )) 'text /* force KEXX and its way of SIGNAL ON NOVALUE ' || ' */' 'sos lineadd lineadd firstcol' 'text /* Usage: [MACRO]' TXT || ' */' 'sos lineadd firstcol' 'text /* Example: ' TXT right( ' ', 7 ) || ' */' 'sos lineadd firstcol' 'text /* Purpose: ' TXT right( ' ', 7 ) || ' */' 'sos lineadd firstcol' ; parse value date() with . . TXT TXT = '(Frank Ellermann,' TXT || ')' /* MODIFY template HERE */ 'text /* Requires: Kedit 5.0 ' right( TXT, 34 ) || ' */' 'sos lineadd lineadd firstcol cr cr cr' 'set alt 0 0' ; 'lineflag nonew all' /* allow to simply QUIT */ TXT = fname.1() /* uppercase macro name */ if words( TXT ) <> 1 then do /* any blanks (on HPFS) */ if EMSG( '"' || TXT || '" required to call' arg(1)) then return 1 /* else continue tests: */ end if verify( TXT, '.' ) = 0 then do /* weird ..KEX on HPFS: */ if EMSG( TXT || '.KEX required to call' arg(1)) then return 1 end if verify( TXT, xrange( 'A', 'Z' )) > 0 then do if EMSG( TXT 'required to call' arg(1)) then return 1 end if IMPL( 'Add' , TXT, 1, 'implicit' ) then return 1 if IMPL( 'ALERT' , TXT, 5, 'implicit' ) then return 1 if IMPL( 'ALL' , TXT, 3, 'implicit' ) then return 1 if IMPL( 'ALter' , TXT, 2, 'implicit' ) then return 1 if IMPL( 'BAckward' , TXT, 2, 'implicit' ) then return 1 if IMPL( 'Bottom' , TXT, 1, 'implicit' ) then return 1 if IMPL( 'CANCEL' , TXT, 6, 'implicit' ) then return 1 if IMPL( 'CAppend' , TXT, 2, 'implicit' ) then return 1 if IMPL( 'CDelete' , TXT, 2, 'implicit' ) then return 1 if IMPL( 'CEnter' , TXT, 2, 'implicit' ) then return 1 if IMPL( 'CFirst' , TXT, 2, 'implicit' ) then return 1 if IMPL( 'CLAst' , TXT, 3, 'implicit' ) then return 1 if IMPL( 'Change' , TXT, 1, 'implicit' ) then return 1 if IMPL( 'CHDir' , TXT, 3, 'implicit' ) then return 1 if IMPL( 'CHDRive' , TXT, 4, 'implicit' ) then return 1 if IMPL( 'CInsert' , TXT, 2, 'implicit' ) then return 1 if IMPL( 'CLocate' , TXT, 2, 'implicit' ) then return 1 if IMPL( 'CMATCH' , TXT, 6, 'implicit' ) then return 1 if IMPL( 'CMSG' , TXT, 4, 'implicit' ) then return 1 if IMPL( 'COMMAND' , TXT, 7, 'implicit' ) then return 1 if IMPL( 'COMPress' , TXT, 4, 'implicit' ) then return 1 if IMPL( 'COpy' , TXT, 2, 'implicit' ) then return 1 if IMPL( 'COUnt' , TXT, 3, 'implicit' ) then return 1 if IMPL( 'COVerlay' , TXT, 3, 'implicit' ) then return 1 if IMPL( 'CReplace' , TXT, 2, 'implicit' ) then return 1 if IMPL( 'CURsor' , TXT, 3, 'implicit' ) then return 1 if IMPL( 'DEBUG' , TXT, 5, 'implicit' ) then return 1 if IMPL( 'DEFine' , TXT, 3, 'implicit' ) then return 1 if IMPL( 'DELete' , TXT, 3, 'implicit' ) then return 1 if IMPL( 'DIALOG' , TXT, 6, 'implicit' ) then return 1 if IMPL( 'DIR' , TXT, 3, 'implicit' ) then return 1 if IMPL( 'DIRAppend' , TXT, 4, 'implicit' ) then return 1 if IMPL( 'DIRSORT' , TXT, 7, 'implicit' ) then return 1 if IMPL( 'DMSG' , TXT, 4, 'implicit' ) then return 1 if IMPL( 'DOS' , TXT, 3, 'implicit' ) then return 1 if IMPL( 'DOSNowait' , TXT, 4, 'implicit' ) then return 1 if IMPL( 'DOSQuiet' , TXT, 4, 'implicit' ) then return 1 if IMPL( 'Down' , TXT, 1, 'implicit' ) then return 1 if IMPL( 'DUPlicate' , TXT, 3, 'implicit' ) then return 1 if IMPL( 'EDITV' , TXT, 5, 'implicit' ) then return 1 if IMPL( 'EMSG' , TXT, 4, 'implicit' ) then return 1 if IMPL( 'ERASE' , TXT, 5, 'implicit' ) then return 1 if IMPL( 'EXPand' , TXT, 3, 'implicit' ) then return 1 if IMPL( 'EXTract' , TXT, 3, 'implicit' ) then return 1 if IMPL( 'FILE' , TXT, 4, 'implicit' ) then return 1 if IMPL( 'FFile' , TXT, 2, 'implicit' ) then return 1 if IMPL( 'FILLbox' , TXT, 4, 'implicit' ) then return 1 if IMPL( 'Find' , TXT, 1, 'implicit' ) then return 1 if IMPL( 'FINDUp' , TXT, 5, 'implicit' ) then return 1 if IMPL( 'FUp' , TXT, 2, 'implicit' ) then return 1 if IMPL( 'FLOW' , TXT, 4, 'implicit' ) then return 1 if IMPL( 'FOrward' , TXT, 2, 'implicit' ) then return 1 if IMPL( 'GET' , TXT, 3, 'implicit' ) then return 1 if IMPL( 'HELP' , TXT, 4, 'implicit' ) then return 1 if IMPL( 'HEXType' , TXT, 4, 'implicit' ) then return 1 if IMPL( 'HIT' , TXT, 3, 'implicit' ) then return 1 if IMPL( 'IMMediate' , TXT, 3, 'implicit' ) then return 1 if IMPL( 'Input' , TXT, 1, 'implicit' ) then return 1 if IMPL( 'Join' , TXT, 1, 'implicit' ) then return 1 if IMPL( 'Kedit' , TXT, 1, 'implicit' ) then return 1 if IMPL( 'KHELP' , TXT, 5, 'implicit' ) then return 1 if IMPL( 'LEft' , TXT, 2, 'implicit' ) then return 1 if IMPL( 'LEFTAdjust' , TXT, 5, 'implicit' ) then return 1 if IMPL( 'LESS' , TXT, 4, 'implicit' ) then return 1 if IMPL( 'Locate' , TXT, 1, 'implicit' ) then return 1 if IMPL( 'LOCK' , TXT, 4, 'implicit' ) then return 1 if IMPL( 'LOWercase' , TXT, 3, 'implicit' ) then return 1 if IMPL( 'LPrefix' , TXT, 2, 'implicit' ) then return 1 if IMPL( 'MACRO' , TXT, 5, 'implicit' ) then return 1 if IMPL( 'MACROS' , TXT, 6, 'implicit' ) then return 1 if IMPL( 'MARK' , TXT, 4, 'implicit' ) then return 1 if IMPL( 'MErge' , TXT, 2, 'implicit' ) then return 1 if IMPL( 'MODify' , TXT, 3, 'implicit' ) then return 1 if IMPL( 'MORE' , TXT, 4, 'implicit' ) then return 1 if IMPL( 'MOve' , TXT, 2, 'implicit' ) then return 1 if IMPL( 'MSG' , TXT, 3, 'implicit' ) then return 1 if IMPL( 'Next' , TXT, 1, 'implicit' ) then return 1 if IMPL( 'NFind' , TXT, 2, 'implicit' ) then return 1 if IMPL( 'NFINDUp' , TXT, 6, 'implicit' ) then return 1 if IMPL( 'NFUp' , TXT, 3, 'implicit' ) then return 1 if IMPL( 'NOMSG' , TXT, 5, 'implicit' ) then return 1 if IMPL( 'Overlay' , TXT, 1, 'implicit' ) then return 1 if IMPL( 'OVERLAYBox' , TXT, 8, 'implicit' ) then return 1 if IMPL( 'PREServe' , TXT, 4, 'implicit' ) then return 1 if IMPL( 'PRint' , TXT, 2, 'implicit' ) then return 1 if IMPL( 'PURge' , TXT, 3, 'implicit' ) then return 1 if IMPL( 'PUT' , TXT, 3, 'implicit' ) then return 1 if IMPL( 'PUTD' , TXT, 4, 'implicit' ) then return 1 if IMPL( 'Query' , TXT, 1, 'implicit' ) then return 1 if IMPL( 'QUIT' , TXT, 4, 'implicit' ) then return 1 if IMPL( 'QQuit' , TXT, 2, 'implicit' ) then return 1 if IMPL( 'READV' , TXT, 5, 'implicit' ) then return 1 if IMPL( 'RECover' , TXT, 3, 'implicit' ) then return 1 if IMPL( 'REDO' , TXT, 4, 'implicit' ) then return 1 if IMPL( 'REFRESH' , TXT, 7, 'implicit' ) then return 1 if IMPL( 'REName' , TXT, 3, 'implicit' ) then return 1 if IMPL( 'REPEat' , TXT, 4, 'implicit' ) then return 1 if IMPL( 'Replace' , TXT, 1, 'implicit' ) then return 1 if IMPL( 'RESet' , TXT, 3, 'implicit' ) then return 1 if IMPL( 'RESTore' , TXT, 4, 'implicit' ) then return 1 if IMPL( 'RGTLEFT' , TXT, 7, 'implicit' ) then return 1 if IMPL( 'RIght' , TXT, 2, 'implicit' ) then return 1 if IMPL( 'RIGHTAdjust' , TXT, 6, 'implicit' ) then return 1 if IMPL( 'SAVE' , TXT, 4, 'implicit' ) then return 1 if IMPL( 'SSave' , TXT, 2, 'implicit' ) then return 1 if IMPL( 'SCHange' , TXT, 3, 'implicit' ) then return 1 if IMPL( 'Set' , TXT, 1, 'implicit' ) then return 1 if IMPL( 'SHift' , TXT, 2, 'implicit' ) then return 1 if IMPL( 'SORT' , TXT, 4, 'implicit' ) then return 1 if IMPL( 'SOS' , TXT, 3, 'implicit' ) then return 1 if IMPL( 'SPlit' , TXT, 2, 'implicit' ) then return 1 if IMPL( 'SPLTJOIN' , TXT, 8, 'implicit' ) then return 1 if IMPL( 'STATus' , TXT, 4, 'implicit' ) then return 1 if IMPL( 'SYNEX' , TXT, 5, 'implicit' ) then return 1 if IMPL( 'TAG' , TXT, 3, 'implicit' ) then return 1 if IMPL( 'TEXT' , TXT, 4, 'implicit' ) then return 1 if IMPL( 'TFind' , TXT, 2, 'implicit' ) then return 1 if IMPL( 'TOP' , TXT, 3, 'implicit' ) then return 1 if IMPL( 'UNDO' , TXT, 4, 'implicit' ) then return 1 if IMPL( 'UNLOCK' , TXT, 6, 'implicit' ) then return 1 if IMPL( 'Up' , TXT, 1, 'implicit' ) then return 1 if IMPL( 'UPPercase' , TXT, 3, 'implicit' ) then return 1 if IMPL( 'Xedit' , TXT, 1, 'implicit' ) then return 1 if IMPL( 'ANSITOOEM' , TXT, 9, 'KeditW' ) then return 1 if IMPL( 'CLIPboard' , TXT, 4, 'KeditW' ) then return 1 if IMPL( 'EXTEND' , TXT, 6, 'KeditW' ) then return 1 if IMPL( 'INIUTIL' , TXT, 7, 'KeditW' ) then return 1 if IMPL( 'OEMTOANSI' , TXT, 9, 'KeditW' ) then return 1 if IMPL( 'POPUP' , TXT, 5, 'KeditW' ) then return 1 if IMPL( 'SHOWDLG' , TXT, 7, 'KeditW' ) then return 1 if IMPL( 'WINdow' , TXT, 3, 'KeditW' ) then return 1 if IMPL( 'WINEXEC' , TXT, 7, 'KeditW' ) then return 1 if IMPL( 'WINHELP' , TXT, 7, 'KeditW' ) then return 1 if words( TXT ) = 1 then do /* check (implicit) SET */ 'nomsg set' TXT /* check SET 'Error 3:' */ if rc = 5 & abbrev( lastmsg.1(), 'Error 3: ' ) then do 'nomsg query' TXT if rc = 0 then do /* normal QUERY message */ BAD = substr( word( lastmsg.1(), 1 ), 1 + length( TXT )) BAD = TXT || BAD || d2c( 10 ) || 'as in' BAD = BAD '[SET]' TXT subword( lastmsg.1(), 2 ) end /* else query error 213 */ else BAD = strip( word( lastmsg.1(), 4 ),, "'" ) if EMSG( TXT 'required to bypass implicit [SET]' BAD ) then return 1 end /* Caveat: SET rc 5 and its 'Error 3: ' message resp. */ end /* QUERY 'Error 213:' may change in future versions */ if SETS( 'BLINK' , TXT, 5 ) then return 1 /* Kedit 5 */ if SETS( 'BORDer' , TXT, 4 ) then return 1 /* Kedit 5 */ if SETS( 'CURSORSHape' , TXT, 8 ) then return 1 /* Kedit 5 */ if SETS( 'EAPreserve' , TXT, 3 ) then return 1 /* Kedit 5 */ if SETS( 'FCASE' , TXT, 5 ) then return 1 /* Kedit 5 */ if SETS( 'KEYBoard' , TXT, 4 ) then return 1 /* Kedit 5 */ if SETS( 'LOGO' , TXT, 4 ) then return 1 /* Kedit 5 */ if SETS( 'MOUSE' , TXT, 5 ) then return 1 /* Kedit 5 */ if SETS( 'MOUSEBAR' , TXT, 8 ) then return 1 /* Kedit 5 */ if SETS( 'PSCReen' , TXT, 4 ) then return 1 /* Kedit 5 */ if SETS( 'RETRace' , TXT, 4 ) then return 1 /* Kedit 5 */ if SETS( 'REXXIO' , TXT, 6 ) then return 1 /* Kedit 5 */ if SETS( 'SHIFTState' , TXT, 6 ) then return 1 /* Kedit 5 */ if SETS( 'SWAP' , TXT, 4 ) then return 1 /* Kedit 5 */ if SETS( 'SYSRC' , TXT, 5 ) then return 1 /* Kedit 5 */ if SETS( 'TOPVIEW' , TXT, 7 ) then return 1 /* Kedit 5 */ if SETS( 'AUTOIndent' , TXT, 5 ) then return 1 /* KeditW */ if SETS( 'BOUNDMark' , TXT, 6 ) then return 1 /* KeditW */ if SETS( 'COLMark' , TXT, 4 ) then return 1 /* KeditW */ if SETS( 'COLORING' , TXT, 8 ) then return 1 /* KeditW */ if SETS( 'CURRBox' , TXT, 5 ) then return 1 /* KeditW */ if SETS( 'CURSORSIze' , TXT, 8 ) then return 1 /* KeditW */ if SETS( 'CURSORType' , TXT, 7 ) then return 1 /* KeditW */ if SETS( 'DEFPROFile' , TXT, 7 ) then return 1 /* KeditW */ if SETS( 'DOCSIZing' , TXT, 6 ) then return 1 /* KeditW */ if SETS( 'ECOLOR' , TXT, 6 ) then return 1 /* KeditW */ if SETS( 'FILEOPEN' , TXT, 8 ) then return 1 /* KeditW */ if SETS( 'INISAVE' , TXT, 7 ) then return 1 /* KeditW */ if SETS( 'INITIALDIR' , TXT, 10 ) then return 1 /* KeditW */ if SETS( 'INITIALDOCsize' , TXT, 10 ) then return 1 /* KeditW */ if SETS( 'INITIALFRAMEsize', TXT, 12 ) then return 1 /* KeditW */ if SETS( 'INITIALINSert' , TXT, 10 ) then return 1 /* KeditW */ if SETS( 'INITIALWidth' , TXT, 8 ) then return 1 /* KeditW */ if SETS( 'INSTANCE' , TXT, 8 ) then return 1 /* KeditW */ if SETS( 'INTERFACE' , TXT, 9 ) then return 1 /* KeditW */ if SETS( 'INTERNATional' , TXT, 8 ) then return 1 /* KeditW */ if SETS( 'KEYSTYLE' , TXT, 8 ) then return 1 /* KeditW */ if SETS( 'MARKSTYLE' , TXT, 9 ) then return 1 /* KeditW */ if SETS( 'OFPW' , TXT, 4 ) then return 1 /* KeditW */ if SETS( 'OPENFilter' , TXT, 5 ) then return 1 /* KeditW */ if SETS( 'QUICKFIND' , TXT, 9 ) then return 1 /* KeditW */ if SETS( 'RECENTFiles' , TXT, 7 ) then return 1 /* KeditW */ if SETS( 'TOOLBAR' , TXT, 7 ) then return 1 /* KeditW */ if SETS( 'TOOLButton' , TXT, 5 ) then return 1 /* KeditW */ if SETS( 'TOOLSet' , TXT, 5 ) then return 1 /* KeditW */ if SETS( 'TRANSLATEIn' , TXT, 10 ) then return 1 /* KeditW */ if SETS( 'TRANSLATEOut' , TXT, 10 ) then return 1 /* KeditW */ if SETS( 'WINMARgin' , TXT, 6 ) then return 1 /* KeditW */ return 0 /* okay, edit new macro */ IMPL: procedure /* -------------------------------------- */ if NOTA( arg(1), arg(2), arg(3)) then return 0 return EMSG( arg(2) 'required to bypass' arg(4) 'COMMAND' arg(1)) SETS: procedure /* -------------------------------------- */ if NOTA( arg(1), arg(2), arg(3)) then return 0 if version.1() = 'KEDIT' then TXT = 'KeditW' else TXT = 'Kedit 5.0' return EMSG( arg(2) 'required to bypass' TXT 'SET' arg(1)) NOTA: procedure /* -------------------------------------- */ if length( arg(1)) < arg(3) /* NOT Abbrev arg. test */ then 'alert' delimit( arg(1)) 'title /KEX ABBREV too short/' else if sign( verify( left( arg(1), arg(3)), xrange( 'A', 'Z' ))) then 'alert' delimit( arg(1)) 'title /KEX ABBREV not A - Z/' else if sign( verify( arg(1), xrange( 'a', 'z' ),, 1 + arg(3))) then 'alert' delimit( arg(1)) 'title /KEX expected a - z/' return \ abbrev( translate( arg(1)), arg(2), arg(3)) EMSG: procedure /* -------------------------------------- */ ALERT.1 = delimit( 'explicit MACRO' arg( 1 )) ALERT.2 = delimit( 'KEX warning' ) 'alert' ALERT.1 'title' ALERT.2 'OKCANCEL' if ALERT.2 <> 'OK' then 'quit' /* continue if OK, else */ return ( ALERT.2 <> 'OK' ) /* QUIT ambiguous macro */ PATH: procedure /* -------------------------------------- */ parse arg FILE, PATH /* search FILE in PATH */ if sign( pos( '*', FILE )) then return '' /* don't find *.* or */ if sign( pos( '?', FILE )) then return '' /* similar file id.s */ 'extract /DIRFORMAT/' /* adapted DIRFORMAT */ 'nomsg dirformat' max( 8, length( FILE )) max( 3, length( FILE )) do while PATH <> '' parse var PATH NAME ';' PATH /* NAME= next directory */ if right( NAME, 1 ) <> '\' then NAME = NAME || '\' 'nomsg dir "' || NAME || FILE || '" (noprof' if rc <> 0 then iterate /* ignore bad path NAME */ do until focuseof() /* match dot file NAMEs */ 'next' ; ID = dirfileid.4() if dirfileid.5() > '' then ID = ID || '.' || dirfileid.5() if translate( ID ) == translate( FILE ) then do if ring.0() > 1 then 'quit' /* found, exit DIR.DIR */ 'dirformat' DIRFORMAT.1 DIRFORMAT.2 return NAME /* return found path */ end end if ring.0() > 1 then 'quit' /* go on, exit DIR.DIR */ end 'dirformat' DIRFORMAT.1 DIRFORMAT.2 /* reset user's DIRFORM */ return '' /* not found: ''-string */