5
- All globas variables, initialization and finalization uses TObject instead
7
This means, using the unit, without calling any of the functions, will not
8
make any reference to the classes, and they should be smart-linked away.
14
Classes, SysUtils, FileUtil, types, math, LazClasses;
18
TLazLoggerLogGroupFlag =
19
( lgfAddedByParamParser, // Not added via Register. This is a placeholder for the enabled-state given by the user, via cmd-line
20
lgfNoDefaultEnabledSpecified // Registered without default
23
TLazLoggerLogGroupFlags = set of TLazLoggerLogGroupFlag;
25
TLazLoggerLogGroup = record
26
ConfigName: String; // case insensitive
28
Flags: TLazLoggerLogGroupFlags;
29
FOpenedIndents: Integer;
31
PLazLoggerLogGroup = ^TLazLoggerLogGroup;
33
TLazLoggerWriteTarget = (
36
lwtTextFile // Data will be ^Text
39
TLazLoggerWriteEvent = procedure(Sender: TObject; S: string; var Handled: Boolean) of object;
40
TLazLoggerWidgetSetWriteEvent = procedure(Sender: TObject;
43
Target: TLazLoggerWriteTarget;
44
Data: Pointer) of object;
48
{ TLazLoggerLogGroupList }
50
TLazLoggerLogGroupList = class(TRefCountedObject)
54
function GetItem(Index: Integer): PLazLoggerLogGroup;
55
function NewItem(const AConfigName: String; ADefaulEnabled: Boolean = False) : PLazLoggerLogGroup;
57
function Add(const AConfigName: String; ADefaulEnabled: Boolean = False) : PLazLoggerLogGroup;
58
function FindOrAdd(const AConfigName: String; ADefaulEnabled: Boolean = False) : PLazLoggerLogGroup;
59
procedure Remove(const AConfigName: String);
60
procedure Remove(const AnEntry: PLazLoggerLogGroup);
63
destructor Destroy; override;
64
procedure Assign(Src: TLazLoggerLogGroupList);
65
function IndexOf(const AConfigName: String): integer;
66
function IndexOf(const AnEntry: PLazLoggerLogGroup): integer;
67
function Find(const AConfigName: String): PLazLoggerLogGroup;
68
function Count: integer;
69
property Item[Index: Integer]: PLazLoggerLogGroup read GetItem; default;
74
TLazLogger = class(TRefCountedObject)
76
FIsInitialized: Boolean;
78
FMaxNestPrefixLen: Integer;
79
FNestLvlIndent: Integer;
81
FLogGroupList: TRefCountedObject; // Using TObject, so if none of the functions is used in the app, then even the rlass should be smart linked
82
FUseGlobalLogGroupList: Boolean;
84
procedure SetMaxNestPrefixLen(AValue: Integer);
85
procedure SetNestLvlIndent(AValue: Integer);
87
function GetLogGroupList: TLazLoggerLogGroupList;
88
procedure SetUseGlobalLogGroupList(AValue: Boolean);
90
procedure DoInit; virtual;
91
procedure DoFinsh; virtual;
93
procedure IncreaseIndent; overload; virtual;
94
procedure DecreaseIndent; overload; virtual;
95
procedure IncreaseIndent({%H-}LogGroup: PLazLoggerLogGroup); overload; virtual;
96
procedure DecreaseIndent({%H-}LogGroup: PLazLoggerLogGroup); overload; virtual;
97
procedure IndentChanged; virtual;
99
procedure DoDbgOut(const {%H-}s: string); virtual;
100
procedure DoDebugLn(const {%H-}s: string); virtual;
101
procedure DoDebuglnStack(const {%H-}s: string); virtual;
103
function ArgsToString(Args: array of const): string;
104
property IsInitialized: Boolean read FIsInitialized;
107
destructor Destroy; override;
108
procedure Assign(Src: TLazLogger); virtual;
112
property NestLvlIndent: Integer read FNestLvlIndent write SetNestLvlIndent;
113
property MaxNestPrefixLen: Integer read FMaxNestPrefixLen write SetMaxNestPrefixLen;
116
function RegisterLogGroup(const AConfigName: String; ADefaulEnabled: Boolean) : PLazLoggerLogGroup; virtual;
117
function RegisterLogGroup(const AConfigName: String) : PLazLoggerLogGroup; virtual;
118
function FindOrRegisterLogGroup(const AConfigName: String; ADefaulEnabled: Boolean) : PLazLoggerLogGroup; virtual;
119
function FindOrRegisterLogGroup(const AConfigName: String) : PLazLoggerLogGroup; virtual;
120
property LogGroupList: TLazLoggerLogGroupList read GetLogGroupList;
121
property UseGlobalLogGroupList: Boolean read FUseGlobalLogGroupList write SetUseGlobalLogGroupList;
123
procedure DebuglnStack(const s: string = '');
125
procedure DbgOut(const s: string = ''); overload;
126
procedure DbgOut(Args: array of const); overload;
127
procedure DbgOut(const S: String; Args: array of const); overload;// similar to Format(s,Args)
128
procedure DbgOut(const s1, s2: string; const s3: string = '';
129
const s4: string = ''; const s5: string = ''; const s6: string = '';
130
const s7: string = ''; const s8: string = ''; const s9: string = '';
131
const s10: string = ''; const s11: string = ''; const s12: string = '';
132
const s13: string = ''; const s14: string = ''; const s15: string = '';
133
const s16: string = ''; const s17: string = ''; const s18: string = ''); overload;
135
procedure DebugLn(const s: string = ''); overload;
136
procedure DebugLn(Args: array of const); overload;
137
procedure DebugLn(const S: String; Args: array of const); overload;// similar to Format(s,Args)
138
procedure DebugLn(const s1, s2: string; const s3: string = '';
139
const s4: string = ''; const s5: string = ''; const s6: string = '';
140
const s7: string = ''; const s8: string = ''; const s9: string = '';
141
const s10: string = ''; const s11: string = ''; const s12: string = '';
142
const s13: string = ''; const s14: string = ''; const s15: string = '';
143
const s16: string = ''; const s17: string = ''; const s18: string = ''); overload;
145
procedure DebugLnEnter(const s: string = ''); overload;
146
procedure DebugLnEnter(Args: array of const); overload;
147
procedure DebugLnEnter(s: string; Args: array of const); overload;
148
procedure DebugLnEnter(const s1, s2: string; const s3: string = '';
149
const s4: string = ''; const s5: string = ''; const s6: string = '';
150
const s7: string = ''; const s8: string = ''; const s9: string = '';
151
const s10: string = ''; const s11: string = ''; const s12: string = '';
152
const s13: string = ''; const s14: string = ''; const s15: string = '';
153
const s16: string = ''; const s17: string = ''; const s18: string = ''); overload;
155
procedure DebugLnExit(const s: string = ''); overload;
156
procedure DebugLnExit(Args: array of const); overload;
157
procedure DebugLnExit(s: string; Args: array of const); overload;
158
procedure DebugLnExit(const s1, s2: string; const s3: string = '';
159
const s4: string = ''; const s5: string = ''; const s6: string = '';
160
const s7: string = ''; const s8: string = ''; const s9: string = '';
161
const s10: string = ''; const s11: string = ''; const s12: string = '';
162
const s13: string = ''; const s14: string = ''; const s15: string = '';
163
const s16: string = ''; const s17: string = ''; const s18: string = ''); overload;
166
procedure DebuglnStack(LogGroup: PLazLoggerLogGroup; const s: string = '');
168
procedure DbgOut(LogGroup: PLazLoggerLogGroup; const s: string = ''); overload;
169
procedure DbgOut(LogGroup: PLazLoggerLogGroup; Args: array of const); overload;
170
procedure DbgOut(LogGroup: PLazLoggerLogGroup; const S: String; Args: array of const); overload;// similar to Format(s,Args)
171
procedure DbgOut(LogGroup: PLazLoggerLogGroup; const s1, s2: string; const s3: string = '';
172
const s4: string = ''; const s5: string = ''; const s6: string = '';
173
const s7: string = ''; const s8: string = ''; const s9: string = '';
174
const s10: string = ''; const s11: string = ''; const s12: string = '';
175
const s13: string = ''; const s14: string = ''; const s15: string = '';
176
const s16: string = ''; const s17: string = ''; const s18: string = ''); overload;
178
procedure DebugLn(LogGroup: PLazLoggerLogGroup; const s: string = ''); overload;
179
procedure DebugLn(LogGroup: PLazLoggerLogGroup; Args: array of const); overload;
180
procedure DebugLn(LogGroup: PLazLoggerLogGroup; const S: String; Args: array of const); overload;// similar to Format(s,Args)
181
procedure DebugLn(LogGroup: PLazLoggerLogGroup; const s1, s2: string; const s3: string = '';
182
const s4: string = ''; const s5: string = ''; const s6: string = '';
183
const s7: string = ''; const s8: string = ''; const s9: string = '';
184
const s10: string = ''; const s11: string = ''; const s12: string = '';
185
const s13: string = ''; const s14: string = ''; const s15: string = '';
186
const s16: string = ''; const s17: string = ''; const s18: string = ''); overload;
188
procedure DebugLnEnter(LogGroup: PLazLoggerLogGroup; const s: string = ''); overload;
189
procedure DebugLnEnter(LogGroup: PLazLoggerLogGroup; Args: array of const); overload;
190
procedure DebugLnEnter(LogGroup: PLazLoggerLogGroup; s: string; Args: array of const); overload;
191
procedure DebugLnEnter(LogGroup: PLazLoggerLogGroup; const s1, s2: string; const s3: string = '';
192
const s4: string = ''; const s5: string = ''; const s6: string = '';
193
const s7: string = ''; const s8: string = ''; const s9: string = '';
194
const s10: string = ''; const s11: string = ''; const s12: string = '';
195
const s13: string = ''; const s14: string = ''; const s15: string = '';
196
const s16: string = ''; const s17: string = ''; const s18: string = ''); overload;
198
procedure DebugLnExit(LogGroup: PLazLoggerLogGroup; const s: string = ''); overload;
199
procedure DebugLnExit(LogGroup: PLazLoggerLogGroup; Args: array of const); overload;
200
procedure DebugLnExit(LogGroup: PLazLoggerLogGroup; s: string; Args: array of const); overload;
201
procedure DebugLnExit(LogGroup: PLazLoggerLogGroup; const s1, s2: string; const s3: string = '';
202
const s4: string = ''; const s5: string = ''; const s6: string = '';
203
const s7: string = ''; const s8: string = ''; const s9: string = '';
204
const s10: string = ''; const s11: string = ''; const s12: string = '';
205
const s13: string = ''; const s14: string = ''; const s15: string = '';
206
const s16: string = ''; const s17: string = ''; const s18: string = ''); overload;
210
{ TLazLoggerWithGroupParam
211
- Provides Enabling/disabling groups from commandline
212
- TLazLogger provides only storage for LogGroups, it does not need to
213
enable/disable them, as it discards all logging anyway
216
TLazLoggerWithGroupParam = class(TLazLogger)
218
FLogAllDefaultDisabled: Boolean;
219
FLogDefaultEnabled: Boolean;
220
FLogParamParsed: Boolean;
221
FParamForEnabledLogGroups: String;
222
procedure SetParamForEnabledLogGroups(AValue: String);
223
procedure ParseParamForEnabledLogGroups;
226
procedure Assign(Src: TLazLogger); override;
227
function RegisterLogGroup(const AConfigName: String): PLazLoggerLogGroup; override;
228
function RegisterLogGroup(const AConfigName: String; ADefaulEnabled: Boolean): PLazLoggerLogGroup; override;
229
function FindOrRegisterLogGroup(const AConfigName: String): PLazLoggerLogGroup; override;
230
function FindOrRegisterLogGroup(const AConfigName: String; ADefaulEnabled: Boolean): PLazLoggerLogGroup; override;
231
// A param on the commandline, that may contain enabled/disabled LogGroups
232
// comma separated list / not present = defaults (none unless emabled in code) / - means none
233
property ParamForEnabledLogGroups: String read FParamForEnabledLogGroups write SetParamForEnabledLogGroups;
236
TLazLoggerNoOutput = class(TLazLogger)
240
{$DEFINE USED_BY_LAZLOGGER_BASE}
241
{$I LazLoggerIntf.inc}
243
function ConvertLineEndings(const s: string): string;
245
function GetParamByNameCount(const AName: String): integer;
246
function GetParamByName(const AName: String; AnIndex: Integer): string;
248
function GetDebugLoggerGroups: TLazLoggerLogGroupList; inline;
249
procedure SetDebugLoggerGroups(ALogGroups: TLazLoggerLogGroupList);
251
function GetDebugLogger: TLazLogger; inline;
252
function GetExistingDebugLogger: TLazLogger; inline; // No Autocreate
253
procedure SetDebugLogger(ALogger: TLazLogger);
255
procedure RecreateDebugLogger;
257
property DebugLogger: TLazLogger read GetDebugLogger write SetDebugLogger;
258
property DebugLoggerGroups: TLazLoggerLogGroupList read GetDebugLoggerGroups write SetDebugLoggerGroups;
261
TLazDebugLoggerCreator = function: TRefCountedObject;
263
// Using base TRefCountedObject, so if none of the functions is used in the app, then even the class should be smart linked
265
LazDebugLoggerCreator: TLazDebugLoggerCreator = nil;
266
OnWidgetSetDebugLn: TLazLoggerWidgetSetWriteEvent;
267
OnWidgetSetDbgOut: TLazLoggerWidgetSetWriteEvent;
271
{$I LazLoggerImpl.inc}
273
var // Using base TRefCountedObject, so if none of the functions is used in the app, then even the class should be smart linked
274
TheLazLogger: TRefCountedObject = nil;
275
PrevLazLogger: TRefCountedObject = nil;
276
TheLazLoggerGroups: TRefCountedObject = nil;
278
procedure CreateDebugLogger;
280
if (TheLazLogger <> nil) then
282
if (LazDebugLoggerCreator <> nil) then
283
TheLazLogger := LazDebugLoggerCreator();
284
if (TheLazLogger = nil) then
285
TheLazLogger := TLazLoggerNoOutput.Create;
286
TLazLogger(TheLazLogger).UseGlobalLogGroupList := True;
287
TheLazLogger.AddReference;
290
function GetDebugLogger: TLazLogger;
292
if (TheLazLogger = nil) then
294
Result := TLazLogger(TheLazLogger);
297
function GetExistingDebugLogger: TLazLogger;
299
if TheLazLogger <> nil then
300
Result := TLazLogger(TheLazLogger)
302
Result := TLazLogger(PrevLazLogger); // Pretend it still exists
305
procedure SetDebugLogger(ALogger: TLazLogger);
307
ReleaseRefAndNil(TheLazLogger);
308
TheLazLogger := ALogger;
309
TheLazLogger.AddReference;
312
procedure RecreateDebugLogger;
314
ReleaseRefAndNil(PrevLazLogger);
315
PrevLazLogger := TheLazLogger; // Pretend it still exists
316
TheLazLogger := nil; // Force creation
319
function GetDebugLoggerGroups: TLazLoggerLogGroupList;
321
if (TheLazLoggerGroups = nil) then begin
322
TheLazLoggerGroups := TLazLoggerLogGroupList.Create;
323
TheLazLoggerGroups.AddReference;
325
Result := TLazLoggerLogGroupList(TheLazLoggerGroups);
328
procedure SetDebugLoggerGroups(ALogGroups: TLazLoggerLogGroupList);
330
ReleaseRefAndNil(TheLazLoggerGroups);
331
TheLazLoggerGroups := ALogGroups;
332
TheLazLoggerGroups.AddReference;
335
function GetParamByNameCount(const AName: String): integer;
341
for i:= 1 to Paramcount do begin
342
if copy(ParamStrUTF8(i),1, l) = AName then
347
function GetParamByName(const AName: String; AnIndex: Integer): string;
352
for i:= 1 to Paramcount do begin
353
if copy(ParamStrUTF8(i),1, l) = AName then begin
355
if AnIndex < 0 then begin
356
Result := copy(ParamStrUTF8(i), l+1, Length(ParamStrUTF8(i))-l);
363
{ TLazLoggerLogGroupList }
365
procedure TLazLoggerLogGroupList.Clear;
367
while FList.Count > 0 do begin
373
function TLazLoggerLogGroupList.GetItem(Index: Integer): PLazLoggerLogGroup;
375
Result := PLazLoggerLogGroup(FList[Index])
378
function TLazLoggerLogGroupList.NewItem(const AConfigName: String;
379
ADefaulEnabled: Boolean): PLazLoggerLogGroup;
382
Result^.ConfigName := UpperCase(AConfigName);
383
Result^.Enabled := ADefaulEnabled;
385
Result^.FOpenedIndents := 0;
388
constructor TLazLoggerLogGroupList.Create;
390
FList := TFPList.Create;
393
destructor TLazLoggerLogGroupList.Destroy;
400
procedure TLazLoggerLogGroupList.Assign(Src: TLazLoggerLogGroupList);
407
for i := 0 to Src.Count - 1 do
408
Add('')^ := Src.Item[i]^;
411
function TLazLoggerLogGroupList.Add(const AConfigName: String;
412
ADefaulEnabled: Boolean): PLazLoggerLogGroup;
414
if Find(AConfigName) <> nil then
415
raise Exception.Create('Duplicate LogGroup ' + AConfigName);
416
Result := NewItem(AConfigName, ADefaulEnabled);
420
function TLazLoggerLogGroupList.FindOrAdd(const AConfigName: String;
421
ADefaulEnabled: Boolean): PLazLoggerLogGroup;
423
Result := Find(AConfigName);
424
if Result <> nil then exit;
425
Result := NewItem(AConfigName, ADefaulEnabled);
429
function TLazLoggerLogGroupList.IndexOf(const AConfigName: String): integer;
434
s := UpperCase(AConfigName);
435
while (Result >= 0) and (Item[Result]^.ConfigName <> s) do
439
function TLazLoggerLogGroupList.IndexOf(const AnEntry: PLazLoggerLogGroup): integer;
442
while (Result >= 0) and (Item[Result] <> AnEntry) do
446
function TLazLoggerLogGroupList.Find(const AConfigName: String): PLazLoggerLogGroup;
451
i := IndexOf(AConfigName);
456
procedure TLazLoggerLogGroupList.Remove(const AConfigName: String);
460
i := IndexOf(AConfigName);
467
procedure TLazLoggerLogGroupList.Remove(const AnEntry: PLazLoggerLogGroup);
471
i := IndexOf(AnEntry);
478
function TLazLoggerLogGroupList.Count: integer;
480
Result := FList.Count;
485
function TLazLogger.GetLogGroupList: TLazLoggerLogGroupList;
487
if UseGlobalLogGroupList then begin
488
Result := DebugLoggerGroups;
492
if FLogGroupList = nil then begin
493
FLogGroupList := TLazLoggerLogGroupList.Create;
494
FLogGroupList.AddReference;
496
Result := TLazLoggerLogGroupList(FLogGroupList);
499
procedure TLazLogger.SetUseGlobalLogGroupList(AValue: Boolean);
501
if FUseGlobalLogGroupList = AValue then Exit;
502
FUseGlobalLogGroupList := AValue;
505
procedure TLazLogger.SetMaxNestPrefixLen(AValue: Integer);
507
if FMaxNestPrefixLen = AValue then Exit;
508
FMaxNestPrefixLen := AValue;
512
procedure TLazLogger.SetNestLvlIndent(AValue: Integer);
514
if FNestLvlIndent = AValue then Exit;
515
FNestLvlIndent := AValue;
519
procedure TLazLogger.DoInit;
524
procedure TLazLogger.DoFinsh;
529
procedure TLazLogger.DoDebuglnStack(const s: string);
534
procedure TLazLogger.IncreaseIndent;
539
procedure TLazLogger.DecreaseIndent;
544
procedure TLazLogger.IncreaseIndent(LogGroup: PLazLoggerLogGroup);
549
procedure TLazLogger.DecreaseIndent(LogGroup: PLazLoggerLogGroup);
554
procedure TLazLogger.IndentChanged;
559
procedure TLazLogger.DoDbgOut(const s: string);
564
procedure TLazLogger.DoDebugLn(const s: string);
569
function TLazLogger.ArgsToString(Args: array of const): string;
574
for i:=Low(Args) to High(Args) do begin
575
case Args[i].VType of
576
vtInteger: Result := Result + dbgs(Args[i].vinteger);
577
vtInt64: Result := Result + dbgs(Args[i].VInt64^);
578
vtQWord: Result := Result + dbgs(Args[i].VQWord^);
579
vtBoolean: Result := Result + dbgs(Args[i].vboolean);
580
vtExtended: Result := Result + dbgs(Args[i].VExtended^);
581
{$ifdef FPC_CURRENCY_IS_INT64}
583
// fpc 2.x has troubles in choosing the right dbgs()
584
// so we convert here
585
vtCurrency: Result := Result + dbgs(int64(Args[i].vCurrency^)/10000, 4);
587
vtCurrency: Result := Result + dbgs(Args[i].vCurrency^);
589
vtString: Result := Result + Args[i].VString^;
590
vtAnsiString: Result := Result + AnsiString(Args[i].VAnsiString);
591
vtChar: Result := Result + Args[i].VChar;
592
vtPChar: Result := Result + Args[i].VPChar;
593
vtPWideChar: Result := {%H-}Result {%H-}+ Args[i].VPWideChar;
594
vtWideChar: Result := Result + AnsiString(Args[i].VWideChar);
595
vtWidestring: Result := Result + AnsiString(WideString(Args[i].VWideString));
596
vtObject: Result := Result + DbgSName(Args[i].VObject);
597
vtClass: Result := Result + DbgSName(Args[i].VClass);
598
vtPointer: Result := Result + Dbgs(Args[i].VPointer);
599
else Result := Result + '?unknown variant?';
604
constructor TLazLogger.Create;
606
FIsInitialized := False;
607
FUseGlobalLogGroupList := False;
609
FMaxNestPrefixLen := 15;
612
FLogGroupList := nil;
615
destructor TLazLogger.Destroy;
618
if TheLazLogger = Self then TheLazLogger := nil;
619
ReleaseRefAndNil(FLogGroupList);
623
procedure TLazLogger.Assign(Src: TLazLogger);
627
FMaxNestPrefixLen := Src.FMaxNestPrefixLen;
628
FNestLvlIndent := Src.FNestLvlIndent;
630
FUseGlobalLogGroupList := Src.FUseGlobalLogGroupList;
631
if (not FUseGlobalLogGroupList) and (Src.FLogGroupList <> nil) then
632
LogGroupList.Assign(Src.LogGroupList);
635
procedure TLazLogger.Init;
637
if FIsInitialized then exit;
639
FIsInitialized := True;
642
procedure TLazLogger.Finish;
644
if FIsInitialized then
646
FIsInitialized := False;
649
function TLazLogger.RegisterLogGroup(const AConfigName: String;
650
ADefaulEnabled: Boolean): PLazLoggerLogGroup;
652
// The basic logger does not add entries from parsig cmd-line. So no need to check
653
Result := LogGroupList.Add(AConfigName, ADefaulEnabled);
656
function TLazLogger.RegisterLogGroup(const AConfigName: String): PLazLoggerLogGroup;
658
Result := LogGroupList.Add(AConfigName);
659
Result^.Flags := Result^.Flags + [lgfNoDefaultEnabledSpecified];
662
function TLazLogger.FindOrRegisterLogGroup(const AConfigName: String;
663
ADefaulEnabled: Boolean): PLazLoggerLogGroup;
665
Result := LogGroupList.FindOrAdd(AConfigName, ADefaulEnabled);
668
function TLazLogger.FindOrRegisterLogGroup(const AConfigName: String): PLazLoggerLogGroup;
670
Result := LogGroupList.FindOrAdd(AConfigName);
671
Result^.Flags := Result^.Flags + [lgfNoDefaultEnabledSpecified];
674
procedure TLazLogger.DebuglnStack(const s: string);
679
procedure TLazLogger.DbgOut(const s: string);
684
procedure TLazLogger.DbgOut(Args: array of const);
686
DoDbgOut(ArgsToString(Args));
689
procedure TLazLogger.DbgOut(const S: String; Args: array of const);
691
DoDbgOut(Format(S, Args));
694
procedure TLazLogger.DbgOut(const s1, s2: string; const s3: string; const s4: string;
695
const s5: string; const s6: string; const s7: string; const s8: string; const s9: string;
696
const s10: string; const s11: string; const s12: string; const s13: string;
697
const s14: string; const s15: string; const s16: string; const s17: string;
700
DoDbgOut(s1+s2+s3+s4+s5+s6+s7+s8+s9+s10+s11+s12+s13+s14+s15+s16+s17+s18);
703
procedure TLazLogger.DebugLn(const s: string);
708
procedure TLazLogger.DebugLn(Args: array of const);
710
DoDebugLn(ArgsToString(Args));
713
procedure TLazLogger.DebugLn(const S: String; Args: array of const);
715
DoDebugLn(Format(S, Args));
718
procedure TLazLogger.DebugLn(const s1, s2: string; const s3: string; const s4: string;
719
const s5: string; const s6: string; const s7: string; const s8: string; const s9: string;
720
const s10: string; const s11: string; const s12: string; const s13: string;
721
const s14: string; const s15: string; const s16: string; const s17: string;
724
DoDebugLn(s1+s2+s3+s4+s5+s6+s7+s8+s9+s10+s11+s12+s13+s14+s15+s16+s17+s18);
727
procedure TLazLogger.DebugLnEnter(const s: string);
733
procedure TLazLogger.DebugLnEnter(Args: array of const);
735
DoDebugLn(ArgsToString(Args));
739
procedure TLazLogger.DebugLnEnter(s: string; Args: array of const);
741
DoDebugLn(Format(S, Args));
745
procedure TLazLogger.DebugLnEnter(const s1, s2: string; const s3: string; const s4: string;
746
const s5: string; const s6: string; const s7: string; const s8: string; const s9: string;
747
const s10: string; const s11: string; const s12: string; const s13: string;
748
const s14: string; const s15: string; const s16: string; const s17: string;
751
DoDebugLn(s1+s2+s3+s4+s5+s6+s7+s8+s9+s10+s11+s12+s13+s14+s15+s16+s17+s18);
755
procedure TLazLogger.DebugLnExit(const s: string);
761
procedure TLazLogger.DebugLnExit(Args: array of const);
764
DoDebugLn(ArgsToString(Args));
767
procedure TLazLogger.DebugLnExit(s: string; Args: array of const);
770
DoDebugLn(Format(S, Args));
773
procedure TLazLogger.DebugLnExit(const s1, s2: string; const s3: string; const s4: string;
774
const s5: string; const s6: string; const s7: string; const s8: string; const s9: string;
775
const s10: string; const s11: string; const s12: string; const s13: string;
776
const s14: string; const s15: string; const s16: string; const s17: string;
780
DoDebugLn(s1+s2+s3+s4+s5+s6+s7+s8+s9+s10+s11+s12+s13+s14+s15+s16+s17+s18);
783
procedure TLazLogger.DebuglnStack(LogGroup: PLazLoggerLogGroup; const s: string);
785
if (LogGroup <> nil) and (not LogGroup^.Enabled) then exit;
789
procedure TLazLogger.DbgOut(LogGroup: PLazLoggerLogGroup; const s: string);
791
if (LogGroup <> nil) and (not LogGroup^.Enabled) then exit;
795
procedure TLazLogger.DbgOut(LogGroup: PLazLoggerLogGroup; Args: array of const);
797
if (LogGroup <> nil) and (not LogGroup^.Enabled) then exit;
798
DoDbgOut(ArgsToString(Args));
801
procedure TLazLogger.DbgOut(LogGroup: PLazLoggerLogGroup; const S: String;
802
Args: array of const);
804
if (LogGroup <> nil) and (not LogGroup^.Enabled) then exit;
805
DoDbgOut(Format(S, Args));
808
procedure TLazLogger.DbgOut(LogGroup: PLazLoggerLogGroup; const s1, s2: string;
809
const s3: string; const s4: string; const s5: string; const s6: string; const s7: string;
810
const s8: string; const s9: string; const s10: string; const s11: string; const s12: string;
811
const s13: string; const s14: string; const s15: string; const s16: string;
812
const s17: string; const s18: string);
814
if (LogGroup <> nil) and (not LogGroup^.Enabled) then exit;
815
DoDbgOut(s1+s2+s3+s4+s5+s6+s7+s8+s9+s10+s11+s12+s13+s14+s15+s16+s17+s18);
818
procedure TLazLogger.DebugLn(LogGroup: PLazLoggerLogGroup; const s: string);
820
if (LogGroup <> nil) and (not LogGroup^.Enabled) then exit;
824
procedure TLazLogger.DebugLn(LogGroup: PLazLoggerLogGroup; Args: array of const);
826
if (LogGroup <> nil) and (not LogGroup^.Enabled) then exit;
827
DoDebugLn(ArgsToString(Args));
830
procedure TLazLogger.DebugLn(LogGroup: PLazLoggerLogGroup; const S: String;
831
Args: array of const);
833
if (LogGroup <> nil) and (not LogGroup^.Enabled) then exit;
834
DoDebugLn(Format(S, Args));
837
procedure TLazLogger.DebugLn(LogGroup: PLazLoggerLogGroup; const s1, s2: string;
838
const s3: string; const s4: string; const s5: string; const s6: string; const s7: string;
839
const s8: string; const s9: string; const s10: string; const s11: string; const s12: string;
840
const s13: string; const s14: string; const s15: string; const s16: string;
841
const s17: string; const s18: string);
843
if (LogGroup <> nil) and (not LogGroup^.Enabled) then exit;
844
DoDebugLn(s1+s2+s3+s4+s5+s6+s7+s8+s9+s10+s11+s12+s13+s14+s15+s16+s17+s18);
847
procedure TLazLogger.DebugLnEnter(LogGroup: PLazLoggerLogGroup; const s: string);
849
if not( (LogGroup <> nil) and (not LogGroup^.Enabled) ) then
851
IncreaseIndent(LogGroup);
854
procedure TLazLogger.DebugLnEnter(LogGroup: PLazLoggerLogGroup; Args: array of const);
856
if not( (LogGroup <> nil) and (not LogGroup^.Enabled) ) then
857
DoDebugLn(ArgsToString(Args));
858
IncreaseIndent(LogGroup);
861
procedure TLazLogger.DebugLnEnter(LogGroup: PLazLoggerLogGroup; s: string;
862
Args: array of const);
864
if not( (LogGroup <> nil) and (not LogGroup^.Enabled) ) then
865
DoDebugLn(Format(S, Args));
866
IncreaseIndent(LogGroup);
869
procedure TLazLogger.DebugLnEnter(LogGroup: PLazLoggerLogGroup; const s1, s2: string;
870
const s3: string; const s4: string; const s5: string; const s6: string; const s7: string;
871
const s8: string; const s9: string; const s10: string; const s11: string; const s12: string;
872
const s13: string; const s14: string; const s15: string; const s16: string;
873
const s17: string; const s18: string);
875
if not( (LogGroup <> nil) and (not LogGroup^.Enabled) ) then
876
DoDebugLn(s1+s2+s3+s4+s5+s6+s7+s8+s9+s10+s11+s12+s13+s14+s15+s16+s17+s18);
877
IncreaseIndent(LogGroup);
880
procedure TLazLogger.DebugLnExit(LogGroup: PLazLoggerLogGroup; const s: string);
882
DecreaseIndent(LogGroup);
883
if (LogGroup <> nil) and (not LogGroup^.Enabled) then exit;
887
procedure TLazLogger.DebugLnExit(LogGroup: PLazLoggerLogGroup; Args: array of const);
889
DecreaseIndent(LogGroup);
890
if (LogGroup <> nil) and (not LogGroup^.Enabled) then exit;
891
DoDebugLn(ArgsToString(Args));
894
procedure TLazLogger.DebugLnExit(LogGroup: PLazLoggerLogGroup; s: string;
895
Args: array of const);
897
DecreaseIndent(LogGroup);
898
if (LogGroup <> nil) and (not LogGroup^.Enabled) then exit;
899
DoDebugLn(Format(S, Args));
902
procedure TLazLogger.DebugLnExit(LogGroup: PLazLoggerLogGroup; const s1, s2: string;
903
const s3: string; const s4: string; const s5: string; const s6: string; const s7: string;
904
const s8: string; const s9: string; const s10: string; const s11: string; const s12: string;
905
const s13: string; const s14: string; const s15: string; const s16: string;
906
const s17: string; const s18: string);
908
DecreaseIndent(LogGroup);
909
if (LogGroup <> nil) and (not LogGroup^.Enabled) then exit;
910
DoDebugLn(s1+s2+s3+s4+s5+s6+s7+s8+s9+s10+s11+s12+s13+s14+s15+s16+s17+s18);
913
{ TLazLoggerWithGroupParam }
915
procedure TLazLoggerWithGroupParam.SetParamForEnabledLogGroups(AValue: String);
917
if FParamForEnabledLogGroups = AValue then Exit;
918
FParamForEnabledLogGroups := AValue;
919
ParseParamForEnabledLogGroups;
922
procedure TLazLoggerWithGroupParam.ParseParamForEnabledLogGroups;
926
g: PLazLoggerLogGroup;
930
c := GetParamByNameCount(FParamForEnabledLogGroups);
931
FLogDefaultEnabled := False;
932
FLogAllDefaultDisabled := FAlse;
934
list := TStringList.Create;
935
for i := 0 to c - 1 do begin
936
s := GetParamByName(FParamForEnabledLogGroups, i);
938
if s = '-' then begin
940
FLogDefaultEnabled := False;
941
for j := 0 to LogGroupList.Count - 1 do
942
LogGroupList[j]^.Enabled := False;
943
FLogAllDefaultDisabled := True;
948
for j := 0 to list.Count - 1 do begin
950
if (s = '-') or (s='') then
951
continue; // invalid, within comma list
956
if s[1] in ['-', '+'] then delete(s,1,1);
961
FLogDefaultEnabled := False;
963
g := LogGroupList.Find(s);
964
if g <> nil then begin
966
g^.Flags := g^.Flags - [lgfNoDefaultEnabledSpecified];
969
g := LogGroupList.Add(s, e);
970
g^.Flags := g^.Flags + [lgfAddedByParamParser];
977
if not FLogParamParsed then begin
978
// first parse, reset default unless specified in RegisterLogGroup();
979
for i := 0 to LogGroupList.Count - 1 do
980
if lgfNoDefaultEnabledSpecified in LogGroupList[i]^.Flags then
981
LogGroupList[i]^.Enabled := FLogDefaultEnabled;
984
FLogParamParsed := True;
987
constructor TLazLoggerWithGroupParam.Create;
990
FLogDefaultEnabled := False;
991
FLogAllDefaultDisabled := False;
994
procedure TLazLoggerWithGroupParam.Assign(Src: TLazLogger);
996
inherited Assign(Src);
997
if (Src <> nil) and (Src is TLazLoggerWithGroupParam) then begin
998
FLogParamParsed := False;
999
FParamForEnabledLogGroups := TLazLoggerWithGroupParam(Src).FParamForEnabledLogGroups;
1003
function TLazLoggerWithGroupParam.RegisterLogGroup(const AConfigName: String): PLazLoggerLogGroup;
1005
Default, DefaultFound: Boolean;
1007
Result := LogGroupList.Find(AConfigName);
1008
Default := FLogDefaultEnabled;
1009
DefaultFound := False;
1010
if Result <> nil then begin
1011
Default := Result^.Enabled;
1012
DefaultFound := not(lgfNoDefaultEnabledSpecified in Result^.Flags);
1015
Result := RegisterLogGroup(AConfigName, Default);
1017
if not DefaultFound then
1018
Result^.Flags := Result^.Flags + [lgfNoDefaultEnabledSpecified];
1021
function TLazLoggerWithGroupParam.RegisterLogGroup(const AConfigName: String;
1022
ADefaulEnabled: Boolean): PLazLoggerLogGroup;
1024
if FLogAllDefaultDisabled then
1025
ADefaulEnabled := False;
1026
Result := LogGroupList.Find(AConfigName);
1027
if Result <> nil then begin
1028
if not(lgfAddedByParamParser in Result^.Flags) then
1029
raise Exception.Create('Duplicate LogGroup ' + AConfigName);
1030
if ADefaulEnabled and not(lgfAddedByParamParser in Result^.Flags) then
1031
Result^.Enabled := True;
1032
Result^.Flags := Result^.Flags - [lgfAddedByParamParser];
1035
Result := LogGroupList.Add(AConfigName, ADefaulEnabled);
1038
function TLazLoggerWithGroupParam.FindOrRegisterLogGroup(const AConfigName: String): PLazLoggerLogGroup;
1040
Result := LogGroupList.Find(AConfigName);
1041
if Result = nil then
1042
Result := RegisterLogGroup(AConfigName)
1044
Result^.Flags := Result^.Flags - [lgfAddedByParamParser];
1047
function TLazLoggerWithGroupParam.FindOrRegisterLogGroup(const AConfigName: String;
1048
ADefaulEnabled: Boolean): PLazLoggerLogGroup;
1050
Result := LogGroupList.Find(AConfigName);
1051
if Result = nil then
1052
Result := RegisterLogGroup(AConfigName, ADefaulEnabled)
1055
if (lgfNoDefaultEnabledSpecified in Result^.Flags) and
1056
not(lgfAddedByParamParser in Result^.Flags)
1058
Result^.Enabled := ADefaulEnabled;
1059
Result^.Flags := Result^.Flags - [lgfNoDefaultEnabledSpecified, lgfAddedByParamParser];
1063
function ConvertLineEndings(const s: string): string;
1066
EndingStart: LongInt;
1070
while (i<=length(Result)) do begin
1071
if Result[i] in [#10,#13] then begin
1074
if (i<=length(Result)) and (Result[i] in [#10,#13])
1075
and (Result[i]<>Result[i-1]) then begin
1078
if (length(LineEnding)<>i-EndingStart)
1079
or (LineEnding<>copy(Result,EndingStart,length(LineEnding))) then begin
1080
// line end differs => replace with current LineEnding
1082
copy(Result,1,EndingStart-1)+LineEnding+copy(Result,i,length(Result));
1083
i:=EndingStart+length(LineEnding);
1090
finalization // Using TObject, so if none of the functions is used in the app, then even the rlass should be smart linked
1091
ReleaseRefAndNil(TheLazLogger);
1092
ReleaseRefAndNil(PrevLazLogger);
1093
ReleaseRefAndNil(TheLazLoggerGroups);