fix conflicts

Signed-off-by: SergeySlice <sergey.slice@gmail.com>
This commit is contained in:
SergeySlice 2020-05-03 20:20:34 +03:00
commit 486f6473ff
15 changed files with 479 additions and 183 deletions

View File

@ -656,8 +656,8 @@
955BEE1123C6B43C00425AB0 /* ThemeManager */,
95E68AC9235B862F002B37A5 /* AppDelegate.swift */,
95C5152E236A0A7400E4A3A8 /* SettingsView.swift */,
95696B7A2401829800AFAD37 /* GengConfig.swift */,
95C51535236B1F7700E4A3A8 /* RunAtLogin.swift */,
95696B7A2401829800AFAD37 /* GengConfig.swift */,
95E68ACB235B862F002B37A5 /* ViewController.swift */,
95E68ADE235B86A1002B37A5 /* bdmesg.swift */,
955689DA23A2728000AD323C /* IO.swift */,

View File

@ -10,6 +10,7 @@ import Cocoa
import ServiceManagement
extension AppDelegate {
//MARK: new login item methods (but buggie)
func setLaunchAtStartup() {
let success : Bool = SMLoginItemSetEnabled(gHelperID, true)
UDs.set(success, forKey: kRunAtLogin)
@ -21,4 +22,99 @@ extension AppDelegate {
UDs.set(success ? false : true, forKey: kRunAtLogin)
UDs.synchronize()
}
//MARK: old login item methods (but working)
func getLoginItemURL(for item: LSSharedFileListItem) -> URL? {
var url : URL? = nil
if #available(OSX 10.10, *) {
url = LSSharedFileListItemCopyResolvedURL(item, 0, nil)?.takeRetainedValue() as URL?
} else {
var ItemURL : Unmanaged<CFURL>? = nil
let flags : UInt32 = UInt32(kLSSharedFileListNoUserInteraction | kLSSharedFileListDoNotMountVolumes)
LSSharedFileListItemResolve(item, flags, &ItemURL, nil)
url = ItemURL?.takeRetainedValue() as URL?
}
return url
}
func addAsLoginItem() -> Bool {
var found : Bool = false
let currentUrl = Bundle.main.bundleURL
if let sharedFileList = LSSharedFileListCreate(nil,
kLSSharedFileListSessionLoginItems.takeRetainedValue(),
nil)?.takeRetainedValue() {
if let snapshot = LSSharedFileListCopySnapshot(sharedFileList,
nil).takeRetainedValue() as? [LSSharedFileListItem] {
for item in snapshot {
if let itemUrl = self.getLoginItemURL(for: item) {
guard let info = NSDictionary(contentsOfFile: itemUrl.path.addPath("Contents/Info.plist")) as? [String: Any] else { continue }
let bi = info[kCFBundleIdentifierKey as String] as? String
if bi == Bundle.main.bundleIdentifier {
// is Clover.app, but is the current one?
if itemUrl == currentUrl {
found = true
} else {
LSSharedFileListItemRemove(sharedFileList, item)
}
}
}
}
}
if !found {
LSSharedFileListInsertItemURL(sharedFileList,
kLSSharedFileListItemBeforeFirst.takeRetainedValue(),
nil,
nil,
currentUrl as CFURL,
nil,
nil)
found = true
}
}
return found
}
func removeAsLoginItem() -> Bool {
// remove any Clover.app logged in
self.removeLaunchAtStartup() // call new method too (just in case store login item somewhere..)
let sharedFileList = LSSharedFileListCreate(nil,
kLSSharedFileListSessionLoginItems.takeRetainedValue(),
nil).takeRetainedValue()
if let snapshot = LSSharedFileListCopySnapshot(sharedFileList, nil).takeRetainedValue() as? [LSSharedFileListItem] {
for item in snapshot {
if let url = self.getLoginItemURL(for: item) {
guard let info = NSDictionary(contentsOfFile: url.path.addPath("Contents/Info.plist")) as? [String: Any] else { continue }
let bi = info[kCFBundleIdentifierKey as String] as? String
if bi == Bundle.main.bundleIdentifier {
let status = LSSharedFileListItemRemove(sharedFileList, item)
return status == 0
}
}
}
}
return true
}
func amILoginItem() -> Bool {
let sharedFileList = LSSharedFileListCreate(nil,
kLSSharedFileListSessionLoginItems.takeRetainedValue(),
nil).takeRetainedValue()
if let snapshot = LSSharedFileListCopySnapshot(sharedFileList, nil).takeRetainedValue() as? [LSSharedFileListItem] {
for item in snapshot {
if let url = self.getLoginItemURL(for: item) {
guard let info = NSDictionary(contentsOfFile: url.path.addPath("Contents/Info.plist")) as? [String: Any] else { continue }
let bi = info[kCFBundleIdentifierKey as String] as? String
if bi == Bundle.main.bundleIdentifier && url == Bundle.main.bundleURL {
return true
}
}
}
}
return false
}
}

View File

@ -202,7 +202,7 @@ final class SettingsViewController:
self.progressBar.isHidden = true
self.runAtLoginButton.state = UDs.bool(forKey: kRunAtLogin) ? .on : .off
self.runAtLoginButton.state = AppSD.amILoginItem() ? .on : .off
self.unmountButton.isEnabled = false
self.autoMountButton.isEnabled = false
self.autoMountButton.isHidden = true
@ -963,13 +963,15 @@ final class SettingsViewController:
// MARK: Run At Login
@IBAction func runAtLogin(_ sender: NSButton!) {
if sender.state == .on {
AppSD.setLaunchAtStartup()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
sender.state = AppSD.addAsLoginItem() ? .on : .off
}
} else {
AppSD.removeLaunchAtStartup()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
//sender.state = AppSD.removeAsLoginItem() ? .on : .off
_ = AppSD.removeAsLoginItem()
}
}
// check the result
sender.state = UDs.bool(forKey: kRunAtLogin) ? .on : .off
}
// MARK: NVRAM editing

View File

