/* nsArray NSIS plug-in by Stuart Welch v1.1.1.7 - 2nd December 2014 */ #include #include "nsArray.h" #include "Array.h" #include "pluginapi.h" HANDLE g_hInstance; extern struct LIST g_arrays; // Frees memory on plug-in unload. static UINT_PTR PluginCallback(enum NSPIM msg) { if (msg == NSPIM_UNLOAD) { UnInitArrays(); } return 0; } int lstrcmpn(TCHAR* a, TCHAR* b, int m, BOOL bIgnoreCase) { int i, j; for (i = 0, j = 0; j < m; i++, j++) { TCHAR ca = bIgnoreCase ? LOWORD(CharLower((LPTSTR)a[i])) : a[i]; TCHAR cb = bIgnoreCase ? LOWORD(CharLower((LPTSTR)b[j])) : b[j]; if (ca < cb) return -1; if (ca > cb) return 1; } return 0; } // Gets the number of elements in an array. NSISFUNC(Length) { DLL_INIT(); { BOOL bOK = FALSE; ALLOC_C(TCHAR, pArg, string_size); if (popstring(pArg) == 0) { struct ARRAY* pArray = GetArray(pArg); if (pArray != NULL) { wsprintf(pArg, TEXT("%d"), pArray->nCount); pushstring(pArg); bOK = TRUE; } } FREE(pArg); if (!bOK) extra->exec_flags->exec_error = 1; } } // Gets a single element in an array. NSISFUNC(Get) { DLL_INIT(); { BOOL bOK = FALSE; ALLOC_C(TCHAR, pArg, string_size); if (popstring(pArg) == 0) { struct ARRAY* pArray = GetArray(pArg); if (popstring(pArg) == 0 && pArray != NULL) { struct ELEMENT* pElement; BOOL bDataOnly = FALSE; if (lstrcmpn(pArg, TEXT("/at="), 4, TRUE) == 0) { pElement = GetElementAt(pArray, myatoi(pArg + 4)); } else { pElement = GetElement(pArray, pArg); bDataOnly = TRUE; } if (pElement != NULL) { pushstring(pElement->pData); if (!bDataOnly) pushstring(pElement->pKey); bOK = TRUE; } } } FREE(pArg); if (!bOK) extra->exec_flags->exec_error = 1; } } // Adds a single value to an array. NSISFUNC(Set) { DLL_INIT(); { BOOL bOK = FALSE; ALLOC_C(TCHAR, pArg, string_size); if (popstring(pArg) == 0) { struct ARRAY* pArray = GetArray(pArg); ALLOC_C(TCHAR, pKey, string_size); if (pArray == NULL) pArray = NewArray(pArg); if (popstring(pArg) == 0) { if (lstrcmpn(pArg, TEXT("/at="), 4, TRUE) == 0) { struct ELEMENT* pElement = GetElementAt(pArray, myatoi(pArg + 4)); if (popstring(pArg) == 0 && pElement != NULL) { SetElementData(pElement, pArg); bOK = TRUE; } } else if (lstrcmpn(pArg, TEXT("/key="), 5, TRUE) == 0) { lstrcpy(pKey, pArg + 5); if (popstring(pArg) == 0 && NewElement(pArray, pKey, pArg) != NULL) bOK = TRUE; } else { GetNextIndex(pArray, pKey); if (NewElement(pArray, pKey, pArg) != NULL) bOK = TRUE; } } FREE(pKey); } FREE(pArg); if (!bOK) extra->exec_flags->exec_error = 1; } } // Adds one or more values to an array. NSISFUNC(SetList) { DLL_INIT(); { int bOK = FALSE; ALLOC_C(TCHAR, pArg, string_size); if (popstring(pArg) == 0) { struct ARRAY* pArray = GetArray(pArg); ALLOC_C(TCHAR, pKey, string_size); if (pArray == NULL) pArray = NewArray(pArg); bOK = TRUE; while (popstring(pArg) == 0) { if (lstrcmpi(pArg, TEXT("/end")) == 0) break; if (lstrcmpn(pArg, TEXT("/at="), 4, TRUE) == 0) { struct ELEMENT* pElement = GetElementAt(pArray, myatoi(pArg + 4)); if (popstring(pArg) == 0 && pElement != NULL) SetElementData(pElement, pArg); else bOK = FALSE; } else if (lstrcmpn(pArg, TEXT("/key="), 5, TRUE) == 0) { lstrcpy(pKey, pArg + 5); if (popstring(pArg) != 0 || NewElement(pArray, pKey, pArg) == NULL) bOK = FALSE; } else { GetNextIndex(pArray, pKey); if (NewElement(pArray, pKey, pArg) == NULL) bOK = FALSE; } } FREE(pKey); } FREE(pArg); if (!bOK) extra->exec_flags->exec_error = 1; } } // Removes a single value from an array. NSISFUNC(Remove) { DLL_INIT(); { BOOL bOK = FALSE; ALLOC_C(TCHAR, pArg, string_size); if (popstring(pArg) == 0) { BOOL fList = FALSE; struct ARRAY* pArray = GetArray(pArg); if (popstring(pArg) == 0) { struct ELEMENT* pElement; if (lstrcmpn(pArg, TEXT("/at="), 4, TRUE) == 0) { pElement = GetElementAt(pArray, myatoi(pArg + 4)); } else if (lstrcmpn(pArg, TEXT("/val="), 5, TRUE) == 0) { pElement = GetElementByVal(pArray, pArg + 5); } else { pElement = GetElement(pArray, pArg); } if (pElement != NULL) { DeleteElement(pArray, pElement); bOK = TRUE; } } } FREE(pArg); if (!bOK) extra->exec_flags->exec_error = 1; } } // Removes one or more values from an array. NSISFUNC(RemoveList) { DLL_INIT(); { BOOL bOK = FALSE; ALLOC_C(TCHAR, pArg, string_size); if (popstring(pArg) == 0) { struct ARRAY* pArray = GetArray(pArg); bOK = TRUE; while (popstring(pArg) == 0) { if (lstrcmpi(pArg, TEXT("/end")) == 0) break; if (pArray != NULL) { struct ELEMENT* pElement; if (lstrcmpn(pArg, TEXT("/at="), 4, TRUE) == 0) { pElement = GetElementAt(pArray, myatoi(pArg + 4)); } else if (lstrcmpn(pArg, TEXT("/val="), 5, TRUE) == 0) { pElement = GetElementByVal(pArray, pArg + 5); } else { pElement = GetElement(pArray, pArg); } if (pElement != NULL) DeleteElement(pArray, pElement); else bOK = FALSE; } } } FREE(pArg); if (!bOK) extra->exec_flags->exec_error = 1; } } // Iterates through array elements. NSISFUNC(Iterate) { DLL_INIT(); { BOOL bOK = FALSE; ALLOC_C(TCHAR, pArg, string_size); if (popstring(pArg) == 0) { struct ARRAY* pArray = GetArray(pArg); BOOL bNext = TRUE; struct ELEMENT* pElement = NULL; if (popstring(pArg) == 0) { if (lstrcmpi(pArg, TEXT("/reset")) == 0) { if (pArray != NULL) { pArray->pCurrentElement = NULL; bOK = TRUE; } bNext = FALSE; } else if (lstrcmpi(pArg, TEXT("/prev")) == 0) { if (pArray != NULL) { pElement = GetPrevElement(pArray); } bNext = FALSE; } else { pushstring(pArg); } } if (bNext && pArray != NULL) { pElement = GetNextElement(pArray); } if (pElement != NULL) { pushstring(pElement->pData); pushstring(pElement->pKey); bOK = TRUE; } } FREE(pArg); if (!bOK) extra->exec_flags->exec_error = 1; } } #ifdef ARRAY_CLEAR // Removes all elements from an array. NSISFUNC(Clear) { DLL_INIT(); { BOOL bOK = FALSE; ALLOC_C(TCHAR, pArg, string_size); if (popstring(pArg) == 0) { struct ARRAY* pArray = GetArray(pArg); if (pArray != NULL) { ClearArray(pArray); bOK = TRUE; } } FREE(pArg); if (!bOK) extra->exec_flags->exec_error = 1; } } #endif #ifdef ARRAY_SORT // Sorts the array. NSISFUNC(Sort) { DLL_INIT(); { BOOL bOK = FALSE; ALLOC_C(TCHAR, pArg, string_size); if (popstring(pArg) == 0) { struct ARRAY* pArray = GetArray(pArg); if (popstring(pArg) == 0 && pArray != NULL) { SortArray(pArray, (enum SA_FLAGS)myatoi_or(pArg)); bOK = TRUE; } } FREE(pArg); if (!bOK) extra->exec_flags->exec_error = 1; } } #endif #ifdef ARRAY_COPY // Copies an array to a new array. NSISFUNC(Copy) { DLL_INIT(); { BOOL bOK = FALSE; ALLOC_C(TCHAR, pArg, string_size); if (popstring(pArg) == 0) { struct ARRAY* pArray = GetArray(pArg); if (popstring(pArg) == 0 && pArray != NULL && CopyArray(pArray, pArg) != NULL) bOK = TRUE; } FREE(pArg); if (!bOK) extra->exec_flags->exec_error = 1; } } // Copies an array's keys to a new array. NSISFUNC(CopyKeys) { DLL_INIT(); { BOOL bOK = FALSE; ALLOC_C(TCHAR, pArg, string_size); if (popstring(pArg) == 0) { struct ARRAY* pArray = GetArray(pArg); if (popstring(pArg) == 0 && pArray != NULL && CopyArrayKeys(pArray, pArg) != NULL) bOK = TRUE; } FREE(pArg); if (!bOK) extra->exec_flags->exec_error = 1; } } #endif #ifdef ARRAY_JOIN // Joins the elements of the array into a string. NSISFUNC(Join) { DLL_INIT(); { BOOL bOK = FALSE; ALLOC_C(TCHAR, pArg, string_size); if (popstring(pArg) == 0) { struct ARRAY* pArray = GetArray(pArg); if (popstring(pArg) == 0 && pArray != NULL) { ALLOC_C(TCHAR, pJoined, string_size); struct ELEMENT* pElement = pArray->pFirstElement; int chars = 0, joinLen = lstrlen(pArg); BOOL bNoEmpty = FALSE; if (popstring(pJoined) == 0) { if (lstrcmpi(pJoined, TEXT("/noempty")) == 0) bNoEmpty = TRUE; else pushstring(pJoined); } bOK = TRUE; lstrcpy(pJoined, TEXT("")); while (pElement != NULL) { if (*pElement->pData || !bNoEmpty) { int length = lstrlen(pElement->pData); lstrcpyn(pJoined + chars, pElement->pData, string_size - chars - 1); chars += length; if (chars >= string_size) { bOK = FALSE; break; } if (pElement->pNext != NULL && (*pElement->pNext->pData || !bNoEmpty)) { lstrcpyn(pJoined + chars, pArg, string_size - chars - 1); chars += joinLen; } if (chars >= string_size) { bOK = FALSE; break; } } pElement = pElement->pNext; } pushstring(pJoined); FREE(pJoined); } } FREE(pArg); if (!bOK) extra->exec_flags->exec_error = 1; } } #endif #ifdef ARRAY_SPLIT // Splits a string into an array using a delimiter string. NSISFUNC(Split) { DLL_INIT(); { BOOL bOK = FALSE; ALLOC_C(TCHAR, pArg, string_size + 1); if (popstring(pArg) == 0) { struct ARRAY* pArray = GetArray(pArg); ALLOC_C(TCHAR, pDel, string_size); if (pArray == NULL) pArray = NewArray(pArg); if (popstring(pArg) == 0 && popstring(pDel) == 0 && pArray != NULL) { int i, j, nDel = lstrlen(pDel), nArg = lstrlen(pArg); ALLOC_C(TCHAR, pKey, string_size); ALLOC_C(TCHAR, pVal, string_size); BOOL bNoEmpty = FALSE; BOOL bIgnoreCase = FALSE; while (popstring(pKey) == 0) { if (lstrcmpi(pKey, TEXT("/noempty")) == 0) { bNoEmpty = TRUE; } else if (lstrcmpi(pKey, TEXT("/ignorecase")) == 0) { bIgnoreCase = TRUE; } else { pushstring(pKey); break; } } pVal[0] = (TCHAR)NULL; if (nArg == 0 && !bNoEmpty) { GetNextIndex(pArray, pKey); NewElement(pArray, pKey, TEXT("")); } for (i = 0, j = 0; i <= nArg; i++) { if (!*pDel) { GetNextIndex(pArray, pKey); pVal[0] = pArg[i]; pVal[1] = (TCHAR)NULL; NewElement(pArray, pKey, pVal); } else { if (lstrcmpn(pArg + i, pDel, nDel, bIgnoreCase) == 0) { if (*pVal || !bNoEmpty) { GetNextIndex(pArray, pKey); NewElement(pArray, pKey, pVal); } i += nDel - 1; pVal[0] = (TCHAR)NULL; j = 0; } else { pVal[j] = pArg[i]; pVal[j + 1] = (TCHAR)NULL; j++; } } } if (j > 0 && (*pVal || !bNoEmpty)) { GetNextIndex(pArray, pKey); NewElement(pArray, pKey, pVal); } FREE(pKey); FREE(pVal); } FREE(pDel); } FREE(pArg); if (!bOK) extra->exec_flags->exec_error = 1; } } #endif #ifdef ARRAY_TOSTRING // Returns a string representation of the array. NSISFUNC(ToString) { DLL_INIT(); { BOOL bOK = FALSE; ALLOC_C(TCHAR, pArg, string_size); if (popstring(pArg) == 0) { struct ARRAY* pArray = GetArray(pArg); if (pArray != NULL) { ALLOC_C(TCHAR, pJoined, string_size); struct ELEMENT* pElement = pArray->pFirstElement; int chars = 0; bOK = TRUE; lstrcpy(pJoined, TEXT("")); while (pElement != NULL) { int length = lstrlen(pElement->pKey); lstrcpyn(pJoined + chars, pElement->pKey, string_size - chars - 1); chars += length; if (chars >= string_size) { bOK = FALSE; break; } lstrcpyn(pJoined + chars, TEXT(" => "), string_size - chars - 1); chars += 4; if (chars >= string_size) { bOK = FALSE; break; } length = lstrlen(pElement->pData); lstrcpyn(pJoined + chars, pElement->pData, string_size - chars - 1); chars += length; if (chars >= string_size) { bOK = FALSE; break; } if (pElement->pNext != NULL) { lstrcpyn(pJoined + chars, TEXT(", "), string_size - chars - 1); chars += 2; } if (chars >= string_size) { bOK = FALSE; break; } pElement = pElement->pNext; } pushstring(pJoined); FREE(pJoined); } } FREE(pArg); if (!bOK) extra->exec_flags->exec_error = 1; } } #endif #ifdef ARRAY_REVERSE // Reverses the contents of an array. NSISFUNC(Reverse) { DLL_INIT(); { BOOL bOK = FALSE; ALLOC_C(TCHAR, pArg, string_size); if (popstring(pArg) == 0) { struct ARRAY* pArray = GetArray(pArg); if (pArray != NULL) { ReverseArray(pArray); bOK = TRUE; } } FREE(pArg); if (!bOK) extra->exec_flags->exec_error = 1; } } #endif BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) { g_hInstance = hInst; if (ul_reason_for_call == DLL_PROCESS_ATTACH) { InitArrays(); } return TRUE; }