-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlibrary.c
9023 lines (7852 loc) · 228 KB
/
library.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/***********************************************************
mini-library 2018-05
Edouard BERGE v0.47
!!! DO NOT INCLUDE THIS FILE, USE library.h !!!
changes v047:
- bugfix linux fnmatch
- TxtStrDupLen
changes v046:
- _internal_readtextfile windows compatibility
changes v045:
- debug info on FileReadBinary
- bugfix in FileSeekBinary (to complete)
changes v044:
- stristr
- CSVGetQuotedFieldNumber
- CSVGetAllQuotedFields
changes v043:
- no INFO/DEBUG/ERROR message if colors are enabled
changes v042:
- TxtToMultiLigne, TxtJustifyAlloc
- better date format check
- XMLGetFieldAttrValue check if there is attributes
changes v041:
- XML core improvement
- FileSeekBinary
- File core can handle an unlimited of files
- BlockFileInit, BlockFileRead, BlockFileWritePrepare, BlockFileWriteFinalize, BlockFileClose
changes v040:
- XML core can handle and check namespaces
- XML core may join contiguous CDATA segments
- XML behaviour of Get functions
- XMLMakeCDATASection
- bugfix in comment duplication in XMLDuplicateField
- bugfix in MemCpy overriding check
changes v039:
- FileWriteLines
changes v038:
- RandIsaacForceSeed
- MaxDouble, MinDouble, MaxFloat, MinFloat
- MaxLong, MinLong, MaxULong, MinULong
- MaxInt, MinInt, MaxUInt, MinUInt
- MaxShortInt, MinShortInt, MaxUShortInt, MinUShortInt
- MaxChar, MinChar, MaxUChar, MinUChar
changes v037:
- MinMaxFloat casting
- FastRand
- XMLGetFieldValue
- FileReadContent
- ChronoGetMicroSecond,ChronoGetNanoSecond
changes v036:
- MemDuplicate give useful informations when memory overflow
- Isaac generator with a "real" random init
changes v035:
- ChronoGetSecond, ChronoGetMilliSecond Windows compliant
- Regexp function wrapper for Windows compatibility
- RandIsaac cryptographically secure pseudorandom generator
changes v034:
- Better casting for memory functions (less warning with verbose compiler)
- More info on MemCheck error
- OpenLibrary allow Linux programm to guess wich caused segfault
- XML core bugfix on CDATA segment
- pthread Windows compliant
- ChronoStart/Stop, NanoSleep Windows compliant
- Dir function Windows compliant (readdir wrapper)
- LookForFile Windows compliant
- _internal_CPUGetCoreNumber Windows compliant
- ChronoGetMilliSecond
- Regexp functions ARE NOT compliant under Windows
- Process functions ARE NOT compliant under Windows
changes v033:
- CorrelationCharStep
changes v032:
- XMLFieldAddAttribute, XMLFieldAddAttributeLong, XMLFieldAddAttributeDouble
- XMLFieldAddAttributeList, XMLFieldAddAttributeListLong, XMLFieldAddAttributeListDouble
- GetYear, GetCurrentYear
- MemDuplicate
- ChronoGetSecond
changes v031:
- Memory(De)Crunch now use LZ4 compression from Yann Colet under New BSD Licence
- MemoryCrunchMax reach better compression ratio (but ten times slower)
- new XML core with full parsing, more integrity checks
- bugfix in FieldArrayAddDynamicValueConcat
- bugfix 64 bits long long casting in TxtSimplifyNumber
- XMLGetFieldAttrValue
- ANSI colors
- MemMove
- NanoSleep
changes v030:
- XML core debug
- Memory core improvement, multi-thread fix
- HashFlush is threaded to run in background
- HashRemoveData, HashPutString, HashGetString, HashPutStringCrunched, HashGetStringCrunched
- MemSet
- Bugfixed FileGetStat when no file found
changes v029: (XML work in progress)
- MemoryCrunch, MemoryDecrunch
- HashPutData, HashGetData, HashFlush, HashFree
- HashPutDataCrunched, HashGetDataCrunched
- BinaryGetCRC
- MemCpy
- ObjectArrayAddDynamicValueConcat
- *ArrayAddDynamicValue optimisation
- XMLGetFieldMulti, XMLDuplicateFieldRecurse, XMLGetFieldAttr
- TxtRegMatch cache mechanism
- FileReadLine(s)XML deprecated
- CSVReadFile, CSVReadFileWithSeparator
changes v028: (XML work in progress)
- CopyFields
- new XML core, XMLParseAttribute, XML attributes, comments and CDATA support, XMLGetField
- FileReadPos
changes v027:
- ProcessFork, ProcessDetach
- IntArrayAddDynamicValueConcat
- FieldArrayAddDynamicValueConcat activated
- FAST_LIBRARY cleaning
- LookForFile rewrite (clever)
- MemDump 32 bits compliant, also bugfixed for char 127
changes v026:
- ProcessSearch, ProcessExists, ProcessInfo, ProcessQuit, ProcessQuitBackGround
- FileReadClose
- TxtGetFile
- TxtSplit optimisation
- FieldArrayAddDynamicValueConcat changes (multi-thread compliant)
- Linux host as default
changes v025:
- TxtConcat, TxtConcatWithSeparator
- ChronoStart optimisation
- ExecuteSysCmdBackGround,ExecuteSysCmdBackGroundPushed,ExecuteSysCmdWaitForThreads
- setdebug is now deprecated
- _internal_strdup optimisation
- SystemInfo now running on Linux platform
- FileExists
changes v024:
- do not display memory stats when using FAST_LIBRARY mode
- FAST_LIBRARY mode use google perftools http://code.google.com/p/gperftools/
- MemFree, MemMalloc, MemCalloc, MemRealloc, MemCheck, MemMonitor are now multi-thread compliant
- strappend, strnappend, strappendchar, strnappendchar
- TxtSplit, TxtMerge, TxtMergeWithSeparator
- strnicmp
changes v023:
- DirReadAllEntriesRecurse, DirMatchAllEntriesRecurse
- FileReadLines, FileReadLinesXML
- TxtGetCRC
- _internal_CPUGetCoreNumber
- FieldArrayAddDynamicValueConcat
- FAST_LIBRARY mode (no check on MemMalloc, MemRealloc of MemFree)
changes v022:
- ChronoStart, ChronoStop
- TxtTrimEnd optimisation
- more includes
changes v021:
- Numeric filter functions
- SmoothBufferInt
- MinMaxDouble, MinMaxLong, MinMaxInt
- CorrelationChar, CorrelationInt
- DirReadAllEntries, DirMatchAllEntries
- ParameterParseFieldList now can parse static buffers
- BugFix in XMLLoadFile
- BugFix in _internal_DirReadGlob
- BugFix in _MemFree
changes v020:
- Now we may disable the memory wrapper (for performance)
- Linux include bugfix
- Bugfixed GetEndianMode
changes v019:
- TxtRegMatch, TxtGlobMatch
- DirMatchEntry
changes v018:
- stricmp
- KeyGetString, KeyGetChoice
- TxtCleanSpecialChar, TxtDeleteSpecialChar, TxtReplaceSpecialChar
changes v017:
- Some bugfixes with va_list usage (Linux)
- Bugfix with programs starting with a Realloc of a NULL pointer and no debug mode
- Better flushing method in _internal_put2log
changes v016:
- Linux compliant
- 64bits compliant
- SystemInfo to display some details about running architecture
- GetAutoEndian to know if the current architecture is big-endian or little-endian
- GetEndianSHORTINT, GetEndianINT, GetEndianLONGLONG to retrieve values regardless of endianness mode
- PutEndianSHORTINT, PutEndianINT, PutEndianLONGLONG to put values in memory regardless of endianness mode
- TxtIsFloat, TxtIsDouble, TxtIsLongDouble
- Some bugfixes in _internal_TxtIsFloat (used for float, double and long double check)
changes v015:
- MemTrace, MemUntrace may use variable label
- Secured writes to text buffer in put2file, ExecuteSysCmd, MemTrace
- MemDump
- TxtGetSubstr
- TxtIsDouble
changes v014:
- Bugfixed FileGetStat error processing
- Harmonisation of errno management
- CloseLibrary checks for opened monitors
- MemTrace, MemUntrace may use label
- _internal_put2log flush when logtype change (to avoid conflicts when both stderr and stdout are redirected together)
changes v013:
- MemTrace, MemUntrace
- Check the memory when freeing memory
changes v012:
- TxtStrReplace is clever with zero size strings
- ChangeDir, GetDir
- ExecuteSysCmdGetLimit
- ExecuteSysCmdBypassError
- ExecuteSysCmd, ExecuteSysCmdBypassError now compute the maximum command line limit
- All filesystem related functions now check for PATH_MAX before processing
changes v011:
- FileChmod
- MakeDirWithRights, MakeDir
- ExecuteSysCmd system limit check (lower for rex compatibility)
- Trim functions now can handle tabs
- ParameterParseFieldList now can handle reversed interval
changes v010:
- Bugfixed MemFree (memory was not freed in the v007, v008, v009)
- Bugfixed Memory monitor leak
- FileRemoveIfExists
- DirRemoveIfExists
- General clean up, comments, internal prototypes harmonisation
changes v009:
- Bugfixed memory leak in CheckDateFormat
- Bugfixed CSVGetAllFields when separator was the very last char of a string (may occur when trimming strings)
- XMLLookForFieldByName, XMLLookForFieldByValue
- FieldArrayAddDynamicValue
- ExecuteSysCmd
- DirRemove now can remove non empty directories recursively
changes v008:
- MemRealloc is more flexible (may realloc to zero size, as a free)
- XML library (parsing, management, file operation)
- ConvertDate (convert any date format to any other)
- Leap year fix in CheckDateFormat
- TxtIsInteger
changes v007:
- Automatic memory check (full in debug_mode, light otherwise)
- TxtIsInvisible function
- TxtTrimEnd, TxtTrimStart, TxtTrimSpace, TxtTrim functions
- Bugfixed LookForFile (memory of callers is now preserved)
changes v006:
- Automatic memory monitor
- CloseLibrary function (check of unfreed memory, unfreed system pointers)
- Bugfixed memory leaks in FileClose and DirClose
changes v005:
- Datetime functions
- Directory reading functions
- File stat function
- Log on file function
- XML specific read function
changes v004:
- CSV field parsing functions
- TxtStrDup function
changes v003:
- Log functions can handle multiple arguments (very useful)
- Library functions do not use buffers for logs anymore...
- INTERNAL_ERROR is now 7 instead of 1 like ABORT_ERROR
- default DEBUG_MODE to 0
changes v002:
- ParameterParseFieldList now can handle interval
- File functions now can handle many file simultaneously
initial release v001:
- Log functions
- Memory management functions
- Text functions (substr, replace)
- File read&write functions
- Parameters array functions
************************************************************/
#define __FILENAME__ "library_v046.c"
#define FUNC ""
#define LIBRARY_NO_MEMORY_WRAPPER 0
/* force DEBUG_MODE to a value */
#ifndef DEBUG_MODE
#define DEBUG_MODE 0
#endif
/* default is a Linux host */
// #ifndef OS_WIN
// #define OS_LINUX 1
// #define OS_AIX 1
// #ifdef OS_LINUX
// #undef OS_AIX
// #endif
// #endif
/* includes for all OS */
#include<stddef.h>
#include<stdint.h>
#include<setjmp.h>
#include<string.h>
#include<stdlib.h>
#include<stdarg.h>
#ifndef OS_WIN
#include<dirent.h>
#endif
#include<stdio.h>
#include<errno.h>
#include<ctype.h>
#include<time.h>
#include<math.h>
#include<sys/types.h>
#include<sys/stat.h>
#ifndef OS_WIN
#include<unistd.h>
#endif
#include<fcntl.h>
#ifndef OS_WIN
#include<regex.h>
#endif
/* OS specific includes */
#ifdef OS_AIX
#include<curses.h>
#endif
#ifdef OS_LINUX
#include<wait.h>
#include<signal.h>
#include<limits.h>
#include<tgmath.h>
#include<pthread.h>
#include<sys/types.h>
#include<sys/timeb.h>
#define ARG_MAX 131072
#endif
#ifdef OS_MACOS
#include<time.h>
#include<sys/wait.h>
#include<signal.h>
#include<limits.h>
#include<tgmath.h>
#include<pthread.h>
#include<sys/types.h>
#include<sys/timeb.h>
#define ARG_MAX 131072
#endif
#ifdef OS_WIN
#include<errno.h>
#include<io.h>
#include<ctype.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<direct.h>
#include<windows.h>
#include<setjmp.h>
#include<intrin.h>
#include<errno.h>
#include<sys/timeb.h>
#include"trex.h"
#include"fnmatch.h"
#include"dirent.h"
#include"winpthread.h"
#define PATH_MAX MAX_PATH
#define ARG_MAX 8191
#else
#include<fnmatch.h>
#endif
#ifndef FAST
#ifdef FAST_LIBRARY
//#include <gperftools/tcmalloc.h>
#if OS_WIN
#define tc_malloc malloc
#define tc_realloc realloc
#define tc_free free
#else
#include "../../code/gperftools-2.0/src/gperftools/tcmalloc.h"
#endif
#endif
#else
/* FAST */
#define tc_malloc malloc
#define tc_realloc realloc
#define tc_free free
#define FAST_LIBRARY 1
#endif
#ifndef RDD
#include"lz4.h"
#endif
#ifndef M_PI
#define M_PI 3.141592653589793238462643
#endif
#ifndef M_LN2
#define M_LN2 0.69314718055994530942
#endif
enum e_bool {
false=0,
true
};
#ifndef OS_WIN
extern char **environ;
#else
char **environ=NULL;
#endif
#define INTERNAL_ERROR 7
#define ABORT_ERROR 1
#define MAX_LINE_BUFFER 16384
#define REG_MATCH 0
#define GET_ENDIAN_UNDEFINED -1
#define GET_LITTLE_ENDIAN 0
#define GET_BIG_ENDIAN 1
#define GET_AUTO_ENDIAN 2
#define PUT_ENDIAN_UNDEFINED GET_ENDIAN_UNDEFINED
#define PUT_LITTLE_ENDIAN GET_LITTLE_ENDIAN
#define PUT_BIG_ENDIAN GET_BIG_ENDIAN
#define PUT_AUTO_ENDIAN GET_AUTO_ENDIAN
#ifndef OS_WIN
#define KNORMAL "\x1B[0m"
#define KRED "\x1B[31m"
#define KGREEN "\x1B[32m"
#define KYELLOW "\x1B[33m"
#define KBLUE "\x1B[34m"
#define KCYAN "\x1B[36m"
#define KWHITE "\x1B[37m"
#else
#define KNORMAL ""
#define KRED ""
#define KGREEN ""
#define KYELLOW ""
#define KBLUE ""
#define KCYAN ""
#define KWHITE ""
#endif
/* statics */
pthread_mutex_t mutex_memory_management;
static char _static_library_txtcleanconvtable[256];
static int _static_library_endian_mode=GET_ENDIAN_UNDEFINED;
static int _static_library_nbfile_opened=0;
static int _static_library_nbfile_opened_max=0;
static int _static_library_nbdir_opened=0;
static int _static_library_nbdir_opened_max=0;
enum e_quote_type {
NO_QUOTE=0,
SINGLE_QUOTE='\'',
DOUBLE_QUOTE='"'
};
/***
LOG functions
output:
- the type of log (info, warning, error)
- the source filename
- the line of the log
- the C function
- the error message
*/
/***
_internal_put2log
internal use, do not call this function
*/
enum e_logtype {
LOG_START,
LOG_STDOUT,
LOG_STDERR
};
int _internal_CPUGetCoreNumber()
{
#undef FUNC
#define FUNC "_internal_CPUGetCoreNumber"
static int nb_cores=0;
#ifdef OS_WIN
SYSTEM_INFO sysinfo;
if (!nb_cores) {
GetSystemInfo( &sysinfo );
nb_cores=sysinfo.dwNumberOfProcessors;
}
#else
if (!nb_cores) {
nb_cores=sysconf(_SC_NPROCESSORS_ONLN );
if (nb_cores<=0)
nb_cores=1;
}
#endif
return nb_cores;
}
#define CPU_NB_CORES _internal_CPUGetCoreNumber()
/***
stricmp, strnicmp
make an strcmp comparison case insensitive
*/
#ifndef OS_WIN
int stricmp(char *str1,char *str2)
{
int idx;
int c1,c2;
if (!str1) return (!str2)?0:-(*str2);
if (!str2) return *str1;
while ((c1=tolower(*str1))==(c2=tolower(*str2)) && *str1)
{
str1++;
str2++;
}
return c1-c2;
}
int strnicmp(char *str1,char *str2,int l)
{
int idx;
int c1=0,c2=0;
if (!l) return 0;
if (!str1) return (!str2)?0:-(*str2);
if (!str2) return *str1;
while (l && (c1=tolower(*str1))==(c2=tolower(*str2)) && *str1)
{
str1++;
str2++;
l--;
}
return c1-c2;
}
#endif
char *stristr(char *str, char *sub)
{
int idx,ls,imax,l;
ls=strlen(sub);
l=strlen(str);
for (idx=0;idx<l-ls;idx++) {
if (strnicmp(&str[idx],sub,ls)==0) {
return str+idx;
}
}
return NULL;
}
char *strn0cpy(char *str1, const char *str2, int lg)
{
if (str1==NULL || str2==NULL) return NULL;
while (lg && *str2) {
*str1++=*str2++;
lg--;
}
*str1=0;
return str1;
}
/***
* strappend, strnappend, strappendchar, strnappendchar
*
* like strcat but returns the number of concatenated char
* this is usefull to optimized many strcat
* anyway the function will check that the pointer is
* the really end of the string. If not, it will seek
* to the end.
*
* char versions optimised for char
* n versions limit the number of concat chars
*
* outstr[0]=0;
* cw =strappend(outstr ,"blablablala");
* cw+=strappend(oustr+cw,"reblablabla");
* cw+=strappend(oustr+cw,"reblablabla");
* cw+=strappend(oustr+cw,"reblablabla");
* strappend(oustr+cw,"reblablabla");
*
*/
/***
* append a string
* return the number of char appened
*/
int strappend(char *Adst, char *Asrc)
{
int Lcpt=0;
/* must be at the end to concat */
while (*Adst) {
Adst++;
}
/* concat and count */
while (*Asrc) {
*Adst++=*Asrc++;
Lcpt++;
}
*Adst=0;
return Lcpt;
}
/***
* append a string, limited to Amax
* return the number of char appened
*/
int strnappend(char *Adst, char *Asrc, int Amax)
{
int Lcpt=0;
if (Amax<1) return 0;
/* must be at the end to concat */
while (*Adst) {
Adst++;
}
/* concat, count and limit */
while (*Asrc && Amax) {
*Adst++=*Asrc++;
Lcpt++;
Amax--;
}
*Adst=0;
return Lcpt;
}
/***
* append a char to a string
* return the number of char appened
*/
int strappendchar(char *Adst, char Asrc)
{
int Lcpt=0;
/* must be at the end to concat */
while (*Adst) {
Adst++;
}
/* concat */
*Adst++=Asrc;
*Adst=0;
return 1;
}
/***
* append a char, limited to Amax
* return the number of char appened
*/
int strnappendchar(char *Adst, char Asrc, int Amax)
{
/* limit */
if (Amax<1) return 0;
/* must be at the end to concat */
while (*Adst) {
Adst++;
}
/* concat, count */
*Adst++=Asrc;
*Adst=0;
return 1;
}
void _internal_put2log(char *logtype, char *cursource, int curline, char *curfunc, ...)
{
#undef FUNC
#define FUNC "_internal_put2log"
static int last_std=LOG_START;
int cur_std;
char *format;
va_list argptr;
long dek=0;
char zedatetime[256];
#ifdef OS_WIN
time_t l_time;
#else
long l_time;
#endif
struct tm *timestruct;
#ifdef OS_WIN
dek=0;
time(&l_time);
#else
l_time = time(&dek);
#endif
timestruct = localtime( &l_time);
sprintf(zedatetime,"%d%02d%02d|%02d:%02d:%02d",timestruct->tm_year+1900,timestruct->tm_mon+1,timestruct->tm_mday,timestruct->tm_hour,timestruct->tm_min,timestruct->tm_sec);
va_start(argptr,curfunc);
format=va_arg(argptr,char *);
if (strcmp(logtype,"INFO ")==0 || strcmp(logtype,"WARN ")==0 || strcmp(logtype,"MONITOR ")==0 || strcmp(logtype,"DEBUG ")==0)
cur_std=LOG_STDOUT;
else
cur_std=LOG_STDERR;
/* when logtype changes from previous value, we flush the previous output buffer */
if (cur_std!=last_std)
{
switch (last_std)
{
case LOG_STDOUT:fflush(stdout);break;
case LOG_START:fflush(stderr);break;
default:break;
}
last_std=cur_std;
}
if (strcmp(logtype,"DEBUG ")==0)
{
if (DEBUG_MODE)
{
fprintf(stdout,KCYAN"%s (%s) L%d - %s - ",zedatetime,cursource,curline,curfunc);
vfprintf(stdout,format,argptr);
fprintf(stdout,KNORMAL"\n");
}
}
else
if (strcmp(logtype,"INFO ")==0 || strcmp(logtype,"WARN ")==0 || strcmp(logtype,"MONITOR ")==0)
{
switch (logtype[0]) {
case 'I':fprintf(stdout,KNORMAL);break;
case 'W':fprintf(stdout,KYELLOW);break;
case 'M':fprintf(stdout,KWHITE);break;
}
fprintf(stdout,"%s (%s) L%d - %s - ",zedatetime,cursource,curline,curfunc);
vfprintf(stdout,format,argptr);
fprintf(stdout,KNORMAL"\n");
}
else
{
fprintf(stderr,KRED"%s (%s) L%d - %s - ",zedatetime,cursource,curline,curfunc);
vfprintf(stderr,format,argptr);
fprintf(stderr,KNORMAL"\n");
}
va_end(argptr);
}
/* prototypes needed in the top of the file */
void CSVFreeFields(char **fields);
#define FreeFields(fields) CSVFreeFields(fields)
#ifndef OS_WIN
mode_t FileGetMode(char *filename);
#define FileIsSocket(filename) ((FileGetMode(filename) & S_IFSOCK)==S_IFSOCK)
#define FileIsLink(filename) ((FileGetMode(filename) & S_IFLNK)==S_IFLNK)
#define FileIsRegular(filename) ((FileGetMode(filename) & S_IFREG)==S_IFREG)
#define FileIsBlockDevice(filename) ((FileGetMode(filename) & S_IFBLK)==S_IFBLK)
#define FileIsDir(filename) ((FileGetMode(filename) & S_IFDIR)==S_IFDIR)
#define FileIsCharacterDevice(filename) ((FileGetMode(filename) & S_IFCHR)==S_IFCHR)
#define FileIsFifo(filename) ((FileGetMode(filename) & S_IFIFO)==S_IFIFO)
#else
#define FileIsDir(filename) printf(filename)
#define FileIsRegular(filename) printf(filename)
#endif
long long FileGetSize(char *filename);
char **_internal_DirReadAllGlob(char *dirname,int globflag,int recurseflag,int sortflag);
#define DirReadEntry(dirname) _internal_DirReadGlob(dirname,0,0)
#define DirMatchEntry(dirname) _internal_DirReadGlob(dirname,1,0)
#define DirReadAllEntries(dirname) _internal_DirReadAllGlob(dirname,0,0,0)
#define DirMatchAllEntries(dirname) _internal_DirReadAllGlob(dirname,1,0,0)
#define DirReadAllEntriesRecurse(dirname) _internal_DirReadAllGlob(dirname,0,1,0)
#define DirMatchAllEntriesRecurse(dirname) _internal_DirReadAllGlob(dirname,1,1,0)
#define DirReadAllEntriesSort(dirname) _internal_DirReadAllGlob(dirname,0,0,1)
#define DirMatchAllEntriesSort(dirname) _internal_DirReadAllGlob(dirname,1,0,1)
#define DirReadAllEntriesRecurseSort(dirname) _internal_DirReadAllGlob(dirname,0,1,1)
#define DirMatchAllEntriesRecurseSort(dirname) _internal_DirReadAllGlob(dirname,1,1,1)
void FileWriteLine(char *filename, char *buffer);
void *_internal_MemRealloc(void *ptr, int size, char *cursource,int curline, char *curfunc);
void _internal_MemFree(void *ptr, char *cursource,int curline, char *curfunc);
#define MemRealloc(ptr,size) _internal_MemRealloc(ptr,size,__FILENAME__,__LINE__,FUNC)
#define MemFree(ptr) _internal_MemFree(ptr,__FILENAME__,__LINE__,FUNC)
void _internal_ObjectArrayAddDynamicValue(void **zearray, void *zeobject, int object_size,int curline, char *curfunc, char *cursource);
void _internal_ObjectArrayAddDynamicValueConcat(void **zearray, int *nbfields, int *maxfields, void *zeobject, int object_size, int curline, char *curfunc, char *cursource);
#define ObjectArrayAddDynamicValue(zearray,zeobject,objsize) _internal_ObjectArrayAddDynamicValue(zearray,zeobject,objsize,__LINE__,FUNC,__FILENAME__)
#define ObjectArrayAddDynamicValueConcat(zearray,nbv,maxv,zeobject,objsize) _internal_ObjectArrayAddDynamicValueConcat(zearray,nbv,maxv,zeobject,objsize,__LINE__,FUNC,__FILENAME__)
void _internal_IntArrayAddDynamicValueConcat(int **zearray, int *nbval, int *maxval, int zevalue, int curline, char *curfunc, char *cursource);
#define IntArrayAddDynamicValueConcat(zearray,nbv,maxv,zevalue) _internal_IntArrayAddDynamicValueConcat(zearray,nbv,maxv,zevalue,__LINE__,FUNC,__FILENAME__)
void _internal_FieldArrayAddDynamicValue(char ***zearray, char *zevalue, int curline, char *curfunc, char *cursource);
#define FieldArrayAddDynamicValue(zearray,zevalue) _internal_FieldArrayAddDynamicValue(zearray,zevalue,__LINE__,FUNC,__FILENAME__)
void _internal_FieldArrayAddDynamicValueConcat(char ***zearray, int *nbfields, int *maxfields, char *zevalue, int curline, char *curfunc, char *cursource);
#define FieldArrayAddDynamicValueConcat(zearray,nb,maxf,zevalue) _internal_FieldArrayAddDynamicValueConcat(zearray,nb,maxf,zevalue,__LINE__,FUNC,__FILENAME__)
/***
logfile
log into a file
internal use, do not call this function
as we must use a temporary buffer before writing to a file
we must compute the final string size to be sure that we
have enough memory for it
*/
void _internal_put2file(char *ferrname, char *format, ...)
{
#undef FUNC
#define FUNC "logfile"
static char *errbuffer=NULL;
static int errbuffer_size=0;
int zelen;
va_list argptr;
if (format==NULL)
{
FileWriteLine(ferrname,NULL);
errbuffer_size=0;
/* conditionnal algo may close file without having opened */
if (errbuffer)
{
MemFree(errbuffer);
errbuffer=NULL;
}
}
else
{
/* check that our temporary buffer is big enough for string plus carriage return */
va_start(argptr,format);
zelen=vsnprintf(NULL,0,format,argptr)+3;
/* we reallocate for a bigger size only */
if (zelen>errbuffer_size)
errbuffer=MemRealloc(errbuffer,zelen);
/* reinit the va_list */
va_end(argptr);
va_start(argptr,format);
vsnprintf(errbuffer,zelen,format,argptr);
va_end(argptr);
strcat(errbuffer,"\n");
FileWriteLine(ferrname,errbuffer);
}
}
/*** LOG macros send useful informations to the put2log function */
#define loginfo(...) _internal_put2log("INFO ",__FILENAME__,__LINE__,FUNC,__VA_ARGS__)
#define logdebug(...) {if (DEBUG_MODE) _internal_put2log("DEBUG ",__FILENAME__,__LINE__,FUNC,__VA_ARGS__);}
#define logmemory(...) {if (DEBUG_MODE>1) _internal_put2log("DEBUG ",__FILENAME__,__LINE__,FUNC,__VA_ARGS__);}
#define logwarn(...) _internal_put2log("WARN ",__FILENAME__,__LINE__,FUNC,__VA_ARGS__)
#define logerr(...) _internal_put2log("ERROR ",__FILENAME__,__LINE__,FUNC,__VA_ARGS__)
#define logfile(...) _internal_put2file(__VA_ARGS__)
#define logfileclose(ferrname) _internal_put2file(ferrname,NULL)
#define _internal_put2fileclose(ferrname) _internal_put2file(ferrname,NULL)
/***
the memory_monitor structure stores for every alloc the
location in the source of the memory call (function, line)
as some additionnal informations like the size and the
auto-incremental number of memory operation.
in addition to that, when allocating memory, we allocate
more than requested to put an header before the memory
block and a footer, after. Both are filled with checksum
and memory codes.
in debug mode, every allocation is checked with those
headers and footers to prevent segmentation fault and
make the debuging easier.
there is also a user memory monitor to trace memory operations
of selected memory areas. The user define a memory zone to
monitor, then every MemCheck, memory is compared to a backup
and a warning is done when modifications are encountered.
note: every functions are disabled in FAST_LIBRARY mode
*/
#define MEM_MONITOR_FRAG_ELEMENT 20000
/* #define MEM_CHECK_FILLER_SIZE 96 */
#if DEBUG_MODE!=0
#define MEM_CHECK_FILLER_SIZE 220
#else
#define MEM_CHECK_FILLER_SIZE 8
#endif
enum e_memory_way {
WAY_MALLOC,
WAY_REALLOC,
WAY_FREE
};
struct s_memory_monitor
{
char *ptr;
unsigned long size;
char *cursource;
char *curfunc;
int curline;
int mem_op;
};
struct s_memory_monitor *mem_monitor=NULL;
struct s_memory_check_header
{
unsigned char filler[MEM_CHECK_FILLER_SIZE];
unsigned long checksum[4]; /* may be 32 or 64 bits depending on the architecture */
};
struct s_memory_check_footer
{
unsigned long checksum[4]; /* may be 32 or 64 bits depending on the architecture */
unsigned char filler[MEM_CHECK_FILLER_SIZE];
};
struct s_memory_trace
{
char *name;
char *ptr;
char *backup;
unsigned long size;
int active;
struct s_memory_trace *next;
};
#ifndef FAST_LIBRARY
/* stats disabled in fast library mode */
static struct s_memory_trace *memory_trace_ROOT=NULL;
static int _static_library_memory_used=0;
static int _static_library_memory_used_max=0;
static int _static_library_memory_monitor_top=0;
static int _static_library_memory_monitor_max=0;
static int _static_library_memory_operation=0;
static int _static_library_memory_aggregate=0;
static int _static_library_memory_active_area=0;
#endif