home *** CD-ROM | disk | FTP | other *** search
/ Hackers Magazine 57 / CdHackersMagazineNr57.iso / Software / Programming / nsis-2.46-setup.exe / Include / StrFunc.nsh < prev    next >
Encoding:
Text File  |  2009-01-13  |  46.9 KB  |  1,785 lines

  1. /*
  2. o-----------------------------------------------------------------------------o
  3. |String Functions Header File 1.09                                            |
  4. (-----------------------------------------------------------------------------)
  5. | By deguix                                     / A Header file for NSIS 2.01 |
  6. | <cevo_deguix@yahoo.com.br>                   -------------------------------|
  7. |                                                                             |
  8. |    This header file contains NSIS functions for string manipulation.        |
  9. o-----------------------------------------------------------------------------o
  10. */
  11.  
  12. !verbose push
  13. !verbose 3
  14. !ifndef STRFUNC_VERBOSITY
  15.   !define STRFUNC_VERBOSITY 3
  16. !endif
  17. !define _STRFUNC_VERBOSITY ${STRFUNC_VERBOSITY}
  18. !undef STRFUNC_VERBOSITY
  19. !verbose ${_STRFUNC_VERBOSITY}
  20.  
  21. !include LogicLib.nsh
  22.  
  23. !ifndef STRFUNC
  24.  
  25.   !define FALSE 0
  26.   !define TRUE 1
  27.  
  28.   ;Header File Identification
  29.  
  30.   !define STRFUNC `String Functions Header File`
  31.   !define STRFUNC_SHORT `StrFunc`
  32.   !define STRFUNC_CREDITS `2004 Diego Pedroso`
  33.  
  34.   ;Header File Version
  35.  
  36.   !define STRFUNC_VERMAJ 1
  37.   !define STRFUNC_VERMED 09
  38.  ;!define STRFUNC_VERMIN 0
  39.  ;!define STRFUNC_VERBLD 0
  40.  
  41.   !define STRFUNC_VER `${STRFUNC_VERMAJ}.${STRFUNC_VERMED}`
  42.  
  43.   ;Header File Init Message Prefix and Postfix
  44.  
  45.   !define STRFUNC_INITMSGPRE `----------------------------------------------------------------------$\r$\n`
  46.   !define STRFUNC_INITMSGPOST `$\r$\n----------------------------------------------------------------------$\r$\n`
  47.  
  48.   ;Header File Init Message
  49.  
  50.   !verbose push
  51.   !verbose 4
  52.   !echo `${STRFUNC_INITMSGPRE}NSIS ${STRFUNC} ${STRFUNC_VER} - Copyright ${STRFUNC_CREDITS}${STRFUNC_INITMSGPOST}`
  53.   !verbose pop
  54.  
  55.   ;Header File Function Init Message Prefix and Postfix
  56.  
  57.   !define STRFUNC_FUNCMSGPRE ``
  58.   !define STRFUNC_FUNCMSGPOST ``
  59.   
  60.   ;Header File Function Macros
  61.  
  62.   !macro STRFUNC_FUNCLIST_INSERT Name
  63.     !ifdef StrFunc_List
  64.       !define StrFunc_List2 `${StrFunc_List}`
  65.       !undef StrFunc_List
  66.       !define StrFunc_List `${StrFunc_List2}|${Name}`
  67.       !undef StrFunc_List2
  68.     !else
  69.       !define StrFunc_List `${Name}`
  70.     !endif
  71.   !macroend
  72.  
  73.   !macro STRFUNC_DEFFUNC Name
  74.     !insertmacro STRFUNC_FUNCLIST_INSERT ${Name}
  75.   
  76.     !define `${Name}` `!insertmacro FUNCTION_STRING_${Name}`
  77.     !define `Un${Name}` `!insertmacro FUNCTION_STRING_Un${Name}`
  78.   !macroend
  79.   
  80.   !macro STRFUNC_FUNC ShortName Credits
  81.     !verbose push
  82.     !verbose 4
  83.  
  84.     !ifndef `Un${ShortName}`
  85.       !echo `${STRFUNC_FUNCMSGPRE}$ {Un${ShortName}} - Copyright ${Credits}${STRFUNC_FUNCMSGPOST}`
  86.       !verbose pop
  87.       !define `Un${ShortName}` `!insertmacro FUNCTION_STRING_Un${ShortName}_Call`
  88.       !define `Un${ShortName}_INCLUDED`
  89.       Function `un.${ShortName}`
  90.     !else
  91.       !echo `${STRFUNC_FUNCMSGPRE}$ {${ShortName}} - Copyright ${Credits}${STRFUNC_FUNCMSGPOST}`
  92.       !verbose pop
  93.       !undef `${ShortName}`
  94.       !define `${ShortName}` `!insertmacro FUNCTION_STRING_${ShortName}_Call`
  95.       !define `${ShortName}_INCLUDED`
  96.       Function `${ShortName}`
  97.     !endif
  98.   !macroend
  99.  
  100.   ;Function Names Startup Definition
  101.  
  102.   !insertmacro STRFUNC_DEFFUNC StrCase
  103.   !define StrCase_List `ResultVar|String|Type`
  104.   !define StrCase_TypeList `Output|Text|Option  U L T S <>`
  105.   !macro `FUNCTION_STRING_UnStrCase`
  106.     !undef UnStrCase
  107.     !insertmacro FUNCTION_STRING_StrCase
  108.   !macroend
  109.   
  110.   !insertmacro STRFUNC_DEFFUNC StrClb
  111.   !define StrClb_List `ResultVar|String|Action`
  112.   !define StrClb_TypeList `Output|Text|Option  > < <>`
  113.   !macro `FUNCTION_STRING_UnStrClb`
  114.     !undef UnStrClb
  115.     !insertmacro FUNCTION_STRING_StrClb
  116.   !macroend
  117.  
  118.   !insertmacro STRFUNC_DEFFUNC StrIOToNSIS
  119.   !define StrIOToNSIS_List `ResultVar|String`
  120.   !define StrIOToNSIS_TypeList `Output|Text`
  121.   !macro `FUNCTION_STRING_UnStrIOToNSIS`
  122.     !undef UnStrIOToNSIS
  123.     !insertmacro FUNCTION_STRING_StrIOToNSIS
  124.   !macroend
  125.  
  126.   !insertmacro STRFUNC_DEFFUNC StrLoc
  127.   !define StrLoc_List `ResultVar|String|StrToSearchFor|CounterDirection`
  128.   !define StrLoc_TypeList `Output|Text|Text|Option > <`
  129.   !macro `FUNCTION_STRING_UnStrLoc`
  130.     !undef UnStrLoc
  131.     !insertmacro FUNCTION_STRING_StrLoc
  132.   !macroend
  133.  
  134.   !insertmacro STRFUNC_DEFFUNC StrNSISToIO
  135.   !define StrNSISToIO_List `ResultVar|String`
  136.   !define StrNSISToIO_TypeList `Output|Text`
  137.   !macro `FUNCTION_STRING_UnStrNSISToIO`
  138.     !undef UnStrNSISToIO
  139.     !insertmacro FUNCTION_STRING_StrNSISToIO
  140.   !macroend
  141.  
  142.   !insertmacro STRFUNC_DEFFUNC StrRep
  143.   !define StrRep_List `ResultVar|String|StrToReplace|ReplacementString`
  144.   !define StrRep_TypeList `Output|Text|Text|Text`
  145.   !macro `FUNCTION_STRING_UnStrRep`
  146.     !undef UnStrRep
  147.     !insertmacro FUNCTION_STRING_StrRep
  148.   !macroend
  149.  
  150.   !insertmacro STRFUNC_DEFFUNC StrSort
  151.   !define StrSort_List `ResultVar|String|LeftStr|CenterStr|RightStr|IncludeLeftStr|IncludeCenterStr|IncludeRightStr`
  152.   !define StrSort_TypeList `Output|Text|Text|Text|Text|Option 1 0|Option 1 0|Option 1 0`
  153.   !macro `FUNCTION_STRING_UnStrSort`
  154.     !undef UnStrSort
  155.     !insertmacro FUNCTION_STRING_StrSort
  156.   !macroend
  157.  
  158.   !insertmacro STRFUNC_DEFFUNC StrStr
  159.   !define StrStr_List `ResultVar|String|StrToSearchFor`
  160.   !define StrStr_TypeList `Output|Text|Text`
  161.   !macro `FUNCTION_STRING_UnStrStr`
  162.     !undef UnStrStr
  163.     !insertmacro FUNCTION_STRING_StrStr
  164.   !macroend
  165.  
  166.   !insertmacro STRFUNC_DEFFUNC StrStrAdv
  167.   !define StrStrAdv_List `ResultVar|String|StrToSearchFor|SearchDirection|ResultStrDirection|DisplayStrToSearch|Loops|CaseSensitive`
  168.   !define StrStrAdv_TypeList `Output|Text|Text|Option > <|Option > <|Option 1 0|Text|Option 0 1`
  169.   !macro `FUNCTION_STRING_UnStrStrAdv`
  170.     !undef UnStrStrAdv
  171.     !insertmacro FUNCTION_STRING_StrStrAdv
  172.   !macroend
  173.  
  174.   !insertmacro STRFUNC_DEFFUNC StrTok
  175.   !define StrTok_List `ResultVar|String|Separators|ResultPart|SkipEmptyParts`
  176.   !define StrTok_TypeList `Output|Text|Text|Mixed L|Option 1 0`
  177.   !macro `FUNCTION_STRING_UnStrTok`
  178.     !undef UnStrTok
  179.     !insertmacro FUNCTION_STRING_StrTok
  180.   !macroend
  181.  
  182.   !insertmacro STRFUNC_DEFFUNC StrTrimNewLines
  183.   !define StrTrimNewLines_List `ResultVar|String`
  184.   !define StrTrimNewLines_TypeList `Output|Text`
  185.   !macro `FUNCTION_STRING_UnStrTrimNewLines`
  186.     !undef UnStrTrimNewLines
  187.     !insertmacro FUNCTION_STRING_StrTrimNewLines
  188.   !macroend
  189.  
  190.   ;Function Codes for Install and Uninstall
  191.  
  192.   # Function StrCase
  193.   ################
  194.  
  195.   !macro FUNCTION_STRING_StrCase
  196.     !insertmacro STRFUNC_FUNC `StrCase` `2004 Diego Pedroso - Based on functions by Dave Laundon`
  197.  
  198.     /*After this point:
  199.       ------------------------------------------
  200.        $0 = String (input)
  201.        $1 = Type (input)
  202.        $2 = StrLength (temp)
  203.        $3 = StartChar (temp)
  204.        $4 = EndChar (temp)
  205.        $5 = ResultStr (temp)
  206.        $6 = CurrentChar (temp)
  207.        $7 = LastChar (temp)
  208.        $8 = Temp (temp)*/
  209.  
  210.       ;Get input from user
  211.       Exch $1
  212.       Exch
  213.       Exch $0
  214.       Exch
  215.       Push $2
  216.       Push $3
  217.       Push $4
  218.       Push $5
  219.       Push $6
  220.       Push $7
  221.       Push $8
  222.  
  223.       ;Initialize variables
  224.       StrCpy $2 ""
  225.       StrCpy $3 ""
  226.       StrCpy $4 ""
  227.       StrCpy $5 ""
  228.       StrCpy $6 ""
  229.       StrCpy $7 ""
  230.       StrCpy $8 ""
  231.  
  232.       ;Upper and lower cases are simple to use
  233.       ${If} $1 == "U"
  234.  
  235.         ;Upper Case System:
  236.         ;------------------
  237.         ; Convert all characters to upper case.
  238.  
  239.         System::Call "User32::CharUpper(t r0 r5)i"
  240.         Goto StrCase_End
  241.       ${ElseIf} $1 == "L"
  242.  
  243.         ;Lower Case System:
  244.         ;------------------
  245.         ; Convert all characters to lower case.
  246.  
  247.         System::Call "User32::CharLower(t r0 r5)i"
  248.         Goto StrCase_End
  249.       ${EndIf}
  250.  
  251.       ;For the rest of cases:
  252.       ;Get "String" length
  253.       StrLen $2 $0
  254.  
  255.       ;Make a loop until the end of "String"
  256.       ${For} $3 0 $2
  257.         ;Add 1 to "EndChar" counter also
  258.         IntOp $4 $3 + 1
  259.  
  260.         # Step 1: Detect one character at a time
  261.  
  262.         ;Remove characters before "StartChar" except when
  263.         ;"StartChar" is the first character of "String"
  264.         ${If} $3 <> 0
  265.           StrCpy $6 $0 `` $3
  266.         ${EndIf}
  267.  
  268.         ;Remove characters after "EndChar" except when
  269.         ;"EndChar" is the last character of "String"
  270.         ${If} $4 <> $2
  271.           ${If} $3 = 0
  272.             StrCpy $6 $0 1
  273.           ${Else}
  274.             StrCpy $6 $6 1
  275.           ${EndIf}
  276.         ${EndIf}
  277.  
  278.         # Step 2: Convert to the advanced case user chose:
  279.  
  280.         ${If} $1 == "T"
  281.  
  282.           ;Title Case System:
  283.           ;------------------
  284.           ; Convert all characters after a non-alphabetic character to upper case.
  285.           ; Else convert to lower case.
  286.  
  287.           ;Use "IsCharAlpha" for the job
  288.           System::Call "*(&t1 r7) i .r8"
  289.           System::Call "*$8(&i1 .r7)"
  290.           System::Free $8
  291.           System::Call "user32::IsCharAlpha(i r7) i .r8"
  292.           
  293.           ;Verify "IsCharAlpha" result and convert the character
  294.           ${If} $8 = 0
  295.             System::Call "User32::CharUpper(t r6 r6)i"
  296.           ${Else}
  297.             System::Call "User32::CharLower(t r6 r6)i"
  298.           ${EndIf}
  299.         ${ElseIf} $1 == "S"
  300.  
  301.           ;Sentence Case System:
  302.           ;------------------
  303.           ; Convert all characters after a ".", "!" or "?" character to upper case.
  304.           ; Else convert to lower case. Spaces or tabs after these marks are ignored.
  305.  
  306.           ;Detect current characters and ignore if necessary
  307.           ${If} $6 == " "
  308.           ${OrIf} $6 == "$\t"
  309.             Goto IgnoreLetter
  310.           ${EndIf}
  311.  
  312.           ;Detect last characters and convert
  313.           ${If} $7 == "."
  314.           ${OrIf} $7 == "!"
  315.           ${OrIf} $7 == "?"
  316.           ${OrIf} $7 == ""
  317.             System::Call "User32::CharUpper(t r6 r6)i"
  318.           ${Else}
  319.             System::Call "User32::CharLower(t r6 r6)i"
  320.           ${EndIf}
  321.         ${ElseIf} $1 == "<>"
  322.  
  323.           ;Switch Case System:
  324.           ;------------------
  325.           ; Switch all characters cases to their inverse case.
  326.  
  327.           ;Use "IsCharUpper" for the job
  328.           System::Call "*(&t1 r6) i .r8"
  329.           System::Call "*$8(&i1 .r7)"
  330.           System::Free $8
  331.           System::Call "user32::IsCharUpper(i r7) i .r8"
  332.           
  333.           ;Verify "IsCharUpper" result and convert the character
  334.           ${If} $8 = 0
  335.             System::Call "User32::CharUpper(t r6 r6)i"
  336.           ${Else}
  337.             System::Call "User32::CharLower(t r6 r6)i"
  338.           ${EndIf}
  339.         ${EndIf}
  340.  
  341.         ;Write the character to "LastChar"
  342.         StrCpy $7 $6
  343.  
  344.         IgnoreLetter:
  345.         ;Add this character to "ResultStr"
  346.         StrCpy $5 `$5$6`
  347.       ${Next}
  348.  
  349.       StrCase_End:
  350.  
  351.     /*After this point:
  352.       ------------------------------------------
  353.        $0 = OutVar (output)*/
  354.  
  355.       ; Copy "ResultStr" to "OutVar"
  356.       StrCpy $0 $5
  357.  
  358.       ;Return output to user
  359.       Pop $8
  360.       Pop $7
  361.       Pop $6
  362.       Pop $5
  363.       Pop $4
  364.       Pop $3
  365.       Pop $2
  366.       Pop $1
  367.       Exch $0
  368.     FunctionEnd
  369.  
  370.   !macroend
  371.  
  372.   !macro FUNCTION_STRING_StrClb
  373.     !insertmacro STRFUNC_FUNC `StrClb` `2004 Diego Pedroso - Based on functions by Nik Medved`
  374.  
  375.     /*After this point:
  376.       ------------------------------------------
  377.        $0 = String (input)
  378.        $1 = Action (input)
  379.        $2 = Lock/Unlock (temp)
  380.        $3 = Temp (temp)
  381.        $4 = Temp2 (temp)*/
  382.  
  383.       ;Get input from user
  384.  
  385.       Exch $1
  386.       Exch
  387.       Exch $0
  388.       Exch
  389.       Push $2
  390.       Push $3
  391.       Push $4
  392.       
  393.       StrCpy $2 ""
  394.       StrCpy $3 ""
  395.       StrCpy $4 ""
  396.  
  397.       ;Open the clipboard to do the operations the user chose (kichik's fix)
  398.       System::Call 'user32::OpenClipboard(i $HWNDPARENT)'
  399.  
  400.       ${If} $1 == ">" ;Set
  401.  
  402.         ;Step 1: Clear the clipboard
  403.         System::Call 'user32::EmptyClipboard()'
  404.  
  405.         ;Step 2: Allocate global heap
  406.         StrLen $2 $0
  407.         IntOp $2 $2 + 1
  408.         System::Call 'kernel32::GlobalAlloc(i 2, i r2) i.r2'
  409.  
  410.         ;Step 3: Lock the handle
  411.         System::Call 'kernel32::GlobalLock(i r2) i.r3'
  412.  
  413.         ;Step 4: Copy the text to locked clipboard buffer
  414.         System::Call 'kernel32::lstrcpyA(i r3, t r0)'
  415.  
  416.         ;Step 5: Unlock the handle again
  417.         System::Call 'kernel32::GlobalUnlock(i r2)'
  418.  
  419.         ;Step 6: Set the information to the clipboard
  420.         System::Call 'user32::SetClipboardData(i 1, i r2)'
  421.  
  422.         StrCpy $0 ""
  423.  
  424.       ${ElseIf} $1 == "<" ;Get
  425.  
  426.         ;Step 1: Get clipboard data
  427.         System::Call 'user32::GetClipboardData(i 1) i .r2'
  428.  
  429.         ;Step 2: Lock and copy data (kichik's fix)
  430.         System::Call 'kernel32::GlobalLock(i r2) t .r0'
  431.  
  432.         ;Step 3: Unlock (kichik's fix)
  433.         System::Call 'kernel32::GlobalUnlock(i r2)'
  434.  
  435.       ${ElseIf} $1 == "<>" ;Swap
  436.  
  437.         ;Step 1: Get clipboard data
  438.         System::Call 'user32::GetClipboardData(i 1) i .r2'
  439.  
  440.         ;Step 2: Lock and copy data (kichik's fix)
  441.         System::Call 'kernel32::GlobalLock(i r2) t .r4'
  442.  
  443.         ;Step 3: Unlock (kichik's fix)
  444.         System::Call 'kernel32::GlobalUnlock(i r2)'
  445.  
  446.         ;Step 4: Clear the clipboard
  447.         System::Call 'user32::EmptyClipboard()'
  448.  
  449.         ;Step 5: Allocate global heap
  450.         StrLen $2 $0
  451.         IntOp $2 $2 + 1
  452.         System::Call 'kernel32::GlobalAlloc(i 2, i r2) i.r2'
  453.  
  454.         ;Step 6: Lock the handle
  455.         System::Call 'kernel32::GlobalLock(i r2) i.r3'
  456.  
  457.         ;Step 7: Copy the text to locked clipboard buffer
  458.         System::Call 'kernel32::lstrcpyA(i r3, t r0)'
  459.  
  460.         ;Step 8: Unlock the handle again
  461.         System::Call 'kernel32::GlobalUnlock(i r2)'
  462.  
  463.         ;Step 9: Set the information to the clipboard
  464.         System::Call 'user32::SetClipboardData(i 1, i r2)'
  465.         
  466.         StrCpy $0 $4
  467.       ${Else} ;Clear
  468.  
  469.         ;Step 1: Clear the clipboard
  470.         System::Call 'user32::EmptyClipboard()'
  471.  
  472.         StrCpy $0 ""
  473.       ${EndIf}
  474.  
  475.       ;Close the clipboard
  476.       System::Call 'user32::CloseClipboard()'
  477.  
  478.     /*After this point:
  479.       ------------------------------------------
  480.        $0 = OutVar (output)*/
  481.  
  482.       ;Return result to user
  483.       Pop $4
  484.       Pop $3
  485.       Pop $2
  486.       Pop $1
  487.       Exch $0
  488.     FunctionEnd
  489.  
  490.   !macroend
  491.  
  492.   # Function StrIOToNSIS
  493.   ####################
  494.  
  495.   !macro FUNCTION_STRING_StrIOToNSIS
  496.     !insertmacro STRFUNC_FUNC `StrIOToNSIS` `2004 "bluenet" - Based on functions by Amir Szekely, Joost Verburg, Dave Laundon and Diego Pedroso`
  497.  
  498.     /*After this point:
  499.       ------------------------------------------
  500.        $R0 = String (input/output)
  501.        $R1 = StartCharPos (temp)
  502.        $R2 = StrLen (temp)
  503.        $R3 = TempStr (temp)
  504.        $R4 = TempRepStr (temp)*/
  505.  
  506.       ;Get input from user
  507.       Exch $R0
  508.       Push $R1
  509.       Push $R2
  510.       Push $R3
  511.       Push $R4
  512.       
  513.       ;Get "String" length
  514.       StrLen $R2 $R0
  515.  
  516.       ;Loop until "String" end is reached
  517.       ${For} $R1 0 $R2
  518.         ;Get the next "String" characters
  519.         StrCpy $R3 $R0 2 $R1
  520.         
  521.         ;Detect if current character is:
  522.         ${If} $R3 == "\\" ;Back-slash
  523.           StrCpy $R4 "\"
  524.         ${ElseIf} $R3 == "\r" ;Carriage return
  525.           StrCpy $R4 "$\r"
  526.         ${ElseIf} $R3 == "\n" ;Line feed
  527.           StrCpy $R4 "$\n"
  528.         ${ElseIf} $R3 == "\t" ;Tab
  529.           StrCpy $R4 "$\t"
  530.         ${Else} ;Anything else
  531.           StrCpy $R4 ""
  532.         ${EndIf}
  533.  
  534.         ;Detect if "TempRepStr" is not empty
  535.         ${If} $R4 != ""
  536.           ;Replace the old characters with the new one
  537.           StrCpy $R3 $R0 $R1
  538.           IntOp $R1 $R1 + 2
  539.           StrCpy $R0 $R0 "" $R1
  540.           StrCpy $R0 "$R3$R4$R0"
  541.           IntOp $R2 $R2 - 1 ;Decrease "StrLen"
  542.           IntOp $R1 $R1 - 2 ;Go back to the next character
  543.         ${EndIf}
  544.       ${Next}
  545.       Pop $R4
  546.       Pop $R3
  547.       Pop $R2
  548.       Pop $R1
  549.       Exch $R0
  550.     FunctionEnd
  551.   !macroend
  552.  
  553.   # Function StrLoc
  554.   ###############
  555.  
  556.   !macro FUNCTION_STRING_StrLoc
  557.     !insertmacro STRFUNC_FUNC `StrLoc` `2004 Diego Pedroso - Based on functions by Ximon Eighteen`
  558.  
  559.     /*After this point:
  560.       ------------------------------------------
  561.        $R0 = OffsetDirection (input)
  562.        $R1 = StrToSearch (input)
  563.        $R2 = String (input)
  564.        $R3 = StrToSearchLen (temp)
  565.        $R4 = StrLen (temp)
  566.        $R5 = StartCharPos (temp)
  567.        $R6 = TempStr (temp)*/
  568.  
  569.       ;Get input from user
  570.       Exch $R0
  571.       Exch
  572.       Exch $R1
  573.       Exch 2
  574.       Exch $R2
  575.       Push $R3
  576.       Push $R4
  577.       Push $R5
  578.       Push $R6
  579.  
  580.       ;Get "String" and "StrToSearch" length
  581.       StrLen $R3 $R1
  582.       StrLen $R4 $R2
  583.       ;Start "StartCharPos" counter
  584.       StrCpy $R5 0
  585.  
  586.       ;Loop until "StrToSearch" is found or "String" reaches its end
  587.       ${Do}
  588.         ;Remove everything before and after the searched part ("TempStr")
  589.         StrCpy $R6 $R2 $R3 $R5
  590.  
  591.         ;Compare "TempStr" with "StrToSearch"
  592.         ${If} $R6 == $R1
  593.           ${If} $R0 == `<`
  594.             IntOp $R6 $R3 + $R5
  595.             IntOp $R0 $R4 - $R6
  596.           ${Else}
  597.             StrCpy $R0 $R5
  598.           ${EndIf}
  599.           ${ExitDo}
  600.         ${EndIf}
  601.         ;If not "StrToSearch", this could be "String" end
  602.         ${If} $R5 >= $R4
  603.           StrCpy $R0 ``
  604.           ${ExitDo}
  605.         ${EndIf}
  606.         ;If not, continue the loop
  607.         IntOp $R5 $R5 + 1
  608.       ${Loop}
  609.  
  610.       ;Return output to user
  611.       Pop $R6
  612.       Pop $R5
  613.       Pop $R4
  614.       Pop $R3
  615.       Pop $R2
  616.       Exch
  617.       Pop $R1
  618.       Exch $R0
  619.     FunctionEnd
  620.  
  621.   !macroend
  622.  
  623.   # Function StrNSISToIO
  624.   ####################
  625.  
  626.   !macro FUNCTION_STRING_StrNSISToIO
  627.     !insertmacro STRFUNC_FUNC `StrNSISToIO` `2004 "bluenet" - Based on functions by Amir Szekely, Joost Verburg, Dave Laundon and Diego Pedroso`
  628.  
  629.     /*After this point:
  630.       ------------------------------------------
  631.        $R0 = String (input/output)
  632.        $R1 = StartCharPos (temp)
  633.        $R2 = StrLen (temp)
  634.        $R3 = TempStr (temp)
  635.        $R4 = TempRepStr (temp)*/
  636.  
  637.       ;Get input from user
  638.       Exch $R0
  639.       Push $R1
  640.       Push $R2
  641.       Push $R3
  642.       Push $R4
  643.       
  644.       ;Get "String" length
  645.       StrLen $R2 $R0
  646.  
  647.       ;Loop until "String" end is reached
  648.       ${For} $R1 0 $R2
  649.         ;Get the next "String" character
  650.         StrCpy $R3 $R0 1 $R1
  651.  
  652.         ;Detect if current character is:
  653.         ${If} $R3 == "$\r" ;Back-slash
  654.           StrCpy $R4 "\r"
  655.         ${ElseIf} $R3 == "$\n" ;Carriage return
  656.           StrCpy $R4 "\n"
  657.         ${ElseIf} $R3 == "$\t" ;Line feed
  658.           StrCpy $R4 "\t"
  659.         ${ElseIf} $R3 == "\" ;Tab
  660.           StrCpy $R4 "\\"
  661.         ${Else} ;Anything else
  662.           StrCpy $R4 ""
  663.         ${EndIf}
  664.  
  665.         ;Detect if "TempRepStr" is not empty
  666.         ${If} $R4 != ""
  667.           ;Replace the old character with the new ones
  668.           StrCpy $R3 $R0 $R1
  669.           IntOp $R1 $R1 + 1
  670.           StrCpy $R0 $R0 "" $R1
  671.           StrCpy $R0 "$R3$R4$R0"
  672.           IntOp $R2 $R2 + 1 ;Increase "StrLen"
  673.         ${EndIf}
  674.       ${Next}
  675.  
  676.       ;Return output to user
  677.       Pop $R4
  678.       Pop $R3
  679.       Pop $R2
  680.       Pop $R1
  681.       Exch $R0
  682.     FunctionEnd
  683.   !macroend
  684.  
  685.   # Function StrRep
  686.   ###############
  687.  
  688.   !macro FUNCTION_STRING_StrRep
  689.     !insertmacro STRFUNC_FUNC `StrRep` `2004 Diego Pedroso - Based on functions by Hendri Adriaens`
  690.  
  691.     /*After this point:
  692.       ------------------------------------------
  693.        $R0 = ReplacementString (input)
  694.        $R1 = StrToSearch (input)
  695.        $R2 = String (input)
  696.        $R3 = RepStrLen (temp)
  697.        $R4 = StrToSearchLen (temp)
  698.        $R5 = StrLen (temp)
  699.        $R6 = StartCharPos (temp)
  700.        $R7 = TempStrL (temp)
  701.        $R8 = TempStrR (temp)*/
  702.  
  703.       ;Get input from user
  704.       Exch $R0
  705.       Exch
  706.       Exch $R1
  707.       Exch
  708.       Exch 2
  709.       Exch $R2
  710.       Push $R3
  711.       Push $R4
  712.       Push $R5
  713.       Push $R6
  714.       Push $R7
  715.       Push $R8
  716.  
  717.       ;Return "String" if "StrToSearch" is ""
  718.       ${IfThen} $R1 == "" ${|} Goto Done ${|}
  719.  
  720.       ;Get "ReplacementString", "String" and "StrToSearch" length
  721.       StrLen $R3 $R0
  722.       StrLen $R4 $R1
  723.       StrLen $R5 $R2
  724.       ;Start "StartCharPos" counter
  725.       StrCpy $R6 0
  726.  
  727.       ;Loop until "StrToSearch" is found or "String" reaches its end
  728.       ${Do}
  729.         ;Remove everything before and after the searched part ("TempStrL")
  730.         StrCpy $R7 $R2 $R4 $R6
  731.  
  732.         ;Compare "TempStrL" with "StrToSearch"
  733.         ${If} $R7 == $R1
  734.           ;Split "String" to replace the string wanted
  735.           StrCpy $R7 $R2 $R6 ;TempStrL
  736.  
  737.           ;Calc: "StartCharPos" + "StrToSearchLen" = EndCharPos
  738.           IntOp $R8 $R6 + $R4
  739.  
  740.           StrCpy $R8 $R2 "" $R8 ;TempStrR
  741.  
  742.           ;Insert the new string between the two separated parts of "String"
  743.           StrCpy $R2 $R7$R0$R8
  744.           ;Now calculate the new "StrLen" and "StartCharPos"
  745.           StrLen $R5 $R2
  746.           IntOp $R6 $R6 + $R3
  747.           ${Continue}
  748.         ${EndIf}
  749.  
  750.         ;If not "StrToSearch", this could be "String" end
  751.         ${IfThen} $R6 >= $R5 ${|} ${ExitDo} ${|}
  752.         ;If not, continue the loop
  753.         IntOp $R6 $R6 + 1
  754.       ${Loop}
  755.  
  756.       Done:
  757.  
  758.     /*After this point:
  759.       ------------------------------------------
  760.        $R0 = OutVar (output)*/
  761.  
  762.       ;Return output to user
  763.       StrCpy $R0 $R2
  764.       Pop $R8
  765.       Pop $R7
  766.       Pop $R6
  767.       Pop $R5
  768.       Pop $R4
  769.       Pop $R3
  770.       Pop $R2
  771.       Pop $R1
  772.       Exch $R0
  773.     FunctionEnd
  774.  
  775.   !macroend
  776.  
  777.   # Function StrSort
  778.   ################
  779.  
  780.   !macro FUNCTION_STRING_StrSort
  781.     !insertmacro STRFUNC_FUNC `StrSort` `2004 Diego Pedroso - Based on functions by Stuart Welch`
  782.  
  783.     /*After this point:
  784.       ------------------------------------------
  785.        $R0 = String (input)
  786.        $R1 = LeftStr (input)
  787.        $R2 = CenterStr (input)
  788.        $R3 = RightStr (input)
  789.        $R4 = IncludeLeftStr (input)
  790.        $R5 = IncludeCenterStr (input)
  791.        $R6 = IncludeRightStr (input)
  792.  
  793.        $0 = StrLen (temp)
  794.        $1 = LeftStrLen (temp)
  795.        $2 = CenterStrLen (temp)
  796.        $3 = RightStrLen (temp)
  797.        $4 = StartPos (temp)
  798.        $5 = EndPos (temp)
  799.        $6 = StartCharPos (temp)
  800.        $7 = EndCharPos (temp)
  801.        $8 = TempStr (temp)*/
  802.  
  803.       ;Get input from user
  804.       Exch $R6
  805.       Exch
  806.       Exch $R5
  807.       Exch
  808.       Exch 2
  809.       Exch $R4
  810.       Exch 2
  811.       Exch 3
  812.       Exch $R3
  813.       Exch 3
  814.       Exch 4
  815.       Exch $R2
  816.       Exch 4
  817.       Exch 5
  818.       Exch $R1
  819.       Exch 5
  820.       Exch 6
  821.       Exch $R0
  822.       Exch 6
  823.       Push $0
  824.       Push $1
  825.       Push $2
  826.       Push $3
  827.       Push $4
  828.       Push $5
  829.       Push $6
  830.       Push $7
  831.       Push $8
  832.  
  833.       ;Parameter defaults
  834.       ${IfThen} $R4 == `` ${|} StrCpy $R4 `1` ${|}
  835.       ${IfThen} $R5 == `` ${|} StrCpy $R5 `1` ${|}
  836.       ${IfThen} $R6 == `` ${|} StrCpy $R6 `1` ${|}
  837.  
  838.       ;Get "String", "CenterStr", "LeftStr" and "RightStr" length
  839.       StrLen $0 $R0
  840.       StrLen $1 $R1
  841.       StrLen $2 $R2
  842.       StrLen $3 $R3
  843.       ;Start "StartCharPos" counter
  844.       StrCpy $6 0
  845.       ;Start "EndCharPos" counter based on "CenterStr" length
  846.       IntOp $7 $6 + $2
  847.  
  848.       ;Loop until "CenterStr" is found or "String" reaches its end
  849.       ${Do}
  850.         ;Remove everything before and after the searched part ("TempStr")
  851.         StrCpy $8 $R0 $2 $6
  852.  
  853.         ;Compare "TempStr" with "CenterStr"
  854.         ${IfThen} $8 == $R2 ${|} ${ExitDo} ${|}
  855.         ;If not, this could be "String" end
  856.         ${IfThen} $7 >= $0 ${|} Goto Done ${|}
  857.         ;If not, continue the loop
  858.         IntOp $6 $6 + 1
  859.         IntOp $7 $7 + 1
  860.       ${Loop}
  861.  
  862.       # "CenterStr" was found
  863.  
  864.       ;Remove "CenterStr" from "String" if the user wants
  865.       ${If} $R5 = ${FALSE}
  866.         StrCpy $8 $R0 $6
  867.         StrCpy $R0 $R0 `` $7
  868.         StrCpy $R0 $8$R0
  869.       ${EndIf}
  870.  
  871.       ;"StartPos" and "EndPos" will record "CenterStr" coordinates for now
  872.       StrCpy $4 $6
  873.       StrCpy $5 $7
  874.       ;"StartCharPos" and "EndCharPos" should be before "CenterStr"
  875.       IntOp $6 $6 - $1
  876.       IntOp $7 $6 + $1
  877.  
  878.       ;Loop until "LeftStr" is found or "String" reaches its start
  879.       ${Do}
  880.         ;Remove everything before and after the searched part ("TempStr")
  881.         StrCpy $8 $R0 $1 $6
  882.  
  883.         ;If "LeftStr" is empty
  884.         ${If} $R1 == ``
  885.           StrCpy $6 0
  886.           StrCpy $7 0
  887.           ${ExitDo}
  888.         ${EndIf}
  889.  
  890.         ;Compare "TempStr" with "LeftStr"
  891.         ${IfThen} $8 == $R1 ${|} ${ExitDo} ${|}
  892.         ;If not, this could be "String" start
  893.         ${IfThen} $6 <= 0 ${|} ${ExitDo} ${|}
  894.         ;If not, continue the loop
  895.         IntOp $6 $6 - 1
  896.         IntOp $7 $7 - 1
  897.       ${Loop}
  898.  
  899.       # "LeftStr" is found or "String" start was reached
  900.  
  901.       ;Remove "LeftStr" from "String" if the user wants
  902.       ${If} $R4 = ${FALSE}
  903.         IntOp $6 $6 + $1
  904.       ${EndIf}
  905.  
  906.       ;Record "LeftStr" first character position on "TempStr" (temporarily)
  907.       StrCpy $8 $6
  908.  
  909.       ;"StartCharPos" and "EndCharPos" should be after "CenterStr"
  910.       ${If} $R5 = ${FALSE}
  911.         StrCpy $6 $4
  912.       ${Else}
  913.         IntOp $6 $4 + $2
  914.       ${EndIf}
  915.       IntOp $7 $6 + $3
  916.       
  917.       ;Record "LeftStr" first character position on "StartPos"
  918.       StrCpy $4 $8
  919.  
  920.       ;Loop until "RightStr" is found or "String" reaches its end
  921.       ${Do}
  922.         ;Remove everything before and after the searched part ("TempStr")
  923.         StrCpy $8 $R0 $3 $6
  924.  
  925.         ;If "RightStr" is empty
  926.         ${If} $R3 == ``
  927.           StrCpy $6 $0
  928.           StrCpy $7 $0
  929.           ${ExitDo}
  930.         ${EndIf}
  931.  
  932.         ;Compare "TempStr" with "RightStr"
  933.         ${IfThen} $8 == $R3 ${|} ${ExitDo} ${|}
  934.         ;If not, this could be "String" end
  935.         ${IfThen} $7 >= $0 ${|} ${ExitDo} ${|}
  936.         ;If not, continue the loop
  937.         IntOp $6 $6 + 1
  938.         IntOp $7 $7 + 1
  939.       ${Loop}
  940.  
  941.       ;Remove "RightStr" from "String" if the user wants
  942.       ${If} $R6 = ${FALSE}
  943.         IntOp $7 $7 - $3
  944.       ${EndIf}
  945.  
  946.       ;Record "RightStr" last character position on "StartPos"
  947.       StrCpy $5 $7
  948.  
  949.       ;As the positionment is relative...
  950.       IntOp $5 $5 - $4
  951.  
  952.       ;Write the string and finish the job
  953.       StrCpy $R0 $R0 $5 $4
  954.       Goto +2
  955.  
  956.       Done:
  957.       StrCpy $R0 ``
  958.  
  959.     /*After this point:
  960.       ------------------------------------------
  961.        $R0 = OutVar (output)*/
  962.  
  963.       ;Return output to user
  964.       Pop $8
  965.       Pop $7
  966.       Pop $6
  967.       Pop $5
  968.       Pop $4
  969.       Pop $3
  970.       Pop $2
  971.       Pop $1
  972.       Pop $0
  973.       Pop $R6
  974.       Pop $R5
  975.       Pop $R4
  976.       Pop $R3
  977.       Pop $R2
  978.       Pop $R1
  979.       Exch $R0
  980.     FunctionEnd
  981.  
  982.   !macroend
  983.   
  984.   # Function StrStr
  985.   ###############
  986.  
  987.   !macro FUNCTION_STRING_StrStr
  988.     !insertmacro STRFUNC_FUNC `StrStr` `2004 Diego Pedroso - Based on functions by Ximon Eighteen`
  989.  
  990.     /*After this point:
  991.       ------------------------------------------
  992.        $R0 = StrToSearch (input)
  993.        $R1 = String (input)
  994.        $R2 = StrToSearchLen (temp)
  995.        $R3 = StrLen (temp)
  996.        $R4 = StartCharPos (temp)
  997.        $R5 = TempStr (temp)*/
  998.  
  999.       ;Get input from user
  1000.       Exch $R0
  1001.       Exch
  1002.       Exch $R1
  1003.       Push $R2
  1004.       Push $R3
  1005.       Push $R4
  1006.       Push $R5
  1007.  
  1008.       ;Get "String" and "StrToSearch" length
  1009.       StrLen $R2 $R0
  1010.       StrLen $R3 $R1
  1011.       ;Start "StartCharPos" counter
  1012.       StrCpy $R4 0
  1013.  
  1014.       ;Loop until "StrToSearch" is found or "String" reaches its end
  1015.       ${Do}
  1016.         ;Remove everything before and after the searched part ("TempStr")
  1017.         StrCpy $R5 $R1 $R2 $R4
  1018.  
  1019.         ;Compare "TempStr" with "StrToSearch"
  1020.         ${IfThen} $R5 == $R0 ${|} ${ExitDo} ${|}
  1021.         ;If not "StrToSearch", this could be "String" end
  1022.         ${IfThen} $R4 >= $R3 ${|} ${ExitDo} ${|}
  1023.         ;If not, continue the loop
  1024.         IntOp $R4 $R4 + 1
  1025.       ${Loop}
  1026.  
  1027.     /*After this point:
  1028.       ------------------------------------------
  1029.        $R0 = OutVar (output)*/
  1030.  
  1031.       ;Remove part before "StrToSearch" on "String" (if there has one)
  1032.       StrCpy $R0 $R1 `` $R4
  1033.  
  1034.       ;Return output to user
  1035.       Pop $R5
  1036.       Pop $R4
  1037.       Pop $R3
  1038.       Pop $R2
  1039.       Pop $R1
  1040.       Exch $R0
  1041.     FunctionEnd
  1042.  
  1043.   !macroend
  1044.  
  1045.   # Function StrStrAdv
  1046.   ##################
  1047.  
  1048.   !macro FUNCTION_STRING_StrStrAdv
  1049.     !insertmacro STRFUNC_FUNC `StrStrAdv` `2003-2004 Diego Pedroso`
  1050.  
  1051.     /*After this point:
  1052.       ------------------------------------------
  1053.        $0 = String (input)
  1054.        $1 = StringToSearch (input)
  1055.        $2 = DirectionOfSearch (input)
  1056.        $3 = DirectionOfReturn (input)
  1057.        $4 = ShowStrToSearch (input)
  1058.        $5 = NumLoops (input)
  1059.        $6 = CaseSensitive (input)
  1060.        $7 = StringLength (temp)
  1061.        $8 = StrToSearchLength (temp)
  1062.        $9 = CurrentLoop (temp)
  1063.        $R0 = EndCharPos (temp)
  1064.        $R1 = StartCharPos (temp)
  1065.        $R2 = OutVar (output)
  1066.        $R3 = Temp (temp)*/
  1067.  
  1068.       ;Get input from user
  1069.  
  1070.       Exch $6
  1071.       Exch
  1072.       Exch $5
  1073.       Exch
  1074.       Exch 2
  1075.       Exch $4
  1076.       Exch 2
  1077.       Exch 3
  1078.       Exch $3
  1079.       Exch 3
  1080.       Exch 4
  1081.       Exch $2
  1082.       Exch 4
  1083.       Exch 5
  1084.       Exch $1
  1085.       Exch 5
  1086.       Exch 6
  1087.       Exch $0
  1088.       Exch 6
  1089.       Push $7
  1090.       Push $8
  1091.       Push $9
  1092.       Push $R3
  1093.       Push $R2
  1094.       Push $R1
  1095.       Push $R0
  1096.  
  1097.       ; Clean $R0-$R3 variables
  1098.       StrCpy $R0 ""
  1099.       StrCpy $R1 ""
  1100.       StrCpy $R2 ""
  1101.       StrCpy $R3 ""
  1102.  
  1103.       ; Verify if we have the correct values on the variables
  1104.       ${If} $0 == ``
  1105.         SetErrors ;AdvStrStr_StrToSearch not found
  1106.         Goto AdvStrStr_End
  1107.       ${EndIf}
  1108.  
  1109.       ${If} $1 == ``
  1110.         SetErrors ;No text to search
  1111.         Goto AdvStrStr_End
  1112.       ${EndIf}
  1113.  
  1114.       ${If} $2 != <
  1115.         StrCpy $2 >
  1116.       ${EndIf}
  1117.  
  1118.       ${If} $3 != <
  1119.         StrCpy $3 >
  1120.       ${EndIf}
  1121.  
  1122.       ${If} $4 <> 0
  1123.         StrCpy $4 1
  1124.       ${EndIf}
  1125.  
  1126.       ${If} $5 <= 0
  1127.         StrCpy $5 0
  1128.       ${EndIf}
  1129.  
  1130.       ${If} $6 <> 1
  1131.         StrCpy $6 0
  1132.       ${EndIf}
  1133.  
  1134.       ; Find "AdvStrStr_String" length
  1135.       StrLen $7 $0
  1136.  
  1137.       ; Then find "AdvStrStr_StrToSearch" length
  1138.       StrLen $8 $1
  1139.  
  1140.       ; Now set up basic variables
  1141.  
  1142.       ${If} $2 == <
  1143.         IntOp $R1 $7 - $8
  1144.         StrCpy $R2 $7
  1145.       ${Else}
  1146.         StrCpy $R1 0
  1147.         StrCpy $R2 $8
  1148.       ${EndIf}
  1149.  
  1150.       StrCpy $9 0 ; First loop
  1151.  
  1152.       ;Let's begin the search
  1153.  
  1154.       ${Do}
  1155.         ; Step 1: If the starting or ending numbers are negative
  1156.         ;         or more than AdvStrStr_StringLen, we return
  1157.         ;         error
  1158.  
  1159.         ${If} $R1 < 0
  1160.           StrCpy $R1 ``
  1161.           StrCpy $R2 ``
  1162.           StrCpy $R3 ``
  1163.           SetErrors ;AdvStrStr_StrToSearch not found
  1164.           Goto AdvStrStr_End
  1165.         ${ElseIf} $R2 > $7
  1166.           StrCpy $R1 ``
  1167.           StrCpy $R2 ``
  1168.           StrCpy $R3 ``
  1169.           SetErrors ;AdvStrStr_StrToSearch not found
  1170.           Goto AdvStrStr_End
  1171.         ${EndIf}
  1172.  
  1173.         ; Step 2: Start the search depending on
  1174.         ;         AdvStrStr_DirectionOfSearch. Chop down not needed
  1175.         ;         characters.
  1176.  
  1177.         ${If} $R1 <> 0
  1178.           StrCpy $R3 $0 `` $R1
  1179.         ${EndIf}
  1180.  
  1181.         ${If} $R2 <> $7
  1182.           ${If} $R1 = 0
  1183.             StrCpy $R3 $0 $8
  1184.           ${Else}
  1185.             StrCpy $R3 $R3 $8
  1186.           ${EndIf}
  1187.         ${EndIf}
  1188.  
  1189.         ; Step 3: Make sure that's the string we want
  1190.  
  1191.         ; Case-Sensitive Support <- Use "AdvStrStr_Temp"
  1192.         ; variable because it won't be used anymore
  1193.  
  1194.         ${If} $6 == 1
  1195.           System::Call `kernel32::lstrcmpA(ts, ts) i.s` `$R3` `$1`
  1196.           Pop $R3
  1197.           ${If} $R3 = 0
  1198.             StrCpy $R3 1 ; Continue
  1199.           ${Else}
  1200.             StrCpy $R3 0 ; Break
  1201.           ${EndIf}
  1202.         ${Else}
  1203.           ${If} $R3 == $1
  1204.             StrCpy $R3 1 ; Continue
  1205.           ${Else}
  1206.             StrCpy $R3 0 ; Break
  1207.           ${EndIf}
  1208.         ${EndIf}
  1209.  
  1210.         ; After the comparasion, confirm that it is the
  1211.         ; value we want.
  1212.  
  1213.         ${If} $R3 = 1
  1214.  
  1215.           ;We found it, return except if the user has set up to
  1216.           ;search for another one:
  1217.           ${If} $9 >= $5
  1218.  
  1219.             ;Now, let's see if the user wants
  1220.             ;AdvStrStr_StrToSearch to appear:
  1221.             ${If} $4 == 0
  1222.               ;Return depends on AdvStrStr_DirectionOfReturn
  1223.               ${If} $3 == <
  1224.                 ; RTL
  1225.                 StrCpy $R0 $0 $R1
  1226.               ${Else}
  1227.                 ; LTR
  1228.                 StrCpy $R0 $0 `` $R2
  1229.               ${EndIf}
  1230.               ${Break}
  1231.             ${Else}
  1232.               ;Return depends on AdvStrStr_DirectionOfReturn
  1233.               ${If} $3 == <
  1234.                 ; RTL
  1235.                 StrCpy $R0 $0 $R2
  1236.               ${Else}
  1237.                 ; LTR
  1238.                 StrCpy $R0 $0 `` $R1
  1239.               ${EndIf}
  1240.               ${Break}
  1241.             ${EndIf}
  1242.           ${Else}
  1243.             ;If the user wants to have more loops, let's do it so!
  1244.             IntOp $9 $9 + 1
  1245.  
  1246.             ${If} $2 == <
  1247.               IntOp $R1 $R1 - 1
  1248.               IntOp $R2 $R2 - 1
  1249.             ${Else}
  1250.               IntOp $R1 $R1 + 1
  1251.               IntOp $R2 $R2 + 1
  1252.             ${EndIf}
  1253.           ${EndIf}
  1254.         ${Else}
  1255.           ; Step 4: We didn't find it, so do steps 1 thru 3 again
  1256.  
  1257.           ${If} $2 == <
  1258.             IntOp $R1 $R1 - 1
  1259.             IntOp $R2 $R2 - 1
  1260.           ${Else}
  1261.             IntOp $R1 $R1 + 1
  1262.             IntOp $R2 $R2 + 1
  1263.           ${EndIf}
  1264.         ${EndIf}
  1265.       ${Loop}
  1266.  
  1267.       AdvStrStr_End:
  1268.  
  1269.       ;Add 1 to AdvStrStr_EndCharPos to be supportable
  1270.       ;by "StrCpy"
  1271.  
  1272.       IntOp $R2 $R2 - 1
  1273.  
  1274.       ;Return output to user
  1275.  
  1276.       Exch $R0
  1277.       Exch
  1278.       Pop $R1
  1279.       Exch
  1280.       Pop $R2
  1281.       Exch
  1282.       Pop $R3
  1283.       Exch
  1284.       Pop $9
  1285.       Exch
  1286.       Pop $8
  1287.       Exch
  1288.       Pop $7
  1289.       Exch
  1290.       Pop $6
  1291.       Exch
  1292.       Pop $5
  1293.       Exch
  1294.       Pop $4
  1295.       Exch
  1296.       Pop $3
  1297.       Exch
  1298.       Pop $2
  1299.       Exch
  1300.       Pop $1
  1301.       Exch
  1302.       Pop $0
  1303.  
  1304.     FunctionEnd
  1305.  
  1306.   !macroend
  1307.  
  1308.   # Function StrTok
  1309.   ###############
  1310.  
  1311.   !macro FUNCTION_STRING_StrTok
  1312.     !insertmacro STRFUNC_FUNC `StrTok` `2004 Diego Pedroso - Based on functions by "bigmac666"`
  1313.     /*After this point:
  1314.       ------------------------------------------
  1315.        $0 = SkipEmptyParts (input)
  1316.        $1 = ResultPart (input)
  1317.        $2 = Separators (input)
  1318.        $3 = String (input)
  1319.        $4 = StrToSearchLen (temp)
  1320.        $5 = StrLen (temp)
  1321.        $6 = StartCharPos (temp)
  1322.        $7 = TempStr (temp)
  1323.        $8 = CurrentLoop
  1324.        $9 = CurrentSepChar
  1325.        $R0 = CurrentSepCharNum
  1326.        */
  1327.  
  1328.       ;Get input from user
  1329.       Exch $0
  1330.       Exch
  1331.       Exch $1
  1332.       Exch
  1333.       Exch 2
  1334.       Exch $2
  1335.       Exch 2
  1336.       Exch 3
  1337.       Exch $3
  1338.       Exch 3
  1339.       Push $4
  1340.       Push $5
  1341.       Push $6
  1342.       Push $7
  1343.       Push $8
  1344.       Push $9
  1345.       Push $R0
  1346.  
  1347.       ;Parameter defaults
  1348.       ${IfThen} $2 == `` ${|} StrCpy $2 `|` ${|}
  1349.       ${IfThen} $1 == `` ${|} StrCpy $1 `L` ${|}
  1350.       ${IfThen} $0 == `` ${|} StrCpy $0 `0` ${|}
  1351.  
  1352.       ;Get "String" and "StrToSearch" length
  1353.       StrLen $4 $2
  1354.       StrLen $5 $3
  1355.       ;Start "StartCharPos" and "ResultPart" counters
  1356.       StrCpy $6 0
  1357.       StrCpy $8 -1
  1358.  
  1359.       ;Loop until "ResultPart" is met, "StrToSearch" is found or
  1360.       ;"String" reaches its end
  1361.       ResultPartLoop: ;"CurrentLoop" Loop
  1362.  
  1363.         ;Increase "CurrentLoop" counter
  1364.         IntOp $8 $8 + 1
  1365.  
  1366.         StrSearchLoop:
  1367.         ${Do} ;"String" Loop
  1368.           ;Remove everything before and after the searched part ("TempStr")
  1369.           StrCpy $7 $3 1 $6
  1370.  
  1371.           ;Verify if it's the "String" end
  1372.           ${If} $6 >= $5
  1373.             ;If "CurrentLoop" is what the user wants, remove the part
  1374.             ;after "TempStr" and itself and get out of here
  1375.             ${If} $8 == $1
  1376.             ${OrIf} $1 == `L`
  1377.               StrCpy $3 $3 $6
  1378.             ${Else} ;If not, empty "String" and get out of here
  1379.               StrCpy $3 ``
  1380.             ${EndIf}
  1381.             StrCpy $R0 `End`
  1382.             ${ExitDo}
  1383.           ${EndIf}
  1384.  
  1385.           ;Start "CurrentSepCharNum" counter (for "Separators" Loop)
  1386.           StrCpy $R0 0
  1387.  
  1388.           ${Do} ;"Separators" Loop
  1389.             ;Use one "Separators" character at a time
  1390.             ${If} $R0 <> 0
  1391.               StrCpy $9 $2 1 $R0
  1392.             ${Else}
  1393.               StrCpy $9 $2 1
  1394.             ${EndIf}
  1395.  
  1396.             ;Go to the next "String" char if it's "Separators" end
  1397.             ${IfThen} $R0 >= $4 ${|} ${ExitDo} ${|}
  1398.  
  1399.             ;Or, if "TempStr" equals "CurrentSepChar", then...
  1400.             ${If} $7 == $9
  1401.               StrCpy $7 $3 $6
  1402.  
  1403.               ;If "String" is empty because this result part doesn't
  1404.               ;contain data, verify if "SkipEmptyParts" is activated,
  1405.               ;so we don't return the output to user yet
  1406.  
  1407.               ${If} $7 == ``
  1408.               ${AndIf} $0 = ${TRUE}
  1409.                 IntOp $6 $6 + 1
  1410.                 StrCpy $3 $3 `` $6
  1411.                 StrCpy $6 0
  1412.                 Goto StrSearchLoop
  1413.               ${ElseIf} $8 == $1
  1414.                 StrCpy $3 $3 $6
  1415.                 StrCpy $R0 "End"
  1416.                 ${ExitDo}
  1417.               ${EndIf} ;If not, go to the next result part
  1418.               IntOp $6 $6 + 1
  1419.               StrCpy $3 $3 `` $6
  1420.               StrCpy $6 0
  1421.               Goto ResultPartLoop
  1422.             ${EndIf}
  1423.  
  1424.             ;Increase "CurrentSepCharNum" counter
  1425.             IntOp $R0 $R0 + 1
  1426.           ${Loop}
  1427.           ${IfThen} $R0 == "End" ${|} ${ExitDo} ${|}
  1428.           
  1429.           ;Increase "StartCharPos" counter
  1430.           IntOp $6 $6 + 1
  1431.         ${Loop}
  1432.  
  1433.     /*After this point:
  1434.       ------------------------------------------
  1435.        $3 = OutVar (output)*/
  1436.  
  1437.       ;Return output to user
  1438.  
  1439.       Pop $R0
  1440.       Pop $9
  1441.       Pop $8
  1442.       Pop $7
  1443.       Pop $6
  1444.       Pop $5
  1445.       Pop $4
  1446.       Pop $0
  1447.       Pop $1
  1448.       Pop $2
  1449.       Exch $3
  1450.     FunctionEnd
  1451.  
  1452.   !macroend
  1453.  
  1454.   # Function StrTrimNewLines
  1455.   ########################
  1456.  
  1457.   !macro FUNCTION_STRING_StrTrimNewLines
  1458.     !insertmacro STRFUNC_FUNC `StrTrimNewLines` `2004 Diego Pedroso - Based on functions by Ximon Eighteen`
  1459.  
  1460.     /*After this point:
  1461.       ------------------------------------------
  1462.        $R0 = String (input)
  1463.        $R1 = TrimCounter (temp)
  1464.        $R2 = Temp (temp)*/
  1465.  
  1466.       ;Get input from user
  1467.       Exch $R0
  1468.       Push $R1
  1469.       Push $R2
  1470.       
  1471.       ;Initialize trim counter
  1472.       StrCpy $R1 0
  1473.  
  1474.       loop:
  1475.         ;Subtract to get "String"'s last characters
  1476.         IntOp $R1 $R1 - 1
  1477.  
  1478.         ;Verify if they are either $\r or $\n
  1479.         StrCpy $R2 $R0 1 $R1
  1480.         ${If} $R2 == `$\r`
  1481.         ${OrIf} $R2 == `$\n`
  1482.           Goto loop
  1483.         ${EndIf}
  1484.  
  1485.       ;Trim characters (if needed)
  1486.       IntOp $R1 $R1 + 1
  1487.       ${If} $R1 < 0
  1488.         StrCpy $R0 $R0 $R1
  1489.       ${EndIf}
  1490.  
  1491.     /*After this point:
  1492.       ------------------------------------------
  1493.        $R0 = OutVar (output)*/
  1494.  
  1495.       ;Return output to user
  1496.       Pop $R2
  1497.       Pop $R1
  1498.       Exch $R0
  1499.     FunctionEnd
  1500.  
  1501.   !macroend
  1502.  
  1503.   ;Function Calls for Install and Uninstall
  1504.  
  1505.   !macro FUNCTION_STRING_StrCase_Call ResultVar String Type
  1506.     !verbose push
  1507.     !verbose 4
  1508.     !echo `$ {StrCase} "${ResultVar}" "${String}" "${Type}"`
  1509.     !verbose pop
  1510.  
  1511.     Push `${String}`
  1512.     Push `${Type}`
  1513.     Call StrCase
  1514.     Pop `${ResultVar}`
  1515.   !macroend
  1516.   !macro FUNCTION_STRING_UnStrCase_Call ResultVar String Type
  1517.     !verbose push
  1518.     !verbose 4
  1519.     !echo `$ {UnStrCase} "${ResultVar}" "${String}" "${Type}"`
  1520.     !verbose pop
  1521.  
  1522.     Push `${String}`
  1523.     Push `${Type}`
  1524.     Call un.StrCase
  1525.     Pop `${ResultVar}`
  1526.   !macroend
  1527.  
  1528.   !macro FUNCTION_STRING_StrClb_Call ResultVar String Action
  1529.     !verbose push
  1530.     !verbose 4
  1531.     !echo `$ {StrClb} "${ResultVar}" "${String}" "${Action}"`
  1532.     !verbose pop
  1533.  
  1534.     Push `${String}`
  1535.     Push `${Action}`
  1536.     Call StrClb
  1537.     Pop `${ResultVar}`
  1538.   !macroend
  1539.   !macro FUNCTION_STRING_UnStrClb_Call ResultVar String Action
  1540.     !verbose push
  1541.     !verbose 4
  1542.     !echo `$ {UnStrClb} "${ResultVar}" "${String}" "${Action}"`
  1543.     !verbose pop
  1544.  
  1545.     Push `${String}`
  1546.     Push `${Action}`
  1547.     Call un.StrClb
  1548.     Pop `${ResultVar}`
  1549.   !macroend
  1550.  
  1551.   !macro FUNCTION_STRING_StrIOToNSIS_Call ResultVar String
  1552.     !verbose push
  1553.     !verbose 4
  1554.     !echo `$ {StrIOToNSIS} "${ResultVar}" "${String}"`
  1555.     !verbose pop
  1556.  
  1557.     Push `${String}`
  1558.     Call StrIOToNSIS
  1559.     Pop `${ResultVar}`
  1560.   !macroend
  1561.   !macro FUNCTION_STRING_UnStrIOToNSIS_Call ResultVar String
  1562.     !verbose push
  1563.     !verbose 4
  1564.     !echo `$ {UnStrIOToNSIS} "${ResultVar}" "${String}"`
  1565.     !verbose pop
  1566.  
  1567.     Push `${String}`
  1568.     Call un.StrIOToNSIS
  1569.     Pop `${ResultVar}`
  1570.   !macroend
  1571.  
  1572.   !macro FUNCTION_STRING_StrLoc_Call ResultVar String StrToSearchFor OffsetDirection
  1573.     !verbose push
  1574.     !verbose 4
  1575.     !echo `$ {StrLoc} "${ResultVar}" "${String}" "${StrToSearchFor}" "${OffsetDirection}"`
  1576.     !verbose pop
  1577.  
  1578.     Push `${String}`
  1579.     Push `${StrToSearchFor}`
  1580.     Push `${OffsetDirection}`
  1581.     Call StrLoc
  1582.     Pop `${ResultVar}`
  1583.   !macroend
  1584.   !macro FUNCTION_STRING_UnStrLoc_Call ResultVar String StrToSearchFor OffsetDirection
  1585.     !verbose push
  1586.     !verbose 4
  1587.     !echo `$ {UnStrLoc} "${ResultVar}" "${String}" "${StrToSearchFor}" "${OffsetDirection}"`
  1588.     !verbose pop
  1589.  
  1590.     Push `${String}`
  1591.     Push `${StrToSearchFor}`
  1592.     Push `${OffsetDirection}`
  1593.     Call un.StrLoc
  1594.     Pop `${ResultVar}`
  1595.   !macroend
  1596.  
  1597.   !macro FUNCTION_STRING_StrNSISToIO_Call ResultVar String
  1598.     !verbose push
  1599.     !verbose 4
  1600.     !echo `$ {StrNSISToIO} "${ResultVar}" "${String}"`
  1601.     !verbose pop
  1602.  
  1603.     Push `${String}`
  1604.     Call StrNSISToIO
  1605.     Pop `${ResultVar}`
  1606.   !macroend
  1607.   !macro FUNCTION_STRING_UnStrNSISToIO_Call ResultVar String
  1608.     !verbose push
  1609.     !verbose 4
  1610.     !echo `$ {UnStrNSISToIO} "${ResultVar}" "${String}"`
  1611.     !verbose pop
  1612.  
  1613.     Push `${String}`
  1614.     Call un.StrNSISToIO
  1615.     Pop `${ResultVar}`
  1616.   !macroend
  1617.  
  1618.   !macro FUNCTION_STRING_StrRep_Call ResultVar String StringToReplace ReplacementString
  1619.     !verbose push
  1620.     !verbose 4
  1621.     !echo `$ {StrRep} "${ResultVar}" "${String}" "${StringToReplace}" "${ReplacementString}"`
  1622.     !verbose pop
  1623.  
  1624.     Push `${String}`
  1625.     Push `${StringToReplace}`
  1626.     Push `${ReplacementString}`
  1627.     Call StrRep
  1628.     Pop `${ResultVar}`
  1629.   !macroend
  1630.   !macro FUNCTION_STRING_UnStrRep_Call ResultVar String StringToReplace ReplacementString
  1631.     !verbose push
  1632.     !verbose 4
  1633.     !echo `$ {UnStrRep} "${ResultVar}" "${String}" "${StringToReplace}" "${ReplacementString}"`
  1634.     !verbose pop
  1635.  
  1636.     Push `${String}`
  1637.     Push `${StringToReplace}`
  1638.     Push `${ReplacementString}`
  1639.     Call un.StrRep
  1640.     Pop `${ResultVar}`
  1641.   !macroend
  1642.  
  1643.   !macro FUNCTION_STRING_StrSort_Call ResultVar String CenterStr LeftStr RightStr IncludeCenterStr IncludeLeftStr IncludeRightStr
  1644.     !verbose push
  1645.     !verbose 4
  1646.     !echo `$ {StrSort} "${ResultVar}" "${String}" "${CenterStr}" "${LeftStr}" "${RightStr}" "${IncludeCenterStr}" "${IncludeLeftStr}" "${IncludeRightStr}"`
  1647.     !verbose pop
  1648.  
  1649.     Push `${String}`
  1650.     Push `${CenterStr}`
  1651.     Push `${LeftStr}`
  1652.     Push `${RightStr}`
  1653.     Push `${IncludeCenterStr}`
  1654.     Push `${IncludeLeftStr}`
  1655.     Push `${IncludeRightStr}`
  1656.     Call StrSort
  1657.     Pop `${ResultVar}`
  1658.   !macroend
  1659.   !macro FUNCTION_STRING_UnStrSort_Call ResultVar String CenterStr LeftStr RightStr IncludeCenterStr IncludeLeftStr IncludeRightStr
  1660.     !verbose push
  1661.     !verbose 4
  1662.     !echo `$ {UnStrSort} "${ResultVar}" "${String}" "${CenterStr}" "${LeftStr}" "${RightStr}" "${IncludeCenterStr}" "${IncludeLeftStr}" "${IncludeRightStr}"`
  1663.     !verbose pop
  1664.  
  1665.     Push `${String}`
  1666.     Push `${CenterStr}`
  1667.     Push `${LeftStr}`
  1668.     Push `${RightStr}`
  1669.     Push `${IncludeCenterStr}`
  1670.     Push `${IncludeLeftStr}`
  1671.     Push `${IncludeRightStr}`
  1672.     Call un.StrSort
  1673.     Pop `${ResultVar}`
  1674.   !macroend
  1675.  
  1676.   !macro FUNCTION_STRING_StrStr_Call ResultVar String StrToSearchFor
  1677.     !verbose push
  1678.     !verbose 4
  1679.     !echo `$ {StrStr} "${ResultVar}" "${String}" "${StrToSearchFor}"`
  1680.     !verbose pop
  1681.  
  1682.     Push `${String}`
  1683.     Push `${StrToSearchFor}`
  1684.     Call StrStr
  1685.     Pop `${ResultVar}`
  1686.   !macroend
  1687.   !macro FUNCTION_STRING_UnStrStr_Call ResultVar String StrToSearchFor
  1688.     !verbose push
  1689.     !verbose 4
  1690.     !echo `$ {UnStrStr} "${ResultVar}" "${String}" "${StrToSearchFor}"`
  1691.     !verbose pop
  1692.  
  1693.     Push `${String}`
  1694.     Push `${StrToSearchFor}`
  1695.     Call un.StrStr
  1696.     Pop `${ResultVar}`
  1697.   !macroend
  1698.  
  1699.   !macro FUNCTION_STRING_StrStrAdv_Call ResultVar String StrToSearchFor SearchDirection ResultStrDirection DisplayStrToSearch Loops CaseSensitive
  1700.     !verbose push
  1701.     !verbose 4
  1702.     !echo `$ {StrStrAdv} "${ResultVar}" "${String}" "${StrToSearchFor}" "${SearchDirection}" "${ResultStrDirection}" "${DisplayStrToSearch}" "${Loops}" "${CaseSensitive}"`
  1703.     !verbose pop
  1704.  
  1705.     Push `${String}`
  1706.     Push `${StrToSearchFor}`
  1707.     Push `${SearchDirection}`
  1708.     Push `${ResultStrDirection}`
  1709.     Push `${DisplayStrToSearch}`
  1710.     Push `${Loops}`
  1711.     Push `${CaseSensitive}`
  1712.     Call StrStrAdv
  1713.     Pop `${ResultVar}`
  1714.   !macroend
  1715.   !macro FUNCTION_STRING_UnStrStrAdv_Call ResultVar String StrToSearchFor SearchDirection ResultStrDirection DisplayStrToSearch Loops CaseSensitive
  1716.     !verbose push
  1717.     !verbose 4
  1718.     !echo `$ {UnStrStrAdv} "${ResultVar}" "${String}" "${StrToSearchFor}" "${SearchDirection}" "${ResultStrDirection}" "${DisplayStrToSearch}" "${Loops}" "${CaseSensitive}"`
  1719.     !verbose pop
  1720.  
  1721.     Push `${String}`
  1722.     Push `${StrToSearchFor}`
  1723.     Push `${SearchDirection}`
  1724.     Push `${ResultStrDirection}`
  1725.     Push `${DisplayStrToSearch}`
  1726.     Push `${Loops}`
  1727.     Push `${CaseSensitive}`
  1728.     Call un.StrStrAdv
  1729.     Pop `${ResultVar}`
  1730.   !macroend
  1731.  
  1732.   !macro FUNCTION_STRING_StrTok_Call ResultVar String Separators ResultPart SkipEmptyParts
  1733.     !verbose push
  1734.     !verbose 4
  1735.     !echo `$ {StrTok} "${ResultVar}" "${String}" "${Separators}" "${ResultPart}" "${SkipEmptyParts}"`
  1736.     !verbose pop
  1737.  
  1738.     Push `${String}`
  1739.     Push `${Separators}`
  1740.     Push `${ResultPart}`
  1741.     Push `${SkipEmptyParts}`
  1742.     Call StrTok
  1743.     Pop `${ResultVar}`
  1744.   !macroend
  1745.   !macro FUNCTION_STRING_UnStrTok_Call ResultVar String Separators ResultPart SkipEmptyParts
  1746.     !verbose push
  1747.     !verbose 4
  1748.     !echo `$ {UnStrTok} "${ResultVar}" "${String}" "${Separators}" "${ResultPart}" "${SkipEmptyParts}"`
  1749.     !verbose pop
  1750.  
  1751.     Push `${String}`
  1752.     Push `${Separators}`
  1753.     Push `${ResultPart}`
  1754.     Push `${SkipEmptyParts}`
  1755.     Call un.StrTok
  1756.     Pop `${ResultVar}`
  1757.   !macroend
  1758.  
  1759.   !macro FUNCTION_STRING_StrTrimNewLines_Call ResultVar String
  1760.     !verbose push
  1761.     !verbose 4
  1762.     !echo `$ {StrTrimNewLines} "${ResultVar}" "${String}"`
  1763.     !verbose pop
  1764.  
  1765.     Push `${String}`
  1766.     Call StrTrimNewLines
  1767.     Pop `${ResultVar}`
  1768.   !macroend
  1769.   !macro FUNCTION_STRING_UnStrTrimNewLines_Call ResultVar String
  1770.     !verbose push
  1771.     !verbose 4
  1772.     !echo `$ {UnStrTrimNewLines} "${ResultVar}" "${String}"`
  1773.     !verbose pop
  1774.  
  1775.     Push `${String}`
  1776.     Call un.StrTrimNewLines
  1777.     Pop `${ResultVar}`
  1778.   !macroend
  1779.  
  1780. !endif
  1781. !verbose 3
  1782. !define STRFUNC_VERBOSITY ${_STRFUNC_VERBOSITY}
  1783. !undef _STRFUNC_VERBOSITY
  1784. !verbose pop
  1785.