Statistiques
| Révision :

root / tmp / org.txm.setups / nsis / Include / StrFunc.nsh @ 3088

Historique | Voir | Annoter | Télécharger (43,42 ko)

1
/*
2
o-----------------------------------------------------------------------------o
3
|String Functions Header File 1.10                                            |
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 3
13
!define /IfNDef STRFUNC_VERBOSITY 3
14
!define /IfNDef _STRFUNC_VERBOSITY ${STRFUNC_VERBOSITY}
15
!define /IfNDef _STRFUNC_CREDITVERBOSITY ${STRFUNC_VERBOSITY}
16
!undef STRFUNC_VERBOSITY
17
!verbose ${_STRFUNC_VERBOSITY}
18

    
19
!include LogicLib.nsh
20

    
21
!ifndef STRFUNC
22

    
23
  !define /IfNDef FALSE 0
24
  !define /IfNDef TRUE 1
25

    
26
  ;Header File Identification
27

    
28
  !define STRFUNC `String Functions Header File`
29
  ;define STRFUNC_SHORT `StrFunc`
30
  !define STRFUNC_CREDITS `2004 Diego Pedroso`
31

    
32
  ;Header File Version
33

    
34
  !define STRFUNC_VERMAJ 1
35
  !define STRFUNC_VERMED 10
36
 ;!define STRFUNC_VERMIN 0
37
 ;!define STRFUNC_VERBLD 0
38

    
39
  !define STRFUNC_VER `${STRFUNC_VERMAJ}.${STRFUNC_VERMED}`
40

    
41
  ;Header File Init Message Prefix and Postfix
42

    
43
  !define STRFUNC_INITMSGPRE `----------------------------------------------------------------------$\r$\n`
44
  !define STRFUNC_INITMSGPOST `$\r$\n----------------------------------------------------------------------$\r$\n`
45

    
46
  ;Header File Init Message
47

    
48
  !verbose push ${_STRFUNC_CREDITVERBOSITY}
49
  !echo `${STRFUNC_INITMSGPRE}NSIS ${STRFUNC} ${STRFUNC_VER} - Copyright ${STRFUNC_CREDITS}${STRFUNC_INITMSGPOST}`
50
  !verbose pop
51

    
52
  ;Header File Function Macros
53

    
54
  !ifdef STRFUNC_USECALLARTIFICIALFUNCTION
55
    !include Util.nsh
56
  !endif
57

    
58
  !define "Using:StrFunc" `!insertmacro STRFUNC_USING `
59
  !macro STRFUNC_USING Name
60
    !if "${STRFUNC_VERBOSITY}" > 4
61
      !verbose push 4
62
    !endif
63
    !ifndef ${Name}_INCLUDED
64
      ${${Name}} ; Invoke !insertmacro STRFUNC_MAKEFUNC
65
    !endif
66
    !if "${STRFUNC_VERBOSITY}" > 4
67
      !verbose pop
68
    !endif
69
  !macroend
70

    
71
  !macro STRFUNC_FUNCLIST_INSERT Name
72
    !ifdef StrFunc_List
73
      !define /ReDef StrFunc_List `${StrFunc_List}|${Name}`
74
    !else
75
      !define StrFunc_List `${Name}`
76
    !endif
77
  !macroend
78

    
79
  !macro STRFUNC_DEFFUNC Name List TypeList
80
    !insertmacro STRFUNC_FUNCLIST_INSERT ${Name}
81
    !define `${Name}_List` `${List}`
82
    !define `${Name}_TypeList` `${TypeList}`
83
    !ifdef STRFUNC_USECALLARTIFICIALFUNCTION
84
      !define `${Name}` `!insertmacro STRFUNC_CALL_${Name} "${un}" `
85
      !define `Un${Name}` `!insertmacro STRFUNC_CALL_${Name} "${un}" `
86
    !else
87
      !define `${Name}` `!insertmacro STRFUNC_MAKEFUNC ${Name} ""`
88
      !define `Un${Name}` `!insertmacro STRFUNC_MAKEFUNC ${Name} Un`
89
    !endif
90
  !macroend
91

    
92
  !macro STRFUNC_MAKEFUNC basename un
93
    !insertmacro STRFUNC_MAKEFUNC_${basename}
94
  !macroend
95

    
96
  !macro STRFUNC_BEGINFUNC basename un credits
97
    !verbose push ${_STRFUNC_CREDITVERBOSITY}
98
    !echo `${U+24}{${un}${basename}} - Copyright ${credits}`
99
    !verbose pop
100
    !define ${un}${basename}_INCLUDED
101
    !ifndef STRFUNC_USECALLARTIFICIALFUNCTION
102
      !define /ReDef ${un}${basename} `!insertmacro STRFUNC_CALL_${basename} "${un}" `
103
      !if "${un}" != ""
104
        Function un.${basename}
105
      !else
106
        Function ${basename}
107
      !endif
108
    !endif
109
  !macroend
110
  !macro STRFUNC_ENDFUNC
111
    !ifndef STRFUNC_USECALLARTIFICIALFUNCTION
112
      FunctionEnd
113
    !endif
114
  !macroend
115

    
116
  !macro STRFUNC_CALL basename un
117
    !ifdef STRFUNC_USECALLARTIFICIALFUNCTION
118
      ${CallArtificialFunction} STRFUNC_MAKEFUNC_${basename}
119
    !else
120
      !if "${un}" != ""
121
        Call un.${basename}
122
      !else
123
        Call ${basename}
124
      !endif
125
    !endif
126
  !macroend
127

    
128

    
129
  ############################################################################  
130
  # StrCase
131
  !insertmacro STRFUNC_DEFFUNC StrCase `ResultVar|String|Type` `Output|Text|Option  U L T S <>`
132

    
133
  !macro STRFUNC_CALL_StrCase un ResultVar String Type
134
    !verbose push ${STRFUNC_VERBOSITY}
135
    !echo `${U+24}{${un}StrCase} "${ResultVar}" "${String}" "${Type}"`
136
    !verbose 2
137
    Push `${String}`
138
    Push `${Type}`
139
    !insertmacro STRFUNC_CALL StrCase "${un}"
140
    Pop ${ResultVar}
141
    !verbose pop
142
  !macroend
143

    
144
  !macro STRFUNC_MAKEFUNC_StrCase
145
    !insertmacro STRFUNC_BEGINFUNC ${basename} `${un}` `2004 Diego Pedroso - Based on functions by Dave Laundon`
146
    /*After this point:
147
      ------------------------------------------
148
       $0 = String (input)
149
       $1 = Type (input)
150
       $2 = StrLength (temp)
151
       $3 = StartChar (temp)
152
       $4 = EndChar (temp)
153
       $5 = ResultStr (temp)
154
       $6 = CurrentChar (temp)
155
       $7 = LastChar (temp)
156
       $8 = Temp (temp)*/
157

    
158
      ;Get input from user
159
      Exch $1
160
      Exch
161
      Exch $0
162
      Exch
163
      Push $2
164
      Push $3
165
      Push $4
166
      Push $5
167
      Push $6
168
      Push $7
169
      Push $8
170

    
171
      ;Initialize variables
172
      StrCpy $2 ""
173
      StrCpy $3 ""
174
      StrCpy $4 ""
175
      StrCpy $5 ""
176
      StrCpy $6 ""
177
      StrCpy $7 ""
178
      StrCpy $8 ""
179

    
180
      ;Upper and lower cases are simple to use
181
      ${If} $1 == "U"
