NSISArray - Documentation

[ NSISArray Script Header Documentation | NSISArray Plug-in Documentation | NSISArray Credits, Changelog & License ]

# NSISArray Script Header Documentation

## 1.0 Script header documentation contents

- 1.1 Introduction
  - 1.1.1 What is an array?
  - 1.1.2 NSISArray vs Afrow UK's Array.nsh script header
- 1.2 Include the script header
  - 1.2.1 Special settings
    - 1.2.1.1 !define ArrayPlugin
    - 1.2.1.2 !define ArrayCallInstDLL
    - 1.2.1.3 !define ArrayValVar $Var
    - 1.2.1.4 !define ArrayErrVar $Var
    - 1.2.1.5 !define ArraySetErrors
- 1.3 Creating an array
  - 1.3.1 Changing the object delimiter
- 1.4 Initialising an array for run-time use
  - 1.4.1 Check if an array has been initialised
- 1.5 Declaring array functions
- 1.6 Array functions
  - 1.6.1 ${myArray->Write}
  - 1.6.2 ${myArray->WriteList}
    - 1.6.2.1 ${myArray->WriteList} & ArrayCallInstDLL
  - 1.6.3 ${myArray->WriteListC}
  - 1.6.4 ${myArray->Put}
  - 1.6.5 ${myArray->Read}
  - 1.6.6 ${myArray->ReadToStack}
  - 1.6.7 ${myArray->Cut}
  - 1.6.8 ${myArray->Push}
  - 1.6.9 ${myArray->Pop}
  - 1.6.10 ${myArray->Shift}
  - 1.6.11 ${myArray->Unshift}
  - 1.6.12 ${myArray->Reverse}
  - 1.6.13 ${myArray->Sort}
  - 1.6.14 ${myArray->Clear}
  - 1.6.15 ${myArray->Splice}
    - 1.6.15.1 ${myArray->Splice} & ArrayCallInstDLL
  - 1.6.16 ${myArray->Swap}
  - 1.6.17 ${myArray->Copy}
  - 1.6.18 ${myArray->Join}
  - 1.6.19 ${myArray->Concat}
  - 1.6.20 ${myArray->Exists} & ${myArray->ExistsI}
  - 1.6.21 ${myArray->Search} & ${myArray->SearchI}
  - 1.6.22 ${myArray->SizeOf}
  - 1.6.23 ${myArray->SetSize}
  - 1.6.24 ${myArray->ReadFirst}, ${myArray->ReadNext} & ${myArray->ReadClose}
  - 1.6.25 ${myArray->ReDim}
  - 1.6.26 ${myArray->FreeUnusedMem}
  - 1.6.27 ${myArray->Subtract}
  - 1.6.28 ${myArray->SetAutoRedim}
- 1.7 Deleting an array object
  - 1.7.1 Unloading the NSISArray plug-in
- 1.8 Array auto-redimensioning
- 1.9 Array debugging
  - 1.9.1 Catching plug-in errors
    - 1.9.1.1 Enabling internal plug-in error messages
    - 1.9.1.2 Checking the $ArrayErr variable
    - 1.9.1.3 Checking for errors with the NSIS IfErrors function
  - 1.9.2 Error messages and codes
  - 1.9.3 NSIS compiler errors
  - 1.9.4 Enabling error messages with ${ArrayErrorStyle}
  - 1.9.5 Special array debugging functions
    - 1.9.5.1 ${myArray->Debug}
    - 1.9.5.2 ${myArray->Print}
- 1.10 Examples
  - 1.10.1 Example 1
  - 1.10.2 Example 2
  - 1.10.3 More working examples
- 1.11 Jumping over NSISArray functions
- 1.12 Calculating memory usage

## 1.1 Introduction

The NSISArray script header is a macro system for the NSISArray plug-in by Afrow UK.

The NSISArray script header masks the plug-in calls with a more friendly scripting language syntax. Everything else is managed on the plug-in side.

Information about the NSISArray plug-in is under the NSISArray Plug-in Documentation section.

Before you write any code, you might want to read section 1.11 Jumping over NSISArray instructions.

### 1.1.1 What is an array?

Arrays allow you to hold masses of data under a single 'object'.

Arrays are very useful when we'd like to store an unknown amount of data. With NSISArray the arrays expand in size when more data is added.

### 1.1.2 NSISArray vs Afrow UK's Array.nsh script header

The first array script header by Afrow UK uses INI files to store the data. It has many of the same functions, but all of the code is written in NSIS and reading and writing to text files makes it much much slower.

The original array script header is still available here; http://nsis.sf.net/wiki/File:Array.zip, although development and support has discontinued.

^ Top

## 1.2 Include the script header

Place !include NSISArray.nsh at the top of your script to start using the script header.

Any array instructions and special settings must be used afterwards and not before.

### 1.2.1 Special settings

Some optional special settings can be !defined before the first ${Array} instruction. These include:

#### 1.2.1.1 !define ArrayPlugin [plugin_name]

Specifies that the script header should use the [plugin_name] plug-in name. By default, the script header uses "NSISArray".

#### 1.2.1.2 !define ArrayCallInstDLL [dll_path]

Specifies that the script header should call the plug-in with CallInstDLL, and call a DLL file at [dll_path].

Note: [dll_path] is the full path to the NSISArray plug-in DLL file at run time. This could be for example, "$EXEDIR\dllcache\Arrays.dll".
Please also note that the ${myArray->WriteList} and ${myArray->Splice} functions change when using this special setting.

#### 1.2.1.3 !define ArrayValVar $Var

Specifies the variable to use within the script header macros for certain purposes. If not defined, the variable $ArrayVal will be declared.

#### 1.2.1.4 !define ArrayErrVar $Var

Specifies the variable to use for error reporting. If not defined, the variable $ArrayErr will be declared.

The $ArrayErr variable will contain the error code when a array function fails. See section 1.9.1.2 Checking the $ArrayErr variable for more information.

#### 1.2.1.5 !define ArraySetErrors

This causes the NSISArray script header to set the NSIS error flag when a call to a plug-in function fails. For more information, see section 1.9.1.3 Checking for errors with the NSIS IfErrors function.

^ Top

## 1.3 Creating an array

To create an array, use:

${Array} myArray [x] [y]

Where myArray is any custom name for an array object.
This function must be used outside Sections and Functions, preferably near the top of your script (but after !include NSISArray.nsh).

The [x] and [y] parameters specify the initial array dimensions. [x] being the number of empty indexes initially allocated to the array and [y] being the initial buffer length of all the array's items.

Both the array's number of allocated indexes and buffer lengths can be changed manually at run time with the ${myArray->ReDim} function.

The minimum value of [x] can be 1 and the minimum value of [y] can be 2.

Please note that the value for buffer lengths ([y]) must always allow for the NULL escaping character on the end of strings to prevent buffer overflows. For example, if you're only putting single characters in the array, the [y] value must be 2 and not 1.

### 1.3.1 Changing the object delimiter

By default, the array delimiter used for object functions is ->. This can be changed using:

${ArrayObj} [new_delimiter]

The [new_delimiter] parameter specifies the delimiter to use, which could be any character or characters of your choice. Some of the script examples under the Examples folder use a dot (.).

