/*REXX*/
'ISREDIT MACRO(PARMS)'
/* TRACE r */
/*-------------------------------------------------------------------*/
/* This SPF Macro: */
/* 1. Determines which language is present based on extenstion. */
/* 2. Calls compiler for language. */
/* 3. Displays any error messages from compiler on screen next to */
/* buggy code. */
/* This Macro is currently setup to work for the following languages:*/
/* 1. .ZBS - BASIC using 32 Bit Software's ZBASIC 4.7 */
/* Parms: P = use mark's preprocessor */
/* 2. .PBS - BASIC using Power BASIC 3.x */
/* 3. .C - C using Mix Software's PowerC 2.2 */
/* Parms: S or none = small memory model */
/* M = medium memory model */
/* L = large memory model */
/* 4. .PRG - XBase using Clipper 5.1 */
/* 5. .COB - Micro Focus COBOL */
/* 6. .CBL - Realia/2 COBOL (Computer Associates) */
/* 7. .BAT - PC Magazine's Public Domain DOS Batch compiler */
/* 8. .REX - Personal REXX 3.0 Compiler */
/* 9. .PBC - BASIC Windows Console Compiler (PowerBASIC) */
/* 10. .PBW - PowerBASIC Windows Compiler - 32 bit */
/* 10. .DL2 - PowerBASIC DLL 2.0 Compiler - 16 bit */
/* 11. .BAS - Visual BASIC 6.0 (Enterprise Edition) */
/* 12. .PHP - PHP on Windows (no server required) */
/* Note: Change pathing to match your PHP .ini file */
/* Syntax: */
/* At the SPFPRO command line, enter COM and press enter. */
/* if the code has been modifed since loading, it is saved first */
/* then compiled. */
/* Options: */
/* For C enter S for small model, M for medium model or L for */
/* large model. */
/* For COBOL, Enter MF to use the Micro Focus COBOL compiler or */
/* no option to use the REALIA/2 Compiler. */
/* NOTE: This macro uses two envrionment variables to determine where*/
/* the compilers reside: */
/* DVAR = Drive where compilers are located (mine are on E) */
/* UTIL = Root directory of compiler directory (mine is \U */
/* \u */
/* Here is where my compilers are: */
/* PowerBASIC DOS E:\U\BASIC\PB35 */
/* CONSOLE E:\U\BASIC\PBCC10\BIN */
/* WINDOWS/DLL E:\U\BASIC\PBDLL60\BIN */
/* Look at the code, change it to meet your needs */
/* By Mark McDonald - 09Jul2005 */
/*-------------------------------------------------------------------*/
/*--- Determine Drive Letter SUB.SPF is Executing From ---*/
TSDRV = XDETSDRV()
TSPFL = XDETREXX()
TSPF = WORD(TSPFL,1)
/*--- Get Arguments(If Any)---*/
OPT1 = TRANSLATE(PARMS)
/*--- Declare Variable Constants and Flags ---*/
FOUND_ONE = 0
/*--- Get rid of previous error lines ---*/
'ISREDIT RESET SPECIAL'
/*--- If source has not been saved, save it ---*/
'ISREDIT (MODIFIED) = DATA_CHANGED'
IF (MODIFIED=YES) THEN
'ISREDIT SAVE'
/*--- Retrieve Path/File Name of Source File ---*/
'ISREDIT (FILENAME) = DATASET'
FILENAME = TRANSLATE(FILENAME)
/*--- Determine Path of Source ---*/
SPATH = SUBSTR(FILENAME,1,LASTPOS("\",FILENAME)-1,1)
SDRV = SUBSTR(SPATH,1,1,' ')
/*--- Retrieve Member Name of Source File ---*/
'ISREDIT (FULLNAME) = MEMBER'
FULLNAME = TRANSLATE(FULLNAME)
MEMNAME = SUBSTR(FULLNAME,1,POS('.',FULLNAME) -1)
/*--- Get DOS Variable DRV - Determines Drive for Compiler (Except VB6) ---*/
DVAR = TSDRV
UTIL = DVAR":\U"
/*--- Get Path ---*/
T = LASTPOS('\',FULLNAME,1)
PATH = LEFT(FULLNAME,T)
/*--- Get Extenstion of File Name ---*/
EXNT = SUBSTR(FULLNAME,POS('.',FULLNAME)+1,3)
/*--- Set Name of Compile Result File ---*/
RESULT = DVAR':\TEMP\'SUBSTR(DATE('J'),3,3," ")''TIME('S')'.TXT'
TRESULT = RESULT
TBAT = DVAR':\TEMP\'SUBSTR(DATE('J'),3,3," ")''TIME('S')'.BAT'
/*--- FreeBASIC Compiler ---*/
IF EXNT = 'BAS' | EXNT = 'FBS' THEN
DO
TBAT = DVAR":\U\BASIC\FBASIC\FBC.EXE "FILENAME" > "RESULT" -s gui"
CALL RDOS TSPF, TBAT
RESULT = TRESULT
SIGNAL SETUPJMP
END
/*--- Visual BASIC 6.0 (Windows)- VB Does not like space in Filename or path! ---*/
/* IF EXNT = 'VBS' THEN
DO
TBAT = "C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\VB98\VB6.EXE"
TBAT = TBAT" "FILENAME" /m /out "RESULT
ADDRESS DOS TBAT
SIGNAL SETUPJMP
END */
/*--- PHP (Windows) -------------------------------------------------*/
IF EXNT = "PHP" THEN
DO
RESULT = DVAR":\TEMP\DRET.PHP"
ADDRESS DOS "ECHO -- > "RESULT
ADDRESS DOS DVAR':\U\PHP\php-win.exe 'FULLNAME
SIGNAL SETUPJMP
END
/*--- Power BASIC DLL 6.0 Compiler (Windows) ------------------------*/
IF EXNT = 'DL6' THEN
DO
RESULT = SPATH'\'MEMNAME".LOG"
ADDRESS DOS DVAR':\U\PB7\BIN\PBWIN.EXE /I 'FILENAME
SIGNAL SETUPJMP
END
/*--- Power BASIC Console Compiler 1.0 (Windows) --------------------*/
IF EXNT = 'PBC' THEN
DO
RESULT = FILENAME".LOG"
TRESULT = RESULT
TBAT = DVAR':\U\BASIC\PBC\BIN\PBCC.EXE /I.\;C:\U\BASIC\PBC\WINAPI;C:\U\BASIC\PBC\CONTOOLS /L /Q'FILENAME
CALL TOSCMD TSPF, TBAT
RESULT = TRESULT
/* ADDRESS DOS TBAT */
SIGNAL SETUPJMP
END
/*--- Prepare Common Call Commands (DOS Only) -----------------------*/
T = LINEOUT(TBAT,SUBSTR(FILENAME,1,2," "))
T = LINEOUT(TBAT,'CD 'SPATH)
/*--- Borland TASM 3.0 (DOS) ----------------------------------------*/
IF EXNT = 'ASM' THEN
T = LINEOUT(TBAT,DVAR':\U\ASM\BC\BIN\TASM.EXE /zn 'FILENAME' > 'RESULT)
/*--- Microsoft C6 (DOS) --------------------------------------------*/
IF EXNT = 'MCS' THEN
T = LINEOUT(TBAT,DVAR':\U\C\C600\BIN\CL /AL /batch 'FILENAME' > 'RESULT)
/*--- PowerC (DOS) --------------------------------------------------*/
IF EXNT = 'C ' THEN DO
T = LINEOUT(TBAT,SUBSTR(FILENAME,1,2," "))
T = LINEOUT(TBAT,'CD 'DVAR':\u\C\pc')
TB = DVAR':\U\C\PC\PC.EXE /ml /e /c /t /i'DVAR':\U\PC 'FILENAME' > 'RESULT
/* SAY TB;PARSE PULL Z;EXIT */
T = LINEOUT(TBAT,TB)
END
/*--- ZBASIC (DOS) --------------------------------------------------*/
IF EXNT = 'ZBS' THEN
CALL ZBASIC
/*--- DOS BATCH Compiler (DOS) --------------------------------------*/
IF EXNT = 'BAT' THEN
T = LINEOUT(TBAT,DVAR':\U\B\BAT2EXEC.COM 'FILENAME' > 'RESULT)
/*--- Power BASIC 3.5 (DOS) -----------------------------------------*/
IF EXNT = 'PBS' THEN
T = LINEOUT(TBAT,DVAR':\U\BASIC\PB35\PBC.EXE /CE 'FILENAME' > 'RESULT)
/*--- CLIPPER (DOS) -------------------------------------------------*/
IF EXNT = 'PRG' THEN
T = LINEOUT(TBAT,DVAR':\U\DB\CLIPPER 'FILENAME' /M > 'RESULT)
/*--- Realia COBOL (DOS) --------------------------------------------*/
IF (EXNT = 'CBL' | exnt = 'COB') THEN
T = LINEOUT(TBAT,DVAR':\U\COB\REAL2\COBOL.EXE 'FILENAME' > 'RESULT)
/* --- Micro Focus Option? ---*/
/* IF OPT1 = MF THEN */
/* CALL MFCOBOL */
/* ELSE */
/* CALL REAL2 */
T = LINEOUT(TBAT,'EXIT')
T = LINEOUT(TBAT)
'ISREDIT DOS 'TBAT
SETUPJMP:
CALL INERROR
EXIT 0
/*--------------------------------------------------------------------*/
/* Subroutines */
/*--------------------------------------------------------------------*/
/*--- MFCOBOL 3.1.4 (DOS) --------------------------------------------*/
MFCOBOL:
'ISREDIT DOS 'DVAR':\U\B\SPFBAT.BAT COB 'FILENAME', 'RESULT' 'SPATH' 'MEMNAME'.OBJ,'
TERM = ' '
CALL INERROR
RETURN
/*--- REAL2 4.2 (DOS) ------------------------------------------------*/
REAL2:
'ISREDIT DOS 'DVAR':\U\B\SPFBAT.BAT CBL 'FILENAME', 'RESULT' 'SPATH' 'MEMNAME'.OBJ,'
CALL INERROR
RETURN
/*--- ZBASIC 4.7 -----------------------------------------------------*/
ZBASIC:
'ISREDIT DOS 'DVAR':\U\BASIC\ZB-32.COM 'FILENAME' 'MEMNAME'.COM > 'RESULT
CALL INERROR
RETURN
/*--- PowerC 2.2 -----------------------------------------------------*/
POWERC:
/* --- Small Model ---*/
/* IF OPT1 = '' | OPT1 = 'S' | OPT1 = 's' THEN */
/* OPT1 = 'ms' */
/* --- Medium Model ---*/
/* IF OPT1 = 'M' | OPT1 = 'm' THEN */
/* OPT1 = 'mm' */
/* --- Large Model ---*/
OPT1 = 'L'
IF OPT1 = 'L' | OPT1 = 'l' THEN
OPT1 = 'mm'
'ISREDIT DOS 'DVAR':\U\B\SPFBAT.BAT C 'FILENAME' 'RESULT' 'SPATH
TERM = '-'
CALL INERROR
RETURN
/*--------------------------------------------------------------------*/
INERROR:
/* --- Reset Error Flag ---*/
FOUND_ONE = 0
/* --- Loop Through Compile Result File - Put Into Array ---*/
CNT = 0
DO WHILE LINES(RESULT) > 0
CNT = CNT + 1
DATA.CNT = LINEIN(RESULT)
END
TCNT = CNT
REAL2FLG = 0
'ISREDIT (LLINE) = LINENUM .ZLAST'
/* --- Loop Through Array - Position Error Messages With Source Code ---*/
DO CNT = 1 TO TCNT
DATALINE = DATA.CNT
LINENO = 0
/* --- Extract Source Code Line Number ---*/
/* --- PHP - Line Number is Last Word in Error Message ---*/
IF EXNT = "PHP" THEN
LINENO = WORD(DATALINE,WORDS(DATALINE))
/* --- PowerC ---*/
IF EXNT = 'C' & POS("Wrong memory model",DATA.3) > 0 THEN
LINENO = 1
IF EXNT = 'C' & POS("** Unresolved references:",DATA.3) > 0 THEN
LINENO = 1
IF EXNT = 'C' & POS(FULLNAME,DATALINE) > 0 THEN
PARSE VAR DATALINE TOSS1 '(' LINENO ')' TOSS
/* --- Boraland Assembler ---*/
IF EXNT = 'ASM' & POS(FULLNAME,DATALINE) > 0 THEN
PARSE VAR DATALINE TOSS1 '(' LINENO ')' TOSS
/* --- Clipper 5.1 ---*/
IF EXNT = 'PRG' & POS(FULLNAME,DATALINE) > 0 THEN
PARSE VAR DATALINE TOSS1 '(' LINENO ')' TOSS
/* --- Power BASIC ---*/
IF EXNT = 'PBS' THEN
DO
IF POS(FULLNAME,DATALINE) > 0 THEN
PARSE VAR DATALINE TOSS1 '(' LINENO ')' TOSS
ELSE DO
IF POS("): Error ",DATALINE) > 0 THEN
DO
PARSE VAR DATALINE TOSS1 '(' LINENO ')' TOSS
IF POS(":",LINENO,1) > 0 THEN
DO
LINENO = TRANSLATE(LINENO," ",":"," ")
LINENO = WORD(LINENO,2)
END
END
END
END
/* --- FreeBasic ---*/
IF EXNT = 'BAS' | EXNT = "FBS" THEN
DO
IF SUBSTR(DATA.1,1,5) = "error" THEN DO
LINENO = 1
END
ELSE DO
PARSE VAR DATALINE TOSS1 '(' LINENO ')' TOSS
END
/* FOUND_ONE = 1 */
END
/* --- Visual BASIC 6.0 ---*/
/* IF EXNT = 'VBS' THEN
DO
IF POS("Compile Error in File",DATALINE) > 0 THEN
DO
PARSE VAR DATALINE TOSS1 ', Line ' LINENO ':' TOSS
LINENO = LINENO + 1
END
END */
/* --- Power BASIC DLL Compiler ---*/
IF EXNT = 'DL6' THEN
DO
IF POS(FULLNAME,DATALINE) > 0 THEN
PARSE VAR DATALINE TOSS1 '(' LINENO ')' TOSS
ELSE DO
IF POS("Error ",DATALINE) > 0 THEN
DO
PARSE VAR DATALINE TOSS1 '(' LINENO ')' TOSS
IF POS(":",LINENO,1) > 0 THEN
DO
LINENO = TRANSLATE(LINENO," ",":"," ")
LINENO = WORD(LINENO,2)
END
END
END
END
/* --- Power BASIC Console Compiler ---*/
IF EXNT = 'PBC' THEN DO
IF POS(FULLNAME,DATALINE) > 0 THEN DO
PARSE VAR DATALINE TOSS1 '(' LINENO':' LINENOHOLD ')' TOSS
FOUND_ONE = 1
END
ELSE DO
IF POS("): Error ",DATALINE) > 0 THEN
DO
PARSE VAR DATALINE TOSS1 '(' LINENO ')' TOSS
IF POS(":",LINENO,1) > 0 THEN
DO
LINENO = TRANSLATE(LINENO," ",":"," ")
LINENO = WORD(LINENO,2)
END
END
END
END
/* --- ZBASIC 4.7 ---*/
IF EXNT = 'ZBS' & POS('Text buffer FULL!',DATALINE) > 0 THEN
LINENO = 1
IF EXNT = 'ZBS' & POS('in Stmt',DATALINE) > 0 THEN
LINENO = SUBSTR(DATALINE,POS(',Line',DATALINE)+6,8)
/* --- Micro-Focus COBOL ---*/
IF EXNT = 'CBL' | EXNT = 'COB' THEN
DO
IF OPT1 = 'MF' THEN
DO
LNCNT = CNT - 1
IF POS(')**',DATALINE) > 73 THEN
LINENO = WORD(DATA.LNCNT,1)
END
/* --- Realia 2 COBOL ---*/
ELSE DO
THOLD = SUBSTR(DATALINE,11,1)
IF THOLD = 'E' | THOLD = 'W' THEN
DO
LNCNT = CNT - 1
PARSE VAR DATALINE LINENO TOSS
END
END
END
/* --- Do We Need to Remove Column Number? ---*/
T = 0
T = POS(':',LINENO,1)
IF T > 0 THEN
DO
LINENOHOLD = LINENO
LINENO = SUBSTR(LINENO,1,T-1)
END
/* --- Make Sure LINENO Does NOT Contain Spaces ---*/
/* LINENO = ABS(LINENO) */
/* --- Does This Line Show the Start of an Error? ---*/
IF LINENO < 1 THEN
ITERATE
/* --- Error Line Beyond End if file? ---*/
IF LINENO > LLINE THEN LINENO = LLINE
DO
FOUND_ONE = 1
/* --- Insert First Error Note Line Into Code ---*/
CALL SEPLINE1
/* --- PowerBASIC Console Compiler? (PBC) ---*/
IF EXNT = "PBC" | EXNT = "DL6" THEN
DO
DATALINE = TOSS1' 'LINENOHOLD
CALL FIXQUOTES
DATALINE = TOSS
END
/* --- Visual BASIC 6? ---*/
/* IF EXNT = "BAS" THEN
DO
DATALINE = TOSS1
CALL FIXQUOTES
DATALINE = "Line "LINENO":"TOSS
END */
/* --- Place Error Lines ---*/
DO FOREVER
CALL FIXQUOTES
CNT = CNT + 1
/* --- Exit Forever Loop? ---*/
IF CNT > TCNT THEN
LEAVE
/* --- Get Next Error Line ---*/
ELSE
DATALINE = DATA.CNT
T = LEFT(DATALINE,LENGTH(TERM))
IF T = TERM THEN
LEAVE
END
/* --- Insert Compile Error Separator Line Into Code ---*/
CALL SEPLINE2
END
END
/* --- Determine If Error Found/Do Appropriate Condition ---*/
CALL IFERROR
EXIT 0
/*--------------------------------------------------------------------*/
SEPLINE1:
ERRLINE = COPIES('=',20)
"ISREDIT LINE_BEFORE " LINENO "= NOTELINE " ERRLINE
RETURN
/*--------------------------------------------------------------------*/
SEPLINE2:
ERRLINE = COPIES('=',69)
"ISREDIT LINE_AFTER " LINENO "= NOTELINE " ERRLINE
RETURN
/*--------------------------------------------------------------------*/
/*--- Change quotes(single/double) to tildes - prevents REXX errors --*/
FIXQUOTES:
ERRLINE = TRANSLATE(DATALINE,"~","'")
ERRLINE = TRANSLATE(ERRLINE,'~','"')
"ISREDIT LINE_BEFORE " LINENO "= NOTELINE '"ERRLINE"'"
RETURN
/*-------------------------------------------------------------------*/
/*--- Positions Cursor to first error line and exits macro ----------*/
IFERROR:
IF FOUND_ONE = 1 THEN
DO
'ISREDIT LOCATE FIRST SPECIAL'
END
ELSE
DO
ZEDSMSG = "COMPILE SUCCESSFUL"
ZEDLMSG = "COMPILER FOUND NO SYNTAX ERRORS DURING COMPILE."
END
'ISPEXEC SETMSG MSG(ISRZ000)'
EXIT 0 /*Returns to Source Code*/
RETURN
/*---------------------------------------------------------------*/
MVAR: PROCEDURE
ARG X
X = TRANSLATE(X)
/* --- Build Semi-Unique Result File Name ---*/
RESULT = 'C:\TEMP\'SUBSTR(DATE('J'),3,3," ")''TIME('S')
TBAT = RESULT'.BAT'
RESULT = RESULT'.TXT'
/* --- Build/Execute Temp BAT File ---*/
T = LINEOUT(TBAT,'SET > 'RESULT)
T = LINEOUT(TBAT,'EXIT')
T = LINEOUT(TBAT)
'ISREDIT DOS 'TBAT
/* --- Find VAR ---*/
DO WHILE LINES(RESULT) > 0
T = TRANSLATE(LINEIN(RESULT))
T = TRANSLATE(T," ","=")
IF WORD(T,1) = X THEN
DO
RETURN WORD(T,2)
END
END
XR = ""
RETURN XR
/*-----------------------------------------------------------------
Determine which REXX interpreter is being used
---------------------------------------------------------------*/
XDETREXX: PROCEDURE
parse version name level date1 date2 date3
TSPF = 0 /* Using a stand-alone REXX Interpreter DOSREXX*/
IF name = "REXXSAA" & date3 = "1994" THEN TSPF = '0 'name /* Using PCDOS REXX*/
IF name = "REXX-r4" THEN TSPF = '1 'name /* Using R4 */
IF name = "REXXPC88" & date3 = "1987" THEN TSPF = '2 'name /* Using REXXIBM (1987)*/
IF name = "REXX/Personal" & date3 = "1992" THEN TSPF = '3 'name /* Using Personal REXX v4*/
IF name = "REXX/2" & date3 = "1995" THEN TSPF = '4 'name /* Using SPFPC v4 */
IF name = "REXX/2" & date3 = "1996" THEN TSPF = '5 'name /* Using SPFPRO */
IF LEFT(name,11) = "REXX-ooRexx" THEN TSPF = '6 'name /* Using OOREXX */
IF LEFT(name,11) = "REXX-Regina" THEN TSPF = '7 'name /* Using Regina */
RETURN (TSPF)
/*-- Pass Command to OS -----------------------------------------------------------------------------*/
TOSCMD: PROCEDURE
PARSE ARG TSPF, TCMD
IF TSPF = 0 THEN ADDRESS COMMAND TCMD /*DOSREXX*/
IF (TSPF = 4 | TSPF = 5) THEN ADDRESS DOS TCMD /*SPFPC4/SPFPRO - Delete if using OOREXX*/
IF TSPF = 6 THEN TCMD /*OOREXX*/
IF TSPF = 7 THEN ADDRESS SYSTEM TCMD /*REGINA*/
RETURN
/*---------------------------------------------------------------------------------------------------*/
/*-- Determine Source Path ----------------------------------*/
XDETSDRV: PROCEDURE
PARSE SOURCE ENV TYPE NAME
/* SAY ENV
SAY TYPE
SAY NAME
EXIT */
TSDRV = LEFT(NAME,1)
RETURN (TSDRV)
/*---------------------------------------------------------------
RDOS - Builds Batch File To Execute OS Commands
REQUIRES EXISTENCE OF C:\TEMP XWORDS XWORD XLATE UNXLATE
Commands Separated by ;
CMD = "IF EXIST C:\TEMP\RDOS.TXT DEL C:\TEMP\RDOS.TXT;"
CMD = CMD"ECHO Gathing data...;"
CMD = CMD"CALL DIR C:\SPFPRO\MACROS\*.* /N /ON > C:\TEMP\RDOS.TXT;"
CMD = CMD"START IEXPLORE C:\TEMP\RDOS.TXT"
CALL RDOS CMD
EXIT
---------------------------------------------------------------*/
RDOS: PROCEDURE
PARSE ARG TSPF, CMD
/*--- Build Semi-Unique Result File Name ---*/
TBAT = "C:\TEMP\RDOS.BAT"
/*--- Build Batch File ---*/
T = LINEOUT(TBAT,"@ECHO OFF",1) /*Turn off Command Echo*/
TCNT = XWORDS(CMD,";") /*Det # OS Commands*/
DO CNT = 1 TO TCNT /*Loop Through Commands*/
TCMD = XWORD(CMD,CNT,";") /*Extract OS Command*/
T = LINEOUT(TBAT,TCMD) /*Write to Batch File*/
END
T = LINEOUT(TBAT,'EXIT') /*Tell Batch to End*/
T = LINEOUT(TBAT) /*Close C:\TEMP\RDOS.BAT*/
/*--- Execute Batch Program ---*/
IF (TSPF = 5 | TSPF = 7) THEN ADDRESS SYSTEM TBAT
IF (TSPF = 1 | TSPF = 6) THEN TBAT
IF (TSPF = 0 | TSPF = 4) THEN ADDRESS COMMAND TBAT
RETURN
/*---------------------------------------------------------------*/
XWORDS: PROCEDURE
PARSE ARG X, XDL
X = XLATE(X,XDL)
NWRDS = WORDS(X)
RETURN (NWRDS)
/*---------------------------------------------------------------*/
XWORD: PROCEDURE
PARSE ARG X, N ,XDL
IF N > XWORDS(X,XDL) THEN RETURN ("")
X = XLATE(X,XDL)
X = WORD(X,N)
X = XUNLATE(X)
RETURN (X)
/*---------------------------------------------------------------*/
XLATE: PROCEDURE
PARSE ARG X, XDL
X = TRANSLATE(X,D2C(253)," ")
X = TRANSLATE(X," ",XDL)
RETURN (X)
/*---------------------------------------------------------------*/
XUNLATE: PROCEDURE
PARSE ARG X
X = TRANSLATE(X," ",D2C(253))
RETURN (X)
/*---------------------------------------------------------------*/
/* Removes Leftmost n characters */
/* T = XTRIML("--ONE",2) returns "ONE" */
/*---------------------------------------------------------------*/
XTRIML: PROCEDURE
PARSE ARG X, N
IF LENGTH(X) - 1 >= N THEN
XR = RIGHT(X,LENGTH(X) - N)
ELSE
XR = X
RETURN (XR)
/*---------------------------------------------------------------*/