182

    
183
        ;Upper Case System:
184
        ;------------------
185
        ; Convert all characters to upper case.
186

    
187
        System::Call "User32::CharUpper(t r0 r5)i"
188
        Goto StrCase_End
189
      ${ElseIf} $1 == "L"
190

    
191
        ;Lower Case System:
192
        ;------------------
193
        ; Convert all characters to lower case.
194

    
195
        System::Call "User32::CharLower(t r0 r5)i"
196
        Goto StrCase_End
197
      ${EndIf}
198

    
199
      ;For the rest of cases:
200
      ;Get "String" length
201
      StrLen $2 $0
202

    
203
      ;Make a loop until the end of "String"
204
      ${For} $3 0 $2
205
        ;Add 1 to "EndChar" counter also
206
        IntOp $4 $3 + 1
207

    
208
        # Step 1: Detect one character at a time
209

    
210
        ;Remove characters before "StartChar" except when
211
        ;"StartChar" is the first character of "String"
212
        ${If} $3 <> 0
213
          StrCpy $6 $0 `` $3
214
        ${EndIf}
215

    
216
        ;Remove characters after "EndChar" except when
217
        ;"EndChar" is the last character of "String"
218
        ${If} $4 <> $2
219
          ${If} $3 = 0
220
            StrCpy $6 $0 1
221
          ${Else}
222
            StrCpy $6 $6 1
223
          ${EndIf}
224
        ${EndIf}
225

    
226
        # Step 2: Convert to the advanced case user chose:
227

    
228
        ${If} $1 == "T"
229

    
230
          ;Title Case System:
231
          ;------------------
232
          ; Convert all characters after a non-alphabetic character to upper case.
233
          ; Else convert to lower case.
234

    
235
          ;Use "IsCharAlpha" for the job
236
          System::Call "*(&t1 r7) p .r8"
237
          System::Call "*$8(&i1 .r7)"
238
          System::Free $8
239
          System::Call "user32::IsCharAlpha(i r7) i .r8"
240
          
241
          ;Verify "IsCharAlpha" result and convert the character
242
          ${If} $8 = 0
243
            System::Call "User32::CharUpper(t r6 r6)i"
244
          ${Else}
245
            System::Call "User32::CharLower(t r6 r6)i"
246
          ${EndIf}
247
        ${ElseIf} $1 == "S"
248

    
249
          ;Sentence Case System:
250
          ;------------------
251
          ; Convert all characters after a ".", "!" or "?" character to upper case.
252
          ; Else convert to lower case. Spaces or tabs after these marks are ignored.
253

    
254
          ;Detect current characters and ignore if necessary
255
          ${If} $6 == " "
256
          ${OrIf} $6 == "$\t"
257
            Goto IgnoreLetter
258
          ${EndIf}
259

    
260
          ;Detect last characters and convert
261
          ${If} $7 == "."
262
          ${OrIf} $7 == "!"
263
          ${OrIf} $7 == "?"
264
          ${OrIf} $7 == ""
265
            System::Call "User32::CharUpper(t r6 r6)i"
266
          ${Else}
267
            System::Call "User32::CharLower(t r6 r6)i"
268
          ${EndIf}
269
        ${ElseIf} $1 == "<>"
270

    
271
          ;Switch Case System:
272
          ;------------------
273
          ; Switch all characters cases to their inverse case.
274

    
275
          ;Use "IsCharUpper" for the job
276
          System::Call "*(&t1 r6) p .r8"
277
          System::Call "*$8(&i1 .r7)"
278
          System::Free $8
279
          System::Call "user32::IsCharUpper(i r7) i .r8"
280
          
281
          ;Verify "IsCharUpper" result and convert the character
282
          ${If} $8 = 0
283
            System::Call "User32::CharUpper(t r6 r6)i"
284
          ${Else}
285
            System::Call "User32::CharLower(t r6 r6)i"
286
          ${EndIf}
287
        ${EndIf}
288

    
289
        ;Write the character to "LastChar"
290
        StrCpy $7 $6
291

    
292
        IgnoreLetter:
293
        ;Add this character to "ResultStr"
294
        StrCpy $5 `$5$6`
295
      ${Next}
296

    
297
      StrCase_End:
298

    
299
    /*After this point:
300
      ------------------------------------------
301
       $0 = OutVar (output)*/
302

    
303
      ; Copy "ResultStr" to "OutVar"
304
      StrCpy $0 $5
305

    
306
      ;Return output to user
307
      Pop $8
308
      Pop $7
309
      Pop $6
310
      Pop $5
311
      Pop $4
312
      Pop $3
313
      Pop $2
314
      Pop $1
315
      Exch $0
316
    !insertmacro STRFUNC_ENDFUNC
317

    
318
  !macroend
319

    
320
  ############################################################################  
321
  # StrClb
322
  !insertmacro STRFUNC_DEFFUNC StrClb `ResultVar|String|Action` `Output|Text|Option  > < <>`
323

    
324
  !macro STRFUNC_CALL_StrClb un ResultVar String Action
325
    !verbose push ${STRFUNC_VERBOSITY}
326
    !echo `${U+24}{${un}StrClb} "${ResultVar}" "${String}" "${Action}"`
327
    !verbose 2
328
    Push `${String}`
329
    Push `${Action}`
330
    !insertmacro STRFUNC_CALL StrClb "${un}"
331
    Pop ${ResultVar}
332
    !verbose pop
333
  !macroend
334

    
335
  !macro STRFUNC_MAKEFUNC_StrClb
336
    !insertmacro STRFUNC_BEGINFUNC ${basename} `${un}` `2004 Diego Pedroso - Based on functions by Nik Medved`
337

    
338
    /*After this point:
339
      ------------------------------------------
340
       $0 = String (input)
341
       $1 = Action (input)
342
       $2 = Lock/Unlock (temp)
343
       $3 = Temp (temp)
344
       $4 = Temp2 (temp)*/
345

    
346
      ;Get input from user
347

    
348
      Exch $1
349
      Exch
350
      Exch $0
351
      Exch
352
      Push $2
353
      Push $3
354
      Push $4
355
      
356
      StrCpy $2 ""
357
      StrCpy $3 ""
358
      StrCpy $4 ""