@ -8,7 +8,7 @@
import Foundation
let daemonVersion = "1.1.3"
let daemonVersion = "1.1.4"
let fm = FileManager.default
@ -277,13 +277,12 @@ func main() {
}
if fm.fileExists(atPath: logPath) {
if let log : String? = try? String(contentsOfFile: logPath) {
if let lines = log?.components(separatedBy: CharacterSet.newlines) {
if lines.count > logLinesMax {
// take only latests
run(cmd: "tail -n \(logLinesMax) \(logPath) 2>/dev/null > \(logPath).tmp")
run(cmd: "mv -f \(logPath).tmp \(logPath)")
}
if let log = try? String(contentsOfFile: logPath) {
let lines = log.components(separatedBy: CharacterSet.newlines)
if lines.count > logLinesMax {
// take only latests
run(cmd: "tail -n \(logLinesMax) \(logPath) 2>/dev/null > \(logPath).tmp")
run(cmd: "mv -f \(logPath).tmp \(logPath)")
}
}
}

View File

@ -528,7 +528,7 @@ uint32_t getUptimeInMilliseconds()
#endif
#endif //PRINTF_LITE_TIMESTAMP_SUPPORT
#ifdef __GNUC__
#ifdef __clang__
static void print_longlong(INT_BIGGEST_TYPE v, unsigned int base, PrintfParams* printfParams) __attribute__((no_sanitize("undefined"))); // disable sanitize because we'll do -v
#endif

View File

@ -831,8 +831,8 @@ CopyKernelAndKextPatches (IN OUT KERNEL_AND_KEXT_PATCHES *Dst,
Dst->KernelPatches[Dst->NrKernels].StartPattern = NULL;
Dst->KernelPatches[Dst->NrKernels].StartMask = NULL;
}
Dst->KernelPatches[Dst->NrKernels].StartPatternLen = Src->KernelPatches[Dst->NrKernels].StartPatternLen;
Dst->KernelPatches[Dst->NrKernels].SearchLen = Src->KernelPatches[Dst->NrKernels].SearchLen;
Dst->KernelPatches[Dst->NrKernels].StartPatternLen = Src->KernelPatches[i].StartPatternLen;
Dst->KernelPatches[Dst->NrKernels].SearchLen = Src->KernelPatches[i].SearchLen;
if (Src->KernelPatches[i].ProcedureName != NULL) {
INTN len = strlen(Src->KernelPatches[i].ProcedureName);
Dst->KernelPatches[Dst->NrKernels].ProcedureName = (__typeof__(Dst->KernelPatches[Dst->NrKernels].ProcedureName))AllocateCopyPool(len, Src->KernelPatches[i].ProcedureName);

View File

@ -1941,6 +1941,10 @@ BOOLEAN
LOADER_ENTRY::KernelUserPatch(IN UINT8 *UKernelData)
{
INTN Num, i = 0, y = 0;
// if we modify directly KernelAndKextPatches->KernelPatches[i].SearchLen, it will wrong for next driver
UINTN SearchLen = KernelAndKextPatches->KernelPatches[i].SearchLen;
// old confuse
// We are using KernelAndKextPatches as set by Custom Entries.
// while config patches go to gSettings.KernelAndKextPatches
@ -1957,14 +1961,14 @@ LOADER_ENTRY::KernelUserPatch(IN UINT8 *UKernelData)
UINTN procLen = 0;
UINTN procAddr = searchProc(UKernelData, KernelAndKextPatches->KernelPatches[i].ProcedureName, &procLen);
DBG_RT("procedure %s found at 0x%llx\n", KernelAndKextPatches->KernelPatches[i].ProcedureName, procAddr);
if (KernelAndKextPatches->KernelPatches[i].SearchLen == 0) {
KernelAndKextPatches->KernelPatches[i].SearchLen = KERNEL_MAX_SIZE;
if (SearchLen == 0) {
SearchLen = KERNEL_MAX_SIZE;
if (procLen > KERNEL_MAX_SIZE) {
procLen = KERNEL_MAX_SIZE - procAddr;
once = true;
}
} else {
procLen = KernelAndKextPatches->KernelPatches[i].SearchLen;
procLen = SearchLen;
}
UINT8 * curs = &UKernelData[procAddr];
UINTN j = 0;
@ -1988,8 +1992,8 @@ LOADER_ENTRY::KernelUserPatch(IN UINT8 *UKernelData)
if (Num) {
y++;
curs += KernelAndKextPatches->KernelPatches[i].SearchLen - 1;
j += KernelAndKextPatches->KernelPatches[i].SearchLen - 1;
curs += SearchLen - 1;
j += SearchLen - 1;
}
DBG_RT( "==> %s : %lld replaces done\n", Num ? "Success" : "Error", Num);
if (once ||
@ -2012,8 +2016,12 @@ BOOLEAN
LOADER_ENTRY::BooterPatch(IN UINT8 *BooterData, IN UINT64 BooterSize)
{
INTN Num, i = 0, y = 0;
if (!KernelAndKextPatches->BootPatches[i].SearchLen) {
KernelAndKextPatches->BootPatches[i].SearchLen = BooterSize;
// if we modify directly KernelAndKextPatches->BootPatches[i].SearchLen, it will wrong for next driver
UINTN SearchLen = KernelAndKextPatches->BootPatches[i].SearchLen;
if (!SearchLen) {
SearchLen = BooterSize;
}
for (; i < KernelAndKextPatches->NrBoots; ++i) {
DBG_RT( "Patch[%lld]: %s\n", i, KernelAndKextPatches->BootPatches[i].Label);
@ -2033,7 +2041,7 @@ LOADER_ENTRY::BooterPatch(IN UINT8 *BooterData, IN UINT64 BooterSize)
DBG_RT( " StartPattern found\n");
Num = SearchAndReplaceMask(curs,
KernelAndKextPatches->BootPatches[i].SearchLen,
SearchLen,
(const UINT8*)KernelAndKextPatches->BootPatches[i].Data,
(const UINT8*)KernelAndKextPatches->BootPatches[i].MaskFind,
KernelAndKextPatches->BootPatches[i].DataLen,
@ -2043,8 +2051,8 @@ LOADER_ENTRY::BooterPatch(IN UINT8 *BooterData, IN UINT64 BooterSize)
);
if (Num) {
y++;
curs += KernelAndKextPatches->KernelPatches[i].SearchLen - 1;
j += KernelAndKextPatches->KernelPatches[i].SearchLen - 1;
curs += SearchLen - 1;
j += SearchLen - 1;
}
DBG_RT( "==> %s : %lld replaces done\n", Num ? "Success" : "Error", Num);

View File

@ -9,7 +9,7 @@
#include "kernel_patcher.h"
#define OLD_METHOD 0
#define OLD_METHOD 1
#ifndef DEBUG_ALL
@ -1018,16 +1018,20 @@ VOID LOADER_ENTRY::AnyKextPatch(UINT8 *Driver, UINT32 DriverSize, CHAR8 *InfoPli
UINTN Num = 0;
INTN Ind;
// if we modify value directly at KernelAndKextPatches->KextPatches[N].SearchLen, it will be wrong for next driver
UINTN SearchLen = KernelAndKextPatches->KextPatches[N].SearchLen;
DBG_RT("\nAnyKextPatch %d: driverAddr = %llx, driverSize = %x\nAnyKext = %s\n",
N, (UINTN)Driver, DriverSize, KernelAndKextPatches->KextPatches[N].Label);
if (!KernelAndKextPatches->KextPatches[N].MenuItem.BValue) {
return;
}
DBG_RT("\nAnyKextPatch %d: driverAddr = %llx, driverSize = %x\nAnyKext = %s\n",
N, (UINTN)Driver, DriverSize, KernelAndKextPatches->KextPatches[N].Label);
if (!KernelAndKextPatches->KextPatches[N].SearchLen ||
(KernelAndKextPatches->KextPatches[N].SearchLen > DriverSize)) {
KernelAndKextPatches->KextPatches[N].SearchLen = DriverSize;
if (!SearchLen ||
(SearchLen > DriverSize)) {
SearchLen = DriverSize;
}
if (KernelAndKextPatches->KPDebug) {
@ -1043,12 +1047,12 @@ VOID LOADER_ENTRY::AnyKextPatch(UINT8 *Driver, UINT32 DriverSize, CHAR8 *InfoPli
UINTN procLen = 0;
UINTN procAddr = searchProcInDriver(Driver, DriverSize, KernelAndKextPatches->KextPatches[N].ProcedureName);
if (KernelAndKextPatches->KextPatches[N].SearchLen == 0) {
KernelAndKextPatches->KextPatches[N].SearchLen = DriverSize;
procLen = DriverSize - procAddr;
once = true;
if (SearchLen == 0) {
SearchLen = DriverSize;
procLen = DriverSize - procAddr;
once = true;
} else {
procLen = KernelAndKextPatches->KextPatches[N].SearchLen;
procLen = SearchLen;
}
UINT8 * curs = &Driver[procAddr];
UINTN j = 0;
@ -1070,8 +1074,8 @@ VOID LOADER_ENTRY::AnyKextPatch(UINT8 *Driver, UINT32 DriverSize, CHAR8 *InfoPli
(const UINT8*)KernelAndKextPatches->KextPatches[N].MaskReplace,
-1);
if (Num) {
curs += KernelAndKextPatches->KextPatches[N].SearchLen - 1;
j += KernelAndKextPatches->KextPatches[N].SearchLen - 1;
curs += SearchLen - 1;
j += SearchLen - 1;
}
}
if (once ||

View File

@ -84,9 +84,9 @@ class XObjArrayNC
}
// This was useful for realtime debugging with a debugger that do not recognise references. That was years and years ago. Probably not needed anymore.
#ifdef _DEBUG_iufasdfsfk
// #ifdef _DEBUG_iufasdfsfk
const TYPE *DbgAt(int i) const { if ( i >= 0 && (xsize)i < _Len ) return &ElementAt ((xsize) i); else return NULL; }
#endif
// #endif
template<typename IntegralType, enable_if(is_integral(IntegralType))>
const TYPE &operator[](IntegralType nIndex) const { return ElementAt(nIndex); }
@ -162,12 +162,12 @@ void XObjArrayNC<TYPE>::Init()
m_allocatedSize = 0;
_Len = 0;
// THis was useful for realtime debugging with a debugger that do not recognise references.
#ifdef _DEBUG_iufasdfsfk
// #ifdef _DEBUG_iufasdfsfk
{
const TYPE *tmp;
tmp = DbgAt(0);
}
#endif
// #endif
}
/* Constructeur */

View File

@ -877,8 +877,10 @@ public:
/* takeValueFrom */
template<typename O, class OtherXStringClass>
ThisXStringClass& takeValueFrom(const __String<O, OtherXStringClass>& S) { strcpy(S.s()); return *((ThisXStringClass*)this); }
template<typename O>
ThisXStringClass& takeValueFrom(const O* S) { strcpy(S); return *((ThisXStringClass*)this); }
template<typename O>
ThisXStringClass& takeValueFrom(const O* S) { strcpy(S); return *((ThisXStringClass*)this); }
template<typename O, enable_if(is_char(O))>
ThisXStringClass& takeValueFrom(const O C) { strcpy(C); return *((ThisXStringClass*)this); }
template<typename O, class OtherXStringClass>
ThisXStringClass& takeValueFrom(const __String<O, OtherXStringClass>& S, size_t len) { strncpy(S.data(0), len); return *((ThisXStringClass*)this); }
template<typename O>
@ -943,7 +945,8 @@ struct __lstring_type<T, _xtools__void_t<typename T::xs_t>, _xtools__void_t<type
#define is___LString(x) is___LString_t(x)::value
/* __string_class_or<T1, T2>::type is T1 is T1 is a subclass of __String. If T1 is not a subclass of __String, returns T2 if it's a subclass of __String */
template <typename T1, typename T2, typename Tdummy=void> struct __string_class_or;
template <typename T1, typename T2, typename Tdummy=void>
struct __string_class_or;
template <typename T1, typename T2>
struct __string_class_or<T1, T2, enable_if_t(!is___String(T1) && !is___String(T2))> { /*typedef double type;*/ };
template <typename T1, typename T2>

View File

@ -15,6 +15,47 @@
#include "XString.h"
template<typename T, typename Tdummy=void>
struct _xstringarray__char_type;
template<typename T>
struct _xstringarray__char_type<T*, enable_if_t(is_char(T))>
{
typedef const T* type;
static const T* getCharPtr(T* t) { return t; }
};
//
//template<typename T>
//struct _xstringarray__char_type<const T*, enable_if_t(is_char(T))>
//{
// typedef const T* type;
// static const T* getCharPtr(const T* t) { return t; }
//};
//
//template<typename T>
//struct _xstringarray__char_type<const T[]>
//{
// typedef const T* type;
// static const T* getCharPtr(const T* t) { return t; }
//};
//
//template<typename T, size_t _Np>
//struct _xstringarray__char_type<const T[_Np]>
//{
// typedef const T* type;
// static const T* getCharPtr(const T* t) { return t; }
//};
template<typename T>
struct _xstringarray__char_type<T, enable_if_t(is___String(T))>
{
typedef const char* type;
static const typename T::char_t* getCharPtr(const T& t) { return t.s(); }
};
#define XStringArraySuper XObjArray<XStringClass>
template<class XStringClass_>
@ -44,36 +85,67 @@ class XStringArray_/* : public XStringArraySuper*/
XStringClass& elementAt(IntegralType i) { return array[i]; }
// const XStringClass& dbg(size_t i) const { return array[i]; }
// template<class XStringClass1, class XStringClass2, class XStringClass3, enable_if(is___String(XStringClass1) && is___String(XStringClass2) && is___String(XStringClass3))>
// XStringClass ConcatAll(const XStringClass1& Separator, const XStringClass2& Prefix, const XStringClass3& Suffix) const
// {
// xsize i;
// XStringClass s;
//
// if ( array.size() > 0 ) {
// s = Prefix;
// s += array.ElementAt(0);
// for ( i=1 ; i<array.size() ; i+=1 ) {
// s += Separator;
// s += array.ElementAt(i);
// }
// s += Suffix;
// }
// return s;
// }
template<class Type1, class Type2, class Type3,
enable_if(
( is_char(Type1) || is_char_ptr(Type1) || is___String(Type1) ) &&
( is_char(Type2) || is_char_ptr(Type2) || is___String(Type2) ) &&
( is_char(Type3) || is_char_ptr(Type3) || is___String(Type3) )
)
>
XStringClass ConcatAll(const Type1& Separator, const Type2& Prefix, const Type3& Suffix) const
{
// auto separator = _xstringarray__char_type<Type1>::getCharPtr(Separator);
// auto prefix = _xstringarray__char_type<Type2>::getCharPtr(Prefix);
// auto suffix = _xstringarray__char_type<Type3>::getCharPtr(Suffix);
template<class XStringClass1, class XStringClass2, class XStringClass3, enable_if(is___String(XStringClass1) && is___String(XStringClass2) && is___String(XStringClass3))>
XStringClass ConcatAll(const XStringClass1& Separator, const XStringClass2& Prefix, const XStringClass3& Suffix) const
{
xsize i;
XStringClass s;
if ( array.size() > 0 ) {
s = Prefix;
s += array.ElementAt(0);
for ( i=1 ; i<array.size() ; i+=1 ) {
s += Separator;
s += array.ElementAt(i);
}
s += Suffix;
}
return s;
}
xsize i;
XStringClass s;
if ( array.size() > 0 ) {
s.takeValueFrom(Prefix);
s += array.ElementAt(0);
for ( i=1 ; i<array.size() ; i+=1 ) {
s += Separator;
s += array.ElementAt(i);
}
s += Suffix;
}
return s;
}
XStringClass ConcatAll() const
{
return ConcatAll(", "_XS8, NullXString, NullXString);
return ConcatAll(", ", "", "");
}
template<class XStringClass1, enable_if(is___String(XStringClass1))>
XStringClass ConcatAll(const XStringClass1& Separator) const
{
return ConcatAll(Separator, NullXString, NullXString);
}
// template<class XStringClass1, enable_if(is___String(XStringClass1))>
// XStringClass ConcatAll(const XStringClass1& Separator) const
// {
// return ConcatAll(Separator, NullXString, NullXString);
// }
template<class Type1, enable_if(is_char(Type1) || is_char_ptr(Type1) || is___String(Type1))>
XStringClass ConcatAll(const Type1& Separator) const
{
return ConcatAll(Separator, "", "");
}
template<class OtherXStringArrayClass>
@ -184,8 +256,10 @@ class XStringArray_/* : public XStringArraySuper*/
array.AddReference(xstr, true);
}
void Add(const XStringClass &aString) { array.AddCopy(aString); }
// void Add(const XStringClass &aString) { array.AddCopy(aString); }
template<typename XStringClass1, enable_if(is___String(XStringClass1))>
void Add(const XStringClass1 &aString) { Add(aString.s()); }
void AddReference(XStringClass *newElement, bool FreeIt) { array.AddReference(newElement, FreeIt); }
template<class OtherXStringClass>
void import(const XStringArray_<OtherXStringClass> &aStrings)
@ -270,12 +344,23 @@ extern const XStringWArray NullXStringWArray;
template<class XStringArrayClass, typename CharType1, typename CharType2, enable_if(is_char(CharType1) && is_char(CharType2))>
XStringArrayClass Split(const CharType1* S, const CharType2* Separator)
//template<class XStringArrayClass, typename CharType1, typename CharType2, enable_if(is_char(CharType1) && is_char(CharType2))>
template<class XStringArrayClass, typename Type1, typename Type2,
enable_if(
( is_char_ptr(Type1) || is___String(Type1) ) &&
( is_char_ptr(Type2) || is___String(Type2) )
)
>
XStringArrayClass Split(Type1 S, const Type2 Separator)
{
XStringArrayClass xsArray;
size_t separatorLength = length_of_utf_string(Separator);
auto s = _xstringarray__char_type<Type1>::getCharPtr(S);
auto separator = _xstringarray__char_type<Type2>::getCharPtr(Separator);
// typename _xstringarray__char_type<Type2>::type separator = Separator;
size_t separatorLength = length_of_utf_string(separator);
if ( separatorLength == 0 ) {
typename XStringArrayClass::XStringClass* xstr;
@ -285,18 +370,22 @@ XStringArrayClass Split(const CharType1* S, const CharType2* Separator)
return xsArray;
}
const CharType1* s = S;
// typename _xstringarray__char_type<Type1>::type s = S;
// const CharType1* s = S;
char32_t char32 = 1;
do
{
while ( XStringAbstract__ncompare(s, Separator, separatorLength, false) == 0 ) {
while ( XStringAbstract__ncompare(s, separator, separatorLength, false) == 0 ) {
// I have to implement a move_forward_one_char in unicode_conversions, as we don't care about char32
for ( size_t i = 0 ; i < separatorLength ; i++ ) s = get_char32_from_string(s, &char32);
}
const CharType1* t = s;
if ( !*s ) return xsArray;
auto t = s;
// typename _xstringarray__char_type<Type1>::type t = s;
// const CharType1* t = s;
size_t nb = 0;
while ( char32 && XStringAbstract__ncompare(t, Separator, separatorLength, false) != 0 ) {
while ( char32 && XStringAbstract__ncompare(t, separator, separatorLength, false) != 0 ) {
nb++;
t = get_char32_from_string(t, &char32);
}
@ -321,34 +410,46 @@ XStringArrayClass Split(const CharType1* S, const CharType2* Separator)
// return Split<XStringArrayClass>(SS, XSeparator);
};
template<class XStringArrayClass, class XStringClass1, class XStringClass2, enable_if(is___String(XStringClass1) && is___String(XStringClass2))>
XStringArrayClass Split(const XStringClass1& S, const XStringClass2& Separator)
template<class XStringArrayClass, class Type1, enable_if( is_char_ptr(Type1) || is___String(Type1) ) >
XStringArrayClass Split(Type1 S)
{
return Split<XStringArrayClass>(S.s(), Separator.s());
//
// XStringArrayClass Ss;
// size_t idxB, idxE;
//
// if ( Separator.length() == 0 ) {
// Ss.Add(S);
// return Ss;
// }
// idxB = 0;
// idxE = S.indexOf(Separator, idxB);
// while ( idxE != MAX_XSIZE ) {
// Ss.Add(S.subString(idxB, idxE-idxB));
// idxB = idxE + Separator.length();
// idxE = S.indexOf(Separator, idxB);
// }
// if ( idxB < S.length() ) Ss.Add(S.subString(idxB, S.length()-idxB));
// return Ss;
return Split<XStringArrayClass>(S, ", ");
};
template<class XStringArrayClass, class XStringClass1, enable_if(!is_char(XStringClass1) && !is_char_ptr(XStringClass1))>
XStringArrayClass Split(const XStringClass1& S)
{
return Split<XStringArrayClass>(S, ", "_XS8);
};
//
//template<class XStringArrayClass, class XStringClass1, class XStringClass2, enable_if(is___String(XStringClass1) && is___String(XStringClass2))>
//XStringArrayClass Split(const XStringClass1& S, const XStringClass2& Separator)
//{
// return Split<XStringArrayClass>(S.s(), Separator.s());
////
//// XStringArrayClass Ss;
//// size_t idxB, idxE;
////
//// if ( Separator.length() == 0 ) {
//// Ss.Add(S);
//// return Ss;
//// }
//// idxB = 0;
//// idxE = S.indexOf(Separator, idxB);
//// while ( idxE != MAX_XSIZE ) {
//// Ss.Add(S.subString(idxB, idxE-idxB));
//// idxB = idxE + Separator.length();
//// idxE = S.indexOf(Separator, idxB);
//// }
//// if ( idxB < S.length() ) Ss.Add(S.subString(idxB, S.length()-idxB));
//// return Ss;
//};
//
//
//template<class XStringArrayClass, class XStringClass1, enable_if(!is_char(XStringClass1) && !is_char_ptr(XStringClass1))>
//XStringArrayClass Split(const XStringClass1& S)
//{
// return Split<XStringArrayClass>(S, ", "_XS8);
//};
#endif

View File

@ -8,23 +8,31 @@ int XStringArray_tests()
// printf("XStringWArray_tests -> Enter\n");
#endif
XStringWArray array1;
{
XStringWArray array1;
if ( !array1.isEmpty() ) return 1;
if ( !array1.isEmpty() ) return 1;
array1.Add(L"1"_XSW);
if ( array1.isEmpty() ) return 2;
if ( array1[0] != "1"_XS8 ) return 21;
array1.Add(L"2"_XSW);
if ( array1[1] != "2"_XS8 ) return 21;
if ( !array1.contains(L"2"_XSW) ) return 5;
array1.Add(L"word1"_XSW);
if ( array1.isEmpty() ) return 2;
if ( array1[0] != "word1"_XS8 ) return 21;
array1.Add(L"other2"_XSW);
if ( array1[1] != "other2"_XS8 ) return 21;
if ( !array1.contains(L"other2"_XSW) ) return 5;
if ( !array1.containsIC(L"oTHer2"_XSW) ) return 6;
}
// Test == and !=
{
XStringWArray array1;
array1.Add(L"word1"_XSW);
array1.Add(L"other2"_XSW);
XStringWArray array1bis;
array1bis.Add(L"1"_XSW);
array1bis.Add(L"2"_XSW);
array1bis.Add(L"word1"_XSW);
array1bis.Add(L"other2"_XSW);
if ( !(array1 == array1bis) ) return 10;
if ( array1 != array1bis ) return 11;
@ -49,42 +57,105 @@ int XStringArray_tests()
if ( array[1] != "word2"_XS8 ) return 32;
if ( array[2] != "word3"_XS8 ) return 33;
}
{
XStringArray array = Split<XStringArray>(" word1 word2 word3 "_XS8, " "_XS8);
XString8 xs = array.ConcatAll(' ', '^', '$');
if ( xs != "^word1 word2 word3$"_XS8 ) return 31;
}
// Test concat and Split
{
XStringWArray array;
array.Add(L"word1"_XSW);
array.Add("other2"_XS8);
array.Add("3333");
array.Add(L"4th_item");
{
XStringW c = array.ConcatAll(L", "_XSW, L"^"_XSW, L"$"_XSW);
if ( c != L"^word1, other2, 3333, 4th_item$"_XSW ) return 1;
}
{
XStringW c = array.ConcatAll(L", ", L"^", L"$");
if ( c != L"^word1, other2, 3333, 4th_item$"_XSW ) return 1;
}
// Test concat and Split
{
XStringW c = array1.ConcatAll(L", "_XSW, L"^"_XSW, L"$"_XSW);
if ( c != L"^1, 2$"_XSW ) return 1;
// Split doesn't handle prefix and suffix yet.
XStringW c = array.ConcatAll(L", ");
// Split doesn't handle prefix and suffix yet.
c = array1.ConcatAll(L", "_XSW);
XStringWArray arraybis = Split<XStringWArray>(c);
if ( array != arraybis ) return 20;
XStringArray array3bis = Split<XStringArray>(c);
if ( array != array3bis ) return 20;
}
// Test Split char[64]
{
char buf[64];
strcpy(buf, "word1 other2 3333 4th_item");
XStringArray array = Split<XStringArray>(buf, " ");
XStringWArray array1bis = Split<XStringWArray>(c);
if ( array1 != array1bis ) return 20;
XStringWArray array2bis = Split<XStringWArray>(c);
if ( array1 != array2bis ) return 20;
XStringArray array3bis = Split<XStringArray>(c);
if ( array1 != array3bis ) return 20;
}
if ( array[0] != "word1"_XS8 ) return 31;
if ( array[1] != "other2"_XS8 ) return 32;
if ( array[2] != "3333"_XS8 ) return 33;
if ( array[3] != "4th_item"_XS8 ) return 34;
}
// Test concat and Split @Pene
{
XStringArray array;
array.Add(L"word1");
array.Add(L"other2");
array.Add(L"3333");
array.Add(L"4th_item");
XStringArray LoadOptions2;
LoadOptions2 = Split<XStringArray>(array.ConcatAll(" "_XS8).wc_str(), " ");
if ( LoadOptions2 != array ) return 22;
LoadOptions2 = Split<XStringArray>(array.ConcatAll(" "_XS8), " ");
if ( LoadOptions2 != array ) return 22;
LoadOptions2 = Split<XStringArray>(array.ConcatAll(" "_XS8), " "_XS8);
if ( LoadOptions2 != array ) return 22;
LoadOptions2 = Split<XStringArray>(array.ConcatAll(" "), " ");
if ( LoadOptions2 != array ) return 22;
LoadOptions2 = array;
if ( LoadOptions2 != array ) return 22;
}
//
{
XStringWArray array;
array.Add(L"word1"_XSW);
array.Add(L"other2"_XSW);
array.Add(L"3333"_XSW);
array.Add(L"4th_item"_XSW);
XStringWArray array2;
array2.Add(L"2"_XSW);
array2.Add(L"1"_XSW);
XStringWArray array2;
array2.Add(L"word1"_XSW);
array2.Add(L"3333"_XSW);
array2.Add(L"other2"_XSW);
array2.Add(L"4th_item"_XSW);
if ( array2[0] != L"2"_XSW ) return 30;
if ( array2[1] != L"1"_XSW ) return 31;
if ( array == array2 ) return 40; // Array != because order is different
if ( !array.Same(array2) ) return 41; // Arrays are the same
}
{
XStringWArray array1;
array1.Add(L"word1"_XSW);
array1.Add(L"other2"_XSW);
if ( array1 == array2 ) return 40; // Array != because order is different
if ( !array1.Same(array2) ) return 41; // Arrays are the same
array1.AddNoNull(L"3333"_XSW);
if ( array1.size() != 3 ) return 50;
array1.AddNoNull(L""_XSW);
if ( array1.size() != 3 ) return 51;
array1.AddEvenNull(XStringW());
if ( array1.size() != 4 ) return 52;
array1.AddID(L"other2"_XSW);
if ( array1.size() != 4 ) return 53;
}
array1.AddNoNull(L"3"_XSW);
if ( array1.size() != 3 ) return 50;
array1.AddNoNull(L""_XSW);
if ( array1.size() != 3 ) return 51;
array1.AddEvenNull(XStringW());
if ( array1.size() != 4 ) return 52;
array1.AddID(L"2"_XSW);
if ( array1.size() != 4 ) return 53;
return 0;

View File

@ -7,6 +7,7 @@
static int nbTest = 0;
static int nbTestFailed = 0;
static bool displayOnlyFailed = true;
static bool displayMainTitle = false;
#define STRINGIFY_(s) #s
@ -500,7 +501,7 @@ SimpleString testDefaultCtor_()
}
#define testDefaultCtor(XStringClass, classEncoding) \
printf("Test %s::testDefaultCtor\n", STRINGIFY(XStringClass)); \
if ( displayMainTitle) printf("Test %s::testDefaultCtor\n", STRINGIFY(XStringClass)); \
testDefaultCtor_<XStringClass>();
@ -598,7 +599,7 @@ SimpleString testTakeValueFrom_(const TestStringSrc& src, const TestStringExpect
}
#define testTakeValueFrom(XStringClass, classEncoding, encoding1) \
printf("Test %s::testTakeValueFrom, strcpy(%s)\n", STRINGIFY(XStringClass), STRINGIFY(encoding1)); \
if ( displayMainTitle) printf("Test %s::testTakeValueFrom, strcpy(%s)\n", STRINGIFY(XStringClass), STRINGIFY(encoding1)); \
for ( size_t i = 0 ; i < nbTestStringMultiCoded ; i++ ) { \
testTakeValueFrom_<XStringClass>(testStringMultiCodedArray[i].encoding1, testStringMultiCodedArray[i].classEncoding); \
} \
@ -638,7 +639,7 @@ SimpleString testEmpty_()
}
#define testEmpty(XStringClass, classEncoding) \
printf("Test %s::testEmpty\n", STRINGIFY(XStringClass)); \
if ( displayMainTitle) printf("Test %s::testEmpty\n", STRINGIFY(XStringClass)); \
testEmpty_<XStringClass>(); \
@ -661,7 +662,7 @@ SimpleString testchar32At_(const InitialValue& initialValue)
}
#define testchar32At(XStringClass, classEncoding, integralType) \
printf("Test %s::testchar32At\n", STRINGIFY(XStringClass)); \
if ( displayMainTitle) printf("Test %s::testchar32At\n", STRINGIFY(XStringClass)); \
for ( size_t i = 0 ; i < nbTestStringMultiCoded ; i++ ) { \
testchar32At_<XStringClass, integralType>(testStringMultiCodedArray[i].classEncoding); \
}
@ -685,7 +686,7 @@ SimpleString testdataSized_()
}
#define testdataSized(XStringClass, classEncoding, integralType) \
printf("Test %s::testdataSized\n", STRINGIFY(XStringClass)); \
if ( displayMainTitle) printf("Test %s::testdataSized\n", STRINGIFY(XStringClass)); \
testdataSized_<XStringClass, integralType>(); \
@ -718,7 +719,7 @@ SimpleString teststrncpy_(const TestStringSameAsClass& encodedSameAsClass, const
}
#define teststrncpy(XStringClass, classEncoding, encoding1) \
printf("Test %s::teststrncpy(%s)\n", STRINGIFY(XStringClass), STRINGIFY(encoding1)); \
if ( displayMainTitle) printf("Test %s::teststrncpy(%s)\n", STRINGIFY(XStringClass), STRINGIFY(encoding1)); \
for ( size_t i = 0 ; i < nbTestStringMultiCoded ; i++ ) { \
teststrncpy_<XStringClass>(testStringMultiCodedArray[i].classEncoding, testStringMultiCodedArray[i].encoding1); \
} \
@ -833,7 +834,7 @@ SimpleString teststrcat_(const InitialValue& initialValue, const TestString<Test
}
#define teststrcat(XStringClass, classEncoding, encoding1, encoding2) \
printf("Test %s(%s)::teststrcat(%s)\n", STRINGIFY(XStringClass), STRINGIFY(encoding1), STRINGIFY(encoding2)); \
if ( displayMainTitle) printf("Test %s(%s)::teststrcat(%s)\n", STRINGIFY(XStringClass), STRINGIFY(encoding1), STRINGIFY(encoding2)); \
for ( size_t i = 0 ; i < nbTestStringMultiCoded ; i++ ) { \
for ( size_t j = 0 ; j < nbTestStringMultiCoded ; j++ ) { \
teststrcat_<XStringClass>(testStringMultiCodedArray[i].encoding1, testStringMultiCodedArray[i].encoding2); \
@ -893,7 +894,7 @@ SimpleString teststrncat_(const InitialValue& initialValue, const ValueToCat& va
}
#define teststrncat(XStringClass, classEncoding, encoding1, encoding2) \
printf("Test %s(%s)::teststrncat(%s)\n", STRINGIFY(XStringClass), STRINGIFY(encoding1), STRINGIFY(encoding2)); \
if ( displayMainTitle) printf("Test %s(%s)::teststrncat(%s)\n", STRINGIFY(XStringClass), STRINGIFY(encoding1), STRINGIFY(encoding2)); \
for ( size_t i = 0 ; i < nbTestStringMultiCoded ; i++ ) { \
for ( size_t j = 0 ; j < nbTestStringMultiCoded ; j++ ) { \
teststrncat_<XStringClass>(testStringMultiCodedArray[i].encoding1, testStringMultiCodedArray[i].encoding2); \
@ -944,7 +945,7 @@ subStr = str.subString(pos, count);
}
#define testSubString(XStringClass, classEncoding) \
printf("Test %s::testSubString\n", STRINGIFY(XStringClass)); \
if ( displayMainTitle) printf("Test %s::testSubString\n", STRINGIFY(XStringClass)); \
for ( size_t i = 0 ; i < nbTestStringMultiCoded ; i++ ) { \
testSubString_<XStringClass>(testStringMultiCodedArray[i].classEncoding); \
} \
@ -1154,7 +1155,7 @@ SimpleString testCompare_(const InitialValue& initialValue)
}
#define testCompare(XStringClass, classEncoding, encoding) \
printf("Test %s::strcmp(%s)\n", STRINGIFY(XStringClass), STRINGIFY(encoding)); \
if ( displayMainTitle) printf("Test %s::strcmp(%s)\n", STRINGIFY(XStringClass), STRINGIFY(encoding)); \
for ( size_t i = 0 ; i < nbTestStringMultiCoded ; i++ ) { \
testCompare_<XStringClass>(testStringMultiCodedArray[i].encoding); \
} \
@ -1325,7 +1326,7 @@ SimpleString testindexOf_(const InitialValue& initialValue)
}
#define testindexOf(XStringClass, classEncoding, encoding) \
printf("Test %s::testindexOf(%s)\n", STRINGIFY(XStringClass), STRINGIFY(encoding)); \
if ( displayMainTitle) printf("Test %s::testindexOf(%s)\n", STRINGIFY(XStringClass), STRINGIFY(encoding)); \
for ( size_t i = 0 ; i < nbTestStringMultiCoded ; i++ ) { \
testindexOf_<XStringClass>(testStringMultiCodedArray[i].encoding); \
} \
@ -1361,7 +1362,7 @@ SimpleString testlastChar_(const InitialValue& initialValue)
}
#define testlastChar(XStringClass, classEncoding) \
printf("Test %s::testlastChar\n", STRINGIFY(XStringClass)); \
if ( displayMainTitle) printf("Test %s::testlastChar\n", STRINGIFY(XStringClass)); \
for ( size_t i = 0 ; i < nbTestStringMultiCoded ; i++ ) { \
testlastChar_<XStringClass>(testStringMultiCodedArray[i].classEncoding); \
} \
@ -1396,7 +1397,7 @@ SimpleString testtrim_(const InitialValue& initialValue, const ExpectedValue& ex
}
#define testtrim(XStringClass, classEncoding) \
printf("Test %s::testtrim\n", STRINGIFY(XStringClass)); \
if ( displayMainTitle) printf("Test %s::testtrim\n", STRINGIFY(XStringClass)); \
for ( size_t i = 0 ; i < nbTestStringMultiCoded4TrimArray ; i++ ) { \
testtrim_<XStringClass>(testStringMultiCoded4TrimArray[i].classEncoding, testStringMultiCoded4TrimArray[i].classEncoding##_expectedResult); \
} \
@ -1448,7 +1449,7 @@ SimpleString teststartWith_(const InitialValue& initialValue)
}
#define teststartWith(XStringClass, classEncoding) \
printf("Test %s::teststartWith\n", STRINGIFY(XStringClass)); \
if ( displayMainTitle) printf("Test %s::teststartWith\n", STRINGIFY(XStringClass)); \
for ( size_t i = 0 ; i < nbTestStringMultiCoded ; i++ ) { \
teststartWith_<XStringClass>(testStringMultiCodedArray[i].classEncoding); \
} \
@ -1478,7 +1479,7 @@ XStringClass xstr2 = initia__String.basename();
}
#define testbasename(XStringClass, classEncoding) \
printf("Test %s::testbasename\n", STRINGIFY(XStringClass)); \
if ( displayMainTitle) printf("Test %s::testbasename\n", STRINGIFY(XStringClass)); \
for ( size_t i = 0 ; i < nbTestStringMultiCoded4BasenameArray ; i++ ) { \
testbasename_<XStringClass>(testStringMultiCoded4BasenameArray[i].classEncoding, testStringMultiCoded4BasenameArray[i].classEncoding##_expectedResult); \
} \
@ -1592,8 +1593,10 @@ int XString_tests()
#ifdef JIEF_DEBUG
if ( nbTestFailed == 0 ) printf("All %d tests succeeded.\n", nbTest);
else printf("%d tests succeeded out of %d.\n", nbTest-nbTestFailed, nbTest);
if ( displayMainTitle ) {
if ( nbTestFailed == 0 ) printf("All %d XString tests succeeded.\n", nbTest);
else printf("%d XString tests succeeded out of %d.\n", nbTest-nbTestFailed, nbTest);
}
#endif
return nbTestFailed > 0;
}

View File

@ -96,28 +96,32 @@ struct _xtools__is_unsigned : public _xtools__is_unsigned_true_false< ( _Tp(0) <
int XToolsCommon_tests()
{
(void)nbTest;
(void)nbTestFailed;
#ifdef JIEF_DEBUG
// printf("XToolsCommon_tests -> Enter\n");
#endif
ASSERT_ALL_INTEGRAL_CHAR(ASSERT_UNSIGNED_TYPE, true)
ASSERT_ALL_INTEGRAL_CHAR(ASSERT_SIZEOF_UNSIGNED_TYPE, true) // expectedResult unused by ASSERT_SIZEOF_UNSIGNED_TYPE
ASSERT_ALL_INTEGRAL(ASSERT_IS_INTEGRAL, true)
ASSERT_ALL_CHAR(ASSERT_IS_INTEGRAL, false)
/* These are static. Means that it's ok if they compile */
ASSERT_ALL_INTEGRAL_CHAR(ASSERT_UNSIGNED_TYPE, true)
ASSERT_ALL_INTEGRAL_CHAR(ASSERT_SIZEOF_UNSIGNED_TYPE, true) // expectedResult unused by ASSERT_SIZEOF_UNSIGNED_TYPE
ASSERT_ALL_INTEGRAL(ASSERT_IS_INTEGRAL, true)
ASSERT_ALL_CHAR(ASSERT_IS_INTEGRAL, false)
ASSERT_ALL_INTEGRAL(ASSERT_IS_CHAR, false)
ASSERT_ALL_CHAR(ASSERT_IS_CHAR, true)
ASSERT_ALL_CHAR_PTR(ASSERT_IS_CHAR_PTR, true)
ASSERT_ALL_INTEGRAL(ASSERT_IS_CHAR, false)
ASSERT_ALL_CHAR(ASSERT_IS_CHAR, true)
ASSERT_ALL_CHAR_PTR(ASSERT_IS_CHAR_PTR, true)
#ifdef JIEF_DEBUG
if ( nbTestFailed == 0 ) printf("All %d tests succeeded.\n", nbTest);
else printf("%d tests succeeded out of %d.\n", nbTest-nbTestFailed, nbTest);
#endif
return nbTestFailed > 0;
return 0; // If a test fail, it doesn't compile.
//
//#ifdef JIEF_DEBUG
// if ( nbTestFailed == 0 ) printf("All %d tests succeeded.\n", nbTest);
// else printf("%d tests succeeded out of %d.\n", nbTest-nbTestFailed, nbTest);
//#endif
// return nbTestFailed > 0;
}

View File

@ -38,18 +38,23 @@ bool all_tests()
// all_ok = false;
// }
#if defined(JIEF_DEBUG)
ret = XStringArray_tests();
if ( ret != 0 ) {
printf("XStringArray_tests() failed at test %d\n", ret);
all_ok = false;
}
ret = XToolsCommon_tests();
if ( ret != 0 ) {
printf("printlib_tests() failed at test %d\n", ret);
all_ok = false;
}
#endif
//return ret;
// ret = XUINTN_tests();
// if ( ret != 0 ) {
// printf("XUINTN_tests() failed at test %d\n", ret);
// all_ok = false;
// }
// ret = XUINTN_tests();
// if ( ret != 0 ) {
// printf("XUINTN_tests() failed at test %d\n", ret);
// all_ok = false;
// }
#endif
#if defined(JIEF_DEBUG) && defined(CLOVER_BUILD)
ret = printlib_tests();
if ( ret != 0 ) {
@ -121,7 +126,7 @@ bool all_tests()
#if defined(JIEF_DEBUG)
if ( all_ok ) {
printf("All tests are ok\n");
printf("All tests succeeded\n");
}
#endif