This function can only be used just after array creation with the ${Array} function and applies to that array object only. It also cannot be used after using the ${ArrayFunc} function.

^ Top

## 1.4 Initialising an array for run-time use

Even after declaring an array with ${Array}, the array still needs to be initialised for use at run-time. This could be in Function .onInit or perhaps just before using the array in a Section.

To initialise an array use:

${myArray->Init}

You must always initialise an array before use.
Note: This is necessarily just before you use the array in your NSIS script, but before the array is used at run-time.

There are error messages specific to the NSISArray script header for this function which are listen under section 1.9.3 NSIS compiler errors.

### 1.4.1 Check if an array has already been initialised

To check if an array has been initialised, use:

${myArray->Inited} [jump_if_initialised] [jump_if_not_initialised]

Both [jump_if_initialised] and [jump_if_not_initialised] can be relative jumps, e.g. +2 or label jumps.

Note: As the NSISArray script header is macro based, the two parameters are not optional. Use 0 or "" for either parameter for a non jump.

For a compilable NSIS script example, see Examples\NSISArray\Inited.nsi.

^ Top

## 1.5 Declaring array functions

To use any of the array functions available, you must declare them at the top of your script first with the ${ArrayFunc} function:

${Array} myArray1
${ArrayFunc} Read
${ArrayFunc} Write
${ArrayFunc} Splice
${Array} myArray2
${ArrayFunc} Cut
${ArrayFunc} Debug

etc...

With the above example the Read, Write and Splice functions will be declared for myArray1; and the Cut and Debug functions will be declared for myArray2.

Failure to declare a function for an individual array will result in the compile error:
'Invalid command: ${myArray->FuncName}'

Please note that you do not need to declare the Init and Delete array functions as they are not optional.

^ Top

## 1.6 Array functions

NSISArray comes with plenty of functions for managing your arrays.

Please note that much like in many programming languages, we refer to array items with an index number. This index number is also zero base, which means the first item in an array will be at index 0 and not 1.

#### 1.6.1 ${myArray->Write} [index] "string"

Writes "string" to [index] in myArray, overwriting any existing items or adding an item if the specified index is one greater than the current highest item index.

${myArray->Write} 0 "A string to save!"

For a compilable NSIS script example, see Examples\NSISArray\Write.nsi.

#### 1.6.2 ${myArray->WriteList} '"string 1" "string 2" "string 3" ... '

Writes a list of strings to myArray. Each separate string in quotes will become a separate array item. Any existing myArray array items that are inside the range of the item list will be overwritten.

${myArray->WriteList} '"One string" "Another string" "One more"'

#### 1.6.2.1 ${myArray->WriteList} & ArrayCallInstDLL

If you're using the ArrayCallInstDLL special setting then you will find that you cannot use the standard ${myArray->WriteList} function. A new format is introduced to deal with passing multiple items to the plug-in.

New format:
${myArray->WriteListBegin}
${myArray->WriteListItem} "string 1"
${myArray->WriteListItem} "string 2"
${myArray->WriteListItem} "string 3"
${myArray->WriteListEnd}

For a compilable NSIS script example, see Examples\NSISArray\WriteList.nsi.

#### 1.6.3 ${myArray->WriteListC} "string 1[char]string 2[char]..." "[char]"

Writes a list of strings to myArray separated by single [char]'s. Each separate string will become a separate array item. Any existing myArray array items that are inside the range of the item list will be overwritten.
Note: [char] must be a single character. A string is not allowed.

${myArray->WriteListC} "One string|Another string|One more" "|"

This is ideal for working with InstallOptions ListBox controls.

For a compilable NSIS script example, see Examples\NSISArray\WriteListC.nsi.

#### 1.6.4 ${myArray->Put} [index] "string"

Puts "string" into myArray at [index]. No existing items are overwritten, but moved up by one.

For a compilable NSIS script example, see Examples\NSISArray\Put.nsi.

#### 1.6.5 ${myArray->Read} $Var [index]

Reads a string from [index] in myArray and places the string into $Var.

For a compilable NSIS script example, see Examples\NSISArray\Read.nsi.

#### 1.6.6 ${myArray->ReadToStack} [index_start] [index_end]

Reads strings from item at [index_start] to [index_end] in myArray and places all strings onto the stack. The strings on the stack can then be looped through via Pop until a specific string is reached.
Note: If [index_end] is a negative number, the end range will be up to the end of the array minus [index_end] inclusive, and so -1 will be up to and including the last item in the array.

Push "stop_popping"
${myArray->ReadToStack} 0 -1
Loop:
Pop $R0
StrCmp $R0 "stop_popping" Done
...do something here...
Goto Loop
Done:

For a compilable NSIS script example, see Examples\NSISArray\ReadToStack.nsi.

#### 1.6.7 ${myArray->Cut} $Var [index]

Cuts a string from myArray at [index]. The string is placed into $Var. Any proceeding array items are moved down by one.

For a compilable NSIS script example, see Examples\NSISArray\Cut.nsi.

#### 1.6.8 ${myArray->Push} "string"

Pushes "string" to the front of myArray.

For a compilable NSIS script example, see Examples\NSISArray\Push.nsi.

#### 1.6.9 ${myArray->Pop} $Var

Pops a string from the front of myArray into $Var.

For a compilable NSIS script example, see Examples\NSISArray\Pop.nsi.

#### 1.6.10 ${myArray->Shift} "string"

Pushes a string to the end of myArray.

For a compilable NSIS script example, see Examples\NSISArray\Shift.nsi.

#### 1.6.11 ${myArray->Unshift} $Var

Pops a string from the end of myArray and places the string into $Var.

For a compilable NSIS script example, see Examples\NSISArray\Unshift.nsi.

#### 1.6.12 ${myArray->Reverse}

Reverses the contents of myArray.

For a compilable NSIS script example, see Examples\NSISArray\Reverse.nsi.

#### 1.6.13 ${myArray->Sort} myArray2

Sorts the contents of myArray alphabetically or numerically, also rearranging the contents of myArray2 into the same order.
The myArray2 parameter is optional (it can be left empty "").

For a compilable NSIS script example, see Examples\NSISArray\Sort.nsi, Examples\NSISArray\Sort2Arrays.nsi and Examples\NSISArray\MakeFileList.nsi.

#### 1.6.14 ${myArray->Clear}

Clears the contents of myArray. All items are removed and the array size is reset to 0.

For a compilable NSIS script example, see Examples\NSISArray\Clear.nsi.

#### 1.6.15 ${myArray->Splice} [index_start] [index_end] '"string 1" "string 2" ... '

Places a list of strings at [index_start] replacing existing array items up to and including [index_end]. If [index_start] and [index_end] are equal, no existing array items are overwritten.

Specifying no list of strings ('') will result in items from [index_start] up to [index_end] inclusive being deleted.

If [index_end] is a negative number, the end range will be up to the end of the array minus [index_end] inclusive, and so -1 will be up to and including the last item in the array.

For a compilable NSIS script example, see Examples\NSISArray\Splice.nsi.

#### 1.6.15.1 ${myArray->Splice} & ArrayCallInstDLL

If you're using the ArrayCallInstDLL special setting then you will find that you cannot use the standard ${myArray->Splice} function. A new format is introduced to deal with passing multiple items to the plug-in.

