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