home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 1995 November
/
PCWK1195.iso
/
inne
/
podstawy
/
dos
/
4dos
/
4uzytki
/
4dtnt.exe
/
STRING.ZIP
/
BUMP.DOC
< prev
next >
Wrap
Text File
|
1991-11-03
|
5KB
|
187 lines
A major idea here is the use of the VALUE of an environment variable
whose NAME is passed by the caller. The result is something like a
function in a high level programming language.
if either argument is omitted or the variable is not in the environment
("%[%2]" == ""), put up the help text and quit with an errorlevel.
if "%1" == "" .or. "%2" == "" .or. "%[%2]" == "" goto help
Make all letters upper case to get away from case sensitivity.
set $foo=%@upper[%1]
Make a string of all the digits from 0 to 35.
set $wstr=0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
Use the semantic equivalent of a "case" statement to check what
number base the user wants (specified in %1). The numbers 2 to 36
are allowed, along with certain mnemonic letters, such as "H" for
hexadecimal. "A"lpha is a special case where only the letters of
the alphabet are used -- not numeric digit characters.
iff %$foo = A then ^ gosub alpha
elseiff %$foo = B then ^ gosub binary
elseiff %$foo = O then ^ gosub octal
elseiff %$foo = H then ^ gosub hex
elseiff %$foo = D then ^ gosub dec
elseiff %$foo = N then ^ gosub an
elseiff %$foo gt 1 .and. %$foo lt 37 then ^ gosub base
else goto help
endiff
iff %$val ne 0 then^unset %2 ^ gosub cleanup ^ goto helpval
else set %2=%$foo ^gosub cleanup^quit 0
endiff
We actually finish here. Everything else is subroutines.
quit
:cleanup
Can't use SETLOCAL because we're modifying the immediate caller's
environment on purpose. Therefore, we have to UNSET our own stuff.
unset $foo $wstr $val $max >& nul
return
Each of the following little subroutines just sets a key parameter
for the main "bumpit" subroutine.
:alpha
set $max=25
set $wstr=%@substr[%$wstr,10,26]
gosub bumpit
return
:binary
set $max=1
gosub bumpit
return
:octal
set $max=7
gosub bumpit
return
:hex
set $max=15
gosub bumpit
return
:dec
set $max=9
gosub bumpit
return
:an
set $max=35
gosub bumpit
return
:base
set $max=%@eval[%$foo-1]
gosub bumpit
return
Here's the beef! All of the above just set the parameters for this.
:bumpit
Make sure all the characters in the input string are valid for this
number base so the result will be meaningful.
gosub validate
if %$val ne 0 return
Aw, shucks, it's valid. Get to work.
Standardize character case
set $foo=%@upper[%[%2]]
Limit the loop to the length of the variable for carry propagation
set $i=%@len[%$foo]
set $j=%@eval[%$i-1]
set $k=%$j
:bumploop
Break the string into three parts: front, target, and rear. "Target"
is the character to be incremented (usually the rightmost unless we
are propagating a carry leftward). "Front" is the part of the string
up to but not including "target". "Rear" is the part of the string
which follows "target". Either "front" or "rear" may be empty. "Rear"
is usually empty unless propagating a carry. If "front" is empty, there
is no place to propagate a carry, even if it is necessary. The latter
could be changed easily if desired.
set $front=
if %$j gt 0 set $front=%@substr[%$foo,0,%$j]
set $targ=%@substr[%$foo,%$j,1]
set $rear=
if %$j lt %$k set $rear=%@substr[%$foo,%@eval[%$j+1],%@eval[%$k-%$j]]
Check to see if "targ" is already at the limit for the number system.
Zero it and keep going if necessary.
set $l=%@index[%$wstr,%$targ]
iff %$l lt %$max then ^ set $targ=%@substr[%$wstr,%@eval[%$l+1],1]^set $j=0
else set $targ=%@substr[%$wstr,0,1]
endiff
Put the string back together
set $foo=%[$front]%[$targ]%[$rear]
See if another iteration one character to the left is needed.
if %$j gt 0 (set $j=%@eval[%$j-1]^goto bumploop)
rem unset $i $j $k $l $front $rear $targ >& nul
return
Check whether all the characters in the environment variable are
OK in this number base. Return 0 if OK, base of the number system
if not.
:validate
set $i=0
:valloop
A valid character will have an index in the "wstr" digit string less
than the base of the number system in question ("max") and greater
than -1 (i.e., not a character completely outside the "wstr" set).
set $val=%@index[%$wstr,%@substr[%[%2],%$i,1]]
if %$val lt 0 .or. %$val gt %$max (set $val=%$max^return)
Keep looping through all the characters in the input string.
set $i=%@eval[%$i+1]
Check for end of loop
iff %$i lt %@len[%[%2]] then ^ goto valloop
else set $val=0^return
endiff
return
:helpval
echo Invalid character detected.
echo .
goto help
:help
echo Usage BUMP mode var
echo
echo ! !
echo ! Any environment variable of the correct type
echo A=alpha [A-Z]
echo B=binary [0-1]
echo D=decimal [0-9]
echo H=hex [0-F]
echo N=alph/num [0-9,A-F]
echo O=octal [0-7]
echo [2-36] [0-(n-1)]
echo New value returned in var
echo Carry propagates left, overflow is ignored
quit 4