New format:
${myArray->SpliceBegin} [index_start] [index_end]
${myArray->SpliceItem} "string 1"
${myArray->SpliceItem} "string 2"
${myArray->SpliceEnd}

The [index_start] and [index_end] parameters are explained under section 1.6.15 ${myArray->Splice} (above).

#### 1.6.16 ${myArray->Swap} [index_1] [index_2]

Swaps the strings in the two indexes in myArray.

For a compilable NSIS script example, see Examples\NSISArray\Swap.nsi.

#### 1.6.17 ${myArray->Copy} myArray2

Copies the contents of myArray to myArray2, overwriting any existing items.

For a compilable NSIS script example, see Examples\NSISArray\Copy.nsi.

#### 1.6.18 ${myArray->Join} myArray2

Copies the contents of myArray onto the end of myArray2.

For a compilable NSIS script example, see Examples\NSISArray\Join.nsi.

#### 1.6.19 ${myArray->Concat} $Var [join_char(s)]

Joins all strings in myArray together with [join_char(s)] and places the output in $Var.

${myArray->Join} $R0 " "

For a compilable NSIS script example, see Examples\NSISArray\Concat.nsi.

#### 1.6.20 ${myArray->Exists} $Var "string" [index]

Finds the index of an item that is exactly equal to "string" case sensitively in myArray after [index].
$Var will contain the item index, or -1 if not found.