359

    
360
      ;Open the clipboard to do the operations the user chose (kichik's fix)
361
      System::Call 'user32::OpenClipboard(p $HWNDPARENT)'
362

    
363
      ${If} $1 == ">" ;Set
364

    
365
        ;Step 1: Clear the clipboard
366
        System::Call 'user32::EmptyClipboard()'
367

    
368
        ;Step 2: Allocate global heap
369
        StrLen $2 $0
370
        IntOp $2 $2 + 1
371
        IntOp $2 $2 * ${NSIS_CHAR_SIZE}
372
        System::Call 'kernel32::GlobalAlloc(i 2, i r2) p.r2'
373

    
374
        ;Step 3: Lock the handle
375
        System::Call 'kernel32::GlobalLock(p r2) i.r3'
376

    
377
        ;Step 4: Copy the text to locked clipboard buffer
378
        System::Call 'kernel32::lstrcpy(p r3, t r0)'
379

    
380
        ;Step 5: Unlock the handle again
381
        System::Call 'kernel32::GlobalUnlock(p r2)'
382

    
383
        ;Step 6: Set the information to the clipboard
384
        System::Call 'user32::SetClipboardData(i 1, p r2)'
385

    
386
        StrCpy $0 ""
387

    
388
      ${ElseIf} $1 == "<" ;Get
389

    
390
        ;Step 1: Get clipboard data
391
        System::Call 'user32::GetClipboardData(i 1) p .r2'
392

    
393
        ;Step 2: Lock and copy data (kichik's fix)
394
        System::Call 'kernel32::GlobalLock(p r2) t .r0'
395

    
396
        ;Step 3: Unlock (kichik's fix)
397
        System::Call 'kernel32::GlobalUnlock(p r2)'
398

    
399
      ${ElseIf} $1 == "<>" ;Swap
400

    
401
        ;Step 1: Get clipboard data
402
        System::Call 'user32::GetClipboardData(i 1) p .r2'
403

    
404
        ;Step 2: Lock and copy data (kichik's fix)
405
        System::Call 'kernel32::GlobalLock(p r2) t .r4'
406

    
407
        ;Step 3: Unlock (kichik's fix)
408
        System::Call 'kernel32::GlobalUnlock(p r2)'
409

    
410
        ;Step 4: Clear the clipboard
411
        System::Call 'user32::EmptyClipboard()'
412

    
413
        ;Step 5: Allocate global heap
414
        StrLen $2 $0
415
        IntOp $2 $2 + 1
416
        IntOp $2 $2 * ${NSIS_CHAR_SIZE}
417
        System::Call 'kernel32::GlobalAlloc(i 2, i r2) p.r2'
418

    
419
        ;Step 6: Lock the handle
420
        System::Call 'kernel32::GlobalLock(p r2) i.r3'
421

    
422
        ;Step 7: Copy the text to locked clipboard buffer
423
        System::Call 'kernel32::lstrcpy(p r3, t r0)'
424

    
425
        ;Step 8: Unlock the handle again
426
        System::Call 'kernel32::GlobalUnlock(p r2)'
427

    
428
        ;Step 9: Set the information to the clipboard
429
        System::Call 'user32::SetClipboardData(i 1, p r2)'
430
        
431
        StrCpy $0 $4
432
      ${Else} ;Clear
433

    
434
        ;Step 1: Clear the clipboard
435
        System::Call 'user32::EmptyClipboard()'
436

    
437
        StrCpy $0 ""
438
      ${EndIf}
439

    
440
      ;Close the clipboard
441
      System::Call 'user32::CloseClipboard()'
442

    
443
    /*After this point:
444
      ------------------------------------------
445
       $0 = OutVar (output)*/
446

    
447
      ;Return result to user
448
      Pop $4
449
      Pop $3
450
      Pop $2
451
      Pop $1
452
      Exch $0
453
    !insertmacro STRFUNC_ENDFUNC
454

    
455
  !macroend
456

    
457
  ############################################################################  
458
  # StrIOToNSIS
459
  !insertmacro STRFUNC_DEFFUNC StrIOToNSIS `ResultVar|String` `Output|Text`
460

    
461
  !macro STRFUNC_CALL_StrIOToNSIS un ResultVar String
462
    !verbose push ${STRFUNC_VERBOSITY}
463
    !echo `${U+24}{${un}StrIOToNSIS} "${ResultVar}" "${String}"`
464
    !verbose 2
465
    Push `${String}`
466
    !insertmacro STRFUNC_CALL StrIOToNSIS "${un}"
467
    Pop ${ResultVar}
468
    !verbose pop
469
  !macroend
470

    
471
  !macro STRFUNC_MAKEFUNC_StrIOToNSIS
472
    !insertmacro STRFUNC_BEGINFUNC ${basename} `${un}` `2004 "bluenet" - Based on functions by Amir Szekely, Joost Verburg, Dave Laundon and Diego Pedroso`
473

    
474
    /*After this point:
475
      ------------------------------------------
476
       $R0 = String (input/output)
477
       $R1 = StartCharPos (temp)
478
       $R2 = StrLen (temp)
479
       $R3 = TempStr (temp)
480
       $R4 = TempRepStr (temp)*/
481

    
482
      ;Get input from user
483
      Exch $R0
484
      Push $R1
485
      Push $R2
486
      Push $R3
487
      Push $R4
488
      
489
      ;Get "String" length
490
      StrLen $R2 $R0
491

    
492
      ;Loop until "String" end is reached
493
      ${For} $R1 0 $R2
494
        ;Get the next "String" characters
495
        StrCpy $R3 $R0 2 $R1
496
        
497
        ;Detect if current character is:
498
        ${If} $R3 == "\\" ;Back-slash
499
          StrCpy $R4 "\"
500
        ${ElseIf} $R3 == "\r" ;Carriage return
501
          StrCpy $R4 "$\r"
502
        ${ElseIf} $R3 == "\n" ;Line feed
503
          StrCpy $R4 "$\n"
504
        ${ElseIf} $R3 == "\t" ;Tab
505
          StrCpy $R4 "$\t"
506
        ${Else} ;Anything else
507
          StrCpy $R4 ""
508
        ${EndIf}
509

    
510
        ;Detect if "TempRepStr" is not empty
511
        ${If} $R4 != ""
512
          ;Replace the old characters with the new one
513
          StrCpy $R3 $R0 $R1
514
          IntOp $R1 $R1 + 2
515
          StrCpy $R0 $R0 "" $R1
516
          StrCpy $R0 "$R3$R4$R0"
517
          IntOp $R2 $R2 - 1 ;Decrease "StrLen"
518
          IntOp $R1 $R1 - 2 ;Go back to the next character
519
        ${EndIf}
520
      ${Next}
521
      Pop $R4
522
      Pop $R3
523
      Pop $R2
524
      Pop $R1
525
      Exch $R0
526
    !insertmacro STRFUNC_ENDFUNC
527
  !macroend
528

    
529
  ############################################################################  
530
  # StrLoc
531
  !insertmacro STRFUNC_DEFFUNC StrLoc `ResultVar|String|StrToSearchFor|CounterDirection` `Output|Text|Text|Option > <`
532

    
533
  !macro STRFUNC_CALL_StrLoc un ResultVar String StrToSearchFor OffsetDirection
534
    !verbose push ${STRFUNC_VERBOSITY}
535
    !echo `${U+24}{${un}StrLoc} "${ResultVar}" "${String}" "${StrToSearchFor}" "${OffsetDirection}"`
536
    !verbose 2
537
    Push `${String}`
538
    Push `${StrToSearchFor}`
539
    Push `${OffsetDirection}`
540
    !insertmacro STRFUNC_CALL StrLoc "${un}"
541
    Pop ${ResultVar}
542
    !verbose pop
543
  !macroend
544

    
545
  !macro STRFUNC_MAKEFUNC_StrLoc
546
    !insertmacro STRFUNC_BEGINFUNC ${basename} `${un}` `2004 Diego Pedroso - Based on functions by Ximon Eighteen`
547

    
548
    /*After this point:
549
      ------------------------------------------
550
       $R0 = OffsetDirection (input)
551
       $R1 = StrToSearch (input)
552
       $R2 = String (input)
553
       $R3 = StrToSearchLen (temp)
554
       $R4 = StrLen (temp)
555
       $R5 = StartCharPos (temp)
556
       $R6 = TempStr (temp)*/
557

    
558
      ;Get input from user
559
      Exch $R0
560
      Exch
561
      Exch $R1
562
      Exch 2
563
      Exch $R2
564
      Push $R3
565
      Push $R4
566
      Push $R5
567
      Push $R6
568

    
569
      ;Get "String" and "StrToSearch" length
570
      StrLen $R3 $R1
571
      StrLen $R4 $R2
572
      ;Start "StartCharPos" counter
573
      StrCpy $R5 0
574

    
575
      ;Loop until "StrToSearch" is found or "String" reaches its end
576
      ${Do}
577
        ;Remove everything before and after the searched part ("TempStr")
578
        StrCpy $R6 $R2 $R3 $R5
579

    
580
        ;Compare "TempStr" with "StrToSearch"
581
        ${If} $R6 == $R1
582
          ${If} $R0 == `<`
583
            IntOp $R6 $R3 + $R5
584
            IntOp $R0 $R4 - $R6
585
          ${Else}
586
            StrCpy $R0 $R5
587
          ${EndIf}
588
          ${ExitDo}
589
        ${EndIf}
590
        ;If not "StrToSearch", this could be "String" end
591
        ${If} $R5 >= $R4
592
          StrCpy $R0 ``
593
          ${ExitDo}
594
        ${EndIf}
595
        ;If not, continue the loop
596
        IntOp $R5 $R5 + 1
597
      ${Loop}
598

    
599
      ;Return output to user
600
      Pop $R6
601
      Pop $R5
602
      Pop $R4
603
      Pop $R3
604
      Pop $R2
605
      Exch
606
      Pop $R1
607
      Exch $R0
608
    !insertmacro STRFUNC_ENDFUNC
609

    
610
  !macroend
611

    
612
  ############################################################################  
613
  # StrNSISToIO
614
  !insertmacro STRFUNC_DEFFUNC StrNSISToIO `ResultVar|String` `Output|Text`
615

    
616
  !macro STRFUNC_CALL_StrNSISToIO un ResultVar String
617
    !verbose push ${STRFUNC_VERBOSITY}
618
    !echo `${U+24}{${un}StrNSISToIO} "${ResultVar}" "${String}"`
619
    !verbose 2
620
    Push `${String}`
621
    !insertmacro STRFUNC_CALL StrNSISToIO "${un}"
622
    Pop ${ResultVar}
623
    !verbose pop
624
  !macroend
625

    
626
  !macro STRFUNC_MAKEFUNC_StrNSISToIO
627
    !insertmacro STRFUNC_BEGINFUNC ${basename} `${un}` `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
    !insertmacro STRFUNC_ENDFUNC
683
  !macroend
684

    
685
  ############################################################################  
686
  # StrRep
687
  !insertmacro STRFUNC_DEFFUNC StrRep `ResultVar|String|StrToReplace|ReplacementString` `Output|Text|Text|Text`
688

    
689
  !macro STRFUNC_CALL_StrRep un ResultVar String StringToReplace ReplacementString
690
    !verbose push ${STRFUNC_VERBOSITY}
691
    !echo `${U+24}{${un}StrRep} "${ResultVar}" "${String}" "${StringToReplace}" "${ReplacementString}"`
692
    !verbose 2
693
    Push `${String}`
694
    Push `${StringToReplace}`
695
    Push `${ReplacementString}`
696
    !insertmacro STRFUNC_CALL StrRep "${un}"
697
    Pop ${ResultVar}
698
    !verbose pop
699
  !macroend
700

    
701
  !macro STRFUNC_MAKEFUNC_StrRep
702
    !insertmacro STRFUNC_BEGINFUNC ${basename} `${un}` `2004 Diego Pedroso - Based on functions by Hendri Adriaens`
703

    
704
    /*After this point:
705
      ------------------------------------------
706
       $R0 = ReplacementString (input)
707
       $R1 = StrToSearch (input)
708
       $R2 = String (input)
709
       $R3 = RepStrLen (temp)
710
       $R4 = StrToSearchLen (temp)
711
       $R5 = StrLen (temp)
712
       $R6 = StartCharPos (temp)
713
       $R7 = TempStrL (temp)
714
       $R8 = TempStrR (temp)*/
715

    
716
      ;Get input from user
717
      Exch $R0
718
      Exch
719
      Exch $R1
720
      Exch
721
      Exch 2
722
      Exch $R2
723
      Push $R3
724
      Push $R4
725
      Push $R5
726
      Push $R6
727
      Push $R7
728
      Push $R8
729

    
730
      ;Return "String" if "StrToSearch" is ""
731
      ${IfThen} $R1 == "" ${|} Goto Done ${|}
732

    
733
      ;Get "ReplacementString", "String" and "StrToSearch" length
734
      StrLen $R3 $R0
735
      StrLen $R4 $R1
736
      StrLen $R5 $R2
737
      ;Start "StartCharPos" counter
738
      StrCpy $R6 0
739

    
740
      ;Loop until "StrToSearch" is found or "String" reaches its end
741
      ${Do}
742
        ;Remove everything before and after the searched part ("TempStrL")
743
        StrCpy $R7 $R2 $R4 $R6
744

    
745
        ;Compare "TempStrL" with "StrToSearch"
746
        ${If} $R7 == $R1
747
          ;Split "String" to replace the string wanted
748
          StrCpy $R7 $R2 $R6 ;TempStrL
749

    
750
          ;Calc: "StartCharPos" + "StrToSearchLen" = EndCharPos
751
          IntOp $R8 $R6 + $R4
752

    
753
          StrCpy $R8 $R2 "" $R8 ;TempStrR
754

    
755
          ;Insert the new string between the two separated parts of "String"
756
          StrCpy $R2 $R7$R0$R8
757
          ;Now calculate the new "StrLen" and "StartCharPos"
758
          StrLen $R5 $R2
759
          IntOp $R6 $R6 + $R3
760
          ${Continue}
761
        ${EndIf}
762

    
763
        ;If not "StrToSearch", this could be "String" end
764
        ${IfThen} $R6 >= $R5 ${|} ${ExitDo} ${|}
765
        ;If not, continue the loop
766
        IntOp $R6 $R6 + 1
767
      ${Loop}
768

    
769
      Done:
770

    
771
    /*After this point:
772
      ------------------------------------------
773
       $R0 = OutVar (output)*/
774

    
775
      ;Return output to user
776
      StrCpy $R0 $R2
777
      Pop $R8
778
      Pop $R7
779
      Pop $R6
780
      Pop $R5
781
      Pop $R4
782
      Pop $R3
783
      Pop $R2
784
      Pop $R1
785
      Exch $R0
786
    !insertmacro STRFUNC_ENDFUNC
787

    
788
  !macroend
789

    
790
  ############################################################################  
791
  # StrSort
792
  !insertmacro STRFUNC_DEFFUNC StrSort `ResultVar|String|CenterStr|LeftStr|RightStr|IncludeLeftStr|IncludeCenterStr|IncludeRightStr` `Output|Text|Text|Text|Text|Option 1 0|Option 1 0|Option 1 0`
793

    
794
  !macro STRFUNC_CALL_StrSort un ResultVar String CenterStr LeftStr RightStr IncludeCenterStr IncludeLeftStr IncludeRightStr
795
    !verbose push ${STRFUNC_VERBOSITY}
796
    !echo `${U+24}{${un}StrSort} "${ResultVar}" "${String}" "${CenterStr}" "${LeftStr}" "${RightStr}" "${IncludeCenterStr}" "${IncludeLeftStr}" "${IncludeRightStr}"`
797
    !verbose 2
798
    Push `${String}`
799
    Push `${CenterStr}`
800
    Push `${LeftStr}`
801
    Push `${RightStr}`
802
    Push `${IncludeCenterStr}`
803
    Push `${IncludeLeftStr}`
804
    Push `${IncludeRightStr}`
805
    !insertmacro STRFUNC_CALL StrSort "${un}"
806
    Pop ${ResultVar}
807
    !verbose pop
808
  !macroend
809

    
810
  !macro STRFUNC_MAKEFUNC_StrSort
811
    !insertmacro STRFUNC_BEGINFUNC ${basename} `${un}` `2004 Diego Pedroso - Based on functions by Stuart Welch`
812

    
813
    /*After this point:
814
      ------------------------------------------
815
       $R0 = String (input)
816
       $R1 = LeftStr (input)
817
       $R2 = CenterStr (input)
818
       $R3 = RightStr (input)
819
       $R4 = IncludeLeftStr (input)
820
       $R5 = IncludeCenterStr (input)
821
       $R6 = IncludeRightStr (input)
822

    
823
       $0 = StrLen (temp)
824
       $1 = LeftStrLen (temp)
825
       $2 = CenterStrLen (temp)
826
       $3 = RightStrLen (temp)
827
       $4 = StartPos (temp)
828
       $5 = EndPos (temp)
829
       $6 = StartCharPos (temp)
830
       $7 = EndCharPos (temp)
831
       $8 = TempStr (temp)*/
832

    
833
      ;Get input from user
834
      Exch $R6
835
      Exch
836
      Exch $R5
837
      Exch
838
      Exch 2
839
      Exch $R4
840
      Exch 2
841
      Exch 3
842
      Exch $R3
843
      Exch 3
844
      Exch 4
845
      Exch $R2
846
      Exch 4
847
      Exch 5
848
      Exch $R1
849
      Exch 5
850
      Exch 6
851
      Exch $R0
852
      Exch 6
853
      Push $0
854
      Push $1
855
      Push $2
856
      Push $3
857
      Push $4
858
      Push $5
859
      Push $6
860
      Push $7
861
      Push $8
862

    
863
      ;Parameter defaults
864
      ${IfThen} $R4 == `` ${|} StrCpy $R4 `1` ${|}
865
      ${IfThen} $R5 == `` ${|} StrCpy $R5 `1` ${|}
866
      ${IfThen} $R6 == `` ${|} StrCpy $R6 `1` ${|}
867

    
868
      ;Get "String", "CenterStr", "LeftStr" and "RightStr" length
869
      StrLen $0 $R0
870
      StrLen $1 $R1
871
      StrLen $2 $R2
872
      StrLen $3 $R3
873
      ;Start "StartCharPos" counter
874
      StrCpy $6 0
875
      ;Start "EndCharPos" counter based on "CenterStr" length
876
      IntOp $7 $6 + $2
877

    
878
      ;Loop until "CenterStr" is found or "String" reaches its end
879
      ${Do}
880
        ;Remove everything before and after the searched part ("TempStr")
881
        StrCpy $8 $R0 $2 $6
882

    
883
        ;Compare "TempStr" with "CenterStr"
884
        ${IfThen} $8 == $R2 ${|} ${ExitDo} ${|}
885
        ;If not, this could be "String" end
886
        ${IfThen} $7 >= $0 ${|} Goto Done ${|}
887
        ;If not, continue the loop
888
        IntOp $6 $6 + 1
889
        IntOp $7 $7 + 1
890
      ${Loop}
891

    
892
      # "CenterStr" was found
893

    
894
      ;Remove "CenterStr" from "String" if the user wants
895
      ${If} $R5 = ${FALSE}
896
        StrCpy $8 $R0 $6
897
        StrCpy $R0 $R0 `` $7
898
        StrCpy $R0 $8$R0
899
      ${EndIf}
900

    
901
      ;"StartPos" and "EndPos" will record "CenterStr" coordinates for now
902
      StrCpy $4 $6
903
      StrCpy $5 $7
904
      ;"StartCharPos" and "EndCharPos" should be before "CenterStr"
905
      IntOp $6 $6 - $1
906
      IntOp $7 $6 + $1
907

    
908
      ;Loop until "LeftStr" is found or "String" reaches its start
909
      ${Do}
910
        ;Remove everything before and after the searched part ("TempStr")
911
        StrCpy $8 $R0 $1 $6
912

    
913
        ;If "LeftStr" is empty
914
        ${If} $R1 == ``
915
          StrCpy $6 0
916
          StrCpy $7 0
917
          ${ExitDo}
918
        ${EndIf}
919

    
920
        ;Compare "TempStr" with "LeftStr"
921
        ${IfThen} $8 == $R1 ${|} ${ExitDo} ${|}
922
        ;If not, this could be "String" start
923
        ${IfThen} $6 <= 0 ${|} ${ExitDo} ${|}
924
        ;If not, continue the loop
925
        IntOp $6 $6 - 1
926
        IntOp $7 $7 - 1
927
      ${Loop}
928

    
929
      # "LeftStr" is found or "String" start was reached
930

    
931
      ;Remove "LeftStr" from "String" if the user wants
932
      ${If} $R4 = ${FALSE}
933
        IntOp $6 $6 + $1
934
      ${EndIf}
935

    
936
      ;Record "LeftStr" first character position on "TempStr" (temporarily)
937
      StrCpy $8 $6
938

    
939
      ;"StartCharPos" and "EndCharPos" should be after "CenterStr"
940
      ${If} $R5 = ${FALSE}
941
        StrCpy $6 $4
942
      ${Else}
943
        IntOp $6 $4 + $2
944
      ${EndIf}
945
      IntOp $7 $6 + $3
946
      
947
      ;Record "LeftStr" first character position on "StartPos"
948
      StrCpy $4 $8
949

    
950
      ;Loop until "RightStr" is found or "String" reaches its end
951
      ${Do}
952
        ;Remove everything before and after the searched part ("TempStr")
953
        StrCpy $8 $R0 $3 $6
954

    
955
        ;If "RightStr" is empty
956
        ${If} $R3 == ``
957
          StrCpy $6 $0
958
          StrCpy $7 $0
959
          ${ExitDo}
960
        ${EndIf}
961

    
962
        ;Compare "TempStr" with "RightStr"
963
        ${IfThen} $8 == $R3 ${|} ${ExitDo} ${|}
964
        ;If not, this could be "String" end
965
        ${IfThen} $7 >= $0 ${|} ${ExitDo} ${|}
966
        ;If not, continue the loop
967
        IntOp $6 $6 + 1
968
        IntOp $7 $7 + 1
969
      ${Loop}
970

    
971
      ;Remove "RightStr" from "String" if the user wants
972
      ${If} $R6 = ${FALSE}
973
        IntOp $7 $7 - $3
974
      ${EndIf}
975

    
976
      ;Record "RightStr" last character position on "StartPos"
977
      StrCpy $5 $7
978

    
979
      ;As the positionment is relative...
980
      IntOp $5 $5 - $4
981

    
982
      ;Write the string and finish the job
983
      StrCpy $R0 $R0 $5 $4
984
      Goto +2
985

    
986
      Done:
987
      StrCpy $R0 ``
988

    
989
    /*After this point:
990
      ------------------------------------------
991
       $R0 = OutVar (output)*/
992

    
993
      ;Return output to user
994
      Pop $8
995
      Pop $7
996
      Pop $6
997
      Pop $5
998
      Pop $4
999
      Pop $3
1000
      Pop $2
1001
      Pop $1
1002
      Pop $0
1003
      Pop $R6
1004
      Pop $R5
1005
      Pop $R4
1006
      Pop $R3
1007
      Pop $R2
1008
      Pop $R1
1009
      Exch $R0
1010
    !insertmacro STRFUNC_ENDFUNC
1011

    
1012
  !macroend
1013

    
1014
  ############################################################################  
1015
  # StrStr
1016
  !insertmacro STRFUNC_DEFFUNC StrStr `ResultVar|String|StrToSearchFor` `Output|Text|Text`
1017

    
1018
  !macro STRFUNC_CALL_StrStr un ResultVar String StrToSearchFor
1019
    !verbose push ${STRFUNC_VERBOSITY}
1020
    !echo `${U+24}{${un}StrStr} "${ResultVar}" "${String}" "${StrToSearchFor}"`
1021
    !verbose 2
1022
    Push `${String}`
1023
    Push `${StrToSearchFor}`
1024
    !insertmacro STRFUNC_CALL StrStr "${un}"
1025
    Pop ${ResultVar}
1026
    !verbose pop
1027
  !macroend
1028

    
1029
  !macro STRFUNC_MAKEFUNC_StrStr
1030
    !insertmacro STRFUNC_BEGINFUNC ${basename} `${un}` `2004 Diego Pedroso - Based on functions by Ximon Eighteen`
1031

    
1032
    /*After this point:
1033
      ------------------------------------------
1034
       $R0 = StrToSearch (input)
1035
       $R1 = String (input)
1036
       $R2 = StrToSearchLen (temp)
1037
       $R3 = StrLen (temp)
1038
       $R4 = StartCharPos (temp)
1039
       $R5 = TempStr (temp)*/
1040

    
1041
      ;Get input from user
1042
      Exch $R0
1043
      Exch
1044
      Exch $R1
1045
      Push $R2
1046
      Push $R3
1047
      Push $R4
1048
      Push $R5
1049

    
1050
      ;Get "String" and "StrToSearch" length
1051
      StrLen $R2 $R0
1052
      StrLen $R3 $R1
1053
      ;Start "StartCharPos" counter
1054
      StrCpy $R4 0
1055

    
1056
      ;Loop until "StrToSearch" is found or "String" reaches its end
1057
      ${Do}
1058
        ;Remove everything before and after the searched part ("TempStr")
1059
        StrCpy $R5 $R1 $R2 $R4
1060

    
1061
        ;Compare "TempStr" with "StrToSearch"
1062
        ${IfThen} $R5 == $R0 ${|} ${ExitDo} ${|}
1063
        ;If not "StrToSearch", this could be "String" end
1064
        ${IfThen} $R4 >= $R3 ${|} ${ExitDo} ${|}
1065
        ;If not, continue the loop
1066
        IntOp $R4 $R4 + 1
1067
      ${Loop}
1068

    
1069
    /*After this point:
1070
      ------------------------------------------
1071
       $R0 = OutVar (output)*/
1072

    
1073
      ;Remove part before "StrToSearch" on "String" (if there has one)
1074
      StrCpy $R0 $R1 `` $R4
1075

    
1076
      ;Return output to user
1077
      Pop $R5
1078
      Pop $R4
1079
      Pop $R3
1080
      Pop $R2
1081
      Pop $R1
1082
      Exch $R0
1083
    !insertmacro STRFUNC_ENDFUNC
1084

    
1085
  !macroend
1086

    
1087
  ############################################################################  
1088
  # StrStrAdv
1089
  !insertmacro STRFUNC_DEFFUNC StrStrAdv `ResultVar|String|StrToSearchFor|SearchDirection|ResultStrDirection|DisplayStrToSearch|Loops|CaseSensitive` `Output|Text|Text|Option > <|Option > <|Option 1 0|Text|Option 0 1`
1090

    
1091
  !macro STRFUNC_CALL_StrStrAdv un ResultVar String StrToSearchFor SearchDirection ResultStrDirection DisplayStrToSearch Loops CaseSensitive
1092
    !verbose push ${STRFUNC_VERBOSITY}
1093
    !echo `${U+24}{${un}StrStrAdv} "${ResultVar}" "${String}" "${StrToSearchFor}" "${SearchDirection}" "${ResultStrDirection}" "${DisplayStrToSearch}" "${Loops}" "${CaseSensitive}"`
1094
    !verbose 2
1095
    Push `${String}`
1096
    Push `${StrToSearchFor}`
1097
    Push `${SearchDirection}`
1098
    Push `${ResultStrDirection}`
1099
    Push `${DisplayStrToSearch}`
1100
    Push `${Loops}`
1101
    Push `${CaseSensitive}`
1102
    !insertmacro STRFUNC_CALL StrStrAdv "${un}"
1103
    Pop ${ResultVar}
1104
    !verbose pop
1105
  !macroend
1106

    
1107
  !macro STRFUNC_MAKEFUNC_StrStrAdv
1108
    !insertmacro STRFUNC_BEGINFUNC ${basename} `${un}` `2003-2004 Diego Pedroso`
1109

    
1110
    /*After this point:
1111
      ------------------------------------------
1112
       $0 = String (input)
1113
       $1 = StringToSearch (input)
1114
       $2 = DirectionOfSearch (input)
1115
       $3 = DirectionOfReturn (input)
1116
       $4 = ShowStrToSearch (input)
1117
       $5 = NumLoops (input)
1118
       $6 = CaseSensitive (input)
1119
       $7 = StringLength (temp)
1120
       $8 = StrToSearchLength (temp)
1121
       $9 = CurrentLoop (temp)
1122
       $R0 = EndCharPos (temp)
1123
       $R1 = StartCharPos (temp)
1124
       $R2 = OutVar (output)
1125
       $R3 = Temp (temp)*/
1126

    
1127
      ;Get input from user
1128

    
1129
      Exch $6
1130
      Exch
1131
      Exch $5
1132
      Exch
1133
      Exch 2
1134
      Exch $4
1135
      Exch 2
1136
      Exch 3
1137
      Exch $3
1138
      Exch 3
1139
      Exch 4
1140
      Exch $2
1141
      Exch 4
1142
      Exch 5
1143
      Exch $1
1144
      Exch 5
1145
      Exch 6
1146
      Exch $0
1147
      Exch 6
1148
      Push $7
1149
      Push $8
1150
      Push $9
1151
      Push $R3
1152
      Push $R2
1153
      Push $R1
1154
      Push $R0
1155

    
1156
      ; Clean $R0-$R3 variables
1157
      StrCpy $R0 ""
1158
      StrCpy $R1 ""
1159
      StrCpy $R2 ""
1160
      StrCpy $R3 ""
1161

    
1162
      ; Verify if we have the correct values on the variables
1163
      ${If} $0 == ``
1164
        SetErrors ;AdvStrStr_StrToSearch not found
1165
        Goto AdvStrStr_End
1166
      ${EndIf}
1167

    
1168
      ${If} $1 == ``
1169
        SetErrors ;No text to search
1170
        Goto AdvStrStr_End
1171
      ${EndIf}
1172

    
1173
      ${If} $2 != <
1174
        StrCpy $2 >
1175
      ${EndIf}
1176

    
1177
      ${If} $3 != <
1178
        StrCpy $3 >
1179
      ${EndIf}
1180

    
1181
      ${If} $4 <> 0
1182
        StrCpy $4 1
1183
      ${EndIf}
1184

    
1185
      ${If} $5 <= 0
1186
        StrCpy $5 0
1187
      ${EndIf}
1188

    
1189
      ${If} $6 <> 1
1190
        StrCpy $6 0
1191
      ${EndIf}
1192

    
1193
      ; Find "AdvStrStr_String" length
1194
      StrLen $7 $0
1195

    
1196
      ; Then find "AdvStrStr_StrToSearch" length
1197
      StrLen $8 $1
1198

    
1199
      ; Now set up basic variables
1200

    
1201
      ${If} $2 == <
1202
        IntOp $R1 $7 - $8
1203
        StrCpy $R2 $7
1204
      ${Else}
1205
        StrCpy $R1 0
1206
        StrCpy $R2 $8
1207
      ${EndIf}
1208

    
1209
      StrCpy $9 0 ; First loop
1210

    
1211
      ;Let's begin the search
1212

    
1213
      ${Do}
1214
        ; Step 1: If the starting or ending numbers are negative
1215
        ;         or more than AdvStrStr_StringLen, we return
1216
        ;         error
1217

    
1218
        ${If} $R1 < 0
1219
          StrCpy $R1 ``
1220
          StrCpy $R2 ``
1221
          StrCpy $R3 ``
1222
          SetErrors ;AdvStrStr_StrToSearch not found
1223
          Goto AdvStrStr_End
1224
        ${ElseIf} $R2 > $7
1225
          StrCpy $R1 ``
1226
          StrCpy $R2 ``
1227
          StrCpy $R3 ``
1228
          SetErrors ;AdvStrStr_StrToSearch not found
1229
          Goto AdvStrStr_End
1230
        ${EndIf}
1231

    
1232
        ; Step 2: Start the search depending on
1233
        ;         AdvStrStr_DirectionOfSearch. Chop down not needed
1234
        ;         characters.
1235

    
1236
        ${If} $R1 <> 0
1237
          StrCpy $R3 $0 `` $R1
1238
        ${EndIf}
1239

    
1240
        ${If} $R2 <> $7
1241
          ${If} $R1 = 0
1242
            StrCpy $R3 $0 $8
1243
          ${Else}
1244
            StrCpy $R3 $R3 $8
1245
          ${EndIf}
1246
        ${EndIf}
1247

    
1248
        ; Step 3: Make sure that's the string we want
1249

    
1250
        ; Case-Sensitive Support <- Use "AdvStrStr_Temp"
1251
        ; variable because it won't be used anymore
1252

    
1253
        ${If} $6 == 1
1254
          System::Call `kernel32::lstrcmp(ts, ts) i.s` `$R3` `$1`
1255
          Pop $R3
1256
          ${If} $R3 = 0
1257
            StrCpy $R3 1 ; Continue
1258
          ${Else}
1259
            StrCpy $R3 0 ; Break
1260
          ${EndIf}
1261
        ${Else}
1262
          ${If} $R3 == $1
1263
            StrCpy $R3 1 ; Continue
1264
          ${Else}
1265
            StrCpy $R3 0 ; Break
1266
          ${EndIf}
1267
        ${EndIf}
1268

    
1269
        ; After the comparasion, confirm that it is the
1270
        ; value we want.
1271

    
1272
        ${If} $R3 = 1
1273

    
1274
          ;We found it, return except if the user has set up to
1275
          ;search for another one:
1276
          ${If} $9 >= $5
1277

    
1278
            ;Now, let's see if the user wants
1279
            ;AdvStrStr_StrToSearch to appear:
1280
            ${If} $4 == 0
1281
              ;Return depends on AdvStrStr_DirectionOfReturn
1282
              ${If} $3 == <
1283
                ; RTL
1284
                StrCpy $R0 $0 $R1
1285
              ${Else}
1286
                ; LTR
1287
                StrCpy $R0 $0 `` $R2
1288
              ${EndIf}
1289
              ${Break}
1290
            ${Else}
1291
              ;Return depends on AdvStrStr_DirectionOfReturn
1292
              ${If} $3 == <
1293
                ; RTL
1294
                StrCpy $R0 $0 $R2
1295
              ${Else}
1296
                ; LTR
1297
                StrCpy $R0 $0 `` $R1
1298
              ${EndIf}
1299
              ${Break}
1300
            ${EndIf}
1301
          ${Else}
1302
            ;If the user wants to have more loops, let's do it so!
1303
            IntOp $9 $9 + 1
1304

    
1305
            ${If} $2 == <
1306
              IntOp $R1 $R1 - 1
1307
              IntOp $R2 $R2 - 1
1308
            ${Else}
1309
              IntOp $R1 $R1 + 1
1310
              IntOp $R2 $R2 + 1
1311
            ${EndIf}
1312
          ${EndIf}
1313
        ${Else}
1314
          ; Step 4: We didn't find it, so do steps 1 thru 3 again
1315

    
1316
          ${If} $2 == <
1317
            IntOp $R1 $R1 - 1
1318
            IntOp $R2 $R2 - 1
1319
          ${Else}
1320
            IntOp $R1 $R1 + 1
1321
            IntOp $R2 $R2 + 1
1322
          ${EndIf}
1323
        ${EndIf}
1324
      ${Loop}
1325

    
1326
      AdvStrStr_End:
1327

    
1328
      ;Add 1 to AdvStrStr_EndCharPos to be supportable
1329
      ;by "StrCpy"
1330

    
1331
      IntOp $R2 $R2 - 1
1332

    
1333
      ;Return output to user
1334

    
1335
      Exch $R0
1336
      Exch
1337
      Pop $R1
1338
      Exch
1339
      Pop $R2
1340
      Exch
1341
      Pop $R3
1342
      Exch
1343
      Pop $9
1344
      Exch
1345
      Pop $8
1346
      Exch
1347
      Pop $7
1348
      Exch
1349
      Pop $6
1350
      Exch
1351
      Pop $5
1352
      Exch
1353
      Pop $4
1354
      Exch
1355
      Pop $3
1356
      Exch
1357
      Pop $2
1358
      Exch
1359
      Pop $1
1360
      Exch
1361
      Pop $0
1362

    
1363
    !insertmacro STRFUNC_ENDFUNC
1364

    
1365
  !macroend
1366

    
1367
  ############################################################################  
1368
  # StrTok
1369
  !insertmacro STRFUNC_DEFFUNC StrTok `ResultVar|String|Separators|ResultPart|SkipEmptyParts` `Output|Text|Text|Mixed L|Option 1 0`
1370

    
1371
  !macro STRFUNC_CALL_StrTok un ResultVar String Separators ResultPart SkipEmptyParts
1372
    !verbose push ${STRFUNC_VERBOSITY}
1373
    !echo `${U+24}{${un}StrTok} "${ResultVar}" "${String}" "${Separators}" "${ResultPart}" "${SkipEmptyParts}"`
1374
    !verbose 2
1375
    Push `${String}`
1376
    Push `${Separators}`
1377
    Push `${ResultPart}`
1378
    Push `${SkipEmptyParts}`
1379
    !insertmacro STRFUNC_CALL StrTok "${un}"
1380
    Pop ${ResultVar}
1381
    !verbose pop
1382
  !macroend
1383

    
1384
  !macro STRFUNC_MAKEFUNC_StrTok
1385
    !insertmacro STRFUNC_BEGINFUNC ${basename} `${un}` `2004 Diego Pedroso - Based on functions by "bigmac666"`
1386
    /*After this point:
1387
      ------------------------------------------
1388
       $0 = SkipEmptyParts (input)
1389
       $1 = ResultPart (input)
1390
       $2 = Separators (input)
1391
       $3 = String (input)
1392
       $4 = StrToSearchLen (temp)
1393
       $5 = StrLen (temp)
1394
       $6 = StartCharPos (temp)
1395
       $7 = TempStr (temp)
1396
       $8 = CurrentLoop
1397
       $9 = CurrentSepChar
1398
       $R0 = CurrentSepCharNum
1399
       */
1400

    
1401
      ;Get input from user
1402
      Exch $0
1403
      Exch
1404
      Exch $1
1405
      Exch
1406
      Exch 2
1407
      Exch $2
1408
      Exch 2
1409
      Exch 3
1410
      Exch $3
1411
      Exch 3
1412
      Push $4
1413
      Push $5
1414
      Push $6
1415
      Push $7
1416
      Push $8
1417
      Push $9
1418
      Push $R0
1419

    
1420
      ;Parameter defaults
1421
      ${IfThen} $2 == `` ${|} StrCpy $2 `|` ${|}
1422
      ${IfThen} $1 == `` ${|} StrCpy $1 `L` ${|}
1423
      ${IfThen} $0 == `` ${|} StrCpy $0 `0` ${|}
1424

    
1425
      ;Get "String" and "StrToSearch" length
1426
      StrLen $4 $2
1427
      StrLen $5 $3
1428
      ;Start "StartCharPos" and "ResultPart" counters
1429
      StrCpy $6 0
1430
      StrCpy $8 -1
1431

    
1432
      ;Loop until "ResultPart" is met, "StrToSearch" is found or
1433
      ;"String" reaches its end
1434
      ResultPartLoop: ;"CurrentLoop" Loop
1435

    
1436
        ;Increase "CurrentLoop" counter
1437
        IntOp $8 $8 + 1
1438

    
1439
        StrSearchLoop:
1440
        ${Do} ;"String" Loop
1441
          ;Remove everything before and after the searched part ("TempStr")
1442
          StrCpy $7 $3 1 $6
1443

    
1444
          ;Verify if it's the "String" end
1445
          ${If} $6 >= $5
1446
            ;If "CurrentLoop" is what the user wants, remove the part
1447
            ;after "TempStr" and itself and get out of here
1448
            ${If} $8 == $1
1449
            ${OrIf} $1 == `L`
1450
              StrCpy $3 $3 $6
1451
            ${Else} ;If not, empty "String" and get out of here
1452
              StrCpy $3 ``
1453
            ${EndIf}
1454
            StrCpy $R0 `End`
1455
            ${ExitDo}
1456
          ${EndIf}
1457

    
1458
          ;Start "CurrentSepCharNum" counter (for "Separators" Loop)
1459
          StrCpy $R0 0
1460

    
1461
          ${Do} ;"Separators" Loop
1462
            ;Use one "Separators" character at a time
1463
            ${If} $R0 <> 0
1464
              StrCpy $9 $2 1 $R0
1465
            ${Else}
1466
              StrCpy $9 $2 1
1467
            ${EndIf}
1468

    
1469
            ;Go to the next "String" char if it's "Separators" end
1470
            ${IfThen} $R0 >= $4 ${|} ${ExitDo} ${|}
1471

    
1472
            ;Or, if "TempStr" equals "CurrentSepChar", then...
1473
            ${If} $7 == $9
1474
              StrCpy $7 $3 $6
1475

    
1476
              ;If "String" is empty because this result part doesn't
1477
              ;contain data, verify if "SkipEmptyParts" is activated,
1478
              ;so we don't return the output to user yet
1479

    
1480
              ${If} $7 == ``
1481
              ${AndIf} $0 = ${TRUE}
1482
                IntOp $6 $6 + 1
1483
                StrCpy $3 $3 `` $6
1484
                StrCpy $6 0
1485
                Goto StrSearchLoop
1486
              ${ElseIf} $8 == $1
1487
                StrCpy $3 $3 $6
1488
                StrCpy $R0 "End"
1489
                ${ExitDo}
1490
              ${EndIf} ;If not, go to the next result part
1491
              IntOp $6 $6 + 1
1492
              StrCpy $3 $3 `` $6
1493
              StrCpy $6 0
1494
              Goto ResultPartLoop
1495
            ${EndIf}
1496

    
1497
            ;Increase "CurrentSepCharNum" counter
1498
            IntOp $R0 $R0 + 1
1499
          ${Loop}
1500
          ${IfThen} $R0 == "End" ${|} ${ExitDo} ${|}
1501
          
1502
          ;Increase "StartCharPos" counter
1503
          IntOp $6 $6 + 1
1504
        ${Loop}
1505

    
1506
    /*After this point:
1507
      ------------------------------------------
1508
       $3 = OutVar (output)*/
1509

    
1510
      ;Return output to user
1511

    
1512
      Pop $R0
1513
      Pop $9
1514
      Pop $8
1515
      Pop $7
1516
      Pop $6
1517
      Pop $5
1518
      Pop $4
1519
      Pop $0
1520
      Pop $1
1521
      Pop $2
1522
      Exch $3
1523
    !insertmacro STRFUNC_ENDFUNC
1524

    
1525
  !macroend
1526

    
1527
  ############################################################################  
1528
  # StrTrimNewLines
1529
  !insertmacro STRFUNC_DEFFUNC StrTrimNewLines `ResultVar|String` `Output|Text`
1530

    
1531
  !macro STRFUNC_CALL_StrTrimNewLines un ResultVar String
1532
    !verbose push ${STRFUNC_VERBOSITY}
1533
    !echo `${U+24}{${un}StrTrimNewLines} "${ResultVar}" "${String}"`
1534
    !verbose 2
1535
    Push `${String}`
1536
    !insertmacro STRFUNC_CALL StrTrimNewLines "${un}"
1537
    Pop ${ResultVar}
1538
    !verbose pop
1539
  !macroend
1540

    
1541
  !macro STRFUNC_MAKEFUNC_StrTrimNewLines
1542
    !insertmacro STRFUNC_BEGINFUNC ${basename} `${un}` `2004 Diego Pedroso - Based on functions by Ximon Eighteen`
1543

    
1544
    /*After this point:
1545
      ------------------------------------------
1546
       $R0 = String (input)
1547
       $R1 = TrimCounter (temp)
1548
       $R2 = Temp (temp)*/
1549

    
1550
      ;Get input from user
1551
      Exch $R0
1552
      Push $R1
1553
      Push $R2
1554
      
1555
      ;Initialize trim counter
1556
      StrCpy $R1 0
1557

    
1558
      loop:
1559
        ;Subtract to get "String"'s last characters
1560
        IntOp $R1 $R1 - 1
1561

    
1562
        ;Verify if they are either $\r or $\n
1563
        StrCpy $R2 $R0 1 $R1
1564
        ${If} $R2 == `$\r`
1565
        ${OrIf} $R2 == `$\n`
1566
          Goto loop
1567
        ${EndIf}
1568

    
1569
      ;Trim characters (if needed)
1570
      IntOp $R1 $R1 + 1
1571
      ${If} $R1 < 0
1572
        StrCpy $R0 $R0 $R1
1573
      ${EndIf}
1574

    
1575
    /*After this point:
1576
      ------------------------------------------
1577
       $R0 = OutVar (output)*/
1578

    
1579
      ;Return output to user
1580
      Pop $R2
1581
      Pop $R1
1582
      Exch $R0
1583
    !insertmacro STRFUNC_ENDFUNC
1584

    
1585
  !macroend
1586

    
1587
  ############################################################################  
1588

    
1589
!endif
1590
!verbose 3
1591
!define STRFUNC_VERBOSITY ${_STRFUNC_VERBOSITY}
1592
!undef _STRFUNC_VERBOSITY
1593
!verbose pop