ON ERROR ON ERROR OFF:REPORT:PRINT ERL:END

REM This code will cope with up to four digits in either the major or
REM minor version number.
REM You will get zero if you have an illegal help string.
REM Keeping the value is BCD format the same as returned by
REM OS_Module 20 facilitates the process of comparing version numbers
REM (the arithmetic comparison operators are still all valid for these
REM version numbers)

REM From: Stewart Brodie
REM Subject: Re: Getting a Module Version
REM Newsgroups: comp.sys.acorn.programmer
REM Date: 2001-08-29 05:35:03 PST
REM http://groups.google.com/groups?selm=fa559fb14a.sbrodie%40sbrodie.cam.pace.co.uk

DIM block% 1024
SYS "OS_GetEnv" TO comm%
SYS "OS_ReadArgs","name,quit,mod,var",comm%,block%,1023
mod$=FNstring(block%!8)
var$=FNstring(block%!12)
IF var$="" OR mod$="" THEN ERROR 0, "Syntax: ModVersion <modulename> <systemvariable>"

ver%=FNget_module_version(mod$)
IF ver%=-1 OSCLI ("SetEval "+var$+" -1") ELSE OSCLI ("SetEval "+var$+" "+LEFT$(STR$~(ver%),3))
END


DEF FNstring(ptr%)
IF ptr%=0 THEN =""
LOCAL a$:a$=""
WHILE ?ptr%>31
a$+=CHR$(?ptr%):ptr%+=1
ENDWHILE:=a$

DEF FNget_module_version(module$)
LOCAL base%,help%,width%,offset%,version%,found_version%
LOCAL minor_shift%,C%,end_loop%

SYS "XOS_Module", 18, module$ TO ,,,base%;f%
IF (f% AND 1)=1 THEN =-1
help%=base%+(base%!&14):width%=0:offset%=0

REM Skip the module name, coping with TABs until the 16th column
WHILE width%<16
  C%=help%?offset%: offset%+=1: IF(C%=0) THEN =0
  IF C%=9 THEN width%=(width%+8)ANDNOT7 ELSE width%+=1
ENDWHILE

REM Search for the next digit.
C%=ASC"0":found_version%=FALSE
WHILE (help%?offset%) <> 0 AND NOT found_version%
  C%=help%?offset%: offset%+=1: found_version% = INSTR("0123456789",CHR$ C%)>0
ENDWHILE

REM Read digits until we hit a non-numeric, accumulating BCD version number
version%=C%-ASC"0":end_loop%=FALSE
WHILE NOT end_loop%
  C%=(help%?offset%)-ASC"0":end_loop%=(C%<0 OR C%>9)
  IF NOT end_loop% THEN version%=(version% << 4) OR C%
  offset%+=1
ENDWHILE
REM Move into final position of top 16 bits
version%=(version% << 16)

REM Did the last loop terminate due to a dot separator?
IF (C%+ASC"0") = ASC"." THEN
  REM Accumulate the minor version number
  minor_shift%=12:end_loop%=FALSE
  WHILE NOT end_loop% AND minor_shift% >= 0
    C%=(help%?offset%)-ASC"0":end_loop%=(C%<0 OR C%>9)
    IF NOT end_loop% version%=version% OR (C% << minor_shift%)
    offset%+=1:minor_shift%-=4
  ENDWHILE
ENDIF

=version%