Note: To search non case sensitively, use ${myArray->ExistsI} (that's a capital i) instead of ${myArray->Exists}.

For a compilable NSIS script example, see Examples\NSISArray\Exists.nsi and Examples\NSISArray\ExistsI.nsi.

#### 1.6.21 ${myArray->Search} $Var "string" [index]

Searches through all items after [index] in myArray for "string" case insensitively.
$Var will contain the item index containing the first match, or -1 if not found.

Note: To search non case sensitively, use ${myArray->SearchI} (that's a capital i) instead of ${myArray->Search}.

For a compilable NSIS script example, see Examples\NSISArray\Search.nsi and Examples\NSISArray\SearchI.nsi.

#### 1.6.22 ${myArray->SizeOf} $Var1 $Var2 $Var3

For myArray, $Var1 will now contain the allocated buffer length for all items in the array.
$Var2 will contain the number of allocated array indexes.
$Var3 will contain the number of items (used indexes) in the array.

#### 1.6.23 ${myArray->SetSize} [size]

Sets the new size of myArray to [size]. If the array is currently smaller than [size], new empty "" items are added. If the array is currently larger than [size], items are removed until it becomes that size.

Note: This does not allocated more memory for more items to be added. To do so, use ${myArray->ReDim}.

For a compilable NSIS script example, see Examples\NSISArray\SetSize.nsi.

#### 1.6.24 ${myArray->ReadFirst} $Handle $OutVar
${myArray->ReadNext} $Handle $OutVar
${myArray->ReadClose} $Handle

These functions are used to loop through an array, and work in a similar fashion to NSIS's FindFirst, FindNext and FindClose.

${myArray->ReadFirst} opens a loop for myArray using the $Handle variable for the handle. The first read value will be in $Var. The error flag will be set if this command fails (which can be checked with IfErrors.) Always use ClearErrors first!

${myArray->ReadNext} reads the next value in the array using the $Handle handle, where the value will be placed into $Var. This also sets the error flag.

${myArray->ReadClose} simply closes the array reading. This isn't really necessary, but it's there to keep in with the style of the other NSIS commands.

ClearErrors
${myArray->ReadFirst} $R0 $R1
Loop:
IfErrors Done
DetailPrint $R1
ClearErrors
${myArray->ReadNext} $R0 $R1
Goto Loop
Done:
${myArray->ReadClose} $R0

For a compilable NSIS script example, see Examples\NSISArray\ReadFirst.nsi.

#### 1.6.25 ${myArray->ReDim} [x] [y]

Redimensions myArray to [x] item indexes and [y] buffer lengths. No existing items will be deleted. If the number of new indexes allocated is less than the number of currently allocated indexes, the excess indexes are deleted. If the new allocated buffer length is less than the currently allocated buffer length, strings of a greater length are truncated.

The minimum value of [x] can be 1 and the minimum value of [y] can be 2.

Please note that the value for buffer lengths ([y]) must always allow for the NULL escaping character on the end of strings to prevent buffer overflows. For example, if you're only putting single characters in the array, the [y] value must be 2 and not 1.

There are error messages specific to the NSISArray script header for this function which are listen under section 1.9.3 NSIS compiler errors.

For a compilable NSIS script example, see Examples\NSISArray\ReDim.nsi.

#### 1.6.26 ${myArray->FreeUnusedMem}

Frees unused memory in myArray by deleting empty item indexes and by decreasing the buffer length for all array items to fit the largest string in the array. Ideally you should call this after you've finished writing to the array.

For a compilable NSIS script example, see Examples\NSISArray\FreeUnusedMem.nsi.

#### 1.6.27 ${myArray->Subtract} myArray2

Removes items from myArray that are also in myArray2. Items are matched case sensitively.

For a compilable NSIS script example, see Examples\NSISArray\Subtract.nsi.

#### 1.6.28 ${myArray->SetAutoRedim} [indexes] [str_len]

Sets the number of indexes and characters to be increased by when the array is to be auto-redimensioned (for extra memory allocation).

If adding lots of items at a time, you should set [indexes] to a larger number than default.

For default values (before or without using this function) and more information on array auto-redimensioning, see section 2.7 Array auto-redimensioning.

There are error messages specific to the NSISArray script header for this function which are listen under section 1.9.3 NSIS compiler errors.

For a compilable NSIS script example, see Examples\NSISArray\SetAutoRedim.nsi.

^ Top

## 1.7 Deleting an array object

Deleting an array is not optional. You must always delete an array when you have finished using it. If you don't, the memory allocated for use may not be freed when the installer is closed.

When you are ready to delete an array, use:

${myArray->Delete}

Deleting an array will remove it from memory, but you can still reference that array in your NSIS script. If you do, however, an error will be thrown by the NSISArray plug-in at run time.

For a compilable NSIS script example which demonstrates how an array object may still be referenced after calling the Delete instrction, see Examples\NSISArray\Delete.nsi.

### 1.7.1 Unloading the NSISArray plug-in

Once all arrays have been deleted with the ${myArray->Delete} function, the plug-in will automatically be unloaded, allowing the plug-in to be deleted from the $PLUGINSDIR folder.

^ Top

## 1.8 Array auto-redimensioning

From NSISArray v1.1 and upwards, arrays are now fully dynamic in both item indexes and buffer lengths.

For a complete extended description, see section 2.7 Array auto-redimensioning.

^ Top

## 1.9 Array debugging

### 1.9.1 Catching plug-in errors

Sometimes errors can occur when calling a plug-in function. Usually they are caused by passing bad parameter values, but there are also a few other reasons.

There are a few methods to check for errors, which are listed below...

#### 1.9.1.1 Enabling plug-in error messages

The NSISArray plug-in can display error message boxes or display errors in the NSIS InstFiles Page log window when an error occurs, except this feature is disabled by default. See section 1.9.4 Enabling error messages with ${ArrayErrorStyle}.

#### 1.9.1.2 Checking the $ArrayErr variable

When errors occur in plug-in function calls, the $ArrayErr variable will always contain the error code, or 0 if no error occured after a plug-in function call.

You can easily check the value of $ArrayErr with straight through functions such as DetailPrint or MessageBox, or with flow control functions such as StrCmp.

You can also force the NSISArray script header to use a different variable for error codes. See section 1.2.1.4 !define ArrayErrVar $Var.

#### 1.9.1.3 Checking for errors with the NSIS IfErrors function

By default, the NSISArray script header does not set the NSIS error flag (with SetErrors). However, there is a setting to enable this which you'll find under section 1.2.1.5 !define ArraySetErrors.

An example of using this feature may be:

ClearErrors
${myArray->Read} $R0 1
IfErrors 0 +2
MessageBox MB_OK|MB_ICONEXCLAMATION \
"Could not read from myArray!"

For a compilable NSIS script example, see Examples\NSISArray\ArrayIfErrors.nsi.

### 1.9.2 Error messages and codes

Error codes are placed in the $ArrayErr after a plug-in function call which you can check yourself with DetailPrint or MessageBox. For a list of error codes and the error messages that they refer to, see plug-in section 2.8.3 Error messages.

Sometimes compiler errors can occur. Those that relate to NSISArray are listed in the section below...

### 1.9.3 NSIS compiler errors

#### 'Invalid command: ${myArray->Init}'

You must declare at least one function for an array (with ${ArrayFunc}) before using the Init function.

#### 'Invalid command: ${myArray->FuncName}'

You're trying to call ${myArray->FuncName} but you haven't declared it for that array with ${ArrayFunc} first.

#### '!insertmacro: macro "Array_FuncName" requires [X] parameter(s), passed [y]!'

You're calling ${myArray->FuncName} with too many or too little parameters required by the macro.

#### 'NSISArray: Please declare an array before declaring functions.'

You're trying to use ${ArrayFunc} before declaring an array with ${Array}.

#### 'NSISArray: You cannot declare a function more than once.'

You're trying to declare the same function with ${ArrayFunc} more than once for the same array.

#### 'NSISArray: You do not need to declare the Init and Delete functions.'

The Init and Delete array functions need not be declared with ${ArrayFunc}.

#### 'NSISArray: An invalid function name has been declared.'

You've passed an incorrect array function name to the ${ArrayFunc} function. Check your spelling.

#### 'NSISArray: You can only set the array object style once.'

You can only change the object delimiter once for an array object.

#### 'NSISArray: You cannot declare more than one array with the same name.'

You've already declared an array of the same name with ${Array}.

#### 'NSISArray: An array can only be initialised once.'

You're calling ${myArray->Init} more than once (for myArray).

#### 'NSISArray: The minimum index count is 1.'

The first parameter for ${myArray->Init} or ${myArray->ReDim} must be greater than or equal to 1.

#### 'NSISArray: The minimum buffer length is 2.'

The second parameter for ${myArray->Init} or ${myArray->ReDim} must be greater than or equal to 2. This is because the null escaping character that ends a string must be taken into account.

#### 'NSISArray: You must add at least 8 index reallocation.'

The first parameter for ${myArray->SetAutoReDim} must be greater than or equal to 8.

#### 'NSISArray: You must add at least 8 bytes for buffer reallocation.'

The second parameter for ${myArray->SetAutoReDim} must be greater than or equal to 8.

### 1.9.4 Enabling error messages with ${ArrayErrorStyle}

By default just the $ArrayErr variable will contain the error code when an array function call fails. However, we can use the following function to enable more debugging features:

${ArrayErrorStyle} [MsgBox|LogWin|Off]

With MsgBox, an error message box will be displayed. With LogWin, the error messages will appear on the NSIS InstFiles Page log window. The error messages will display the caller function name, the error code and the error message that is associated with it.

Use Off to disable the extra error reporting feature.

This instruction can only be used inside Functions and Sections. Using LogWin will only work in Sections.

For a compilable NSIS script example, see Examples\NSISArray\ArrayErrorStyle.nsi.

### 1.9.5 Special array debugging functions

#### 1.9.5.1 ${myArray->Debug}

This will display a debug screen with a list-box containing the array items in myArray, including some general statistics.

There are also buttons to navigate between arrays that are currently in use.

#### 1.9.5.2 ${myArray->Print} [index]

This will print the value of the item at [index] in the InstFiles page log window (uses DetailPrint). Obviously you need to call this from within a Section (or a Function being called from a Section).

Section "-dummy"
${myArray->Write} 0 "hello"
${myArray->Print} 0 ## Outputs "hello"
SectionEnd

^ Top

## 1.10 Examples

### 1.10.1 Example 1

Name "NSISArray-Example1"
OutFile "NSISArray-Example1.exe"
!include "NSISArray.nsh"
${Array} Array1 5 11
${ArrayFunc} WriteList
${ArrayFunc} Cut
${ArrayFunc} Swap
${ArrayFunc} Concat
Section
## Initialise array for use
${Array1->Init}
## Write a new array
${Array1->WriteList} '"Hi" "I am" "Afrow UK." "My name is" "Stuart!"'
## Cut out 2nd item
${Array1->Cut} $R0 1
DetailPrint $R0 ; == "I am"
## Swap "Afrow UK!" and "Stuart!"
${Array1->Swap} 1 3
## Join strings together with " "
${Array1->Concat} $R0 " "
DetailPrint $R0 ; == "Hi Stuart! My name is Afrow UK."
## Don't need the array anymore
${Array1->Delete}
SectionEnd

### 1.10.2 Example 2

Name "NSISArray-Example2"
OutFile "NSISArray-Example2.exe"
!include "NSISArray.nsh"
${Array} Array2 5 26
${ArrayFunc} Shift
${ArrayFunc} Push
${ArrayFunc} Write
${ArrayFunc} Sort
${ArrayFunc} Splice
${ArrayFunc} Read
${ArrayFunc} Unshift
Section
## Initialise array for use
${Array2->Init}
## Write a new array
${Array2->Shift} "1st shift"
${Array2->Shift} "2nd shift"
${Array2->Push} "1 push"
${Array2->Push} "2nd push"
${Array2->Write} 4 "I like writing"
## Sort the array alphabetically or numerically
${Array2->Sort} ""
## Replace last two items with one
${Array2->Splice} 3 4 '"I don$\'t like writing much"'
## Read from the array
${Array2->Read} $R0 0
DetailPrint $R0 ; == "1 push"
${Array2->Read} $R0 1
DetailPrint $R0 ; == "1st shift"
${Array2->Read} $R0 2
DetailPrint $R0 ; == "2nd push"
${Array2->Unshift} $R0
DetailPrint $R0 ; == "I don't like writing much"
## Don't need the array anymore
${Array2->Delete}
SectionEnd

### 1.10.3 More working examples

You can find more working NSIS script examples in the NSIS\Examples\NSISArray folder. There's an example script for every NSISArray script header function.

^ Top

## 1.11 Jumping over NSISArray functions

You cannot jump over any NSISArray script header instructions with relative jumps...

StrCmp $R0 "blah" 0 +2
${myArray->Cut} $R1 3

NSISArray script header instructions are macros that contain more than one line of NSIS code and therefore a relative jump will not work. You must use labels to jump to instead...

StrCmp $R0 "blah" 0 noCut
${myArray->Cut} $R1 3
noCut:

^ Top

## 1.12 Calculating memory usage

To calculate the amount of memory being used by the NSISArray plug-in, you can use the SizeOf function to return the number of item indexes allocated, indexes used and the length of allocated buffers. Times them together to get the total number of bytes allocated for use.

${myArray1->SizeOf} $R3 $R1 $R2
IntOp $R0 $R1 * $R2
${myArray2->SizeOf} $R4 $R2 $R3
IntOp $R1 $R2 * $R3
IntOp $R0 $R0 + $R1
## $R0 == total number of bytes allocated by myArray1 and myArray2.
IntOp $R0 $R0 / 1024
## $R0 == total number of kilobytes (KB) allocated by myArray1 and myArray2.
IntOp $R0 $R0 / 1024
## $R0 == total number of megabytes (MB) allocated by myArray1 and myArray2.

^ Top

# NSISArray Plug-in Documentation

## 2.0 Plug-in documentation contents

- 2.1 Introduction
- 2.2 Plug-in loading
- 2.3 Plug-in DLL information
- 2.4 Creating an array
  - 2.4.1 Checking if an array has been created
- 2.5 Array functions
  - 2.5.1 NSISArray::Write
  - 2.5.2 NSISArray::WriteList
  - 2.5.3 NSISArray::WriteListC
  - 2.5.4 NSISArray::Put
  - 2.5.5 NSISArray::Read
  - 2.5.6 NSISArray::ReadToStack
  - 2.5.7 NSISArray::Cut
  - 2.5.8 NSISArray::Push
  - 2.5.9 NSISArray::Pop
  - 2.5.10 NSISArray::Shift
  - 2.5.11 NSISArray::Unshift
  - 2.5.12 NSISArray::Reverse
  - 2.5.13 NSISArray::Sort
  - 2.5.14 NSISArray::Clear
  - 2.5.15 NSISArray::Splice
  - 2.5.16 NSISArray::Swap
  - 2.5.17 NSISArray::Copy
  - 2.5.18 NSISArray::Join
  - 2.5.19 NSISArray::Concat
  - 2.5.20 NSISArray::Exists & NSISArray::ExistsI
  - 2.5.21 NSISArray::Search & NSISArray::SearchI
  - 2.5.22 NSISArray::SizeOf
  - 2.5.23 NSISArray::SetSize
  - 2.5.24 NSISArray::ArrayCount
  - 2.5.25 NSISArray::ReDim
  - 2.5.26 NSISArray::FreeUnusedMem
  - 2.5.27 NSISArray::Subtract
  - 2.5.28 NSISArray::SetAutoReDim
- 2.6 Deleting an array object
  - 2.6.1 Unloading the NSISArray plug-in
- 2.7 Array auto-redimensioning
- 2.8 Array debugging
  - 2.8.1 The array debug dialog
  - 2.8.2 Enabling plug-in error messages
  - 2.8.3 Error messages
    - 2.8.3.1 "(1) Array name already declared."
    - 2.8.3.2 "(2) Parameters error."
    - 2.8.3.3 "(3) Index out of range."
    - 2.8.3.4 "(4) Array does not exist."
    - 2.8.3.5 "(5) Cannot declare any more arrays."
    - 2.8.3.6 "(6) Memory could not be allocated."
- 2.9 NSIS special build for large strings
- 3.0 Recompiling NSISArray

^ Top

## 2.1 Introduction

The NSISArray plug-in is a powerful extension for Nullsoft Scriptable Install System that adds support for dynamic arrays for use with the NSIS scripting language.

It contains many functions that allows an NSIS programmer to dynamically create, delete and manipulate their arrays in many ways.

The documentation covers all plug-in functions that the plug-in offers with general descriptions and information about their parameters.

^ Top

## 2.2 Plug-in loading

When using the plug-in manually (without the script header), you must use /NOUNLOAD with every plug-in call. Or you can use SetPluginUnload alwaysoff.

NSISArray::FuncName /NOUNLOAD ...

Or...

SetPluginUnload alwaysoff
NSISArray::FuncName ...
...
SetPluginUnload manual

^ Top

## 2.3 Plug-in DLL information

Below is a list of general information regarding the standard NSISArray.dll plug-in:

- NSISArray (NSISArray.dll, 18KB)
  - 32 bytes for array names.
  - 8 bytes for array index references (for plug-in input).
  - 8 total arrays.
  - 16 more array item indexes are allocated per auto-reallocation (by default before or when not using SetAutoReDim).
  - 32 more bytes are allocated per auto-reallocation (by default before or when not using SetAutoReDim).

If any of these do not fit your requirements, you will need to recompile the plug-in DLL. See section 3.0 Recompiling NSISArray.

^ Top

## 2.4 Creating an array

To create a new array, use:

NSISArray::New /NOUNLOAD myArray [x] [y]

Where myArray is any custom name for an array object, [x] specifies the initial number of indexes to allocate and [y] specifies the initial buffer lengths to use.

The minimum value of [x] can be 1 and the minimum value of [y] can be 2.

Please note that the value for buffer lengths ([y]) must always allow for the NULL escaping character on the end of strings to prevent buffer overflows. For example, if you're only putting single characters in the array, the [y] value must be 2 and not 1.

### 2.4.1 Checking if an array has been created

To check if an array has been created, use:

NSISArray::ArrayExists /NOUNLOAD myArray
Pop $Var

The $Var variable will contain 1 if the array exists (has been created) or 0 if it does not exist.

^ Top

## 2.5 Array functions

The NSISArray plug-in comes with plenty of functions for managing your arrays.

Please note that much like in many programming languages, we refer to array items with an index number. This index number is also zero base, which means the first item in an array will be at index 0 and not 1.

#### 2.5.1 NSISArray::Write /NOUNLOAD myArray [index] "string"

Writes "string" to [index] in myArray, overwriting any existing items or adding an item if the specified index is one greater than the current highest item index.

NSISArray::Write /NOUNLOAD 0 "A string to save!"

#### 2.5.2 NSISArray::WriteList /NOUNLOAD myArray "string 1" "string 2" ... /END

Writes a list of strings to myArray. Each separate string in quotes will become a separate array item. Any existing myArray array items that are inside the range of the item list will be overwritten.

NSISArray::WriteList /NOUNLOAD myArray "String" "Another" "One more" /END

#### 2.5.3 NSISArray::WriteListC /NOUNLOAD

myArray "string 1[char]string 2[char] ... " "[char]"

Writes a list of strings to myArray separated by single [char]'s. Each separate string will become a separate array item. Any existing myArray array items that are inside the range of the item list will be overwritten.
Note: [char] must be a single character. A string is not allowed.

NSISArray::WriteListC /NOUNLOAD myArray "One string|Another|One more" "|"

This is ideal for working with InstallOptions ListBox controls.

#### 2.5.4 NSISArray::Put /NOUNLOAD myArray [index] "string"

Puts "string" into myArray at [index]. No existing items are overwritten, but moved up by one.

#### 2.5.5 NSISArray::Read /NOUNLOAD myArray [index]
Pop $Var

Reads a string from [index] in myArray and places the string onto the stack ready for a Pop $Var.

#### 2.5.6 NSISArray::ReadToStack /NOUNLOAD myArray

Reads strings from item at [index_start] to [index_end] in myArray and places all strings onto the stack. The strings on the stack can then be looped through via Pop until a specific string is reached.
Note: If [index_end] is a negative number, the end range will be up to the end of the array minus [index_end] inclusive, and so -1 will be up to and including the last item in the array.

Push "stop_popping"
NSISArray::ReadToStack /NOUNLOAD myArray 0 -1
Loop:
Pop $R0
StrCmp $R0 "stop_popping" Done
...do something here...
Goto Loop
Done:

#### 2.5.7 NSISArray::Cut /NOUNLOAD myArray [index]
Pop $Var

Cuts a string from myArray at [index]. The string is placed onto the stack ready for a Pop $Var. Any proceeding array items are moved down by one.

#### 2.5.8 NSISArray::Push /NOUNLOAD myArray "string"

Pushes "string" to the front of myArray.

#### 2.5.9 NSISArray::Pop /NOUNLOAD myArray
Pop $Var

Pops a string from the front of myArray onto the stack ready for a Pop $Var.

#### 2.5.10 NSISArray::Shift /NOUNLOAD myArray "string"

Pushes a string to the end of myArray.

#### 2.5.11 NSISArray::Unshift /NOUNLOAD myArray
Pop $Var

Pops a string from the end of myArray and places the string onto the stack ready for a Pop $Var.

#### 2.5.12 NSISArray::Reverse /NOUNLOAD myArray

Reverses the contents of myArray.

#### 2.5.13 NSISArray::Sort /NOUNLOAD myArray myArray2

Sorts the contents of myArray alphabetically or numerically, also rearranging the contents of myArray2 into the same order.
The myArray2 parameter is optional (it can be left empty "").

#### 2.5.14 NSISArray::Clear /NOUNLOAD myArray

Clears the contents of myArray. All items are removed and the array size is reset to 0.

#### 2.5.15 NSISArray::Splice /NOUNLOAD

myArray [index_start] [index_end] '"string 1" "string 2" ... '

Places a list of strings at [index_start] replacing existing array items up to but not including [index_end]. If [index_start] and [index_end] are equal, no existing array items are overwritten.

Specifying no list of strings ('') before /END will result in items from [index_start] up to [index_end] exclusive being deleted.

If [index_end] is a negative number, the end range will be up to the end of the array minus [index_end] inclusive, and so -1 will be up to and including the last item in the array.

#### 2.5.16 NSISArray::Swap /NOUNLOAD myArray [index_1] [index_2]

Swaps the strings in the two indexes in myArray.

#### 2.5.17 NSISArray::Copy /NOUNLOAD myArray myArray2

Copies the contents of myArray to myArray2, overwriting any existing items.

#### 2.5.18 NSISArray::Join /NOUNLOAD myArray myArray2

Copies the contents of myArray onto the end of myArray2.

#### 2.5.19 NSISArray::Concat /NOUNLOAD myArray [join_char(s)]
Pop $Var

Joins all strings in myArray together with [join_char(s)] and places the output onto the stack ready for a Pop $Var.

NSISArray::Join /NOUNLOAD myArray " "
Pop $R0

#### 2.5.20 NSISArray::Exists /NOUNLOAD myArray "string" [index]
Pop $Var

Finds the index of an item that is exactly equal to "string" case sensitively in myArray after [index].
$Var will contain the item index, or -1 if not found.

Note: To search non case sensitively, use NSISArray::ExistsI (that's a capital i) instead of NSISArray::Exists.

#### 2.5.21 NSISArray::Search /NOUNLOAD myArray "string" [index]
Pop $Var

Searches through all items after [index] in myArray for "string" case insensitively, and places the output onto the stack ready for a Pop $Var.
$Var will contain the item index containing the first match, or -1 if not found.

Note: To search non case sensitively, use NSISArray::SearchI (that's a capital i) instead of NSISArray::Search.

#### 2.5.22 NSISArray::SizeOf /NOUNLOAD myArray
Pop $Var1
Pop $Var2
Pop $Var3

For myArray, $Var1 will now contain the allocated buffer length for all strings in the array.
$Var2 will contain the number of allocated array indexes.
$Var3 will contain the number of items (used indexes) in the array.

#### 2.5.23 NSISArray::SetSize /NOUNLOAD myArray [size]

Sets the new size of myArray to [size]. If the array is currently smaller than [size], new empty "" items are added. If the array is currently larger than [size], items are removed until it becomes that size.

Note: This does not allocated more memory for more items to be added. To do so, use NSISArray::ReDim.

#### 2.5.24 NSISArray::ArrayCount /NOUNLOAD
Pop $Var

$Var will contain the number of arrays currently allocated.

#### 2.5.25 NSISArray::ReDim /NOUNLOAD [x] [y]

Redimensions myArray to [x] item indexes and [y] buffer lengths. No existing items will be deleted. If the number of new indexes allocated is less than the number of currently allocated indexes, the excess indexes are deleted. If the new allocated buffer length is less than the currently allocated string length, strings of a greater length are truncated.

The minimum value of [x] can be 1 and the minimum value of [y] can be 2.

Please note that the value for buffer lengths ([y]) must always allow for the NULL character on the end of strings to prevent buffer overflows. For example, if you're only putting single characters in the array, the [y] value must be 2 and not 1.

#### 2.5.26 NSISArray::FreeUnusedMem /NOUNLOAD

Frees unused memory in myArray by deleting empty item indexes and by decreasing the buffer length of all items to fit the largest string in the array. Ideally you should call this after you've finished writing to the array.

#### 2.5.27 NSISArray::Subtract /NOUNLOAD myArray myArray2

Removes items from myArray that are also in myArray2. Items are matched case sensitively.

#### 2.5.28 NSISArray::SetAutoRedim /NOUNLOAD [indexes] [str_len]

Sets the number of indexes and characters to be increased by when the array is to be auto-redimensioned (for extra memory allocation).

If adding lots of items at a time, you should set [indexes] to a larger number than default.

For default values (before or without using this function) and more information on array auto-redimensioning, see section 2.7 Array auto-redimensioning.

For a compilable NSIS script example, see Examples\NSISArray\SetAutoRedim.nsi.

^ Top

## 2.6 Deleting an array object

To delete an array object, use:

NSISArray::Delete /NOUNLOAD myArray

Deleting an array will remove it from memory and you can no longer reference that array.

### 2.6.1 Unloading the NSISArray plug-in

To unload the NSISArray plug-in after use, call:

NSISArray::Unload

You could call this in a Section, or perhaps in the .onGUIEnd function.
We must not use /NOUNLOAD here, so that the plug-in is unloaded from memory. The DLL along with the $PLUGINSDIR folder can then be deleted successfully by the installer without a reboot.

^ Top

## 2.7 Array auto-redimensioning

From NSISArray v1.1 and upwards, arrays are now fully dynamic in both item indexes and buffer lengths.

When an array is full and then a new item is added, the array will be automatically resized to fit the new array item in. 16 more indexes will be allocated by default so that more memory re-allocation will not have to re-occur for another 16 more items being added.

Similarly, when a string is added to the array with a length greater than the allocated buffer length, the array will be resized. 32 more bytes will also be added on top so that the array may not have to be redimensioned again.

For setting the re-allocation amounts, see NSISArray::SetAutoReDim (or ${myArray->SetAutoReDim} for the NSISArray script header).

If you want to free up any excess memory allocated, use NSISArray::FreeUnusedMem (or ${myArray->FreeUnusedMem} for the NSISArray script header). This should really only be used when you've finished writing to the array.

^ Top

## 2.8 Array debugging

### 2.8.1 The array debug dialog

You can easily check the state of an array by calling:

NSISArray::Debug /NOUNLOAD myArray

This will display a debug screen with a list-box containing the array items in myArray, including some general statistics.

There are also buttons to navigate between arrays that are currently in use.

### 2.8.2 Enabling plug-in error messages

By default, you will never get error reports when NSISArray function calls fail. This is so that the least amount of NSIS code is needed when working with the plug-in. However, there are a few error reporting methods available for debugging purposes.

To enable error reporting of a certain style, use:

NSISArray::ErrorStyle /NOUNLOAD [style]

Where [style] is a value from 0 to 5:

Value | Feature
--- | ---
0 | No error reporting is used.
1 | Error codes are placed on the NSIS stack before any return values associated with the function being called.
2 | No stack errors are used but instead the plug-in will display an error message box with the function name, the error code and the message associated with that error code.
3 | Both the stack and error message boxes are enabled.
4 | Error messages are placed in the NSIS InstFiles Page log window. This only works inside a Section.
5 | Both the stack and log window error messages are enabled.

If [style] is empty ("") then the function will place the current error style number (from 0 to 5) on the NSIS stack.

Example:
; Get current ErrorStyle
NSISArray::ErrorStyle /NOUNLOAD ""
Pop $R0 # Current ErrorStyle setting
NSISArray::ErrorStyle /NOUNLOAD 4
; Do something
; Set ErrorStyle back
NSISArray::ErrorStyle /NOUNLOAD $R0

This example demonstrates the use of ErrorStyle 1:
NSISArray::ErrorStyle /NOUNLOAD 1
NSISArray::Read /NOUNLOAD 3
Pop $R0 # Error code (if any)
Pop $R1 # Return value (or "" if error occured)

### 2.8.3 Error messages

Below is a list of possible plug-in errors...

#### 2.8.3.1 "(1) Array name already declared."

This will occur if you try to create two arrays of the same name with NSISArray::New (or ${myArray::Init}).

#### 2.8.3.2 "(2) Parameters error."

This occurs when the incorrect amount of parameters is passed to the NSISArray plug-in, or when an empty ("") value is used for a parameter that should not be empty.

#### 2.8.3.3 "(3) Index out of range."

Specifying an index that is either negative or greater than the number of items already existing in the array will cause this error message to occur.
You can find out the size of an array with NSISArray::SizeOf (or ${myArray->SizeOf}).

#### 2.8.3.4 "(4) Array does not exist."

This occurs when trying to reference an array object that does not exist (has not been created).

#### 2.8.3.5 "(5) Cannot declare any more arrays."

This only occurs with NSISArray::New (or ${myArray->Init}) when you are trying to declare more than 8 arrays.

#### 2.8.3.6 "(6) Memory could not be allocated."

If memory allocation fails for any reason, then this error will be returned. Note that this should only happen when there is no more address space in the program's (NSIS's) default memory heap and each default. Fortunately, all programs are allocated 2GB of address space to work with, so running out of memory in which case is very unlikely.

^ Top

## 2.9 NSIS special build for large strings

There is a special NSIS build on the NSIS website which allows strings to be up to 8191 characters in length. This special build can be used with NSISArray for WriteListC or Concat, where a large amount of items may be added to an array or taken out of an array in one single string variable. NSISArray allocates NSIS_MAX_STRLEN bytes for array input and output. Therefore, using the NSIS 8192 characters string length special build will cause the plug-in to allocate 8192 bytes for all array input and output.

^ Top

## 3.0 Recompiling NSISArray

NSISArray was written in Microsoft Visual C++ 6.

Settings defines can be modified at the top of the main C++ script (NSISArray.cpp). There are individual defines for each individual function.
To perform the recompile, open up the NSISArray.dsw file in Microsoft Visual C++, go to Build > Set Active Configuration and select "NSISArray - Win32 Release". You can then do a Build > Build NSISArray.dll to build the DLL file (which will be placed in the NSIS 'Plugins' folder if you're compiling from NSIS\Contrib\NSISArray).

^ Top

# NSISArray Credits, Changelog & License

## Credits

- NSISArray plug-in written by Afrow UK in Microsoft Visual C++ 6.
- NSISArray plug-in script header written by Afrow UK.
- Documentation written by Afrow UK, style sheet based on Modern UI readme style sheet by Joost Verburg.
- Special thanks to Microsoft for their great article on dynamic arrays in C :) .
- Special thanks to Comperio for bug hunting and his working example scripts for
  NSISArray < v1.0, which many of the current example scripts are based upon.

If you have an issue with NSISArray which you think could be a bug, or you need general help with using NSISArray, please post a topic in the NSISArray plug-in topic on the NSIS Forums at:
http://forums.winamp.com/showthread.php?threadid=22227

## Changelog

- v1.8 (21st May 2008)
  - Empty joining string can be used with Concat.
  - Fixed some memory leaks caused if GlobalAlloc() failed.
  - Fixed crash on debug dialog for strings over 255 characters.

- v1.7 (18th October 2007)
  - Fixed bug with ReadToStack parameters validation.

- v1.6 (12th October 2007)
  - Fixed Subtract function not removing the correct items.
  - Found and fixed memory leak in Delete function.
  - Increased array name buffer size from 16 to 32 bytes.

- v1.5 (8th June 2007)
  - Fixed memory leak in ReDimArray function that caused random crashing.
  - Added GlobalFree calls for local variables using GlobalAlloc (added v1.4).
  - Added some more compiler (script header) and plug-in error messages/codes.
  - Indexes and buffer length increases for array auto-redimensioning is no longer hard-coded. Both can now be changed with the SetAutoReDim function.
  - More source code cleaning.
  - Added more examples and updated old ones.
  - Added more details to debugging dialog.
  - (RC2) Fixed parameter validation in New, ReDim and SetAutoReDim.

- v1.4 (6th June 2007)
  - Removed large 8192 fixed length strings and used the NSIS compiler string length instead.
  - Removed 1024 fixed length strings and used the NSIS compiler string length instead.
  - Added Subtract function.
  - Code cleanup and optimisation.

- v1.3 (27th July 2006)
  - Fixed concat function returning less than NSIS_MAX_STRLEN in characters.
  - Fixed script header SizeOf function accepting parameters in incorrect order (Jnuw).
  - Updated readme missing SizeOf information (Jnuw).
  - Added SizeOf example script.
  - Fixed problems with Write function parameters (and others with the same problem).
  - EnableErrorMsgBox function removed.
  - ErrorStyle function re-added with new parameter types.
  - Added support for error messages in the NSIS InstFiles page log window.
  - Removed ${ArrayEnableErrorMsgBox} from script header and replaced it with ${ArrayErrorStyle} [MsgBox|LogWin|Off].
  - (RC3) Added Off option for ${ArrayErrorStyle}.
  - (RC3) Fixed problem with some functions always returning 0.
  - (RC3) Script header now sets ErrorStyle to 1 which is required.

- v1.2 (26th April 2006)
  - Removed ArrayErrorMsgBox script header setting.
  - Added NSISArray::EnableErrorMsgBox (or ${ArrayEnableErrorMsgBox}) function to enable and disable error message boxes at run time.
  - Added ArraySetErrors script header settings to enable use of SetErrors.
  - Added ArrayValVar script header setting to set $ArrayVar.
  - Added ArrayErrVar script header setting to set $ArrayErr.
  - Cleaned up error reporting code in NSISArray plug-in.
  - Error codes are now always pushed to the stack before anything else.
  - Now even when using EnableErrorMsgBox, error codes are still pushed to the stack before anything else.
  - Script header setting defines can now go after including the script header and before using the ${Array} instruction.

- v1.1 (21st April 2006)
  - Project moved to Microsoft Visual C++ 6 from .NET 2003.
  - Arrays are now dynamic. Added two extra parameters for ${Array} keyword (and New plug-in function) to specify initial array size.
  - Added automatic array memory reallocation if data overflow of both array items and buffer lengths occur.
  - Array items to be deleted are now left undeleted, but marked as deleted for overwriting (more efficient).
  - Where possible, changed swapping/movement/replacement of array data in functions to movement of pointers only. This is much more efficient.
  - Added ReDim plug-in function to increase an array's item and buffer length.
  - Added FreeUnusedMem plug-in function to free unused memory by removing extra allocated items and trimming allocated columns to a length of the highest string length in the array.
  - Added ArrayCount plug-in function to return the number of arrays that have been initialised.
  - Removed ${ArrayUnload} keyword. The Delete script header function now unloads the plug-in by calling the plug-in Unload function when all arrays have been deleted.
  - SizeOf plug-in function now returns three values instead of one. The first is the currently allocated buffer length for array strings, the second being the number of array indexes allocated and the last is the number of array indexes in use.
  - Added Next and Prev buttons to the debug dialog which display statistics and data for the different arrays currently allocated.
  - Removed NSISArray128.dll from distribution.
  - Wrote custom internal strcpy function to prevent buffer over-running and corruption.
  - New internal atoi function used that accepts negative integers.
  - Removed (commented out) calls to internal ClearString due to use of new custom strcpy function.
  - Added C++ compile time defines to enable/disable plug-in functions.
  - Fixed Print script header function (had too many parameters).
  - Fixed problems with error reporting and the NSIS stack.
  - Cleaned all example scripts and C++ source code.
  - Script header functions now require declaration before use with the ${ArrayFunc} keyword.
  - Removed ArrayNoValVar define requirement to disable declaration of $ArrayVal variable.
  - Removed IsEmpty, IsFull and IsInRange functions. The SizeOf function with StrCmp or IntCmp can be used as a replacement.
  - Added ArrayCallInstDLL [dll_path] define so that the script header calls the NSISArray plug-in with CallInstDLL instead of the standard way which stores the plug-in in $PLUGINSDIR.
  - With ArrayCallInstDLL defined, script header functions Splice and WriteList become SpliceBegin, SpliceItem, SpliceEnd and WriteBegin
  - Fixed general bugs with some functions: ReadToStack; WriteListC and a few others.
  - Re-wrote Splice function.

- v1.0 (1st March 2006)
  - Fixed Pop function in plug-in (was taking unnecessary plug-in call parameter).
  - Fixed Pop function in script header (was calling Push instead!)

- v0.9 (6th December 2005)
  - Fixed bug in Sort function. Sort would no longer sort when only using one array.
  - Removed NCB file from source distribution.
  - Fixed ArraySize. Should be 32 not 1024 for default (refers to array items/indexes not buffer lengths).
  - Added code to WriteListC to induce Index out of range error if the number of items being written to the array is bigger than the array itself (the items are still written to the array however).
  - NSISArray128.dll now has a 256 character buffer length for array items.
  - Fixed ReadToStack function which was not working at all!
  - WriteList throws Index out of range error if the number of items being written is greater than the number of indexes in the array.
  - Added source code defines for 256 x 128 arrays.
  - Made all function variables static to fix stack corruption when large variables were being created within functions.
  - Added code to clear the contents of all function variables when done with to prevent transfer of buffer contents from one function call to the next.
  - Added Print [index] function to script header.
  - Fixed Search and SearchI functions (re-wrote my_strstr function).

- v0.8 (17th August 2005)
  - Added IsFull function to script header.
  - Added IsEmpty function to script header.
  - Added IsInRange [index] function to script header.
  - Added ArrayExists / Inited functions.

- v0.7 (14th August 2005)
  - The two arrays must be the same size when using the Sort function.
  - Added SetSize function.
  - Fixed Debug list-box which was set to multi-column.
  - Added ReadFirst, ReadNext & ReadClose script header commands.

- v0.6 (2nd August 2005)
  - szLarge global buffer was not being cleared before use.
  - Added [index] for Exists and ExistsI which defines the index to start searching from.
  - Added [index_start] and [index_end] for ReadToStack.
  - [index_end] for ReadToStack and Splice can be negative (for ranges from the end of an array).
  - Added 23 NSIS example scripts by Comperio (in NSIS\Examples\NSISArray).
  - Added function to set whether to use message boxes or the stack for errors.
  - Added NSISArray::Unload function to unload DLL (for deleting).
  - Added a second parameter to the Sort function which can be of another array name to be rearranged into the same order as the sorted array (works like associative arrays).

- v0.5 (1st August 2005)
  - Fixed bug with Debug where it was getting the array index from latoi instead of getArrayByName.
  - Search is case sensitive; added SearchI which is case insensitive.
  - ReadToStack was returning array items in order which meant Pop[ping] them would be in reverse order.
  - Some old pre v0.1 code was still in NSISArray.nsh.
  - Fixed Splice where the 2nd index parameter should be up to but not including [index].
  - szLarge global buffer was not being cleared before use.

- v0.4 (29th July 2005)
  - Fixed bug where using Write to an existing array index would still increment array used index count.
  - Fixed WriteListC which generally did not work as it should :p .
  - Fixed Put function which had a bad loop causing it to fail.

- v0.3 (28th July 2005)
  - Fixed SizeOf function returning zero-based array size (which would be false).

- v0.2 (25th July 2005)
  - Fixed parameters error with SizeOf.
  - Fixed parameters error with Search macro in NSISArray.nsh.

- v0.1 (23rd July 2005)
  - First set of array functions.
  - Array debug dialog.
  - Two plug-in builds for array types.

## License

    Copyright © 2007 Afrow UK

    This software is provided 'as-is', without any express or implied
    warranty. In no event will the authors be held liable for any damages
    arising from the use of this software.

    Permission is granted to anyone to use this software for any purpose,
    including commercial applications, and to alter it and redistribute
    it freely, subject to the following restrictions:

    1. The origin of this software must not be misrepresented;
       you must not claim that you wrote the original software.
       If you use this software in a product, an acknowledgment in the
       product documentation would be appreciated but is not required.
    2. Altered versions must be plainly marked as such,
       and must not be misrepresented as being the original software.
    3. This notice may not be removed or altered from any distribution.