Unit KambiUtils

DescriptionusesClasses, Interfaces, Objects and RecordsFunctions and ProceduresTypesConstantsVariables

Description

Kambi (Michalis Kamburelis) various basic utilities.

This unit is a bag for simple and generally useful things. As a rule (to not let myself put too much things here) this unit must not use any objects defined in Classes unit (i.e. this unit can't use Classes unit, directly or indirectly). So not only GUI libs like VCL, LCL or CLX can't be utilized in this unit, but also many other non-visual classes (e.g. streams, lists). The only classes that may be defined and used here are exceptions (the base Exception class comes from SysUtils unit) and TDyn*Array classes.

Initialization of this unit does some things that you should be aware of (for me, these things are just a must-have for my every program, reasoning is given below):

Things from Pascal RTL / FCL / etc. that you shouldn't use because I have better replacemenets here:

uses

Overview

Classes, Interfaces, Objects and Records

Name Description
Class TDynArrayBase  
Class TDynArray_1  
Class TDynArray_2  
Class TDynArray_3  
Class TDynArray_4  
Class TDynArray_5  
Class TDynArray_6  
Class TDynArray_7  
Class TDynArray_8  
Class TDynArray_9  
Class TDynArray_10  
Class TDynArray_11  
Class TDynArray_12  
Class TDynArray_13  
Class TDynArray_14  
Class TDynArray_15  
Class TDynArray_16  
Class TDynFloatArray  
Class TDynSingleArray  
Class TDynCardinalArray  
Class TDynBooleanArray  
Class TCodeBreaker TCodeBreaker is a special class intended to be 1.
Class EInternalError This exception should signal some internal error in program, i.e.
Class ECheckFailed See Check
Class EWithHiddenClassName wyjatki dziedziczace od EWithHiddenClassName sa normalnymi wyjatkami tyle ze beda w inny sposob formatowane funkcja ExceptMessage : ExceptMessage NIE bedzie zawieralo nazwy klasy tych wyjatkow.
Class BreakProgram This class is specially handled in my exception handler.
Class EInvalidParams Command-line parameters utilities
Class TParametersArray  
Class EKambiOSError I don't ever use RaiseLastOSError or OSCheck or EOSError, instead I'm using my own EKambiOSError, KambiOSCheck, RaiseLastKambiOSError.

Functions and Procedures

procedure Sort(Arr: pointer; ArrRecordSize: Cardinal; IsSmallerFunc: TIsSmallerFunc; IsSmallerFuncData: Pointer; FirstIndex, LastIndex: integer; CountToUseSimpleSort: Integer = DefaultCountToUseSimpleSort ); overload;
procedure Sort(Arr: pointer; ArrRecordSize: Cardinal; ArrStride: integer; IsSmallerFunc: TIsSmallerFunc; IsSmallerFuncData: Pointer; FirstIndex, LastIndex: integer; CountToUseSimpleSort: Integer = DefaultCountToUseSimpleSort ); overload;
procedure SortByObject(Arr: pointer; ArrRecordSize: Cardinal; IsSmallerFunc: TIsSmallerFuncByObject; FirstIndex, LastIndex: integer; CountToUseSimpleSort: Integer = DefaultCountToUseSimpleSort ); overload;
procedure SortByObject(Arr: pointer; ArrRecordSize: Cardinal; ArrStride: integer; IsSmallerFunc: TIsSmallerFuncByObject; FirstIndex, LastIndex: integer; CountToUseSimpleSort: Integer = DefaultCountToUseSimpleSort ); overload;
procedure Check(TrueValue: boolean; const ErrMessage: string);
function ArrayPosPointer(A: pointer; const Arr: array of pointer): Integer; overload;
function ArrayPosStr(const A: string; const Arr: array of string): Integer; overload;
function ArrayPosInt(A: Integer; const Arr: array of Integer): Integer; overload;
function ArrayPosCard(A: Cardinal; const Arr: array of Cardinal): Integer; overload;
function ArrayPosExt(A: Extended; const Arr: array of Extended): Integer; overload;
function ArrayPosText(const A: string; const Arr: array of string; IgnoreCase: boolean =true): Integer; overload;
function PArrayPosStr(const A: string; Arr: PString; ArrCount: Integer): Integer; overload;
function PArrayPosText(const A: string; Arr: PString; ArrCount: Integer; IgnoreCase: boolean =true): Integer; overload;
function Iff(boolval: boolean; trueval, falseval: string) : string; overload;
function Iff(boolval: boolean; trueval, falseval: Integer) : Integer; overload;
function Iff(boolval: boolean; trueval, falseval: Float) : Float; overload;
function Iff(boolval: boolean; trueval, falseval: Cardinal): Cardinal; overload;
function Iff(boolval: boolean; trueval, falseval: char) : char; overload;
function SFPCVersion: string;
function SCompilerDescription: string;
function SVrmlEngineProgramHelpSuffix(const DisplayProgramName: string; const Version: string; WrapLines: boolean): string;
function ExceptMessage(E: TObject; ExceptAddr: Pointer = nil ): string; overload;
procedure OutputException(E: TObject; ExceptAddr: Pointer = nil ); overload;
procedure HaltBool(Value: boolean);
procedure HaltOnException(proc: TProcedure); overload;
procedure HaltOnException(proc: TProcedure; HaltCode: integer); overload;
procedure ProgramBreak(AHaltCode: Integer =0 ); overload;
procedure ParamCountEqual(ParamValue: integer);
procedure ParamCountEqGreater(ParamValue: integer);
procedure ParamCountEqLesser(ParamValue: integer);
function IsPresentInPars(const sarr: array of string; IgnoreCase: boolean; FirstPar, LastPar: Cardinal): boolean; overload;
function IsPresentInPars(const sarr: array of string; IgnoreCase: boolean): boolean; overload;
function IsHelpPresentInPars: boolean;
function SetBit(bitnum:byte; bitset:byte; value:boolean):byte;
function SetBit1(bitnum:byte; bitset:byte):byte;
function SetBit0(bitnum:byte; bitset:byte):byte;
procedure SetBit_var(bitnum:byte; var bitset:byte; value:boolean);
procedure SetBit1_var(bitnum:byte; var bitset:byte);
procedure SetBit0_var(bitnum:byte; var bitset:byte);
function GetBit(bitnum:byte; bitset:byte):boolean;
function GetBitLongWord(bitnum:byte; bitset:LongWord):boolean;
function SetBit1LongWord(bitnum:byte; bitset:LongWord):LongWord;
function SetBit0LongWord(bitnum:byte; bitset:LongWord):LongWord;
function SetBitLongWord(bitnum:byte; bitset:LongWord; value:boolean):LongWord;
function RandomBitsByte(OneChance:Extended):byte;
function KamReadLink(const FileName: string): string;
procedure SwapValues(var a, b: Int64); overload;
procedure SwapValues(var a, b: Integer); overload;
procedure SwapValues(var a, b: Cardinal); overload;
procedure SwapValues(var a, b: Single); overload;
procedure SwapValues(var a, b: Double); overload;
procedure SwapValues(var a, b: char); overload;
procedure OrderUp(var mniejsza, wieksza: Int64 ); overload;
procedure OrderUp(var mniejsza, wieksza: Integer ); overload;
procedure OrderUp(var mniejsza, wieksza: Cardinal); overload;
procedure OrderUp(var mniejsza, wieksza: Single ); overload;
procedure OrderUp(var mniejsza, wieksza: Double ); overload;
procedure OrderUp(x, y: Integer; var mniejsza, wieksza: Integer ); overload;
procedure OrderUp(x, y: Cardinal; var mniejsza, wieksza: Cardinal); overload;
procedure OrderUp(x, y: Single; var mniejsza, wieksza: Single ); overload;
procedure OrderUp(x, y: Double; var mniejsza, wieksza: Double ); overload;
function min(const a, b: Int64): Int64; overload;
function min(const a, b: integer): integer; overload;
function min(const a, b: cardinal): cardinal; overload;
function min(const a, b: Single): Single; overload;
function min(const a, b: Double): Double; overload;
function min(const a, b, c: Int64): Int64; overload;
function min(const a, b, c: integer): integer; overload;
function min(const a, b, c: cardinal): cardinal; overload;
function min(const a, b, c: Single): Single; overload;
function min(const a, b, c: Double): Double; overload;
function max(const a, b: Int64): Int64; overload;
function max(const a, b: integer): integer; overload;
function max(const a, b: cardinal): cardinal; overload;
function max(const a, b: Single): Single; overload;
function max(const a, b: Double): Double; overload;
function max(const a, b, c: Int64): Int64; overload;
function max(const a, b, c: integer): integer; overload;
function max(const a, b, c: cardinal): cardinal; overload;
function max(const a, b, c: Single): Single; overload;
function max(const a, b, c: Double): Double; overload;
procedure MinTo1st(var a: Int64 ; const b: Int64 ); overload;
procedure MinTo1st(var a: Integer ; const b: Integer ); overload;
procedure MinTo1st(var a: Cardinal; const b: Cardinal); overload;
procedure MinTo1st(var a: Single ; const b: Single ); overload;
procedure MinTo1st(var a: Double ; const b: Double ); overload;
procedure MaxTo1st(var a: Int64 ; const b: Int64 ); overload;
procedure MaxTo1st(var a: Integer ; const b: Integer ); overload;
procedure MaxTo1st(var a: Cardinal; const b: Cardinal); overload;
procedure MaxTo1st(var a: Single ; const b: Single ); overload;
procedure MaxTo1st(var a: Double ; const b: Double ); overload;
function IndexMax(const a0, a1, a2: Double): Integer; overload;
function IndexMin(const a0, a1, a2: Double): Integer; overload;
function Between(const a, vBegin, vEnd: Int64): boolean; overload;
function Between(const a, vBegin, vEnd: integer): boolean; overload;
function Between(const a, vBegin, vEnd: cardinal): boolean; overload;
function Between(const a, vBegin, vEnd: Float): boolean; overload;
function Clamped(const a, vBegin, vEnd: Int64): Int64; overload;
function Clamped(const a, vBegin, vEnd: integer): integer; overload;
function Clamped(const a, vBegin, vEnd: cardinal): cardinal; overload;
function Clamped(const a, vBegin, vEnd: Single): Single; overload;
function Clamped(const a, vBegin, vEnd: Double): Double; overload;
procedure Clamp(var a: Int64; const vBegin, vEnd: Int64); overload;
procedure Clamp(var a: integer; const vBegin, vEnd: integer); overload;
procedure Clamp(var a: cardinal; const vBegin, vEnd: cardinal); overload;
procedure Clamp(var a: Single; const vBegin, vEnd: Single); overload;
procedure Clamp(var a: Double; const vBegin, vEnd: Double); overload;
procedure RestOf3dCoords(coord: integer; out first, second: integer);
function ChangeIntCycle(value, change, maxValue: integer): integer;
function Lerp(const a: Single; const l, h: Integer): Single; overload;
function Lerp(const a: Single; const l, h: Cardinal): Single; overload;
function Lerp(const a, l, h: Single): Single; overload;
function Lerp(const a: Double; const l, h: Integer): Double; overload;
function Lerp(const a: Double; const l, h: Cardinal): Double; overload;
function Lerp(const a, l, h: Double): Double; overload;
function RoundUpToMultiply(value, multiplicator: Integer): Integer;
function BiggestPowerOf2(Value: Cardinal): Cardinal;
function Biggest2Exponent(Value: Cardinal): integer;
function Smallest2Exponent(Value: Cardinal): Integer;
function Smallest2Power(Value: Cardinal): Cardinal;
function IsPowerOf2(Value: Cardinal): boolean;
function DivRoundUp(Value, Divider: Cardinal): Cardinal; overload;
function DivRoundUp(Value, Divider: Integer): Integer; overload;
function MapRange(sourceVal, sourceBegin, sourceEnd, destBegin, destEnd: integer): float; overload;
function MapRange(sourceVal, sourceBegin, sourceEnd, destBegin, destEnd: float ): float; overload;
function RandomFloatRange(const RangeBegin, RangeEnd: Float): Float;
function AngleRadPointToPoint(x1, y1, x2, y2: Single): Single;
function NatNatPower(Base, Exponent: Cardinal): Cardinal;
function RandomPlusMinus: integer;
function GeneralPower(const Base, Exponent: Float): Float;
function ArcCot(x: Float): Float;
function SmallFactorial(n: Integer): Int64;
procedure KamDivMod(Dividend: Integer; Divisor: Word; out Result, Remainder: SmallInt);
procedure DivUnsignedMod(Dividend: Integer; Divisor: Word; out Result: Smallint; out Remainder: Word);
function CeilDiv(const A, B: Cardinal): Cardinal;
procedure MinMax(const x0, x1, x2: Double; out min, max: Double); overload;
procedure MinMax(const x0, x1, x2: Single; out min, max: Single); overload;
function KamCoTan(const Value: Float): Float;
function DeleteFileExt(const filename:string):string;
function ExtractOnlyFilename(const filename:string):string;
function ChangeFilePath(const fname, NewPath:string):string;
function DuplicateSlash(const s:string):string;
function IsPathDelim(c:char):boolean;
function InclPathDelim(const s:string):string;
function ExclPathDelim(const s:string):string;
function RelativeFilename(const fname:string):string;
function NiceFileName(const fname:string):string;
function IsPathAbsolute(const path:string):boolean;
function IsPathAbsoluteOnDrive(const path:string):boolean;
function SpecialDirName(const dirname:string):boolean;
function AppendToFilename(const FileName, Suffix:string):string;
function ExpandFilePath(const FilePath:string):string;
function LastKambiOSError: LongWord;
procedure RaiseLastKambiOSError; overload;
procedure RaiseLastKambiOSError(const AdditionalDescription: string); overload;
procedure KambiOSCheck(TrueValue: boolean); overload;
procedure KambiOSCheck(TrueValue: boolean; const AdditionalDescription: string); overload;
function PointerAdd(p: pointer; add: integer): pointer;
function GetClearMem(Size: integer; ClearValue: byte =0): pointer; overload;
procedure FreeMemNiling(var p: pointer);
function CheckIsMemCharFilled(const Data; Size: Integer; AChar: Char): Integer;
function IsMemCharFilled(const Data; Size: Integer; AChar: Char): boolean;
function IsMemWordFilled(const Data; Size: Integer; Value: Word): boolean;
function IsMemDWordFilled(const Data; Size: Integer; Value: DWord): boolean;
function ReadlnInt(const Prompt: string): integer;
function ReadlnStr(const Prompt: string): string;
function ReadlnYesNo(Prompt: string; Default: TYesNoDefault): boolean;
function ReadlnChoice(Prompt: string; const Choices: array of string; Choice0Default, IgnoreCase: boolean): Integer;
procedure ErrorWrite(const s: string); overload;
procedure WarningWrite(const s: string); overload;
procedure InfoWrite(const s: string); overload;
procedure ErrorWrite(const s: string; const args: array of const); overload;
procedure WarningWrite(const s: string; const args: array of const); overload;
procedure InfoWrite(const s: string; const args: array of const); overload;
procedure InfoWriteParts(const TitleFormat: string; const Messages: array of string);

Types

TIsSmallerFunc = function (const A, B, Data: Pointer): boolean;
TIsSmallerFuncByObject = function (const A, B: Pointer): boolean of object;
Float = Math.Float ;
PFloat = Math.PFloat ;
PCardinal = ˆCardinal;
PLongWord = ˆLongWord;
PShortint = ˆShortint;
PBoolean = ˆBoolean;
TDynArrayItem_1 = Cardinal;
PDynArrayItem_1 = PCardinal;
TInfiniteArray_1 = array[0..MaxInt div SizeOf(TDynArrayItem_1)-1]of TDynArrayItem_1;
PInfiniteArray_1 = ˆTInfiniteArray_1;
TDynArrayItemIsSmallerFunc_1 = function (const a, b: TDynArrayItem_1): boolean;
TDynArrayItemIsSmallerFuncByObject_1 = function (const a, b: TDynArrayItem_1): boolean of object;
TArray_Cardinal = TInfiniteArray_1 ;
PArray_Cardinal = PInfiniteArray_1 ;
TDynArrayItem_2 = Integer ;
PDynArrayItem_2 = PInteger ;
TInfiniteArray_2 = array[0..MaxInt div SizeOf(TDynArrayItem_2)-1]of TDynArrayItem_2;
PInfiniteArray_2 = ˆTInfiniteArray_2;
TDynArrayItemIsSmallerFunc_2 = function (const a, b: TDynArrayItem_2): boolean;
TDynArrayItemIsSmallerFuncByObject_2 = function (const a, b: TDynArrayItem_2): boolean of object;
TDynIntegerArray = TDynArray_2 ;
TArray_Integer = TInfiniteArray_2 ;
PArray_Integer = PInfiniteArray_2 ;
TDynArrayItem_3 = Float ;
PDynArrayItem_3 = PFloat ;
TInfiniteArray_3 = array[0..MaxInt div SizeOf(TDynArrayItem_3)-1]of TDynArrayItem_3;
PInfiniteArray_3 = ˆTInfiniteArray_3;
TDynArrayItemIsSmallerFunc_3 = function (const a, b: TDynArrayItem_3): boolean;
TDynArrayItemIsSmallerFuncByObject_3 = function (const a, b: TDynArrayItem_3): boolean of object;
TArray_Float = TInfiniteArray_3 ;
PArray_Float = PInfiniteArray_3 ;
TDynArrayItem_4 = Byte ;
PDynArrayItem_4 = PByte ;
TInfiniteArray_4 = array[0..MaxInt div SizeOf(TDynArrayItem_4)-1]of TDynArrayItem_4;
PInfiniteArray_4 = ˆTInfiniteArray_4;
TDynArrayItemIsSmallerFunc_4 = function (const a, b: TDynArrayItem_4): boolean;
TDynArrayItemIsSmallerFuncByObject_4 = function (const a, b: TDynArrayItem_4): boolean of object;
TDynByteArray = TDynArray_4 ;
TArray_Byte = TInfiniteArray_4 ;
PArray_Byte = PInfiniteArray_4 ;
TDynArrayItem_5 = Shortint;
PDynArrayItem_5 = PShortint;
TInfiniteArray_5 = array[0..MaxInt div SizeOf(TDynArrayItem_5)-1]of TDynArrayItem_5;
PInfiniteArray_5 = ˆTInfiniteArray_5;
TDynArrayItemIsSmallerFunc_5 = function (const a, b: TDynArrayItem_5): boolean;
TDynArrayItemIsSmallerFuncByObject_5 = function (const a, b: TDynArrayItem_5): boolean of object;
TDynShortintArray = TDynArray_5 ;
TArray_Shortint = TInfiniteArray_5 ;
PArray_Shortint = PInfiniteArray_5 ;
TDynArrayItem_6 = Smallint;
PDynArrayItem_6 = PSmallint;
TInfiniteArray_6 = array[0..MaxInt div SizeOf(TDynArrayItem_6)-1]of TDynArrayItem_6;
PInfiniteArray_6 = ˆTInfiniteArray_6;
TDynArrayItemIsSmallerFunc_6 = function (const a, b: TDynArrayItem_6): boolean;
TDynArrayItemIsSmallerFuncByObject_6 = function (const a, b: TDynArrayItem_6): boolean of object;
TDynSmallintArray = TDynArray_6 ;
TArray_Smallint = TInfiniteArray_6 ;
PArray_Smallint = PInfiniteArray_6 ;
TDynArrayItem_7 = Word ;
PDynArrayItem_7 = PWord ;
TInfiniteArray_7 = array[0..MaxInt div SizeOf(TDynArrayItem_7)-1]of TDynArrayItem_7;
PInfiniteArray_7 = ˆTInfiniteArray_7;
TDynArrayItemIsSmallerFunc_7 = function (const a, b: TDynArrayItem_7): boolean;
TDynArrayItemIsSmallerFuncByObject_7 = function (const a, b: TDynArrayItem_7): boolean of object;
TDynWordArray = TDynArray_7 ;
TArray_Word = TInfiniteArray_7 ;
PArray_Word = PInfiniteArray_7 ;
TDynArrayItem_8 = Longint ;
PDynArrayItem_8 = PLongint ;
TInfiniteArray_8 = array[0..MaxInt div SizeOf(TDynArrayItem_8)-1]of TDynArrayItem_8;
PInfiniteArray_8 = ˆTInfiniteArray_8;
TDynArrayItemIsSmallerFunc_8 = function (const a, b: TDynArrayItem_8): boolean;
TDynArrayItemIsSmallerFuncByObject_8 = function (const a, b: TDynArrayItem_8): boolean of object;
TDynLongintArray = TDynArray_8 ;
TArray_Longint = TInfiniteArray_8 ;
PArray_Longint = PInfiniteArray_8 ;
TDynArrayItem_9 = Int64 ;
PDynArrayItem_9 = PInt64 ;
TInfiniteArray_9 = array[0..MaxInt div SizeOf(TDynArrayItem_9)-1]of TDynArrayItem_9;
PInfiniteArray_9 = ˆTInfiniteArray_9;
TDynArrayItemIsSmallerFunc_9 = function (const a, b: TDynArrayItem_9): boolean;
TDynArrayItemIsSmallerFuncByObject_9 = function (const a, b: TDynArrayItem_9): boolean of object;
TDynInt64Array = TDynArray_9 ;
TArray_Int64 = TInfiniteArray_9 ;
PArray_Int64 = PInfiniteArray_9 ;
TDynArrayItem_10 = Extended;
PDynArrayItem_10 = PExtended;
TInfiniteArray_10 = array[0..MaxInt div SizeOf(TDynArrayItem_10)-1]of TDynArrayItem_10;
PInfiniteArray_10 = ˆTInfiniteArray_10;
TDynArrayItemIsSmallerFunc_10 = function (const a, b: TDynArrayItem_10): boolean;
TDynArrayItemIsSmallerFuncByObject_10 = function (const a, b: TDynArrayItem_10): boolean of object;
TDynExtendedArray = TDynArray_10;
TArray_Extended = TInfiniteArray_10;
PArray_Extended = PInfiniteArray_10;
TDynArrayItem_11 = Double ;
PDynArrayItem_11 = PDouble ;
TInfiniteArray_11 = array[0..MaxInt div SizeOf(TDynArrayItem_11)-1]of TDynArrayItem_11;
PInfiniteArray_11 = ˆTInfiniteArray_11;
TDynArrayItemIsSmallerFunc_11 = function (const a, b: TDynArrayItem_11): boolean;
TDynArrayItemIsSmallerFuncByObject_11 = function (const a, b: TDynArrayItem_11): boolean of object;
TDynDoubleArray = TDynArray_11;
TArray_Double = TInfiniteArray_11;
PArray_Double = PInfiniteArray_11;
TDynArrayItem_12 = Single ;
PDynArrayItem_12 = PSingle ;
TInfiniteArray_12 = array[0..MaxInt div SizeOf(TDynArrayItem_12)-1]of TDynArrayItem_12;
PInfiniteArray_12 = ˆTInfiniteArray_12;
TDynArrayItemIsSmallerFunc_12 = function (const a, b: TDynArrayItem_12): boolean;
TDynArrayItemIsSmallerFuncByObject_12 = function (const a, b: TDynArrayItem_12): boolean of object;
TArray_Single = TInfiniteArray_12;
PArray_Single = PInfiniteArray_12;
TDynArrayItem_13 = Pointer ;
PDynArrayItem_13 = PPointer ;
TInfiniteArray_13 = array[0..MaxInt div SizeOf(TDynArrayItem_13)-1]of TDynArrayItem_13;
PInfiniteArray_13 = ˆTInfiniteArray_13;
TDynArrayItemIsSmallerFunc_13 = function (const a, b: TDynArrayItem_13): boolean;
TDynArrayItemIsSmallerFuncByObject_13 = function (const a, b: TDynArrayItem_13): boolean of object;
TDynPointerArray = TDynArray_13;
TArray_Pointer = TInfiniteArray_13;
PArray_Pointer = PInfiniteArray_13;
TDynArrayItem_14 = LongWord;
PDynArrayItem_14 = PLongWord;
TInfiniteArray_14 = array[0..MaxInt div SizeOf(TDynArrayItem_14)-1]of TDynArrayItem_14;
PInfiniteArray_14 = ˆTInfiniteArray_14;
TDynArrayItemIsSmallerFunc_14 = function (const a, b: TDynArrayItem_14): boolean;
TDynArrayItemIsSmallerFuncByObject_14 = function (const a, b: TDynArrayItem_14): boolean of object;
TDynLongWordArray = TDynArray_14;
TArray_LongWord = TInfiniteArray_14;
PArray_LongWord = PInfiniteArray_14;
TDynArrayItem_15 = String ;
PDynArrayItem_15 = PString ;
TInfiniteArray_15 = array[0..MaxInt div SizeOf(TDynArrayItem_15)-1]of TDynArrayItem_15;
PInfiniteArray_15 = ˆTInfiniteArray_15;
TDynArrayItemIsSmallerFunc_15 = function (const a, b: TDynArrayItem_15): boolean;
TDynArrayItemIsSmallerFuncByObject_15 = function (const a, b: TDynArrayItem_15): boolean of object;
TDynStringArray = TDynArray_15;
TArray_String = TInfiniteArray_15;
PArray_String = PInfiniteArray_15;
TDynArrayItem_16 = Boolean ;
PDynArrayItem_16 = PBoolean ;
TInfiniteArray_16 = array[0..MaxInt div SizeOf(TDynArrayItem_16)-1]of TDynArrayItem_16;
PInfiniteArray_16 = ˆTInfiniteArray_16;
TDynArrayItemIsSmallerFunc_16 = function (const a, b: TDynArrayItem_16): boolean;
TDynArrayItemIsSmallerFuncByObject_16 = function (const a, b: TDynArrayItem_16): boolean of object;
TArray_Boolean = TInfiniteArray_16;
PArray_Boolean = PInfiniteArray_16;
PByteArray = ˆTByteArray;
TByteArray = array[0..MaxInt div SizeOf(Byte)-1] of Byte;
TArray_PChar = array[0..MaxInt div SizeOf(PChar)-1]of PChar;
PArray_PCharTArray_PChar;
TArray_TObject = array[0..MaxInt div SizeOf(Pointer)-1]of TObject;
PArray_TObjectTArray_TObject;
PString = ˆAnsiString;
PtrObject = ˆTObject;
TPointerUInt = PtrUInt;
TPointerSInt = PtrInt;
TYesNoDefault = (...);

Constants

DefaultCountToUseSimpleSort = 10;
nl = LineEnding;
RootDir = '/' ;
bit0=1;
bit1=2;
bit2=4;
bit3=8;
bit4=16;
bit5=32;
bit6=64;
bit7=128;
bit8=256;
enatural = 2.71828182845905;
sqrt2 = 1.4142135623730950488016887242097;
HalfPi = 1.57079632679489661923;
F8087_Except :Word = $3F;
F8087_InvalidOp_Except :Word = 1;
F8087_DenormalizedOperand_Except :Word = 1 shl 1;
F8087_DivZero_Except :Word = 1 shl 2;
F8087_Overflow_Except :Word = 1 shl 3;
F8087_Underflow_Except :Word = 1 shl 4;
F8087_PrecError_Except :Word = 1 shl 5;
F8087_Precision :Word = 3 shl 8;
F8087_Single_Precision :Word = 0;
F8087_Reserved_Precision :Word = 1 shl 8;
F8087_Double_Precision :Word = 2 shl 8;
F8087_Extended_Precision :Word = 3 shl 8;
F8087_Round :Word = 3 shl 10;
F8087_NearestOrEven_Round :Word = 0;
F8087_Down_Round :Word = 1 shl 10;
F8087_Up_Round :Word = 2 shl 10;
F8087_TowardZero_Round :Word = 3 shl 10;
F8087_Infinity :Word = 1 shl 12;
F8087_Projective_Infinity :Word = 0;
F8087_Affine_Infinity :Word = 1 shl 12;

Variables

BonusErrorMessg: string ='';
HaltCodeOnException: Integer = 1;
Parameters: TParametersArray;
LocaleDecimalSeparator: char;

Description

Functions and Procedures

procedure Sort(Arr: pointer; ArrRecordSize: Cardinal; IsSmallerFunc: TIsSmallerFunc; IsSmallerFuncData: Pointer; FirstIndex, LastIndex: integer; CountToUseSimpleSort: Integer = DefaultCountToUseSimpleSort ); overload;

This Sorts table of any items.

You must give Arr — pointer to items array in memory, and ArrRecordSize — size (in bytes) of every item, IsSmaller – function that for two arguments should return is "a < b" true (i.e. I'm assuming here that IsSmaller works like mathematical "<" — it's not reflexive (not IsSmaller(a, a)), for a <> b either IsSmaller(a, b) or IsSmaller(b, a) (but not both), it's transitive.

Using parameters FirstIndex and LastIndex you can sort only part of the array, items outside given range will be be even read. (actually you could achieve effect of FirstIndex by simply shifting the pointer Arr, but using FirstIndex is more comfortable). If FirstIndex>LastIndex, this is NOP.

It sorts items ascending, i.e. Arr[FirstIndex] <= ... <= Arr[LastIndex]. (where meaning of "<=" is implicated by meaning of "<" which is given by IsSmaller).

TODO: Polish below.

Jeszcze slowo o wskaznikach jakie bedzie dostawac IsSmallerFunc : mianowicie te wskazniki niekoniecznie zawsze beda rowne PointerAdd(Arr, ArrStride*n) dla jakiegos n. Byc moze wybierajac np. element dzielacy dla quicksorta skopiujemy sobie jego wartosc na chwile i wtedy wskaznik bedzie wskazywal na lokalna kopie danej wartosci ? Kopiowanie bedziemy musieli robic metodami nisko-poziomowymi wiec i tak nie ma problemu z rzeczami ktore wymagaja Initialize/Finalize. Chociaz moze byc w zwiazku z tym problem jesli IsSmallerFunc bedzie moglo przy okazji zmodyfikowac jakos zawartosc danego rekordu - no coz, nie moze tego robic ! IsSmaller powinno byc ladna funkcja.

Ze wzgledu na to ze w srodku Sort samo wykonuje przestawianie elementow na liscie wiec argument ArrRecordSize nie moze byc oszukany - musi byc wiekszy od zera i musi rzeczywiscie obejmowac dokladnie zawartosc rekordu. Z drugiej strony mozesz zawsze uzyc wersji z ArrStride jezeli rekordy ktore chcesz przestawiac sa przeplecione z innymi danymi ktorych nie chcesz przestawiac razem z rekordami. ArrStride mowi co ile bajtow jest nastepny rekord. Domyslnie ArrStride to ArrRecordSize. Oczywiscie mozna sobie zrobic krzywde jezeli podasz np. ArrRecordSize>0 i ArrStride w zakresie [0..ArrRecordSize).

W klasach TDyn*Array zaimplementowalem wersje tej procedury bezpieczna ze wzgledu na typy - tam podajesz tylko funkcje typu function (const a,b:<typ>): boolean [of object]; gdzie <typ> to typ elementow tablicy.

TODO: chwilowo ArrStride nie moze byc ujemne (to moze czasem pozwolic na pewne sztuczki). TODO: zrobic tez wersje ktora zamiast ArrRecordSize pobiera SwapItemsFunc.

procedure Sort(Arr: pointer; ArrRecordSize: Cardinal; ArrStride: integer; IsSmallerFunc: TIsSmallerFunc; IsSmallerFuncData: Pointer; FirstIndex, LastIndex: integer; CountToUseSimpleSort: Integer = DefaultCountToUseSimpleSort ); overload;
 
procedure SortByObject(Arr: pointer; ArrRecordSize: Cardinal; IsSmallerFunc: TIsSmallerFuncByObject; FirstIndex, LastIndex: integer; CountToUseSimpleSort: Integer = DefaultCountToUseSimpleSort ); overload;
 
procedure SortByObject(Arr: pointer; ArrRecordSize: Cardinal; ArrStride: integer; IsSmallerFunc: TIsSmallerFuncByObject; FirstIndex, LastIndex: integer; CountToUseSimpleSort: Integer = DefaultCountToUseSimpleSort ); overload;
 
procedure Check(TrueValue: boolean; const ErrMessage: string);

if not TrueValue then raise ECheckFailed.Create(ErrMessage).

function ArrayPosPointer(A: pointer; const Arr: array of pointer): Integer; overload;

podstawowe zastosowanie ArrayPos jest do zapisywania instrukcji case variable of val1 : inst1; val2 : inst2; else instElse; end; (gdzie variable: Typ) w taki sposob aby Typ nie musial byc typem ordered (np. moze byc stringiem) a val1, val2 nie musialby byc stalymi. Zapisz case jako case ArrayPos(variable,[val1, val2]) of 0 : inst1; 1 : inst2; else instElse; end; ArrayPos(A: T; Arr: Array of T) zwraca pozycje A w Arr (liczac od zera), zwraca -1 jesli A nie wystepuje w Arr.

function ArrayPosStr(const A: string; const Arr: array of string): Integer; overload;
 
function ArrayPosInt(A: Integer; const Arr: array of Integer): Integer; overload;
 
function ArrayPosCard(A: Cardinal; const Arr: array of Cardinal): Integer; overload;
 
function ArrayPosExt(A: Extended; const Arr: array of Extended): Integer; overload;
 
function ArrayPosText(const A: string; const Arr: array of string; IgnoreCase: boolean =true): Integer; overload;
 
function PArrayPosStr(const A: string; Arr: PString; ArrCount: Integer): Integer; overload;
 
function PArrayPosText(const A: string; Arr: PString; ArrCount: Integer; IgnoreCase: boolean =true): Integer; overload;
 
function Iff(boolval: boolean; trueval, falseval: string) : string; overload;

Iff functions ————————————————————-

function Iff(boolval: boolean; trueval, falseval: Integer) : Integer; overload;
 
function Iff(boolval: boolean; trueval, falseval: Float) : Float; overload;
 
function Iff(boolval: boolean; trueval, falseval: Cardinal): Cardinal; overload;
 
function Iff(boolval: boolean; trueval, falseval: char) : char; overload;
 
function SFPCVersion: string;

This is a string describing FPC version, in the form version.release.patch .

This is actually a constant (for every run of a program it has always the same value) but I can't declare it as a Pascal constant because it must use "Format" function that is not allowed in constant expressions.

function SCompilerDescription: string;

SCompilerDescription is a short name and version of Pascal compiler used to compile this unit. It is a constant, actually, but I cannot declare it as a constant because it must call SFPCVersion that is not declared as a constant.

Calculating nice SCompilerDescription uses compiler directives defined at time of compilation, and not all compilers allow to define such things in a uniform manner (i.e. in a way that is guaranteed to work on all, present and future, compiler versions). So I can't promise here that this function will always return something precise, I do not even promise that it will compile with all FPC, GPC, Delphi versions. Only compiler versions that I, Kambi, use, will be properly defined here.

That said, all FPC versions supporting macros FPC_VERSION/RELEASE/PATCH are guaranteed to be nicely reported by this function.

function SVrmlEngineProgramHelpSuffix(const DisplayProgramName: string; const Version: string; WrapLines: boolean): string;

Print some common info for programs released on [http://vrmlengine.sourceforge.net/]. This is useful only for programs released on this WWW page by Michalis. Resulting string is multiline, delimited by nl.

Parameters
DisplayProgramName
Usually ProgramName, but you can give here something else if you want.
Version
For my programs this usually looks like '%d.%d.%d' and conforms to [http://vrmlengine.sourceforge.net/versioning.php]
WrapLines
If true then resulting string will not have lines longer than 80 characters. Suitable for printing program help message on stdout, e.g. in response to --help option.
function ExceptMessage(E: TObject; ExceptAddr: Pointer = nil ): string; overload;

Except message zwraca komunikat jaki program powinien wyswietlic w reakcji na jakies ogolne exception. Komunikat zawiera ProgramName, E.ClassName, E.Message (o ile E is Exception), ExceptAddr (o ile jest <> nil i jest zdefiniowany symbol DEBUG) i BonusErrorMesssg.

procedure OutputException(E: TObject; ExceptAddr: Pointer = nil ); overload;

OutputException = ErrorWrite(ExceptMessage(E)); Taki wygodny skrot

procedure HaltBool(Value: boolean);

If Value then Halt(0), else Halt(1).

It is the standard convention of command-line programs to exit with code 0 on success and <> 0 on failure. Or (for some programs like `test') exit with code 0 to indicate true result and <> 0 to indicate false result. So you will probably want to pass here some boolean variable indicating "Success" or "TestPassed".

procedure HaltOnException(proc: TProcedure); overload;

This calls Proc and catches all exceptions inside Proc, and in case of exception in Proc it does OutputException and Halt(HaltCode). The result is that HaltOnException doesn't raise any exception, never. It always deals with exceptions inside Proc itself.

For the special exception class BreakProgram, it does simply Halt(BreakProgram(E).ExitCode)) (no OutputException in this case).

When symbol DEBUG is defined, then HaltOnException works differently — it just calls Proc (and doesn't catch any exceptions).

This is particularly useful under Delphi/Win32. There main program should never exit with exception. Because such exception (because of Delphi stupidity ?) shows ugly Windows dialog box saying something like "Program exited unexpectedly, contain with author etc. bullshit". There is no way for me to avoid this dialog box, even by my own ExceptProc. See comments at the beginning of this file kambiutils_program_exit.inc.

procedure HaltOnException(proc: TProcedure; HaltCode: integer); overload;

This is just like HaltOnException(HaltCodeOnException).

procedure ProgramBreak(AHaltCode: Integer =0 ); overload;

ProgramBreak = raise BreakProgram.Create(AHaltCode);

procedure ParamCountEqual(ParamValue: integer);

Check is ParamCount equal (or ">=" for ParamCountEqGreater or "<=" for for ParamCountEqLesser) to ParamValue.

Exceptions raised
EInvalidParams
If the checked condition is not satisfied.
procedure ParamCountEqGreater(ParamValue: integer);
 
procedure ParamCountEqLesser(ParamValue: integer);
 
function IsPresentInPars(const sarr: array of string; IgnoreCase: boolean; FirstPar, LastPar: Cardinal): boolean; overload;

czy ktorys z parametrow ParStr(FirstPar) .. ParStr(LastPar) jest rowny ktoremus z sarr ? Jezeli nie podasz FirstPar i LastPar to zostana przyjete jako 1, ParCount.

function IsPresentInPars(const sarr: array of string; IgnoreCase: boolean): boolean; overload;
 
function IsHelpPresentInPars: boolean;

IsHelpPresentInPars = IsPresentInPars(['-?', '-h', '–help'], false)

function SetBit(bitnum:byte; bitset:byte; value:boolean):byte;
 
function SetBit1(bitnum:byte; bitset:byte):byte;

jesli value=stala, to lepiej uzyj setbit0/1 !

function SetBit0(bitnum:byte; bitset:byte):byte;
 
procedure SetBit_var(bitnum:byte; var bitset:byte; value:boolean);
 
procedure SetBit1_var(bitnum:byte; var bitset:byte);
 
procedure SetBit0_var(bitnum:byte; var bitset:byte);
 
function GetBit(bitnum:byte; bitset:byte):boolean;
 
function GetBitLongWord(bitnum:byte; bitset:LongWord):boolean;
 
function SetBit1LongWord(bitnum:byte; bitset:LongWord):LongWord;
 
function SetBit0LongWord(bitnum:byte; bitset:LongWord):LongWord;
 
function SetBitLongWord(bitnum:byte; bitset:LongWord; value:boolean):LongWord;
 
function RandomBitsByte(OneChance:Extended):byte;

cos speszial : bajt ktorego kazdy bit jest wylosowany na 1 z szansa OneChance

function KamReadLink(const FileName: string): string;

FileName is symlink, returns where FileName points. This is equivalent to readlink from libc, but it's much more comfortable since it returns result as string. Also, it's better than Unix.FpReadLink(pathstr) because Unix.FpReadLink 1) is not available when USE_LIBC 2) introduces 255 chars limit (ShortString) on result.

Raises EKambiOSError in case of failure (non-existing FileName etc.)

procedure SwapValues(var a, b: Int64); overload;

zamien wartosci a z b

procedure SwapValues(var a, b: Integer); overload;
 
procedure SwapValues(var a, b: Cardinal); overload;
 
procedure SwapValues(var a, b: Single); overload;
 
procedure SwapValues(var a, b: Double); overload;
 
procedure SwapValues(var a, b: char); overload;
 
procedure OrderUp(var mniejsza, wieksza: Int64 ); overload;

Jesli nie jest mniejsza<=wieksza to zamien wartosciami dwie zmienne. Po wywolaniu tych proc. zawsze mniejsza<=wieksza

procedure OrderUp(var mniejsza, wieksza: Integer ); overload;
 
procedure OrderUp(var mniejsza, wieksza: Cardinal); overload;
 
procedure OrderUp(var mniejsza, wieksza: Single ); overload;
 
procedure OrderUp(var mniejsza, wieksza: Double ); overload;
 
procedure OrderUp(x, y: Integer; var mniejsza, wieksza: Integer ); overload;

laduje do mniejsza, wieksza wartosci x, y tak zeby mniejsza<=wieksza

procedure OrderUp(x, y: Cardinal; var mniejsza, wieksza: Cardinal); overload;
 
procedure OrderUp(x, y: Single; var mniejsza, wieksza: Single ); overload;
 
procedure OrderUp(x, y: Double; var mniejsza, wieksza: Double ); overload;
 
function min(const a, b: Int64): Int64; overload;

Return minimum / maximum from 2 / 3 items.

function min(const a, b: integer): integer; overload;
 
function min(const a, b: cardinal): cardinal; overload;
 
function min(const a, b: Single): Single; overload;
 
function min(const a, b: Double): Double; overload;
 
function min(const a, b, c: Int64): Int64; overload;
 
function min(const a, b, c: integer): integer; overload;
 
function min(const a, b, c: cardinal): cardinal; overload;
 
function min(const a, b, c: Single): Single; overload;
 
function min(const a, b, c: Double): Double; overload;
 
function max(const a, b: Int64): Int64; overload;
 
function max(const a, b: integer): integer; overload;
 
function max(const a, b: cardinal): cardinal; overload;
 
function max(const a, b: Single): Single; overload;
 
function max(const a, b: Double): Double; overload;
 
function max(const a, b, c: Int64): Int64; overload;
 
function max(const a, b, c: integer): integer; overload;
 
function max(const a, b, c: cardinal): cardinal; overload;
 
function max(const a, b, c: Single): Single; overload;
 
function max(const a, b, c: Double): Double; overload;
 
procedure MinTo1st(var a: Int64 ; const b: Int64 ); overload;

These work like A := Min(A, B). But they are a (very little) faster, since they avoid all the mem copying work when A is equal to Min(A, B).

procedure MinTo1st(var a: Integer ; const b: Integer ); overload;
 
procedure MinTo1st(var a: Cardinal; const b: Cardinal); overload;
 
procedure MinTo1st(var a: Single ; const b: Single ); overload;
 
procedure MinTo1st(var a: Double ; const b: Double ); overload;
 
procedure MaxTo1st(var a: Int64 ; const b: Int64 ); overload;

These work like A := Max(A, B). But they are a (very little) faster, since they avoid all the mem copying work when A is equal to Max(A, B).

procedure MaxTo1st(var a: Integer ; const b: Integer ); overload;
 
procedure MaxTo1st(var a: Cardinal; const b: Cardinal); overload;
 
procedure MaxTo1st(var a: Single ; const b: Single ); overload;
 
procedure MaxTo1st(var a: Double ; const b: Double ); overload;
 
function IndexMax(const a0, a1, a2: Double): Integer; overload;

zwraca indeks (0, 1 lub 2) maximum / minimum

function IndexMin(const a0, a1, a2: Double): Integer; overload;
 
function Between(const a, vBegin, vEnd: Int64): boolean; overload;
 
function Between(const a, vBegin, vEnd: integer): boolean; overload;
 
function Between(const a, vBegin, vEnd: cardinal): boolean; overload;
 
function Between(const a, vBegin, vEnd: Float): boolean; overload;
 
function Clamped(const a, vBegin, vEnd: Int64): Int64; overload;
 
function Clamped(const a, vBegin, vEnd: integer): integer; overload;
 
function Clamped(const a, vBegin, vEnd: cardinal): cardinal; overload;
 
function Clamped(const a, vBegin, vEnd: Single): Single; overload;
 
function Clamped(const a, vBegin, vEnd: Double): Double; overload;
 
procedure Clamp(var a: Int64; const vBegin, vEnd: Int64); overload;
 
procedure Clamp(var a: integer; const vBegin, vEnd: integer); overload;
 
procedure Clamp(var a: cardinal; const vBegin, vEnd: cardinal); overload;
 
procedure Clamp(var a: Single; const vBegin, vEnd: Single); overload;
 
procedure Clamp(var a: Double; const vBegin, vEnd: Double); overload;
 
procedure RestOf3dCoords(coord: integer; out first, second: integer);

RestOf3dCoords : idea jest taka : coord to numer wymiaru 3d, a wiec 0, 1 lub 2. Chcemy do first i second wygenerowac pozostale dwa wymiary. A wiec coord=0 => (first, second) := (1, 2), coord=1 => (first, second) := (0, 2), coord=2 => (first, second) := (0, 1)

function ChangeIntCycle(value, change, maxValue: integer): integer;

zwraca value zwiekszone o change. change moze byc takze ujemne. Zmiany value beda sie zmieniac cyklicznie i w rezultacie zwrocony wynik bedzie zawsze w zakresie 0..maxValue. (nawet jesli poczatkowe value nie bedzie w tym zakresie)

function Lerp(const a: Single; const l, h: Integer): Single; overload;

(1-a) * l + a*h

function Lerp(const a: Single; const l, h: Cardinal): Single; overload;
 
function Lerp(const a, l, h: Single): Single; overload;
 
function Lerp(const a: Double; const l, h: Integer): Double; overload;
 
function Lerp(const a: Double; const l, h: Cardinal): Double; overload;
 
function Lerp(const a, l, h: Double): Double; overload;
 
function RoundUpToMultiply(value, multiplicator: Integer): Integer;

RoundUpToMultiply zaokragla value do najmniejszej wielokrotnosci multiplicatora wiekszej lub rownej value.

function BiggestPowerOf2(Value: Cardinal): Cardinal;

BiggestPowerOf2 zwraca najwieksza potege 2 mniejsza lub rowna Value. Jezeli Value = 0 zwroci 0.

function Biggest2Exponent(Value: Cardinal): integer;

j.w. tyle ze tutaj zwracamy ktora to jest potega 2 zamiast od razu ta potege dwojki. Bigget2Exponent(0) = -1.

function Smallest2Exponent(Value: Cardinal): Integer;

Smallest2Exponent zwraca najmniejsza liczbe taka ze 2ˆSmallest2Exponent(Value) >= Value.

Smallest2Exponent(0) = -1 (zeby zaznaczyc ze jest to sytuacja inna niz gdy Value=1, gdzie zwracamy 0).

function Smallest2Power(Value: Cardinal): Cardinal;

Smallest2Power zwraca od razu 2ˆSmallest2Exponent(Value) (zwraca 0 jezeli Value=0).

function IsPowerOf2(Value: Cardinal): boolean;

zwraca true <=> Value=1 or Value=2 or Value=4 itd. (az do max potegi dwojki <=High(cardinal)

function DivRoundUp(Value, Divider: Cardinal): Cardinal; overload;
 
function DivRoundUp(Value, Divider: Integer): Integer; overload;
 
function MapRange(sourceVal, sourceBegin, sourceEnd, destBegin, destEnd: integer): float; overload;

sourceVal jest wartoscia z zakresu sourceBegin..sourceEnd.

Niech

  a = odleglosc sourceVal od sourceBegin (czyli abs(sourceVal-sourceBegin))
  b = old. sourceVal od sourceEnd

Chcemy znalezc liczbe taka zeby jej odleglosc do destBegin miala sie do jej odleglosci do destEnd tak samo jak a do b i zeby byla po tej samej stronie zakresu, tj.

  jezeli sourceBegin<sourceEnd<sourceVal lub sourceBegin>sourceEnd>sourceVal
      to destBegin  <destEnd  <result    lub destBegin>  destEnd>  result
  jezeli sourceBegin<sourceVal<sourceEnd lub sourceBegin>sourceVal>sourceEnd
      to destBegin<  result<   destEnd   lub destBegin  >result   >destEnd
  jezeli sourceVal<sourceBegin<sourceEnd lub sourceVal>sourceBegin>sourceEnd
      to result<   destBegin<  destEnd   lub result   >destBegin>  destEnd

Jak widac oba zakresy moga byc rosnace, moga byc oba malejace a moze byc jeden malejacy a jeden rosnacy - zawsze zadanie ma 1 wynik dzieki powyzszej definicji.

function MapRange(sourceVal, sourceBegin, sourceEnd, destBegin, destEnd: float ): float; overload;
 
function RandomFloatRange(const RangeBegin, RangeEnd: