CharIndexReplace: Replace char in string with char size

From NSIS Wiki
Jump to navigationJump to search
Author: Afrow UK (talk, contrib)


Description

This function replaces characters in a string with the size of that character specified by a character list.

This is very useful for version strings, where we might want to compare 9.0a to 9.0c (DirectX). This can be called first, and then the 'a' would become '01' and 'c' will become '03'.

In theory, you could use this to encode a string, but you'd have to write a function to convert it back!

Example 1

Push "abcdefghijklmnopqrstuvwxyz" ; character list
Push "2.3d" ; string (version)
Call CharIndexReplace
Pop $R0
; $R0 = 2.304

d is replaced with 04, because it's the 4th character from the start of the list.

Example 2

Push "abcdefghijklmnopqrstuvwxyz" ; character list
Push "3.92T.22.11a" ; string (version)
Call CharIndexReplace
Pop $R0
; $R0 = 3.9220.22.1101

T is replaced with 20, because it's the 20th character from the start of the list.

a is replaced with 01, because it's the 1st character on the list.

Usage

Push "abcdefghijklmnopqrstuvwxyz" ; character list
Push "xx.xx.xx.xx" ; string (version)
Call CharIndexReplace
Pop $R0 ; output

or

${CharIndexReplace} "abcdefghijklmnopqrstuvwxyz" "xx.xx.xx.xx" "$R0"

Notes

  • You can't use more than 99 characters in the character list (not that you should need to, but still.)
  • You do not have to include upper-case alphabetical characters in your character list as NSIS's StrCmp is not case-sensitive.

The Function

!macro CharIndexReplace Chars String OutVar
 Push "${Chars}"
 Push "${String}"
  Call CharIndexReplace
 Pop "${OutVar}"
!macroend
!define CharIndexReplace "!insertmacro CharIndexReplace"
 
Function CharIndexReplace
Exch $R0
Exch
Exch $R1
Push $R2
Push $R3
Push $R4
Push $R5
 
StrCpy $R4 0
 
NextStrChar:
 StrCpy $R2 $R0 1 $R4
 StrCmp $R2 "" Done
 StrCpy $R5 0
 
LoopChars:
 StrCpy $R3 $R1 1 $R5
 StrCmp $R3 "" 0 +3
  IntOp $R4 $R4 + 1
  Goto NextStrChar
 
 IntOp $R5 $R5 + 1
 StrCmp $R3 $R2 0 LoopChars
 
  StrCpy $R2 $R0 $R4
  IntOp $R4 $R4 + 1
  StrCpy $R3 $R0 "" $R4
 
  IntCmp $R5 9 0 0 +3
   StrCpy $R0 $R20$R5$R3
   Goto +2
   StrCpy $R0 $R2$R5$R3
 
   StrLen $R2 $R4
   IntOp $R2 $R2 - 1
   IntOp $R4 $R4 + $R2
   Goto NextStrChar
 
Done:
Pop $R5
Pop $R4
Pop $R3
Pop $R2
Pop $R1
Exch $R0
FunctionEnd

-Stu