NSIS版本号比较-VersionCompare Bug

问题:

今天发现自己之前写的NSIS脚本中有个BUG,BUG的来源正是NSIS的版本号比较函数:VersionCompare

这个函数在比较"2008.3.15.1"和"2008.05.1.10"返回的不是期待的2,却是1

于是,可怕的事情发生了……

 

 

解决:

同类的几个函数,经过一番测试,采用下面这个函数。

http://nsis.sourceforge.net/Comparing_Two_Version_Numbers

 

不过原来有个小bug,就是没有初始化自己的变量,会导致多次调用时的结果出错。

于是我也修改之后直接在wiki上提交了我的修改,并在这里转载这个函数,以便下次使用。

 

  1. ;  From:http://nsis.sourceforge.net/Comparing_Two_Version_Numbers
  2. ;  Created 1/5/05 by Comperio
  3. ;
  4. ;   Usage:
  5. ;   ${VersionCheck} "Version1" "Version2" "outputVar"
  6. ;       Version1 = 1st version number
  7. ;       Version2 = 2nd version number
  8. ;       outputVar = Variable used to store the ouput
  9. ;
  10. ;   Return values:
  11. ;       0 = both versions are equal
  12. ;       1 = Version 1 is NEWER than version 2
  13. ;       2 = Version1 is OLDER than version 2
  14. ;   Rules for Version Numbers:
  15. ;       Version numbers must always be a string of numbers only.  (A dot
  16. ;       in the name is optional). 
  17. ;
  18. ;   [Variables]
  19. var P1  ; file pointer, used to "remember" the position in the Version1 string
  20. var P2  ; file pointer, used to "remember" the position in the Version2 string
  21. var V1  ;version number from Version1
  22. var V2  ;version number from Version2
  23. Var Reslt   ; holds the return flag
  24. ;   [Macros]
  25. !macro VersionCheck Ver1 Ver2 OutVar
  26.     ;   To make this work, one character must be added to the version string:
  27.     Push "x${Ver2}"
  28.     Push "x${Ver1}"
  29.     Call VersionCheckF
  30.     Pop ${OutVar}
  31. !macroend
  32. ;   [Defines]
  33. !define VersionCheck "!insertmacro VersionCheck"
  34. ;   [Functions]
  35. Function VersionCheckF
  36.     Exch $1 ; $1 contains Version 1
  37.     Exch
  38.     Exch $2 ; $2 contains Version 2
  39.     Exch
  40.     Push $R0
  41.     ;   initialize Variables
  42.     StrCpy $V1 ""
  43.     StrCpy $V2 ""
  44.     StrCpy $P1 ""
  45.     StrCpy $P2 ""
  46.     StrCpy $Reslt ""
  47.     ;   Set the file pointers:
  48.     IntOp $P1 $P1 + 1
  49.     IntOp $P2 $P2 + 1
  50.     ;  ******************* Get 1st version number for Ver1 **********************
  51.     V11:
  52.     ;   I use $1 and $2 to help keep identify "Ver1" vs. "Ver2"
  53.     StrCpy $R0 $1 1 $P1 ;$R0 contains the character at position $P1
  54.     IntOp $P1 $P1 + 1   ;increments the file pointer for the next read
  55.     StrCmp $R0 "" V11end 0  ;check for empty string
  56.     strCmp $R0 "." v11end 0
  57.     strCpy $V1 "$V1$R0"
  58.     Goto V11
  59.     V11End:
  60.     StrCmp $V1 "" 0 +2
  61.     StrCpy $V1 "0"  
  62.     ;  ******************* Get 1st version number for Ver2 **********************
  63.     V12:
  64.     StrCpy $R0 $2 1 $P2 ;$R0 contains the character at position $P1
  65.     IntOp $P2 $P2 + 1   ;increments the file pointer for the next read
  66.     StrCmp $R0 "" V12end 0  ;check for empty string
  67.     strCmp $R0 "." v12end 0
  68.     strCpy $V2 "$V2$R0"
  69.     Goto V12
  70.     V12End:
  71.     StrCmp $V2 "" 0 +2
  72.     StrCpy $V2 "0"  
  73.     ;   At this point, we can compare the results.  If the numbers are not
  74.     ;       equal, then we can exit
  75.     IntCmp $V1 $V2 cont1 older1 newer1
  76.     older1: ; Version 1 is older (less than) than version 2
  77.     StrCpy $Reslt 2
  78.     Goto ExitFunction
  79.     newer1: ; Version 1 is newer (greater than) Version 2
  80.     StrCpy $Reslt 1
  81.     Goto ExitFunction
  82.     Cont1: ;Versions are the same.  Continue searching for differences
  83.     ;   Reset $V1 and $V2
  84.     StrCpy $V1 ""
  85.     StrCpy $V2 ""
  86.     ;  ******************* Get 2nd version number for Ver1 **********************   
  87.     V21:
  88.     StrCpy $R0 $1 1 $P1 ;$R0 contains the character at position $P1
  89.     IntOp $P1 $P1 + 1   ;increments the file pointer for the next read
  90.     StrCmp $R0 "" V21end 0  ;check for empty string
  91.     strCmp $R0 "." v21end 0
  92.     strCpy $V1 "$V1$R0"
  93.     Goto V21
  94.     V21End:
  95.     StrCmp $V1 "" 0 +2
  96.     StrCpy $V1 "0"  
  97.     ;  ******************* Get 2nd version number for Ver2 **********************
  98.     V22:
  99.     StrCpy $R0 $2 1 $P2 ;$R0 contains the character at position $P1
  100.     IntOp $P2 $P2 + 1   ;increments the file pointer for the next read
  101.     StrCmp $R0 "" V22end 0  ;check for empty string
  102.     strCmp $R0 "." V22end 0
  103.     strCpy $V2 "$V2$R0"
  104.     Goto V22
  105.     V22End:
  106.     StrCmp $V2 "" 0 +2
  107.     StrCpy $V2 "0"  
  108.     ;   At this point, we can compare the results.  If the numbers are not
  109.     ;       equal, then we can exit
  110.     IntCmp $V1 $V2 cont2 older2 newer2
  111.     older2: ; Version 1 is older (less than) than version 2
  112.     StrCpy $Reslt 2 
  113.     Goto ExitFunction
  114.     newer2: ; Version 1 is newer (greater than) Version 2
  115.     StrCpy $Reslt 1
  116.     Goto ExitFunction
  117.     Cont2: ;Versions are the same.  Continue searching for differences
  118.     ;   Reset $V1 and $V2
  119.     StrCpy $V1 ""
  120.     StrCpy $V2 ""   
  121.     ;  ******************* Get 3rd version number for Ver1 **********************   
  122.     V31:
  123.     StrCpy $R0 $1 1 $P1 ;$R0 contains the character at position $P1
  124.     IntOp $P1 $P1 + 1   ;increments the file pointer for the next read
  125.     StrCmp $R0 "" V31end 0  ;check for empty string
  126.     strCmp $R0 "." v31end 0
  127.     strCpy $V1 "$V1$R0"
  128.     Goto V31
  129.     V31End:
  130.     StrCmp $V1 "" 0 +2
  131.     StrCpy $V1 "0"  
  132.     ;  ******************* Get 3rd version number for Ver2 **********************
  133.     V32:
  134.     StrCpy $R0 $2 1 $P2 ;$R0 contains the character at position $P1
  135.     IntOp $P2 $P2 + 1   ;increments the file pointer for the next read
  136.     StrCmp $R0 "" V32end 0  ;check for empty string
  137.     strCmp $R0 "." V32end 0
  138.     strCpy $V2 "$V2$R0"
  139.     Goto V32
  140.     V32End:
  141.     StrCmp $V2 "" 0 +2
  142.     StrCpy $V2 "0"  
  143.     ;   At this point, we can compare the results.  If the numbers are not
  144.     ;       equal, then we can exit
  145.     IntCmp $V1 $V2 cont3 older3 newer3
  146.     older3: ; Version 1 is older (less than) than version 2
  147.     StrCpy $Reslt 2
  148.     Goto ExitFunction
  149.     newer3: ; Version 1 is newer (greater than) Version 2
  150.     StrCpy $Reslt 1
  151.     Goto ExitFunction
  152.     Cont3: ;Versions are the same.  Continue searching for differences
  153.     ;   Reset $V1 and $V2
  154.     StrCpy $V1 ""
  155.     StrCpy $V2 ""
  156.     ;  ******************* Get 4th version number for Ver1 **********************   
  157.     V41:
  158.     StrCpy $R0 $1 1 $P1 ;$R0 contains the character at position $P1
  159.     IntOp $P1 $P1 + 1   ;increments the file pointer for the next read
  160.     StrCmp $R0 "" V41end 0  ;check for empty string
  161.     strCmp $R0 "." v41end 0
  162.     strCpy $V1 "$V1$R0"
  163.     Goto V41
  164.     V41End:
  165.     StrCmp $V1 "" 0 +2
  166.     StrCpy $V1 "0"  
  167.     ;  ******************* Get 4th version number for Ver2 **********************
  168.     V42:
  169.     StrCpy $R0 $2 1 $P2 ;$R0 contains the character at position $P1
  170.     IntOp $P2 $P2 + 1   ;increments the file pointer for the next read
  171.     StrCmp $R0 "" V42end 0  ;check for empty string
  172.     strCmp $R0 "." V42end 0
  173.     strCpy $V2 "$V2$R0"
  174.     Goto V42
  175.     V42End:
  176.     StrCmp $V2 "" 0 +2
  177.     StrCpy $V2 "0"  
  178.     ;   At this point, we can compare the results.  If the numbers are not
  179.     ;       equal, then we can exit
  180.     IntCmp $V1 $V2 cont4 older4 newer4
  181.     older4: ; Version 1 is older (less than) than version 2
  182.     StrCpy $Reslt 2
  183.     Goto ExitFunction
  184.     newer4: ; Version 1 is newer (greater than) Version 2
  185.     StrCpy $Reslt 1
  186.     Goto ExitFunction
  187.     Cont4: 
  188.     ;Versions are the same.  We've reached the end of the version
  189.     ;   strings, so set the function to 0 (equal) and exit
  190.     StrCpy $Reslt 0
  191.     ExitFunction:
  192.     Pop $R0
  193.     Pop $1
  194.     Pop $2
  195.     Push $Reslt
  196. FunctionEnd

我的修改

  1. (cur) (last)  12:3531 December 2008 219.131.237.209 (Talk) (6,929 bytes) (→if have not initialized the variables, the second call will be not correct.如果不初始化,之后的调用结果将是错误的) (undo)
  2. Revision as of 10:16, 6 June 2006 (edit)
    Afrow UK ( Talk | contribs)
    (Description)
    ← Older edit
    Current revision (12:35, 31 December 2008) (edit) (undo)
    219.131.237.209 ( Talk)
    (if have not initialized the variables, the second call will be not correct.如果不初始化,之后的调用结果将是错误的)
     
    Line 55: Line 55:
    Exch
    Exch
    Push $R0
    Push $R0
     +
    ; initialize Variables
     +
    StrCpy $V1 ""
     +
    StrCpy $V2 ""
     +
    StrCpy $P1 ""
     +
    StrCpy $P2 ""
     +
    StrCpy $Reslt ""
    ; Set the file pointers:
    ; Set the file pointers:
    IntOp $P1 $P1 + 1
    IntOp $P1 $P1 + 1

The End.

你可能感兴趣的:(脚本,File,macros,Numbers,variables,Pointers)