aboutsummaryrefslogtreecommitdiff
path: root/project
diff options
context:
space:
mode:
authorWiimm <none>2020-09-30 13:20:16 +0200
committerWiimm <none>2020-09-30 13:20:16 +0200
commit646b95d113309378591b75a290ee6c62a04f3772 (patch)
treea94864e8cef5fc0fbffb7e69d46d688e7caaae3d /project
parenteaf1f8f8ce68b80ebdcefb45896461a89b47e1e1 (diff)
SZS v2.20a.beta1: Test Mac build
Diffstat (limited to 'project')
-rw-r--r--project/Makefile4
-rw-r--r--project/dclib/dclib-basics.c404
-rw-r--r--project/dclib/dclib-basics.h105
-rw-r--r--project/dclib/dclib-color.c303
-rw-r--r--project/dclib/dclib-color.h6
-rw-r--r--project/dclib/dclib-debug.c368
-rw-r--r--project/dclib/dclib-debug.h65
-rw-r--r--project/dclib/dclib-file.c642
-rw-r--r--project/dclib/dclib-file.h112
-rw-r--r--project/dclib/dclib-network.c4
-rw-r--r--project/dclib/dclib-network.h22
-rw-r--r--project/dclib/dclib-numeric.c89
-rw-r--r--project/dclib/dclib-ui.c4
-rw-r--r--project/dclib/dclib-xdump.c39
-rw-r--r--project/dclib/dclib-xdump.h18
-rwxr-xr-x[-rw-r--r--]project/gen-template.sh0
-rwxr-xr-x[-rw-r--r--]project/gen-text-file.sh0
-rw-r--r--project/revision.sh2
-rw-r--r--project/src/lib-brres.c2
-rw-r--r--project/src/lib-brres.h1
-rw-r--r--project/src/lib-checksum.c1
-rw-r--r--project/src/lib-checksum.h3
-rw-r--r--project/src/lib-ctcode.c1
-rw-r--r--project/src/lib-file.c6
-rw-r--r--project/src/lib-kcl.c1
-rw-r--r--project/src/lib-kmp-text.c6
-rw-r--r--project/src/lib-kmp.c42
-rw-r--r--project/src/lib-kmp.h2
-rw-r--r--project/src/lib-lecode.c12
-rw-r--r--project/src/lib-mdl.c1
-rw-r--r--project/src/lib-pat.c1
-rw-r--r--project/src/lib-std.c95
-rw-r--r--project/src/lib-std.h24
-rw-r--r--project/src/lib-szs-create.c42
-rw-r--r--project/src/lib-szs.c301
-rw-r--r--project/src/lib-szs.h62
-rw-r--r--project/src/lib-xbmg.c1
-rw-r--r--project/src/wbmgt.c8
-rw-r--r--project/src/wctct.c8
-rw-r--r--project/src/wimgt.c8
-rw-r--r--project/src/wkclt.c8
-rw-r--r--project/src/wkmpt.c8
-rw-r--r--project/src/wlect.c12
-rw-r--r--project/src/wmdlt.c8
-rw-r--r--project/src/wpatt.c8
-rw-r--r--project/src/wstrt.c8
-rw-r--r--project/src/wszst.c350
-rw-r--r--project/src/wtest.c10
-rw-r--r--project/templates/HISTORY.txt7
-rw-r--r--project/templates/module/last-history.txt9
50 files changed, 1902 insertions, 1341 deletions
diff --git a/project/Makefile b/project/Makefile
index 47360d2..4190bbc 100644
--- a/project/Makefile
+++ b/project/Makefile
@@ -58,8 +58,8 @@ WPATT_LONG = Wiimms PAT Tool
WSTRT_SHORT = wstrt
WSTRT_LONG = Wiimms StaticR Tool
-VERSION_NUM = 2.19b
-BETA_VERSION = 0
+VERSION_NUM = 2.20a
+BETA_VERSION = 1
# 0:off -1:"beta" >0:"beta#"
URI_HOME = https://szs.wiimm.de/
diff --git a/project/dclib/dclib-basics.c b/project/dclib/dclib-basics.c
index 4a166df..64ea883 100644
--- a/project/dclib/dclib-basics.c
+++ b/project/dclib/dclib-basics.c
@@ -148,12 +148,13 @@ void PrintSettingsDCLIB ( FILE *f, int indent )
#endif
}
+//
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void SetupMultiProcessing()
{
- multi_processing = true;
+ ProgInfo.multi_processing = true;
}
///////////////////////////////////////////////////////////////////////////////
@@ -161,27 +162,28 @@ void SetupMultiProcessing()
void SetupProgname ( int argc, char ** argv, ccp tname, ccp tvers, ccp ttitle )
{
if (tname)
- toolname = tname;
+ ProgInfo.toolname = tname;
if (tvers)
- toolversion = tvers;
+ ProgInfo.toolversion = tvers;
if (ttitle)
- tooltitle = ttitle;
+ ProgInfo.tooltitle = ttitle;
- if (!progpath)
+ if (!ProgInfo.progpath)
{
char path[PATH_MAX];
int res = GetProgramPath( path, sizeof(path), true, argc > 0 ? argv[0] : 0 );
if ( res > 0 )
- progpath = STRDUP(path);
+ ProgInfo.progpath = STRDUP(path);
}
if ( argc > 0 && *argv && **argv )
{
ccp slash = strrchr(*argv,'/');
- progname = slash ? slash + 1 : *argv;
+ ProgInfo.progname = slash ? slash + 1 : *argv;
}
else
- progname = toolname && *toolname ? toolname : "?";
+ ProgInfo.progname = ProgInfo.toolname && *ProgInfo.toolname
+ ? ProgInfo.toolname : "?";
}
///////////////////////////////////////////////////////////////////////////////
@@ -189,33 +191,78 @@ void SetupProgname ( int argc, char ** argv, ccp tname, ccp tvers, ccp ttitle )
ccp ProgramPath()
{
static bool done = false;
- if ( !progpath && !done )
+ if ( !ProgInfo.progpath && !done )
{
done = true;
char path[PATH_MAX];
int res = GetProgramPath( path, sizeof(path), true, 0 );
if ( res > 0 )
- progpath = STRDUP(path);
+ ProgInfo.progpath = STRDUP(path);
}
- return progpath;
+ return ProgInfo.progpath;
}
///////////////////////////////////////////////////////////////////////////////
ccp ProgramDirectory()
{
- if (!progdir)
+ if (!ProgInfo.progdir)
{
ccp path = ProgramPath();
if (path)
{
ccp end = strrchr(path,'/');
const uint len = end ? end - path : strlen(path);
- progdir = MEMDUP(path,len);
+ ProgInfo.progdir = MEMDUP(path,len);
}
}
- return progdir;
+ return ProgInfo.progdir;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+void DefineLogDirectory ( ccp path0, bool force )
+{
+ PRINT("DefineLogDirectory(%s,%d)\n",path0,force);
+ if ( path0 && *path0 && ( force || !ProgInfo.logdir ))
+ {
+ char path[PATH_MAX];
+ StringCopyS(path,sizeof(path),path0);
+ if (!ExistDirectory(path,0))
+ {
+ char *slash = strrchr(path,'/');
+ if (slash)
+ *slash = 0;
+ else
+ {
+ path[0] = '.';
+ path[1] = 0;
+ }
+
+ if (!ExistDirectory(path,0))
+ return;
+ }
+
+ int len = strlen(path);
+ while ( len > 0 && path[len-1] == '/' )
+ path[--len] = 0;
+
+ if ( len > 0 )
+ {
+ FreeString(ProgInfo.logdir);
+ ProgInfo.logdir = MEMDUP(path,len);
+ PRINT("#LOG-DIR: %s\n",ProgInfo.logdir);
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+ccp GetLogDirectory()
+{
+ return ProgInfo.logdir ? ProgInfo.logdir : ".";
}
///////////////////////////////////////////////////////////////////////////////
@@ -401,8 +448,8 @@ char * StringCat2E ( char * buf, ccp buf_end, ccp src1, ccp src2 )
// RESULT: end of copied string pointing to NULL
// 'src*' may be a NULL pointer.
- ASSERT(buf);
- ASSERT(buf<buf_end);
+ DASSERT(buf);
+ DASSERT(buf<buf_end);
buf_end--;
if (src1)
@@ -431,8 +478,8 @@ char * StringCat3E ( char * buf, ccp buf_end, ccp src1, ccp src2, ccp src3 )
// RESULT: end of copied string pointing to NULL
// 'src*' may be a NULL pointer.
- ASSERT(buf);
- ASSERT(buf<buf_end);
+ DASSERT(buf);
+ DASSERT(buf<buf_end);
buf_end--;
if (src1)
@@ -2049,7 +2096,7 @@ int ScanSplitArg
**argv_buf = argv_predef,
**argv_dest = argv_predef,
**argv_end = argv_predef + N_PREDEF;
- *argv_dest++ = progname ? (char*)progname : "";
+ *argv_dest++ = ProgInfo.progname ? (char*)ProgInfo.progname : "";
uint argv_size = 0;
if (!work_buf)
@@ -5085,309 +5132,6 @@ enumError Command_COLORS
//
///////////////////////////////////////////////////////////////////////////////
-/////////////// global commands: TESTCOLORS ///////////////
-///////////////////////////////////////////////////////////////////////////////
-// [[color_info_t]]
-
-typedef struct color_info_t
-{
- bool valid; // >0: data below is valid
-
- u8 m_index; // index of 0..255 for "\e[*m"
-
- s8 m_red; // -1:invalid, 0..5: red value of 'm_index'
- s8 m_green; // -1:invalid, 0..5: green value of 'm_index'
- s8 m_blue; // -1:invalid, 0..5: blue value of 'm_index'
- s8 m_gray; // -1:invalid, 0..23: gray value of 'm_index'
-
- u32 ref_color; // reference colors, based on 'm_index';
- u32 src_color; // scanned color
-}
-color_info_t;
-
-///////////////////////////////////////////////////////////////////////////////
-
-static bool AssignColorInfo ( color_info_t *ci, u32 rgb )
-{
- DASSERT(ci);
- memset(ci,0,sizeof(*ci));
-
- ci->src_color = rgb & 0xffffff;
- ci->m_index = ConvertColorRGBToM256(ci->src_color);
- ci->ref_color = ConvertColorM256ToRGB(ci->m_index);
-
- const uint r = ci->ref_color >> 16 & 0xff;
- const uint g = ci->ref_color >> 8 & 0xff;
- const uint b = ci->ref_color & 0xff;
-
- ci->m_red = SingleColorToM6(r);
- ci->m_green = SingleColorToM6(g);
- ci->m_blue = SingleColorToM6(b);
-
- ci->m_gray = ( r + g + b + 21 ) / 30;
- if ( ci->m_gray > 23 )
- ci->m_gray = 23;
- else if ( ci->m_gray > 0 )
- ci->m_gray--;
-
- return ci->valid = 1;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-static bool ScanColorInfo ( color_info_t *ci, ccp arg )
-{
- DASSERT(ci);
- memset(ci,0,sizeof(*ci));
- if ( arg && *arg )
- {
- arg = SkipControls(arg);
-
- ulong num, r, g, b;
- if ( *arg >= 'g' && *arg <= 'z' )
- {
- const char mode = *arg;
- arg = SkipControls(arg+1);
-
- num = str2ul(arg,0,10);
- switch (mode)
- {
- case 'm':
- return AssignColorInfo(ci,ConvertColorM256ToRGB(num));
-
- case 'g':
- return AssignColorInfo(ci,ConvertColorM256ToRGB(232 + num % 24));
-
- case 'c':
- r = num / 100 % 10;
- g = num / 10 % 10;
- b = num % 10;
- goto rgb5;
- }
- }
- else
- {
- char *end;
- num = str2ul(arg,&end,16);
-
- ci->valid = true;
- if ( end - arg <= 3 )
- {
- r = num >> 8 & 15;
- g = num >> 4 & 15;
- b = num & 15;
-
- rgb5:
- if ( r > 5 ) r = 5;
- if ( g > 5 ) g = 5;
- if ( b > 5 ) b = 5;
- return AssignColorInfo(ci,ConvertColorM256ToRGB(16 + 36*r + 6*g + b));
- }
- return AssignColorInfo(ci,num);
- }
- }
-
- return ci->valid;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-static void PrintColorInfo ( FILE *f, color_info_t *ci )
-{
- DASSERT(f);
- DASSERT(ci);
-
- if (ci->valid)
- fprintf(f," %06x -> %06x : %3u : %u,%u,%u : %2u"
- " \e[48;5;16;38;5;%um test \e[0m"
- " \e[48;5;244;38;5;%um test \e[0m"
- " \e[48;5;231;38;5;%um test \e[0m "
- " \e[38;5;16;48;5;%um test \e[0m"
- " \e[38;5;244;48;5;%um test \e[0m"
- " \e[38;5;231;48;5;%um test \e[0m\n",
- ci->src_color, ci->ref_color,
- ci->m_index, ci->m_red, ci->m_green, ci->m_blue, ci->m_gray,
- ci->m_index, ci->m_index, ci->m_index,
- ci->m_index, ci->m_index, ci->m_index );
- else
- fputs(" --\n",f);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-enumError Command_TESTCOLORS ( int argc, char ** argv )
-{
- #if HAVE_PRINT
- GetColorByName(colout,"blue");
- #endif
-
- printf("TEST COLORS: %u arguments:\n",argc);
-
- bool sep = true;
- int idx;
- for ( idx = 0; idx < argc; idx++ )
- {
- ccp minus = strchr(argv[idx],'-');
- if ( minus || sep )
- {
- putchar('\n');
- sep = false;
- if ( strlen(argv[idx]) == 1 )
- continue;
- }
-
- color_info_t ci1;
- ScanColorInfo(&ci1,argv[idx]);
- PrintColorInfo(stdout,&ci1);
-
- if (!minus)
- continue;
-
- color_info_t ci2;
- ScanColorInfo(&ci2,minus+1);
- if ( ci2.ref_color == ci1.ref_color )
- continue;
-
- int r1 = ci1.ref_color >> 16 & 0xff;
- int g1 = ci1.ref_color >> 8 & 0xff;
- int b1 = ci1.ref_color & 0xff;
- int r2 = ci2.ref_color >> 16 & 0xff;
- int g2 = ci2.ref_color >> 8 & 0xff;
- int b2 = ci2.ref_color & 0xff;
-
- int n_steps = abs( r2 - r1 );
- int diff = abs( g2 - g1 );
- if ( n_steps < diff )
- n_steps = diff;
- diff = abs( b2 - b1 );
- if ( n_steps < diff )
- n_steps = diff;
-
- u8 prev_m = ci1.m_index;
- u32 prev_rgb = ci1.ref_color;
- int i;
- for ( i = 1; i <= n_steps; i++ )
- {
- uint r = ( r2 - r1 ) * i / n_steps + r1;
- uint g = ( g2 - g1 ) * i / n_steps + g1;
- uint b = ( b2 - b1 ) * i / n_steps + b1;
- u8 new_m = ConvertColorRGB3ToM256(r,g,b);
- if ( prev_m != new_m )
- {
- prev_m = new_m;
- color_info_t ci3;
- AssignColorInfo(&ci3,r<<16|g<<8|b);
- if ( prev_rgb != ci3.ref_color )
- {
- prev_rgb = ci3.src_color = ci3.ref_color;
- PrintColorInfo(stdout,&ci3);
- }
- }
- }
- sep = true;
- }
- putchar('\n');
- return ERR_OK;
-}
-
-//
-///////////////////////////////////////////////////////////////////////////////
-/////////////// color helpers ///////////////
-///////////////////////////////////////////////////////////////////////////////
-//
-// https://en.wikipedia.org/wiki/ANSI_escape_code
-// https://jonasjacek.github.io/colors/
-//
-// 0..15: 000000 800000 008000 808000 000080 800080 008080 c0c0c0
-// 808080 ff0000 00ff00 ffff00 0000ff ff00ff 00ffff ffffff
-// => real colors varies on implementation
-//
-// 6x6x6: 0 95 135 175 215 255 == 00 5f 87 af d7 ff
-//
-// gray: 8 18 28 ... 238 == 08 12 1c 26 30 3a ... e4 ee f8
-//
-///////////////////////////////////////////////////////////////////////////////
-//
-// mkw-ana testcol 000000-ffffff
-// mkw-ana testcol 500-550 550-050 050-055 055-005 005-505 505-500
-//
-///////////////////////////////////////////////////////////////////////////////
-
-u32 ColorTab_M0_M15[16] =
-{
- 0x000000, 0x800000, 0x008000, 0x808000,
- 0x000080, 0x800080, 0x008080, 0xc0c0c0,
- 0x808080, 0xff0000, 0x00ff00, 0xffff00,
- 0x0000ff, 0xff00ff, 0x00ffff, 0xffffff,
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-u8 ConvertColorRGB3ToM256 ( u8 r, u8 g, u8 b )
-{
- // 0..5
- const int r6 = SingleColorToM6(r);
- const int g6 = SingleColorToM6(g);
- const int b6 = SingleColorToM6(b);
-
- u8 m256 = 36*r6 + 6*g6 + b6 + 16;
- uint delta = abs ( ( r6 ? 55 + 40 * r6 : 0 ) - r )
- + abs ( ( g6 ? 55 + 40 * g6 : 0 ) - g )
- + abs ( ( b6 ? 55 + 40 * b6 : 0 ) - b );
-
- //printf("%02x>%u %02x>%u %02x>%u : m=%u delta=%d\n",r,r6,g,g6,b,b6,m256,delta);
-
- int m, gray, prev = 0x1000000;
- for ( m = 232, gray = 8; m < 256; m++, gray += 10 )
- {
- const uint d = abs( gray - r ) + abs( gray - g ) + abs( gray - b );
- if ( d > prev )
- break;
- if ( d <= delta )
- {
- delta = d;
- m256 = m;
- }
- prev = d;
- }
-
- return m256;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-u8 ConvertColorRGBToM256 ( u32 rgb )
-{
- return ConvertColorRGB3ToM256( rgb >> 16, rgb >> 8, rgb );
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-u32 ConvertColorM256ToRGB ( u8 m256 )
-{
- if ( m256 < 16 )
- return ColorTab_M0_M15[m256];
-
- if ( m256 < 232 )
- {
- m256 -= 16;
- const uint r = m256 / 36;
- const uint g = m256 / 6 % 6;
- const uint b = m256 % 6;
-
- u32 col = 0;
- if (r) col |= 0x370000 + 0x280000 * r;
- if (g) col |= 0x003700 + 0x002800 * g;
- if (b) col |= 0x000037 + 0x000028 * b;
- return col;
- }
-
- m256 -= 232;
- return 0x080808 + m256 * 0x0a0a0a;
-}
-
-//
-///////////////////////////////////////////////////////////////////////////////
/////////////// dynamic data support ///////////////
///////////////////////////////////////////////////////////////////////////////
@@ -8042,12 +7786,20 @@ int opt_new = 0;
///////////////////////////////////////////////////////////////////////////////
-uint CreateUniqueId ( int range )
+uint CreateUniqueIdN ( int range )
{
static uint unique_id = 1;
- const uint ret = unique_id;
- if ( range > 0 )
- unique_id += range;
+
+ if ( range <= 0 )
+ return unique_id;
+
+ uint ret = unique_id;
+ unique_id += range;
+ if ( unique_id < ret ) // overflow
+ {
+ ret = 1;
+ unique_id = ret + range;
+ }
return ret;
}
diff --git a/project/dclib/dclib-basics.h b/project/dclib/dclib-basics.h
index 96053d6..a13c748 100644
--- a/project/dclib/dclib-basics.h
+++ b/project/dclib/dclib-basics.h
@@ -1156,12 +1156,18 @@ void PrintSettingsDCLIB ( FILE *f, int indent );
void SetupProgname ( int argc, char ** argv,
ccp tool_name, ccp tool_vers, ccp tool_title );
-// return NULL or 'progpath', calc GetProgramPath() once if needed
+// return NULL or 'ProgInfo.progpath', calc GetProgramPath() once if needed
ccp ProgramPath(void);
-// return NULL or 'progdir', calc ProgramPath() once if needed
+// return NULL or 'ProgInfo.progdir', calc ProgramPath() once if needed
ccp ProgramDirectory(void);
+// path0 can be a directory or a filename (->dir extracted)
+void DefineLogDirectory ( ccp path0, bool force );
+
+// get 'ProgInfo.logdir' without tailing '/' ("." as fall back)
+ccp GetLogDirectory();
+
#ifdef __CYGWIN__
ccp ProgramPathNoExt(void);
#else
@@ -2251,8 +2257,10 @@ uint EncodeBase64
int source_len, // length of 'source'; if <0: use strlen(source)
const char encode64[64+1], // encoding table; if NULL: use TableEncode64default
bool use_filler, // use filler for aligned output
+
ccp next_line, // not NULL: use this string as new line sep
- uint next_line_trigger // >0: use 'next_line' every # input bytes
+ uint bytes_per_line // >0: use 'next_line' every # input bytes
+ // will be rounded down to multiple of 3
);
//-----------------------------------------------------------------------------
@@ -2268,15 +2276,35 @@ mem_t EncodeBase64Circ
const char encode64[64+1] // encoding table; if NULL: use TableEncode64default
);
+//-----------------------------------------------------------------------------
+
+uint EncodeBase64ml // ml: multi line
+(
+ // returns the number of scanned bytes of 'source'
+
+ char *buf, // valid destination buffer
+ uint buf_size, // size of 'buf', >= 4
+ const void *source, // NULL or data to encode
+ int source_len, // length of 'source'; if <0: use strlen(source)
+ const char encode64[64+1], // encoding table; if NULL: use TableEncode64default
+ bool use_filler, // use filler for aligned output
+
+ int indent, // indention of output
+ ccp prefix, // NULL or prefix before encoded data
+ ccp eol, // line terminator, if NULL then use NL
+ int bytes_per_line // create a new line every # input bytes
+ // will be rounded down to multiple of 3
+);
+
///////////////////////////////////////////////////////////////////////////////
-static inline uint EncodeBase64Len ( uint src_len )
+static inline uint GetEncodeBase64Len ( uint src_len )
{ return 4 * (src_len+2) / 3; }
-static inline uint EncodeBase64FillLen ( uint src_len )
+static inline uint GetEncodeBase64FillLen ( uint src_len )
{ return (src_len+2) / 3 * 4; }
-static inline uint DecodeBase64Len ( uint src_len )
+static inline uint GetDecodeBase64Len ( uint src_len )
{ return 3 * src_len / 4; }
///////////////////////////////////////////////////////////////////////////////
@@ -3396,7 +3424,7 @@ ccp PrintTimeByFormat
// returns temporary buffer by GetCircBuf();
ccp format, // format string for strftime()
- time_t time // seconds since epoch -> time()
+ time_t tim // seconds since epoch; 0 is replaced by time()
);
ccp PrintTimeByFormatUTC
@@ -3404,7 +3432,7 @@ ccp PrintTimeByFormatUTC
// returns temporary buffer by GetCircBuf();
ccp format, // format string for strftime()
- time_t time // seconds since epoch -> time()
+ time_t tim // seconds since epoch; 0 is replaced by time()
);
//-----------------------------------------------------------------------------
@@ -3414,7 +3442,8 @@ ccp PrintUsecByFormat
// returns temporary buffer by GetCircBuf();
ccp format, // format string for strftime()
- time_t time, // seconds since epoch -> time()
+ // 1-6 '@' in row replaced by digits of 'usec'
+ time_t tim, // seconds since epoch
uint usec // micro second of second
);
@@ -3423,13 +3452,13 @@ ccp PrintUsecByFormatUTC
// returns temporary buffer by GetCircBuf();
ccp format, // format string for strftime()
- time_t time, // seconds since epoch -> time()
+ // 1-6 '@' in row replaced by digits of 'usec'
+ time_t tim, // seconds since epoch
uint usec // micro second of second
);
//-----------------------------------------------------------------------------
-
ccp PrintTimevalByFormat
(
// returns temporary buffer by GetCircBuf();
@@ -3438,7 +3467,6 @@ ccp PrintTimevalByFormat
const struct timeval *tv // time to print, if NULL use gettimeofday()
);
-
ccp PrintTimevalByFormatUTC
(
// returns temporary buffer by GetCircBuf();
@@ -4856,6 +4884,7 @@ typedef enum SaveRestoreType_t
SRT_BOOL, // type bool
SRT_UINT, // unsigned int of any size (%llu)
SRT_HEX, // unsigned int of any size as hex (%#llx)
+ SRT_COUNT, // unsigned int of any size (%llu), used as array counter
SRT_INT, // signed int of any size (%lld)
SRT_FLOAT, // float (%.8g) or double (%.16g) or long double (%.20g)
SRT_XFLOAT, // float or double or long double as hex-float (%a/%La)
@@ -4864,10 +4893,15 @@ typedef enum SaveRestoreType_t
SRT_STRING_ALLOC, // alloced string, var is ccp or char*
SRT_MEM, // alloced string, var is mem_t
+ SRT_DEF_ARRAY, // define/end an array of structs
+
SRT__IS_LIST, //----- from here: print lists; also used as separator
SRT_STRING_FIELD, // var is StringField_t
SRT_PARAM_FIELD, // var is ParamField_t
+
+
+ SRT_F_SIZE = 0x100, // factor for implicit size-modes for numerical types
}
SaveRestoreType_t;
@@ -4879,7 +4913,8 @@ typedef struct SaveRestoreTab_t
uint offset; // offset of variable
uint size; // sizeof( var or string )
ccp name; // name in configuration file
- u16 n_elem; // >0: is array with N elements
+ s16 n_elem; // >0: is array with N elements
+ // <0: is array with -N elements, use last SRT_COUNT
u8 type; // SaveRestoreType_t
u8 emode; // EncodeMode_t
}
@@ -4896,6 +4931,7 @@ __attribute__ ((packed)) SaveRestoreTab_t;
#define DEF_SRT_BOOL(v,n) DEF_SRT_VAR(v,1,n,SRT_BOOL,0)
#define DEF_SRT_UINT(v,n) DEF_SRT_VAR(v,1,n,SRT_UINT,0)
#define DEF_SRT_HEX(v,n) DEF_SRT_VAR(v,1,n,SRT_HEX,0)
+#define DEF_SRT_COUNT(v,n) DEF_SRT_VAR(v,1,n,SRT_COUNT,0)
#define DEF_SRT_INT(v,n) DEF_SRT_VAR(v,1,n,SRT_INT,0)
#define DEF_SRT_FLOAT(v,n) DEF_SRT_VAR(v,1,n,SRT_FLOAT,0)
#define DEF_SRT_XFLOAT(v,n) DEF_SRT_VAR(v,1,n,SRT_XFLOAT,0)
@@ -4907,7 +4943,7 @@ __attribute__ ((packed)) SaveRestoreTab_t;
#define DEF_SRT_STRING_FIELD(v,n,e) DEF_SRT_VAR(v,1,n,SRT_STRING_FIELD,e)
#define DEF_SRT_PARAM_FIELD(v,n,e) DEF_SRT_VAR(v,1,n,SRT_PARAM_FIELD,e)
-//--- n elements
+//--- n elements : if n<0, then n_elem=-n && use last SRT_COUNT
#define DEF_SRT_BOOL_N(v,ne,n) DEF_SRT_VAR(v,ne,n,SRT_BOOL,0)
#define DEF_SRT_UINT_N(v,ne,n) DEF_SRT_VAR(v,ne,n,SRT_UINT,0)
@@ -4937,6 +4973,40 @@ __attribute__ ((packed)) SaveRestoreTab_t;
#define DEF_SRT_STR_ALLOC_A(v,n,e) DEF_SRT_ARRAY(v,n,SRT_STRING_ALLOC,e)
#define DEF_SRT_MEM_A(v,n,e) DEF_SRT_ARRAY(v,n,SRT_MEM,e)
+//--- auto array, use last SRT_COUNT for element-count
+
+#define DEF_SRT_ARRAY_C(v,n,t,e) \
+ {offsetof(SRT_NAME,v), sizeof(((SRT_NAME*)0)->v[0]), n, \
+ -(s16)(sizeof(((SRT_NAME*)0)->v)/sizeof(*((SRT_NAME*)0)->v)), t, e }
+
+#define DEF_SRT_BOOL_AC(v,n) DEF_SRT_ARRAY_C(v,n,SRT_BOOL,0)
+#define DEF_SRT_UINT_AC(v,n) DEF_SRT_ARRAY_C(v,n,SRT_UINT,0)
+#define DEF_SRT_HEX_AC(v,n) DEF_SRT_ARRAY_C(v,n,SRT_HEX,0)
+#define DEF_SRT_INT_AC(v,n) DEF_SRT_ARRAY_C(v,n,SRT_INT,0)
+#define DEF_SRT_FLOAT_AC(v,n) DEF_SRT_ARRAY_C(v,n,SRT_FLOAT,0)
+#define DEF_SRT_XFLOAT_AC(v,n) DEF_SRT_ARRAY_C(v,n,SRT_XFLOAT,0)
+
+#define DEF_SRT_STR_SIZE_AC(v,n,e) DEF_SRT_ARRAY_C(v,n,SRT_STRING_SIZE,e)
+#define DEF_SRT_STR_ALLOC_AC(v,n,e) DEF_SRT_ARRAY_C(v,n,SRT_STRING_ALLOC,e)
+#define DEF_SRT_MEM_AC(v,n,e) DEF_SRT_ARRAY_C(v,n,SRT_MEM,e)
+
+//--- array of structs
+
+#define DEF_SRT_ARRAY_FL(f,l) \
+ {offsetof(SRT_NAME,f), sizeof(((SRT_NAME*)0)->f), 0, \
+ (offsetof(SRT_NAME,l)-offsetof(SRT_NAME,f))/sizeof(((SRT_NAME*)0)->f)+1, \
+ SRT_DEF_ARRAY, 0 }
+
+#define DEF_SRT_ARRAY_FLC(f,l) \
+ {offsetof(SRT_NAME,f), sizeof(((SRT_NAME*)0)->f), 0, \
+ -(s16)((offsetof(SRT_NAME,l)-offsetof(SRT_NAME,f)) \
+ /sizeof(((SRT_NAME*)0)->f)+1), SRT_DEF_ARRAY, 0 }
+
+#define DEF_SRT_ARRAY_N(v,ne) DEF_SRT_VAR(v[0],ne,0,SRT_DEF_ARRAY,0)
+#define DEF_SRT_ARRAY_A(v) DEF_SRT_ARRAY(v,0,SRT_DEF_ARRAY,0)
+#define DEF_SRT_ARRAY_AC(v) DEF_SRT_ARRAY_C(v,0,SRT_DEF_ARRAY,0)
+#define DEF_SRT_ARRAY_END() {0,0,0,0,SRT_DEF_ARRAY,0}
+
//--- special
#define DEF_SRT_SEPARATOR() {0,0,0,0,SRT__IS_LIST,0}
@@ -4945,6 +5015,9 @@ __attribute__ ((packed)) SaveRestoreTab_t;
///////////////////////////////////////////////////////////////////////////////
+extern int srt_auto_dump;
+extern FILE *srt_auto_dump_file;
+
void DumpStateTable
(
FILE *f, // valid output file
@@ -5234,7 +5307,9 @@ extern int opt_new; // default 0
float double2float ( double d ); // reduce precision
-uint CreateUniqueId ( int range );
+uint CreateUniqueIdN ( int range );
+static inline uint CreateUniqueId() { return CreateUniqueIdN(1); }
+static inline uint CreateUniqueIdNBO() { return htonl(CreateUniqueIdN(1)); }
void Sha1Hex2Bin ( sha1_hash_t bin, ccp src, ccp end );
void Sha1Bin2Hex ( sha1_hex_t hex, cvp bin );
diff --git a/project/dclib/dclib-color.c b/project/dclib/dclib-color.c
index 341c915..19c49fb 100644
--- a/project/dclib/dclib-color.c
+++ b/project/dclib/dclib-color.c
@@ -688,6 +688,309 @@ uint PrintColoredLines
//
///////////////////////////////////////////////////////////////////////////////
+/////////////// global commands: TESTCOLORS ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[color_info_t]]
+
+typedef struct color_info_t
+{
+ bool valid; // >0: data below is valid
+
+ u8 m_index; // index of 0..255 for "\e[*m"
+
+ s8 m_red; // -1:invalid, 0..5: red value of 'm_index'
+ s8 m_green; // -1:invalid, 0..5: green value of 'm_index'
+ s8 m_blue; // -1:invalid, 0..5: blue value of 'm_index'
+ s8 m_gray; // -1:invalid, 0..23: gray value of 'm_index'
+
+ u32 ref_color; // reference colors, based on 'm_index';
+ u32 src_color; // scanned color
+}
+color_info_t;
+
+///////////////////////////////////////////////////////////////////////////////
+
+static bool AssignColorInfo ( color_info_t *ci, u32 rgb )
+{
+ DASSERT(ci);
+ memset(ci,0,sizeof(*ci));
+
+ ci->src_color = rgb & 0xffffff;
+ ci->m_index = ConvertColorRGBToM256(ci->src_color);
+ ci->ref_color = ConvertColorM256ToRGB(ci->m_index);
+
+ const uint r = ci->ref_color >> 16 & 0xff;
+ const uint g = ci->ref_color >> 8 & 0xff;
+ const uint b = ci->ref_color & 0xff;
+
+ ci->m_red = SingleColorToM6(r);
+ ci->m_green = SingleColorToM6(g);
+ ci->m_blue = SingleColorToM6(b);
+
+ ci->m_gray = ( r + g + b + 21 ) / 30;
+ if ( ci->m_gray > 23 )
+ ci->m_gray = 23;
+ else if ( ci->m_gray > 0 )
+ ci->m_gray--;
+
+ return ci->valid = 1;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static bool ScanColorInfo ( color_info_t *ci, ccp arg )
+{
+ DASSERT(ci);
+ memset(ci,0,sizeof(*ci));
+ if ( arg && *arg )
+ {
+ arg = SkipControls(arg);
+
+ ulong num, r, g, b;
+ if ( *arg >= 'g' && *arg <= 'z' )
+ {
+ const char mode = *arg;
+ arg = SkipControls(arg+1);
+
+ num = str2ul(arg,0,10);
+ switch (mode)
+ {
+ case 'm':
+ return AssignColorInfo(ci,ConvertColorM256ToRGB(num));
+
+ case 'g':
+ return AssignColorInfo(ci,ConvertColorM256ToRGB(232 + num % 24));
+
+ case 'c':
+ r = num / 100 % 10;
+ g = num / 10 % 10;
+ b = num % 10;
+ goto rgb5;
+ }
+ }
+ else
+ {
+ char *end;
+ num = str2ul(arg,&end,16);
+
+ ci->valid = true;
+ if ( end - arg <= 3 )
+ {
+ r = num >> 8 & 15;
+ g = num >> 4 & 15;
+ b = num & 15;
+
+ rgb5:
+ if ( r > 5 ) r = 5;
+ if ( g > 5 ) g = 5;
+ if ( b > 5 ) b = 5;
+ return AssignColorInfo(ci,ConvertColorM256ToRGB(16 + 36*r + 6*g + b));
+ }
+ return AssignColorInfo(ci,num);
+ }
+ }
+
+ return ci->valid;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static void PrintColorInfo ( FILE *f, color_info_t *ci )
+{
+ DASSERT(f);
+ DASSERT(ci);
+
+ if (ci->valid)
+ fprintf(f," %06x -> %06x : %3u : %u,%u,%u : %2u"
+ " \e[48;5;16;38;5;%um test \e[0m"
+ " \e[48;5;244;38;5;%um test \e[0m"
+ " \e[48;5;231;38;5;%um test \e[0m "
+ " \e[38;5;16;48;5;%um test \e[0m"
+ " \e[38;5;244;48;5;%um test \e[0m"
+ " \e[38;5;231;48;5;%um test \e[0m\n",
+ ci->src_color, ci->ref_color,
+ ci->m_index, ci->m_red, ci->m_green, ci->m_blue, ci->m_gray,
+ ci->m_index, ci->m_index, ci->m_index,
+ ci->m_index, ci->m_index, ci->m_index );
+ else
+ fputs(" --\n",f);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+enumError Command_TESTCOLORS ( int argc, char ** argv )
+{
+ #if HAVE_PRINT
+ GetColorByName(colout,"blue");
+ #endif
+
+ printf("TEST COLORS: %u arguments:\n",argc);
+
+ bool sep = true;
+ int idx;
+ for ( idx = 0; idx < argc; idx++ )
+ {
+ ccp minus = strchr(argv[idx],'-');
+ if ( minus || sep )
+ {
+ putchar('\n');
+ sep = false;
+ if ( strlen(argv[idx]) == 1 )
+ continue;
+ }
+
+ color_info_t ci1;
+ ScanColorInfo(&ci1,argv[idx]);
+ PrintColorInfo(stdout,&ci1);
+
+ if (!minus)
+ continue;
+
+ color_info_t ci2;
+ ScanColorInfo(&ci2,minus+1);
+ if ( ci2.ref_color == ci1.ref_color )
+ continue;
+
+ int r1 = ci1.ref_color >> 16 & 0xff;
+ int g1 = ci1.ref_color >> 8 & 0xff;
+ int b1 = ci1.ref_color & 0xff;
+ int r2 = ci2.ref_color >> 16 & 0xff;
+ int g2 = ci2.ref_color >> 8 & 0xff;
+ int b2 = ci2.ref_color & 0xff;
+
+ int n_steps = abs( r2 - r1 );
+ int diff = abs( g2 - g1 );
+ if ( n_steps < diff )
+ n_steps = diff;
+ diff = abs( b2 - b1 );
+ if ( n_steps < diff )
+ n_steps = diff;
+
+ u8 prev_m = ci1.m_index;
+ u32 prev_rgb = ci1.ref_color;
+ int i;
+ for ( i = 1; i <= n_steps; i++ )
+ {
+ uint r = ( r2 - r1 ) * i / n_steps + r1;
+ uint g = ( g2 - g1 ) * i / n_steps + g1;
+ uint b = ( b2 - b1 ) * i / n_steps + b1;
+ u8 new_m = ConvertColorRGB3ToM256(r,g,b);
+ if ( prev_m != new_m )
+ {
+ prev_m = new_m;
+ color_info_t ci3;
+ AssignColorInfo(&ci3,r<<16|g<<8|b);
+ if ( prev_rgb != ci3.ref_color )
+ {
+ prev_rgb = ci3.src_color = ci3.ref_color;
+ PrintColorInfo(stdout,&ci3);
+ }
+ }
+ }
+ sep = true;
+ }
+ putchar('\n');
+ return ERR_OK;
+}
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// color helpers ///////////////
+///////////////////////////////////////////////////////////////////////////////
+//
+// https://en.wikipedia.org/wiki/ANSI_escape_code
+// https://jonasjacek.github.io/colors/
+//
+// 0..15: 000000 800000 008000 808000 000080 800080 008080 c0c0c0
+// 808080 ff0000 00ff00 ffff00 0000ff ff00ff 00ffff ffffff
+// => real colors varies on implementation
+//
+// 6x6x6: 0 95 135 175 215 255 == 00 5f 87 af d7 ff
+//
+// gray: 8 18 28 ... 238 == 08 12 1c 26 30 3a ... e4 ee f8
+//
+///////////////////////////////////////////////////////////////////////////////
+//
+// mkw-ana testcol 000000-ffffff
+// mkw-ana testcol 500-550 550-050 050-055 055-005 005-505 505-500
+//
+///////////////////////////////////////////////////////////////////////////////
+
+u32 ColorTab_M0_M15[16] =
+{
+ 0x000000, 0x800000, 0x008000, 0x808000,
+ 0x000080, 0x800080, 0x008080, 0xc0c0c0,
+ 0x808080, 0xff0000, 0x00ff00, 0xffff00,
+ 0x0000ff, 0xff00ff, 0x00ffff, 0xffffff,
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+u8 ConvertColorRGB3ToM256 ( u8 r, u8 g, u8 b )
+{
+ // 0..5
+ const int r6 = SingleColorToM6(r);
+ const int g6 = SingleColorToM6(g);
+ const int b6 = SingleColorToM6(b);
+
+ u8 m256 = 36*r6 + 6*g6 + b6 + 16;
+ uint delta = abs ( ( r6 ? 55 + 40 * r6 : 0 ) - r )
+ + abs ( ( g6 ? 55 + 40 * g6 : 0 ) - g )
+ + abs ( ( b6 ? 55 + 40 * b6 : 0 ) - b );
+
+ //printf("%02x>%u %02x>%u %02x>%u : m=%u delta=%d\n",r,r6,g,g6,b,b6,m256,delta);
+
+ int m, gray, prev = 0x1000000;
+ for ( m = 232, gray = 8; m < 256; m++, gray += 10 )
+ {
+ const uint d = abs( gray - r ) + abs( gray - g ) + abs( gray - b );
+ if ( d > prev )
+ break;
+ if ( d <= delta )
+ {
+ delta = d;
+ m256 = m;
+ }
+ prev = d;
+ }
+
+ return m256;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+u8 ConvertColorRGBToM256 ( u32 rgb )
+{
+ return ConvertColorRGB3ToM256( rgb >> 16, rgb >> 8, rgb );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+u32 ConvertColorM256ToRGB ( u8 m256 )
+{
+ if ( m256 < 16 )
+ return ColorTab_M0_M15[m256];
+
+ if ( m256 < 232 )
+ {
+ m256 -= 16;
+ const uint r = m256 / 36;
+ const uint g = m256 / 6 % 6;
+ const uint b = m256 % 6;
+
+ u32 col = 0;
+ if (r) col |= 0x370000 + 0x280000 * r;
+ if (g) col |= 0x003700 + 0x002800 * g;
+ if (b) col |= 0x000037 + 0x000028 * b;
+ return col;
+ }
+
+ m256 -= 232;
+ return 0x080808 + m256 * 0x0a0a0a;
+}
+
+//
+///////////////////////////////////////////////////////////////////////////////
/////////////// terminal ///////////////
///////////////////////////////////////////////////////////////////////////////
diff --git a/project/dclib/dclib-color.h b/project/dclib/dclib-color.h
index 6591f2e..c18de42 100644
--- a/project/dclib/dclib-color.h
+++ b/project/dclib/dclib-color.h
@@ -625,7 +625,7 @@ void PrintColorSetHelper
/////////////// color helpers ///////////////
///////////////////////////////////////////////////////////////////////////////
-u32 ColorTab_M0_M15[16]; // first 16 colors of "\e[m"
+extern u32 ColorTab_M0_M15[16]; // first 16 colors of "\e[m"
// return a m256 index
u8 ConvertColorRGB3ToM256 ( u8 r, u8 g, u8 b );
@@ -719,12 +719,12 @@ void PrintColorModes
// RedirectStdFiles() don't cange it, if it is NULL.
//
// stdmsg, colmsg:
-// Special output for catcable messages. Initalized by SetupStdMsg()
+// Special output for catcable messages. Initialized by SetupStdMsg()
// and set to the first not NULL of stdout, stderr and stdlog.
//
// stdwrn, colwrn:
// Output file of PrintError() functions.
-// Initalized to a copy of stderr.
+// Initialized to a copy of stderr.
//
////////////////////////////////////////////////////////////////////////////
diff --git a/project/dclib/dclib-debug.c b/project/dclib/dclib-debug.c
index fd51f17..f6a474f 100644
--- a/project/dclib/dclib-debug.c
+++ b/project/dclib/dclib-debug.c
@@ -45,10 +45,7 @@
#include "dclib-basics.h"
#include "dclib-file.h"
-
-#if ENABLE_HEXDUMP_WRAPPER > 0
- #include "dclib-xdump.h"
-#endif
+#include "dclib-xdump.h"
//
///////////////////////////////////////////////////////////////////////////////
@@ -381,18 +378,7 @@ void ListErrorCodes
/////////////// error handling ///////////////
///////////////////////////////////////////////////////////////////////////////
-ccp progpath = 0;
-ccp progdir = 0;
-ccp progname = 0;
-
-ccp toolname = 0;
-ccp toolversion = 0;
-ccp tooltitle = 0;
-
-bool multi_processing = false;
-enumError last_error = ERR_OK;
-enumError max_error = ERR_OK;
-u32 error_count = 0;
+ProgInfo_t ProgInfo = {0};
///////////////////////////////////////////////////////////////////////////////
@@ -436,9 +422,9 @@ enumError PrintErrorArg ( ccp func, ccp file, unsigned int line,
}
char msg[1000];
- if (!progname)
- progname = "?";
- const int plen = strlen(progname)+2;
+ if (!ProgInfo.progname)
+ ProgInfo.progname = "?";
+ const int plen = strlen(ProgInfo.progname)+2;
if ( !format && err_code > ERR_NOT_IMPLEMENTED )
format = "Program is aborted immediately!";
@@ -491,21 +477,21 @@ enumError PrintErrorArg ( ccp func, ccp file, unsigned int line,
{
if ( err_code > ERR_WARNING )
fprintf(stdwrn,"%s%s%s:%s ERROR #%d [%s] in %s() @ %s#%d%s\n",
- prefix, coln, progname, col1, err_code,
+ prefix, coln, ProgInfo.progname, col1, err_code,
GetErrorName(err_code,0), func, file, line, col0 );
else
fprintf(stdwrn,"%s%s%s:%s WARNING in %s() @ %s#%d%s\n",
- prefix, coln, progname, col1, func, file, line, col0 );
+ prefix, coln, ProgInfo.progname, col1, func, file, line, col0 );
}
else
{
if ( err_code > ERR_WARNING )
fprintf(stdwrn,"%s%s%s:%s ERROR #%d [%s]%s\n",
- prefix, coln, progname, col1, err_code,
+ prefix, coln, ProgInfo.progname, col1, err_code,
GetErrorName(err_code,0), col0 );
else
fprintf(stdwrn,"%s%s%s:%s WARNING%s\n",
- prefix, coln, progname, col1, col0 );
+ prefix, coln, ProgInfo.progname, col1, col0 );
}
#if defined(EXTENDED_ERRORS) && EXTENDED_ERRORS > 1
@@ -518,8 +504,8 @@ enumError PrintErrorArg ( ccp func, ccp file, unsigned int line,
}
else
{
- fprintf(stdwrn,"%s%s:",prefix,progname);
- PutLines(stdwrn,plen,fw,strlen(progname)+1,prefix,msg,0);
+ fprintf(stdwrn,"%s%s:",prefix,ProgInfo.progname);
+ PutLines(stdwrn,plen,fw,strlen(ProgInfo.progname)+1,prefix,msg,0);
}
if (syserr)
@@ -531,14 +517,16 @@ enumError PrintErrorArg ( ccp func, ccp file, unsigned int line,
fflush(stdwrn);
if ( err_code > ERR_OK )
- error_count++;
+ {
+ ProgInfo.error_count++;
- last_error = err_code;
- if ( max_error < err_code )
- max_error = err_code;
+ ProgInfo.last_error = err_code;
+ if ( ProgInfo.max_error < err_code )
+ ProgInfo.max_error = err_code;
- if ( err_code > ERR_NOT_IMPLEMENTED )
- exit(err_code);
+ if ( err_code > ERR_NOT_IMPLEMENTED )
+ exit(err_code);
+ }
return err_code;
}
@@ -563,7 +551,7 @@ enumError PrintErrorStat ( enumError err, int verbose, ccp cmdname )
}
fprintf(stdwrn,"%s: Command '%s' returns with status #%d [%s]\n",
- progname, cmdname, err, GetErrorName(err,0) );
+ ProgInfo.progname, cmdname, err, GetErrorName(err,0) );
}
return err;
}
@@ -601,55 +589,6 @@ bool mark_used ( ccp name, ... )
/////////////// hexdump ///////////////
///////////////////////////////////////////////////////////////////////////////
-#if ENABLE_HEXDUMP_WRAPPER > 1
- int enable_xdump_wrapper = 1;
-#elif ENABLE_HEXDUMP_WRAPPER
- int enable_xdump_wrapper = 0;
-#endif
-
-ccp hexdump_prefix = "";
-ccp hexdump_eol = "\n";
-bool hexdump_align = false;
-
-//-----------------------------------------------------------------------------
-
-#if ENABLE_HEXDUMP_WRAPPER > 0
-
-static void SetupXDumpWrapper
-(
- XDump_t *xd,
- FILE *f,
- int indent,
- u64 addr,
- int addr_fw,
- int row_len
-)
-{
- DASSERT(xd);
- InitializeXDump(xd);
-
- xd->f = f;
- xd->prefix = hexdump_prefix;
- xd->eol = hexdump_eol;
- xd->mode_align = hexdump_align;
- xd->indent = indent;
- xd->start_addr = addr;
- xd->min_addr_fw = addr_fw;
- xd->min_width = row_len;
- xd->format = XDUMPF_INT_1;
- xd->print_format = false;
- xd->print_summary = false;
- xd->print_diff_sep = false;
-
- hexdump_prefix = EmptyString;
- hexdump_eol = "\n";
- hexdump_align = false;
-}
-
-#endif
-
-//-----------------------------------------------------------------------------
-
uint HexDump16 ( FILE * f, int indent, u64 addr,
const void * data, size_t count )
{
@@ -675,101 +614,10 @@ uint HexDump ( FILE * f, int indent, u64 addr, int addr_fw, int row_len,
if ( !f || !p_data || !count )
return 0;
- #if ENABLE_HEXDUMP_WRAPPER == 1 || ENABLE_HEXDUMP_WRAPPER == 2
- if (enable_xdump_wrapper)
- #endif
-
- #if ENABLE_HEXDUMP_WRAPPER > 0
- {
XDump_t xd;
- SetupXDumpWrapper(&xd,f,indent,addr,addr_fw,row_len);
+ InitializeXDumpEx(&xd,f,indent,addr,addr_fw,row_len);
const int stat = XDump(&xd,p_data,count,true);
return stat < 0 ? 0 : stat;
- }
- #endif
-
- #if ENABLE_HEXDUMP_WRAPPER < 3
-
- const int MAX_LEN = 256;
- char buf[MAX_LEN+2];
-
- const u8 * data = (const u8 *)p_data;
-
- indent = NormalizeIndent(indent);
- addr_fw = NormalizeIndent(addr_fw);
-
- const bool show_ascii = row_len >= 0;
- if ( row_len < 0 )
- row_len = -row_len;
- else if ( row_len < 1 )
- row_len = 16;
- else if ( row_len > MAX_LEN )
- row_len = MAX_LEN;
-
- uint skip = 0;
- if ( (s64)addr != -1 )
- {
- const int fw = snprintf(buf,sizeof(buf),"%llx",addr+count-1);
- if ( addr_fw < fw )
- addr_fw = fw;
-
- if (hexdump_align)
- {
- skip = addr % row_len;
- addr -= skip;
- }
- }
-
- uint line_count = 0;
- while ( count > 0 )
- {
- if ( (s64)addr == -1 )
- fprintf(f,"%s%*s", hexdump_prefix, indent,"" );
- else
- {
- fprintf(f,"%s%*s%*llx:", hexdump_prefix, indent,"", addr_fw, addr );
- addr += row_len;
- }
- char * dest = buf;
- if (!skip)
- *dest++ = ':';
-
- int i;
- for ( i = 0; i < row_len; i++ )
- {
- if ( skip > 0 )
- {
- fprintf(f,"%s ", i&3 ? "" : " " );
- *dest++ = ' ';
- if (!--skip)
- *dest++ = ':';
- }
- else
- {
- u8 ch = *data++;
- if ( count > 0 )
- {
- count--;
- fprintf(f,"%s%02x ", i&3 ? "" : " ", ch );
- *dest++ = ch < ' ' || ch >= 0x7f ? '.' : ch;
- }
- else
- fprintf(f,"%s ", i&3 ? "" : " " );
- }
- }
- *dest = 0;
- if (show_ascii)
- fprintf(f,"%s:%s",buf,hexdump_eol);
- else
- fputs(hexdump_eol,f);
- line_count++;
- }
-
- hexdump_prefix = "";
- hexdump_eol = "\n";
- hexdump_align = false;
- return line_count;
- #endif
}
//-----------------------------------------------------------------------------
@@ -790,23 +638,11 @@ uint HexDump0 ( FILE * f, int indent, u64 addr, int addr_fw, int row_len,
if ( !f || !p_data || !count )
return 0;
- #if ENABLE_HEXDUMP_WRAPPER == 1 || ENABLE_HEXDUMP_WRAPPER == 2
- if (enable_xdump_wrapper)
- #endif
-
- #if ENABLE_HEXDUMP_WRAPPER > 0
- {
XDump_t xd;
- SetupXDumpWrapper(&xd,f,indent,addr,addr_fw,row_len);
+ InitializeXDumpEx(&xd,f,indent,addr,addr_fw,row_len);
xd.mode_ignore = true;
const int stat = XDump(&xd,p_data,count,true);
return stat < 0 ? 0 : stat;
- }
- #endif
-
- #if ENABLE_HEXDUMP_WRAPPER < 3
- return HexDump( f, indent, addr, addr_fw, row_len, p_data, count );
- #endif
}
//-----------------------------------------------------------------------------
@@ -827,158 +663,10 @@ void HexDiff ( FILE * f, int indent, u64 addr, int addr_fw, int row_len,
if (!f)
return;
- #if ENABLE_HEXDUMP_WRAPPER == 1 || ENABLE_HEXDUMP_WRAPPER == 2
- if (enable_xdump_wrapper)
- #endif
-
- #if ENABLE_HEXDUMP_WRAPPER > 0
- {
XDump_t xd;
- SetupXDumpWrapper(&xd,f,indent,addr,addr_fw,row_len);
+ InitializeXDumpEx(&xd,f,indent,addr,addr_fw,row_len);
XDiff(&xd, p_data1,count1,true, p_data2,count2,true, 0,false );
return;
- }
- #endif
-
- #if ENABLE_HEXDUMP_WRAPPER < 3
-
- const int MAX_LEN = 256;
- char buf[MAX_LEN+2];
-
- const u8 * data1 = p_data1 ? (const u8 *)p_data1 : (u8*)EmptyString;
- const u8 * data2 = p_data2 ? (const u8 *)p_data2 : (u8*)EmptyString;
-
- indent = NormalizeIndent(indent);
- addr_fw = NormalizeIndent(addr_fw);
-
- const bool show_ascii = row_len >= 0;
- if ( row_len < 0 )
- row_len = -row_len;
- else if ( row_len < 1 )
- row_len = 16;
- else if ( row_len > MAX_LEN )
- row_len = MAX_LEN;
-
- uint skip = 0;
-
- if ( (s64)addr != -1 )
- {
- const size_t count = count1 > count2 ? count1 : count2;
- const int fw = snprintf(buf,sizeof(buf),"%llx",addr+count-1);
- if ( addr_fw < fw )
- addr_fw = fw;
-
- if (hexdump_align)
- {
- skip = addr % row_len;
- addr -= skip;
- }
- }
-
- while ( count1 > 0 && count2 > 0 )
- {
- size_t count = count1 < count2 ? count1 : count2;
- if ( count > row_len )
- count = row_len;
- noPRINT(" cnt=%zd,%zd -> %zd; cmp=%d\n",
- count1, count2, count, memcmp(data1,data2,count) );
-
- if (memcmp(data1,data2,count))
- {
- //--- print first line
-
- if (IS_M1(addr))
- fprintf(f,"%s%*s<", hexdump_prefix, indent,"" );
- else
- fprintf(f,"%s%*s<%*llx:", hexdump_prefix, indent,"", addr_fw, addr );
-
- char * dest = buf;
- if (!skip)
- *dest++ = ':';
-
- int i;
- for ( i = 0; i < row_len; i++ )
- {
- if ( skip > 0 )
- {
- fprintf(f,"%s ", i&3 ? "" : " " );
- *dest++ = ' ';
- if (!--skip)
- *dest++ = ':';
- }
- else
- {
- u8 ch = data1[i];
- if ( i < count1 )
- {
- fprintf(f,"%s%02x ", i&3 ? "" : " ", ch );
- *dest++ = ch < ' ' || ch >= 0x7f ? '.' : ch;
- }
- else
- fprintf(f,"%s ", i&3 ? "" : " " );
- }
- }
- *dest = 0;
- if (show_ascii)
- fprintf(f,"%s:%s",buf,hexdump_eol);
- else
- fputs(hexdump_eol,f);
-
-
- //--- print second line
-
- if (IS_M1(addr))
- fprintf(f,"%s%*s>", hexdump_prefix, indent,"" );
- else
- fprintf(f,"%s%*s>%*llx:", hexdump_prefix, indent,"", addr_fw, addr );
-
- dest = buf;
- if (!skip)
- *dest++ = ':';
-
- for ( i = 0; i < row_len; i++ )
- {
- if ( skip > 0 )
- {
- fprintf(f,"%s ", i&3 ? "" : " " );
- *dest++ = ' ';
- if (!--skip)
- *dest++ = ':';
- }
- else
- {
- u8 ch = data2[i];
- if ( i < count2 )
- {
- if ( ch == data1[i] )
- fprintf(f,"%s . ", i&3 ? "" : " " );
- else
- fprintf(f,"%s%02x ", i&3 ? "" : " ", ch );
- *dest++ = ch < ' ' || ch >= 0x7f ? '.' : ch;
- }
- else
- fprintf(f,"%s ", i&3 ? "" : " " );
- }
- }
- *dest = 0;
- if (show_ascii)
- fprintf(f,"%s:%s",buf,hexdump_eol);
- else
- fputs(hexdump_eol,f);
- }
- data1 += count;
- data2 += count;
- count1 -= count;
- count2 -= count;
- if (!IS_M1(addr))
- addr += count;
-
- }
- hexdump_prefix = "";
- hexdump_eol = "\n";
- hexdump_align = false;
-
- #endif
}
//
@@ -998,14 +686,14 @@ static void trace_helper ( int print_stderr, ccp format, va_list arg )
if (!TRACE_FILE)
{
char extend[16];
- if (multi_processing)
+ if (ProgInfo.multi_processing)
snprintf(extend,sizeof(extend),"-%u",getpid());
else
*extend = 0;
char fname[1000];
- if ( progname && *progname && *progname != '?' )
- snprintf( fname, sizeof(fname), "_trace-%s%s.tmp", progname, extend );
+ if ( ProgInfo.progname && *ProgInfo.progname && *ProgInfo.progname != '?' )
+ snprintf( fname, sizeof(fname), "_trace-%s%s.tmp", ProgInfo.progname, extend );
else
snprintf( fname, sizeof(fname), "_trace-%s.tmp", extend );
@@ -1373,8 +1061,8 @@ static FILE * OpenMemLog()
{
done = true;
char fname[500];
- if ( progname && *progname && *progname != '?' )
- snprintf(fname,sizeof(fname),"_trace_alloc-%s-%u.tmp",progname,getpid());
+ if ( ProgInfo.progname && *ProgInfo.progname && *ProgInfo.progname != '?' )
+ snprintf(fname,sizeof(fname),"_trace_alloc-%s-%u.tmp",ProgInfo.progname,getpid());
else
snprintf(fname,sizeof(fname),"_trace_alloc-%u.tmp",getpid());
diff --git a/project/dclib/dclib-debug.h b/project/dclib/dclib-debug.h
index 34726f1..cec834f 100644
--- a/project/dclib/dclib-debug.h
+++ b/project/dclib/dclib-debug.h
@@ -41,23 +41,37 @@
//
///////////////////////////////////////////////////////////////////////////////
-/////////////// error handling ///////////////
+/////////////// program info ///////////////
///////////////////////////////////////////////////////////////////////////////
+// [[ProgInfo_t]]
-extern ccp progpath; // full path of program, use ProgramPath() to access
-extern ccp progdir; // directory part of progpath, use ProgramDirectory() to access
-extern ccp progname; // program name, based on path or directly set
+typedef struct ProgInfo_t
+{
+ ccp progpath; // full path of program, use ProgramPath() to access
+ ccp progdir; // directory part of progpath, use ProgramDirectory() to access
+ ccp progname; // program name, based on path or directly set
-extern ccp toolname; // name of the tool, set by SetupProgname()
-extern ccp toolversion; // version of the tool, set by SetupProgname()
-extern ccp tooltitle; // title of the tool, set by SetupProgname()
+ ccp logdir; // log directory, set by DefineLogDirectory()
+ // and GetLogDirectory()
-extern bool multi_processing;
-extern enumError last_error;
-extern enumError max_error;
-extern u32 error_count;
+ ccp toolname; // name of the tool, set by SetupProgname()
+ ccp toolversion; // version of the tool, set by SetupProgname()
+ ccp tooltitle; // title of the tool, set by SetupProgname()
-//-----------------------------------------------------------------------------
+ bool multi_processing; // TRUE: program uses multiple thread
+
+ enumError last_error; // last error, set by PrintErrorArg()
+ enumError max_error; // max error, set by PrintErrorArg()
+ u32 error_count; // number of errors, set by PrintErrorArg()
+}
+ProgInfo_t;
+
+extern ProgInfo_t ProgInfo;
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// error handling ///////////////
+///////////////////////////////////////////////////////////////////////////////
extern ccp (*GetErrorNameHook)( int stat, ccp ret_not_found );
extern ccp (*GetErrorTextHook)( int stat, ccp ret_not_found );
@@ -126,29 +140,12 @@ bool mark_used ( ccp name, ... );
/////////////// hexdump ///////////////
///////////////////////////////////////////////////////////////////////////////
-// 0: don't use XDump
-// 1: use 'enable_xdump_wrapper' to decide and init it with FALSE
-// 2: use 'enable_xdump_wrapper' to decide and init it with TRUE
-// 3: force usage of XDump
-
-#ifndef ENABLE_HEXDUMP_WRAPPER
- #ifdef TEST
- #define ENABLE_HEXDUMP_WRAPPER 3
- #else
- #define ENABLE_HEXDUMP_WRAPPER 3
- #endif
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
-
-#if ENABLE_HEXDUMP_WRAPPER
- extern int enable_xdump_wrapper;
-#endif
-
extern ccp hexdump_prefix;
extern ccp hexdump_eol;
extern bool hexdump_align;
+//-----------------------------------------------------------------------------
+
// HexDump*() return the number of printed lines
uint HexDump ( FILE * f, int indent, u64 addr, int addr_fw, int row_len,
@@ -186,7 +183,7 @@ void HexDiff16 ( FILE * f, int indent, u64 addr,
// If symbol 'DEBUG' or symbol _DEBUG' is defined, then and only then
// DEBUG, DASSERT and TRACING are enabled.
//
-// There are to function like macros defined:
+// Defined functions/macros:
//
// TRACE ( ccp format, ... );
// Print to console only if TRACING is enabled.
@@ -197,10 +194,10 @@ void HexDiff16 ( FILE * f, int indent, u64 addr,
// Like TRACE(), but print only if 'condition' is true.
//
// TRACELINE
-// Print out current line and source.
+// Print out current line and source if TRACING is defined.
//
// TRACE_SIZEOF ( object_or_type );
-// Print out `sizeof(object_or_type)´
+// Print out `sizeof(object_or_type)´ if TRACING is defined.
//
// ASSERT(cond);
// If condition is false: print info and exit program.
diff --git a/project/dclib/dclib-file.c b/project/dclib/dclib-file.c
index 0cd2478..a4849e3 100644
--- a/project/dclib/dclib-file.c
+++ b/project/dclib/dclib-file.c
@@ -36,6 +36,7 @@
#include <sys/types.h>
#include <sys/ioctl.h>
+#include <sys/time.h>
#include <fcntl.h>
#include <string.h>
#include <time.h>
@@ -197,8 +198,19 @@ FileAttrib_t * ClearFileAttrib
FileAttrib_t * dest // NULL or destination attribute
)
{
+ #if USE_NEW_FILEATTRIB
if (dest)
+ {
memset(dest,0,sizeof(*dest));
+ dest->atime.tv_nsec =
+ dest->mtime.tv_nsec =
+ dest->ctime.tv_nsec =
+ dest->itime.tv_nsec = UTIME_OMIT;
+ }
+ #else
+ if (dest)
+ memset(dest,0,sizeof(*dest));
+ #endif
return dest;
}
@@ -210,7 +222,17 @@ FileAttrib_t * TouchFileAttrib
)
{
DASSERT(dest);
+ #if USE_NEW_FILEATTRIB
+ struct timeval tv;
+ if (!gettimeofday(&tv,0))
+ {
+ dest->atime.tv_sec = tv.tv_sec;
+ dest->atime.tv_nsec = tv.tv_usec * 1000;
+ dest->mtime = dest->ctime = dest->itime = dest->atime;
+ }
+ #else
dest->mtime = dest->ctime = dest->atime = dest->itime = time(0);
+ #endif
return dest;
}
@@ -226,21 +248,46 @@ FileAttrib_t * SetFileAttrib
{
DASSERT(dest);
+ #if USE_NEW_FILEATTRIB
+
if (src_fa)
memcpy(dest,src_fa,sizeof(*dest));
else if (src_stat)
{
memset(dest,0,sizeof(*dest));
- if ( S_ISREG(src_stat->st_mode) )
+ if (S_ISREG(src_stat->st_mode))
+ {
+ dest->atime = src_stat->st_atim;
+ dest->mtime = src_stat->st_mtim;
+ dest->ctime = src_stat->st_ctim;
+ dest->itime = CompareTimeSpec(&dest->mtime,&dest->ctime) > 0
+ ? dest->mtime : dest->ctime;
+ dest->size = src_stat->st_size;
+ }
+ else
+ ClearFileAttrib(dest);
+ dest->mode = src_stat->st_mode;
+ }
+
+ #else
+
+ if (src_fa)
+ memcpy(dest,src_fa,sizeof(*dest));
+ else if (src_stat)
+ {
+ memset(dest,0,sizeof(*dest));
+ if (S_ISREG(src_stat->st_mode))
{
+ dest->atime = src_stat->st_atime;
dest->mtime = src_stat->st_mtime;
dest->ctime = src_stat->st_ctime;
dest->itime = dest->mtime > dest->ctime ? dest->mtime : dest->ctime;
- dest->atime = src_stat->st_atime;
dest->size = src_stat->st_size;
}
dest->mode = src_stat->st_mode;
}
+
+ #endif
return dest;
}
@@ -255,11 +302,51 @@ FileAttrib_t * MaxFileAttrib
{
DASSERT(dest);
+ #if USE_NEW_FILEATTRIB
+
if (src_fa)
{
+ if (CompareTimeSpec(&dest->atime,&src_fa->atime)>0) dest->atime = src_fa->atime;
+ if (CompareTimeSpec(&dest->mtime,&src_fa->mtime)>0) dest->mtime = src_fa->mtime;
+ if (CompareTimeSpec(&dest->ctime,&src_fa->ctime)>0) dest->ctime = src_fa->ctime;
+ if (CompareTimeSpec(&dest->itime,&src_fa->itime)>0) dest->itime = src_fa->itime;
+
+ if ( dest->size < src_fa->size )
+ dest->size = src_fa->size;
+ dest->mode = src_fa->mode;
+ }
+
+ if (src_stat)
+ {
+ if ( S_ISREG(src_stat->st_mode) )
+ {
+ if ( CompareTimeSpec(&dest->atime,&src_stat->st_atim) > 0 )
+ dest->atime = src_stat->st_atim;
+
+ if ( CompareTimeSpec(&dest->mtime,&src_stat->st_mtim) > 0 )
+ dest->mtime = src_stat->st_mtim;
+
+ if ( CompareTimeSpec(&dest->ctime,&src_stat->st_ctim) > 0 )
+ dest->ctime = src_stat->st_ctim;
+
+ if ( CompareTimeSpec(&dest->itime,&src_stat->st_mtim) > 0 )
+ dest->itime = src_stat->st_mtim;
+ if ( CompareTimeSpec(&dest->itime,&src_stat->st_ctim) > 0 )
+ dest->itime = src_stat->st_ctim;
+
+ if ( dest->size < src_stat->st_size )
+ dest->size = src_stat->st_size;
+ }
+ dest->mode = src_stat->st_mode;
+ }
+
+ #else
+
+ if (src_fa)
+ {
+ if ( dest->atime < src_fa->atime ) dest->atime = src_fa->atime;
if ( dest->mtime < src_fa->mtime ) dest->mtime = src_fa->mtime;
if ( dest->ctime < src_fa->ctime ) dest->ctime = src_fa->ctime;
- if ( dest->atime < src_fa->atime ) dest->atime = src_fa->atime;
if ( dest->itime < src_fa->itime ) dest->itime = src_fa->itime;
if ( dest->size < src_fa->size ) dest->size = src_fa->size;
@@ -271,9 +358,9 @@ FileAttrib_t * MaxFileAttrib
{
if ( S_ISREG(src_stat->st_mode) )
{
+ if ( dest->atime < src_stat->st_atime ) dest->atime = src_stat->st_atime;
if ( dest->mtime < src_stat->st_mtime ) dest->mtime = src_stat->st_mtime;
if ( dest->ctime < src_stat->st_ctime ) dest->ctime = src_stat->st_ctime;
- if ( dest->atime < src_stat->st_atime ) dest->atime = src_stat->st_atime;
if ( dest->itime < dest->mtime ) dest->itime = dest->mtime;
if ( dest->itime < dest->ctime ) dest->itime = dest->ctime;
@@ -283,6 +370,8 @@ FileAttrib_t * MaxFileAttrib
dest->mode = src_stat->st_mode;
}
+ #endif
+
return dest;
}
@@ -298,6 +387,30 @@ FileAttrib_t * NormalizeFileAttrib
if ( fa->size < 0 )
fa->size = 0;
+ #if USE_NEW_FILEATTRIB
+
+ if (IsTimeSpecNull(&fa->mtime))
+ {
+ if (!IsTimeSpecNull(&fa->itime))
+ fa->mtime = fa->itime;
+ else if (!IsTimeSpecNull(&fa->ctime))
+ fa->mtime = fa->ctime;
+ }
+
+ if (IsTimeSpecNull(&fa->itime))
+ fa->itime = CompareTimeSpec(&fa->ctime,&fa->mtime) > 0
+ ? fa->ctime : fa->mtime;
+
+ if (IsTimeSpecNull(&fa->ctime))
+ fa->ctime = CompareTimeSpec(&fa->itime,&fa->mtime) > 0
+ ? fa->itime : fa->mtime;
+
+ if (IsTimeSpecNull(&fa->atime))
+ fa->atime = CompareTimeSpec(&fa->itime,&fa->ctime) > 0
+ ? fa->itime : fa->ctime;
+
+ #else
+
time_t mtime = fa->mtime;
if (!mtime)
{
@@ -320,9 +433,23 @@ FileAttrib_t * NormalizeFileAttrib
if (!fa->atime)
fa->atime = fa->itime > fa->ctime ? fa->itime : fa->ctime;
+ #endif
+
return fa;
}
+///////////////////////////////////////////////////////////////////////////////
+// struct timespec helpers
+
+const struct timespec null_timespec = {0,0};
+
+int CompareTimeSpec0 ( const struct timespec *a, const struct timespec *b )
+{
+ if (!a) a = &null_timespec;
+ if (!b) b = &null_timespec;
+ return CompareTimeSpec(a,b);
+}
+
//
///////////////////////////////////////////////////////////////////////////////
/////////////// simple UNIX+TCP socket connect ///////////////
@@ -723,14 +850,18 @@ enumError CloseFile
TRACE("UNLINK %s\n",f->fname);
unlink(f->fname);
}
+ #if USE_NEW_FILEATTRIB
+ else if ( set_time == 1 && !IsTimeSpecNull(&f->fatt.mtime) )
+ utimensat(AT_FDCWD,f->fname,f->fatt.times,0);
+ #else
else if ( set_time == 1 && f->fatt.mtime )
{
struct utimbuf ubuf;
ubuf.actime = f->fatt.atime
? f->fatt.atime : f->fatt.mtime;
ubuf.modtime = f->fatt.mtime;
- utime(f->fname,&ubuf);
}
+ #endif
else if ( set_time > 1 || f->fmode & FM_TOUCH )
{
utime(f->fname,0);
@@ -1300,7 +1431,7 @@ s64 GetFileSize
if ( stat(path,&st) || !S_ISREG(st.st_mode) )
{
if ( fatt && !fatt_max )
- memset(fatt,0,sizeof(*fatt));
+ ClearFileAttrib(fatt);
return not_found_val;
}
@@ -2081,7 +2212,7 @@ uint ReadMemFileAt
enumError LoadMemFile
(
MemFile_t *mf, // MemFile_t data
- bool init_mf, // true: initalize 'mf' first
+ bool init_mf, // true: initialize 'mf' first
ccp path1, // NULL or part #1 of path
ccp path2, // NULL or part #2 of path
@@ -2677,7 +2808,7 @@ ccp FindConfigFile
//--- empty strings like NULL
- if ( share_name && !*share_name ) share_name = progname;
+ if ( share_name && !*share_name ) share_name = ProgInfo.progname;
if ( file_name && !*file_name ) file_name = 0;
if ( prog_ext && !*prog_ext ) prog_ext = 0;
@@ -4178,7 +4309,7 @@ enumError RestoreState
//--- scan name
ccp name = ptr;
- while ( isalnum((int)*ptr) || *ptr == '-' || *ptr == '_' || *ptr == '@' )
+ while ( *ptr >= '!' && *ptr <= '~' && *ptr != '=' )
ptr++;
char *name_end = ptr;
@@ -4449,6 +4580,11 @@ mem_t GetParamFieldMEM
/////////////// save + restore config by table ///////////////
///////////////////////////////////////////////////////////////////////////////
+int srt_auto_dump = 0;
+FILE *srt_auto_dump_file = 0;
+
+///////////////////////////////////////////////////////////////////////////////
+
void DumpStateTable
(
FILE *f, // valid output file
@@ -4461,6 +4597,12 @@ void DumpStateTable
return;
indent = NormalizeIndent(indent);
+ printf(
+ "%*s off size *n(e) ty em name\n"
+ "%*s----------------------------------\n",
+ indent,"",
+ indent,"" );
+
for ( ; srt->type != SRT__TERM; srt++ )
{
if ( srt->type == SRT__IS_LIST )
@@ -4471,10 +4613,11 @@ void DumpStateTable
putc('\n',f);
}
else
- fprintf(f,"%*s%4u %4u *%-3u %2u %2u %s\n",
+ fprintf(f,"%*s%4u %4u *%-4d %2u %2u %s\n",
indent,"",
srt->offset, srt->size, srt->n_elem, srt->type, srt->emode,
- srt->name ? srt->name : "-" );
+ srt->name ? srt->name
+ : srt->type == SRT_DEF_ARRAY ? " >ARRAY" : "-" );
}
}
@@ -4502,32 +4645,28 @@ static void print_scs_name ( FILE *f, int fw, int use_tab, ccp format, ... )
//-----------------------------------------------------------------------------
-static u64 SCS_get_uint ( const u8* data, int idx, const SaveRestoreTab_t *srt )
+static u64 SCS_get_uint ( const u8* data, int size )
{
- DASSERT(srt);
-
- switch(srt->size)
+ switch(size)
{
- case 1: return ((u8*) (data+srt->offset))[idx];
- case 2: return ((u16*)(data+srt->offset))[idx];
- case 4: return ((u32*)(data+srt->offset))[idx];
- case 8: return ((u64*)(data+srt->offset))[idx];
+ case 1: return *(u8*) data;
+ case 2: return *(u16*)data;
+ case 4: return *(u32*)data;
+ case 8: return *(u64*)data;
}
return 0;
}
//-----------------------------------------------------------------------------
-static s64 SCS_get_int ( const u8* data, int idx, const SaveRestoreTab_t *srt )
+static u64 SCS_get_int ( const u8* data, int size )
{
- DASSERT(srt);
-
- switch(srt->size)
+ switch(size)
{
- case 1: return ((s8*) (data+srt->offset))[idx];
- case 2: return ((s16*)(data+srt->offset))[idx];
- case 4: return ((s32*)(data+srt->offset))[idx];
- case 8: return ((s64*)(data+srt->offset))[idx];
+ case 1: return *(s8*) data;
+ case 2: return *(s16*)data;
+ case 4: return *(s32*)data;
+ case 8: return *(s64*)data;
}
return 0;
}
@@ -4558,6 +4697,7 @@ static void SCS_save_string ( FILE *f, ccp src, int slen, EncodeMode_t emode )
}
}
+//
//-----------------------------------------------------------------------------
void SaveCurrentStateByTable
@@ -4576,6 +4716,13 @@ void SaveCurrentStateByTable
if ( !f || !data0 || !srt )
return;
+ if ( srt_auto_dump && srt_auto_dump_file )
+ {
+ if ( srt_auto_dump > 0 )
+ srt_auto_dump--;
+ DumpStateTable(srt_auto_dump_file,0,srt);
+ }
+
if (!prefix)
prefix = EmptyString;
const uint prelen = strlen(prefix);
@@ -4603,10 +4750,27 @@ void SaveCurrentStateByTable
}
const int use_tab = (fw_name&7) ? 0 : (fw_name/8)*8+7;
- const u8 *data = data0;
+ const u8 *data = data0;
+ uint last_count = 0;
+ uint aelem_count = 0;
+ uint aelem_offset = 0;
for ( ; srt->type != SRT__TERM; srt++ )
{
+ if ( srt->type == SRT_DEF_ARRAY )
+ {
+ aelem_offset = srt->size;
+ if ( srt->n_elem < 0 )
+ {
+ aelem_count = -srt->n_elem;
+ if ( aelem_count > last_count )
+ aelem_count = last_count;
+ }
+ else
+ aelem_count = srt->n_elem;
+ continue;
+ }
+
if ( srt->type == SRT__IS_LIST )
{
if ( srt->name )
@@ -4622,51 +4786,85 @@ void SaveCurrentStateByTable
if ( srt->type < SRT__IS_LIST )
print_scs_name(f,fw_name,use_tab,"%s%s",prefix,srt->name);
+ int n_elem, elem_off;
+ bool have_array = aelem_count && aelem_offset;
+ if (have_array)
+ {
+ elem_off = aelem_offset;
+ n_elem = aelem_count;
+ }
+ else
+ {
+ elem_off = srt->size;
+ n_elem = srt->n_elem;
+ if ( n_elem < 0 )
+ {
+ have_array = true;
+ n_elem = -n_elem;
+ if ( n_elem > last_count )
+ n_elem = last_count;
+ }
+ else if ( n_elem > 1 )
+ have_array = true;
+ }
+
uint i, offset;
switch(srt->type)
{
case SRT_BOOL:
- if ( srt->n_elem > 1 )
+ if (have_array)
{
- for ( i = 0; i < srt->n_elem; i++ )
- fprintf(f,"%s%u", i ? "," : "", SCS_get_uint(data,i,srt)!=0 );
+ const u8 *d = data + srt->offset;
+ for ( i = 0; i < n_elem; i++, d += elem_off )
+ fprintf(f,"%s%u", i ? "," : "", SCS_get_uint(d,srt->size)!=0 );
fputc('\n',f);
}
else
- fprintf(f,"%u\n",SCS_get_uint(data,0,srt)!=0);
+ fprintf(f,"%u\n",SCS_get_uint(data+srt->offset,srt->size)!=0);
break;
+ case SRT_COUNT:
+ last_count = 0;
+ // fall through
case SRT_UINT:
- if ( srt->n_elem > 1 )
+ if (have_array)
{
- for ( i = 0; i < srt->n_elem; i++ )
- fprintf(f,"%s%llu", i ? "," : "", SCS_get_uint(data,i,srt) );
+ const u8 *d = data + srt->offset;
+ for ( i = 0; i < n_elem; i++, d += elem_off )
+ fprintf(f,"%s%llu", i ? "," : "", SCS_get_uint(d,srt->size) );
fputc('\n',f);
}
else
- fprintf(f,"%llu\n",SCS_get_uint(data,0,srt));
+ {
+ const u64 num = SCS_get_uint(data+srt->offset,srt->size);
+ if ( srt->type == SRT_COUNT && num <= UINT_MAX )
+ last_count = num;
+ fprintf(f,"%llu\n",num);
+ }
break;
case SRT_HEX:
- if ( srt->n_elem > 1 )
+ if (have_array)
{
- for ( i = 0; i < srt->n_elem; i++ )
- fprintf(f,"%s%#llx", i ? "," : "", SCS_get_uint(data,i,srt) );
+ const u8 *d = data + srt->offset;
+ for ( i = 0; i < n_elem; i++, d += elem_off )
+ fprintf(f,"%s%#llx", i ? "," : "", SCS_get_uint(d,srt->size) );
fputc('\n',f);
}
else
- fprintf(f,"%#llx\n",SCS_get_uint(data,0,srt));
+ fprintf(f,"%#llx\n",SCS_get_uint(data+srt->offset,srt->size));
break;
case SRT_INT:
- if ( srt->n_elem > 1 )
+ if (have_array)
{
- for ( i = 0; i < srt->n_elem; i++ )
- fprintf(f,"%s%lld", i ? "," : "", SCS_get_int(data,i,srt) );
+ const u8 *d = data + srt->offset;
+ for ( i = 0; i < n_elem; i++, d += elem_off )
+ fprintf(f,"%s%lld", i ? "," : "", SCS_get_int(d,srt->size) );
fputc('\n',f);
}
else
- fprintf(f,"%lld\n",SCS_get_int(data,0,srt));
+ fprintf(f,"%lld\n",SCS_get_int(data+srt->offset,srt->size));
break;
case SRT_FLOAT:
@@ -4674,25 +4872,25 @@ void SaveCurrentStateByTable
{
case sizeof(float):
{
- for ( i = 0; i < srt->n_elem; i++ )
- fprintf(f,"%s%.8g", i ? "," : "",
- ((float*)(data+srt->offset))[i] );
+ const u8 *d = data + srt->offset;
+ for ( i = 0; i < n_elem; i++, d += elem_off )
+ fprintf(f, "%s%.8g", i ? "," : "", *(float*)d );
}
break;
case sizeof(double):
{
- for ( i = 0; i < srt->n_elem; i++ )
- fprintf(f,"%s%.16g", i ? "," : "",
- ((double*)(data+srt->offset))[i] );
+ const u8 *d = data + srt->offset;
+ for ( i = 0; i < n_elem; i++, d += elem_off )
+ fprintf(f, "%s%.16g", i ? "," : "", *(double*)d );
}
break;
case sizeof(long double):
{
- for ( i = 0; i < srt->n_elem; i++ )
- fprintf(f,"%s%.20Lg", i ? "," : "",
- ((long double*)(data+srt->offset))[i] );
+ const u8 *d = data + srt->offset;
+ for ( i = 0; i < n_elem; i++, d += elem_off )
+ fprintf(f, "%s%.20Lg", i ? "," : "", *(long double*)d );
}
break;
@@ -4707,25 +4905,25 @@ void SaveCurrentStateByTable
{
case sizeof(float):
{
- for ( i = 0; i < srt->n_elem; i++ )
- fprintf(f,"%s%a", i ? "," : "",
- ((float*)(data+srt->offset))[i] );
+ const u8 *d = data + srt->offset;
+ for ( i = 0; i < n_elem; i++, d += elem_off )
+ fprintf(f, "%s%a", i ? "," : "", *(float*)d );
}
break;
case sizeof(double):
{
- for ( i = 0; i < srt->n_elem; i++ )
- fprintf(f,"%s%a", i ? "," : "",
- ((double*)(data+srt->offset))[i] );
+ const u8 *d = data + srt->offset;
+ for ( i = 0; i < n_elem; i++, d += elem_off )
+ fprintf(f, "%s%a", i ? "," : "", *(double*)d );
}
break;
case sizeof(long double):
{
- for ( i = 0; i < srt->n_elem; i++ )
- fprintf(f,"%s%La", i ? "," : "",
- ((long double*)(data+srt->offset))[i] );
+ const u8 *d = data + srt->offset;
+ for ( i = 0; i < n_elem; i++, d += elem_off )
+ fprintf(f, "%s%La", i ? "," : "", *(long double*)d );
}
break;
@@ -4738,37 +4936,40 @@ void SaveCurrentStateByTable
//-----
case SRT_STRING_SIZE:
- for ( i = 0, offset = srt->offset;; offset += srt->size )
- {
- SCS_save_string(f,(char*)(data+offset),-1,srt->emode);
- if ( ++i == srt->n_elem )
- break;
- fputc(',',f);
- }
+ if ( n_elem > 0 )
+ for ( i = 0, offset = srt->offset;; offset += elem_off )
+ {
+ SCS_save_string(f,(char*)(data+offset),-1,srt->emode);
+ if ( ++i == n_elem )
+ break;
+ fputc(',',f);
+ }
fputc('\n',f);
break;
case SRT_STRING_ALLOC:
- for ( i = 0, offset = srt->offset;; offset += srt->size )
- {
- SCS_save_string(f,*(ccp*)(data+offset),-1,srt->emode);
- if ( ++i == srt->n_elem )
- break;
- fputc(',',f);
- }
+ if ( n_elem > 0 )
+ for ( i = 0, offset = srt->offset;; offset += elem_off )
+ {
+ SCS_save_string(f,*(ccp*)(data+offset),-1,srt->emode);
+ if ( ++i == n_elem )
+ break;
+ fputc(',',f);
+ }
fputc('\n',f);
break;
case SRT_MEM:
{
- for ( i = 0, offset = srt->offset;; offset += srt->size )
- {
- mem_t *mem = (mem_t*)(data+offset);
- SCS_save_string(f,mem->ptr,mem->len,srt->emode);
- if ( ++i == srt->n_elem )
- break;
- fputc(',',f);
- }
+ if ( n_elem > 0 )
+ for ( i = 0, offset = srt->offset;; offset += elem_off )
+ {
+ mem_t *mem = (mem_t*)(data+offset);
+ SCS_save_string(f,mem->ptr,mem->len,srt->emode);
+ if ( ++i == n_elem )
+ break;
+ fputc(',',f);
+ }
fputc('\n',f);
break;
}
@@ -4813,6 +5014,7 @@ void SaveCurrentStateByTable
}
}
+//
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
@@ -4826,13 +5028,41 @@ void RestoreStateByTable
{
DASSERT(rs);
DASSERT(srt);
+ DASSERT(data0);
+ if ( !rs || !data0 || !srt )
+ return;
+
+ if ( srt_auto_dump && srt_auto_dump_file )
+ {
+ if ( srt_auto_dump > 0 )
+ srt_auto_dump--;
+ DumpStateTable(srt_auto_dump_file,0,srt);
+ }
- char buf[4000]; // ???
+ char buf[4000];
if (!prefix)
prefix = EmptyString;
+ uint last_count = 0;
+ uint aelem_count = 0;
+ uint aelem_offset = 0;
+
for ( ; srt->type != SRT__TERM; srt++ )
{
+ if ( srt->type == SRT_DEF_ARRAY )
+ {
+ aelem_offset = srt->size;
+ if ( srt->n_elem < 0 )
+ {
+ aelem_count = -srt->n_elem;
+ if ( aelem_count > last_count )
+ aelem_count = last_count;
+ }
+ else
+ aelem_count = srt->n_elem;
+ continue;
+ }
+
if ( srt->type == SRT__IS_LIST || !srt->name )
continue;
@@ -4841,155 +5071,187 @@ void RestoreStateByTable
if ( srt->type < SRT__IS_LIST )
StringCat2S(buf,sizeof(buf),prefix,srt->name);
+ int n_elem, elem_off;
+ if ( aelem_count && aelem_offset )
+ {
+ elem_off = aelem_offset;
+ n_elem = aelem_count;
+ }
+ else
+ {
+ elem_off = srt->size;
+ n_elem = srt->n_elem;
+ if ( n_elem < 0 )
+ {
+ n_elem = -n_elem;
+ if ( n_elem > last_count )
+ n_elem = last_count;
+ }
+ }
+
switch(srt->type)
{
+ case SRT_COUNT:
+ last_count = 0;
+ // fall through
case SRT_BOOL:
case SRT_UINT:
case SRT_HEX:
- {
- ParamFieldItem_t *it = GetParamField(rs,buf);
- if (!it)
- break;
-
- char *src = (char*)it->data;
- u8 *val = (u8*)(data+srt->offset);
- uint i = 0;
- while (*src)
+ if (n_elem)
{
- u64 num = str2ull(src,&src,10);
- switch(srt->size)
+ ParamFieldItem_t *it = GetParamField(rs,buf);
+ if (!it)
+ break;
+
+ char *src = (char*)it->data;
+ u8 *val = (u8*)(data+srt->offset);
+ uint i = 0;
+ while (*src)
{
- case 1: *(u8*) val = num; break;
- case 2: *(u16*)val = num; break;
- case 4: *(u32*)val = num; break;
- case 8: *(u64*)val = num; break;
+ u64 num = str2ull(src,&src,10);
+ if ( !i && srt->type == SRT_COUNT && num <= UINT_MAX )
+ last_count = num;
+
+ switch(srt->size)
+ {
+ case 1: *(u8*) val = num; break;
+ case 2: *(u16*)val = num; break;
+ case 4: *(u32*)val = num; break;
+ case 8: *(u64*)val = num; break;
+ }
+ if ( ++i == n_elem )
+ break;
+ val += elem_off;
+ if ( *src == ',' )
+ src++;
}
- if ( ++i == srt->n_elem )
- break;
- val += srt->size;
- if ( *src == ',' )
- src++;
}
break;
- }
case SRT_INT:
- {
- ParamFieldItem_t *it = GetParamField(rs,buf);
- if (!it)
- break;
-
- char *src = (char*)it->data;
- u8 *val = (u8*)(data+srt->offset);
- uint i = 0;
- while (*src)
+ if (n_elem)
{
- s64 num = str2ll(src,&src,10);
- switch(srt->size)
+ ParamFieldItem_t *it = GetParamField(rs,buf);
+ if (!it)
+ break;
+
+ char *src = (char*)it->data;
+ u8 *val = (u8*)(data+srt->offset);
+ uint i = 0;
+ while (*src)
{
- case 1: *(s8*) val = num; break;
- case 2: *(s16*)val = num; break;
- case 4: *(s32*)val = num; break;
- case 8: *(s64*)val = num; break;
+ s64 num = str2ll(src,&src,10);
+ switch(srt->size)
+ {
+ case 1: *(s8*) val = num; break;
+ case 2: *(s16*)val = num; break;
+ case 4: *(s32*)val = num; break;
+ case 8: *(s64*)val = num; break;
+ }
+ if ( ++i == n_elem )
+ break;
+ val += elem_off;
+ if ( *src == ',' )
+ src++;
}
- if ( ++i == srt->n_elem )
- break;
- val += srt->size;
- if ( *src == ',' )
- src++;
}
break;
- }
case SRT_FLOAT:
case SRT_XFLOAT:
- {
- ParamFieldItem_t *it = GetParamField(rs,buf);
- if (!it)
- break;
-
- char *src = (char*)it->data;
- u8 *val = (u8*)(data+srt->offset);
- uint i = 0;
- while (*src)
+ if (n_elem)
{
- switch(srt->size)
+ ParamFieldItem_t *it = GetParamField(rs,buf);
+ if (!it)
+ break;
+
+ char *src = (char*)it->data;
+ u8 *val = (u8*)(data+srt->offset);
+ uint i = 0;
+ while (*src)
{
- case sizeof(float): *(float*)val = strtof(src,&src); break;
- case sizeof(double): *(double*)val = strtod(src,&src); break;
- case sizeof(long double): *(long double*)val = strtold(src,&src); break;
+ switch(srt->size)
+ {
+ case sizeof(float): *(float*)val = strtof(src,&src); break;
+ case sizeof(double): *(double*)val = strtod(src,&src); break;
+ case sizeof(long double): *(long double*)val = strtold(src,&src); break;
+ }
+ if ( ++i == n_elem )
+ break;
+ val += elem_off;
+ if ( *src == ',' )
+ src++;
}
- if ( ++i == srt->n_elem )
- break;
- val += srt->size;
- if ( *src == ',' )
- src++;
}
break;
- }
//-----
case SRT_STRING_SIZE:
- {
- ParamFieldItem_t *it = GetParamField(rs,buf);
- mem_list_t ml;
- DecodeByModeMemList(&ml,2,it?(ccp)it->data:0,-1,srt->emode,0);
+ if (n_elem)
+ {
+ ParamFieldItem_t *it = GetParamField(rs,buf);
+ mem_list_t ml;
+ DecodeByModeMemList(&ml,2,it?(ccp)it->data:0,-1,srt->emode,0);
- char *val = (char*)(data+srt->offset);
- uint i;
- for ( i = 0; i < srt->n_elem; i++, val += srt->size )
- StringCopyS( val, srt->size, i<ml.used ? ml.list[i].ptr : 0 );
- ResetMemList(&ml);
+ char *val = (char*)(data+srt->offset);
+ uint i;
+ for ( i = 0; i < n_elem; i++, val += elem_off )
+ StringCopyS( val, srt->size, i<ml.used ? ml.list[i].ptr : 0 );
+ ResetMemList(&ml);
+ }
break;
- }
case SRT_STRING_ALLOC:
- {
- ParamFieldItem_t *it = GetParamField(rs,buf);
- mem_list_t ml;
- DecodeByModeMemList(&ml,2,it?(ccp)it->data:0,-1,srt->emode,0);
-
- ccp *val = (ccp*)(data+srt->offset);
- uint i;
- for ( i = 0; i < srt->n_elem; i++, val++ )
+ if (n_elem)
{
- FreeString(*val);
- *val = 0;
- if ( i < ml.used )
+ ParamFieldItem_t *it = GetParamField(rs,buf);
+ mem_list_t ml;
+ DecodeByModeMemList(&ml,2,it?(ccp)it->data:0,-1,srt->emode,0);
+
+ ccp *val = (ccp*)(data+srt->offset);
+ uint i;
+ for ( i = 0; i < n_elem; i++ )
{
- mem_t *m = ml.list+i;
- if ( m->ptr )
- *val = m->ptr == EmptyString ? EmptyString : MEMDUP(m->ptr,m->len);
+ FreeString(*val);
+ *val = 0;
+ if ( i < ml.used )
+ {
+ mem_t *m = ml.list+i;
+ if ( m->ptr )
+ *val = m->ptr == EmptyString ? EmptyString : MEMDUP(m->ptr,m->len);
+ }
+ val = (ccp*)( (u8*)val + elem_off );
}
+ ResetMemList(&ml);
}
- ResetMemList(&ml);
break;
- }
case SRT_MEM:
- {
- ParamFieldItem_t *it = GetParamField(rs,buf);
- mem_list_t ml;
- DecodeByModeMemList(&ml,2,it?(ccp)it->data:0,-1,srt->emode,0);
-
- mem_t *val = (mem_t*)(data+srt->offset);
- uint i;
- for ( i = 0; i < srt->n_elem; i++, val++ )
+ if (n_elem)
{
- FreeString(val->ptr);
- val->ptr = 0;
- val->len = 0;
- if ( i < ml.used )
+ ParamFieldItem_t *it = GetParamField(rs,buf);
+ mem_list_t ml;
+ DecodeByModeMemList(&ml,2,it?(ccp)it->data:0,-1,srt->emode,0);
+
+ mem_t *val = (mem_t*)(data+srt->offset);
+ uint i;
+ for ( i = 0; i < n_elem; i++ )
{
- mem_t *m = ml.list+i;
- if ( m->ptr )
- *val = m->ptr == EmptyString ? EmptyMem : DupMem(*m);
+ FreeString(val->ptr);
+ val->ptr = 0;
+ val->len = 0;
+ if ( i < ml.used )
+ {
+ mem_t *m = ml.list+i;
+ if ( m->ptr )
+ *val = m->ptr == EmptyString ? EmptyMem : DupMem(*m);
+ }
+ val = (mem_t*)( (u8*)val + elem_off );
}
+ ResetMemList(&ml);
}
- ResetMemList(&ml);
break;
- }
//-----
@@ -5038,7 +5300,7 @@ void RestoreStateByTable
break;
}
}
- }
+ }
}
//
diff --git a/project/dclib/dclib-file.h b/project/dclib/dclib-file.h
index 532ff5f..d2be55c 100644
--- a/project/dclib/dclib-file.h
+++ b/project/dclib/dclib-file.h
@@ -126,10 +126,42 @@ ccp GetFileOpenMode
///////////////////////////////////////////////////////////////////////////////
/////////////// struct FileAttrib_t ///////////////
///////////////////////////////////////////////////////////////////////////////
+
+#ifndef USE_NEW_FILEATTRIB
+ #define USE_NEW_FILEATTRIB 1
+#endif
+
+#undef FILEATTRIB_SEC
+#if USE_NEW_FILEATTRIB
+ #define FILEATTRIB_SEC(t) ((t).tv_sec)
+#else
+ #define FILEATTRIB_SEC(t) (t)
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
// [[FileAttrib_t]]
typedef struct FileAttrib_t
{
+ #if USE_NEW_FILEATTRIB
+
+ union
+ {
+ struct timespec times[4];
+ struct
+ {
+ // order compatible to utimensat() and futimens()
+ struct timespec atime; // last ascces time
+ struct timespec mtime; // time of last content modification
+ struct timespec ctime; // time of file creation or last status change
+ struct timespec itime; // insertion time (special time for archives)
+ };
+ };
+
+ size_t size; // file size
+ mode_t mode; // file mode
+
+ #else
time_t mtime; // time of last content modification
time_t ctime; // time of file creation or last status change
time_t atime; // last ascces time
@@ -137,6 +169,8 @@ typedef struct FileAttrib_t
size_t size; // file size
mode_t mode; // file mode
+ #endif
+
}
FileAttrib_t;
@@ -147,6 +181,9 @@ FileAttrib_t * ClearFileAttrib
FileAttrib_t * dest // NULL or destination attribute
);
+static inline FileAttrib_t * ZeroFileAttrib ( FileAttrib_t * dest )
+ { DASSERT(dest); memset(dest,0,sizeof(*dest)); return dest; }
+
FileAttrib_t * TouchFileAttrib
(
FileAttrib_t * dest // valid destination attribute
@@ -183,6 +220,45 @@ FileAttrib_t * NormalizeFileAttrib
FileAttrib_t * fa // valid attribute
);
+///////////////////////////////////////////////////////////////////////////////
+// struct timespec helpers
+
+extern const struct timespec null_timespec;
+
+// NULL pointers allowed
+int CompareTimeSpec0 ( const struct timespec *a, const struct timespec *b );
+
+// NULL pointers forbidden
+static inline int CompareTimeSpec
+ ( const struct timespec *a, const struct timespec *b )
+{
+ DASSERT(a);
+ DASSERT(b);
+ return a->tv_sec < b->tv_sec ? -1
+ : a->tv_sec > b->tv_sec ? 1
+ : a->tv_nsec < b->tv_nsec ? -1
+ : a->tv_nsec > b->tv_nsec;
+}
+
+// NULL pointers forbidden
+static inline int CompareTimeSpecVal
+ ( const struct timespec *a, const struct timeval *b )
+{
+ DASSERT(a);
+ DASSERT(b);
+ return a->tv_sec < b->tv_sec ? -1
+ : a->tv_sec > b->tv_sec ? 1
+ : a->tv_nsec < b->tv_usec*1000 ? -1
+ : a->tv_nsec > b->tv_usec*1000;
+}
+
+static inline bool IsTimeSpecNull ( const struct timespec *ts )
+{
+ return !ts
+ || ts->tv_nsec > 1000000000 // includes UTIME_NOW || UTIME_OMIT
+ || !ts->tv_nsec && !ts->tv_sec;
+}
+
//
///////////////////////////////////////////////////////////////////////////////
/////////////// struct File_t ///////////////
@@ -632,7 +708,7 @@ static inline uint ReadMemFile
enumError LoadMemFile
(
MemFile_t *mf, // MemFile_t data
- bool init_mf, // true: initalize 'mf' first
+ bool init_mf, // true: initialize 'mf' first
ccp path1, // NULL or part #1 of path
ccp path2, // NULL or part #2 of path
@@ -881,43 +957,17 @@ uint NumberedFilename
);
///////////////////////////////////////////////////////////////////////////////
+
#if 0
-///////////////////////////////////////////////////////////////////////////////
-char * SplitSubPath
-(
+ char * SplitSubPath
+ (
char * buf, // destination buffer
size_t buf_size, // size of 'buf'
ccp path // source path, if NULL: use 'buf'
-);
-
-enumError LoadFile
-(
- ccp path1, // NULL or part #1 of path
- ccp path2, // NULL or part #2 of path
- size_t skip, // skip num of bytes before reading
- void * data, // destination buffer, size = 'size'
- size_t size, // size to read
- int silent, // 0: print all error messages
- // 1: suppress file size warning
- // 2: suppress all error messages
- FileAttrib_t * fatt, // not NULL: store file attributes
- bool fatt_max // true: store *max* values to 'fatt'
-);
-
-enumError SaveFile
-(
- ccp path1, // NULL or part #1 of path
- ccp path2, // NULL or part #2 of path
- bool overwrite, // true: force overwriting
- const void * data, // data to write
- uint data_size, // size of 'data'
- FileAttrib_t * fatt // not NULL: set timestamps using this attribs
-);
+ );
-///////////////////////////////////////////////////////////////////////////////
#endif
-///////////////////////////////////////////////////////////////////////////////
//
///////////////////////////////////////////////////////////////////////////////
diff --git a/project/dclib/dclib-network.c b/project/dclib/dclib-network.c
index c7b5914..15fdf0d 100644
--- a/project/dclib/dclib-network.c
+++ b/project/dclib/dclib-network.c
@@ -1703,7 +1703,7 @@ void InitializeTCPStream ( TCPStream_t *ts, int sock )
{
DASSERT(ts);
memset(ts,0,sizeof(*ts));
- ts->unique_id = CreateUniqueId(1);
+ ts->unique_id = CreateUniqueId();
ts->sock = sock;
ts->poll_index = M1(ts->poll_index);
LOG_TCP_STREAM(ts,0,"%s","INIT()");
@@ -2534,7 +2534,7 @@ void InitializeTCPHandler
{
DASSERT(th);
memset(th,0,sizeof(*th));
- th->unique_id = CreateUniqueId(1);
+ th->unique_id = CreateUniqueId();
th->data_size = data_size;
th->OnAllowStream = IsStreamAllowed;
diff --git a/project/dclib/dclib-network.h b/project/dclib/dclib-network.h
index b533761..4cf099f 100644
--- a/project/dclib/dclib-network.h
+++ b/project/dclib/dclib-network.h
@@ -444,17 +444,17 @@ typedef struct ip4_head_t
{
// http://de.wikipedia.org/wiki/IP-Paket
- u8 vers_ihl; // high nibble: version, low nibble: IHL (Ip Header Len)
- u8 tos;
- u16 total_len;
- u16 id;
- u16 frag_off; // low 12 bits: fragment offset, high 4 bits: flags
- u8 ttl;
- u8 protocol;
- u16 checksum;
- u32 ip_src;
- u32 ip_dest;
- // optional: options + padding
+ /*00*/ u8 vers_ihl; // high nibble: version, low nibble: IHL (Ip Header Len)
+ /*01*/ u8 tos;
+ /*02*/ u16 total_len;
+ /*04*/ u16 id;
+ /*06*/ u16 frag_off; // low 12 bits: fragment offset, high 4 bits: flags
+ /*08*/ u8 ttl;
+ /*09*/ u8 protocol;
+ /*0a*/ u16 checksum;
+ /*0c*/ u32 ip_src;
+ /*10*/ u32 ip_dest;
+ /*14*/ // optional: options + padding
}
__attribute__ ((packed)) ip4_head_t;
diff --git a/project/dclib/dclib-numeric.c b/project/dclib/dclib-numeric.c
index 379e021..8be5cf6 100644
--- a/project/dclib/dclib-numeric.c
+++ b/project/dclib/dclib-numeric.c
@@ -1267,8 +1267,10 @@ uint EncodeBase64
int source_len, // length of 'source'; if <0: use strlen(source)
const char encode64[64+1], // encoding table; if NULL: use TableEncode64default
bool use_filler, // use filler for aligned output
+
ccp next_line, // not NULL: use this string as new line sep
- uint next_line_trigger // >0: use 'next_line' every # input bytes
+ uint bytes_per_line // >0: use 'next_line' every # input bytes
+ // will be rounded down to multiple of 3
)
{
DASSERT(buf);
@@ -1278,11 +1280,11 @@ uint EncodeBase64
noPRINT("EncodeBase64(sz=%u,len=%d,fil=%d)\n",buf_size,source_len,use_filler);
if (!next_line)
- next_line_trigger = ~0;
- else if (!next_line_trigger)
- next_line_trigger = 19;
+ bytes_per_line = ~0;
+ else if (!bytes_per_line)
+ bytes_per_line = 19;
else
- next_line_trigger /= 3;
+ bytes_per_line /= 3;
char *dest = buf;
char *dest_end = buf + buf_size - 4;
@@ -1299,7 +1301,7 @@ uint EncodeBase64
while ( src < src_end && dest < dest_end )
{
- if ( ++n_tupel > next_line_trigger && next_line )
+ if ( ++n_tupel > bytes_per_line && next_line )
{
char *next = StringCopyE(dest,(char*)buf+buf_size,next_line);
if ( next >= dest_end )
@@ -1382,6 +1384,49 @@ mem_t EncodeBase64Circ
}
///////////////////////////////////////////////////////////////////////////////
+
+
+uint EncodeBase64ml // ml: multi line
+(
+ // returns the number of scanned bytes of 'source'
+
+ char *buf, // valid destination buffer
+ uint buf_size, // size of 'buf', >= 4
+ const void *source, // NULL or data to encode
+ int source_len, // length of 'source'; if <0: use strlen(source)
+ const char encode64[64+1], // encoding table; if NULL: use TableEncode64default
+ bool use_filler, // use filler for aligned output
+
+ int indent, // indention of output
+ ccp prefix, // NULL or prefix before encoded data
+ ccp eol, // line terminator, if NULL then use NL
+ int bytes_per_line // create a new line every # input bytes
+ // will be rounded down to multiple of 3
+)
+{
+ indent = NormalizeIndent(indent);
+ if (!eol)
+ eol = "\n";
+
+ char linesep[200];
+ int pre_pos;
+ snprintf(linesep,sizeof(linesep),"%s%n%*s%s",
+ eol,
+ &pre_pos,
+ indent, "",
+ prefix ? prefix : ""
+ );
+
+ char *end = buf + buf_size;
+ char *dest = StringCopyE(buf,end,linesep+pre_pos);
+ const uint scanned = EncodeBase64( dest, end-dest, source, source_len,
+ encode64, use_filler, linesep, bytes_per_line );
+ dest = buf + strlen(buf);
+ StringCopyE(dest,end,eol);
+ return scanned;
+}
+
+///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
uint EncodeJSON
@@ -1793,22 +1838,22 @@ uint EncodeByMode
case ENCODE_BASE64:
len = EncodeBase64(buf,buf_size,source,slen,TableEncode64,true,0,0);
- len = EncodeBase64FillLen(len);
+ len = GetEncodeBase64FillLen(len);
break;
case ENCODE_BASE64URL:
len = EncodeBase64(buf,buf_size,source,slen,TableEncode64url,true,0,0);
- len = EncodeBase64FillLen(len);
+ len = GetEncodeBase64FillLen(len);
break;
case ENCODE_BASE64STAR:
len = EncodeBase64(buf,buf_size,source,slen,TableEncode64star,true,0,0);
- len = EncodeBase64FillLen(len);
+ len = GetEncodeBase64FillLen(len);
break;
case ENCODE_BASE64XML:
len = EncodeBase64(buf,buf_size,source,slen,TableEncode64xml,true,0,0);
- len = EncodeBase64FillLen(len);
+ len = GetEncodeBase64FillLen(len);
break;
case ENCODE_JSON:
@@ -2050,11 +2095,14 @@ ccp PrintTimeByFormat
// returns temporary buffer by GetCircBuf();
ccp format, // format string for strftime()
- time_t time // seconds since epoch -> time()
+ time_t tim // seconds since epoch; 0 is replaced by time()
)
{
+ if (!tim)
+ tim = time(0);
+
char buf[100];
- struct tm *tm = localtime(&time);
+ struct tm *tm = localtime(&tim);
const uint len = strftime(buf,sizeof(buf),format,tm);
return CopyCircBuf(buf,len+1);
}
@@ -2066,11 +2114,14 @@ ccp PrintTimeByFormatUTC
// returns temporary buffer by GetCircBuf();
ccp format, // format string for strftime()
- time_t time // seconds since epoch -> time()
+ time_t tim // seconds since epoch; 0 is replaced by time()
)
{
+ if (!tim)
+ tim = time(0);
+
char buf[100];
- struct tm *tm = gmtime(&time);
+ struct tm *tm = gmtime(&tim);
const uint len = strftime(buf,sizeof(buf),format,tm);
return CopyCircBuf(buf,len+1);
}
@@ -2082,12 +2133,13 @@ ccp PrintUsecByFormat
// returns temporary buffer by GetCircBuf();
ccp format, // format string for strftime()
- time_t time, // seconds since epoch -> time()
+ // 1-6 '@' in row replaced by digits of 'usec'
+ time_t tim, // seconds since epoch
uint usec // micro second of second
)
{
char buf[100];
- struct tm *tm = localtime(&time);
+ struct tm *tm = localtime(&tim);
const uint len = strftime(buf,sizeof(buf),format,tm);
char *at = strchr(buf,'@');
if (at)
@@ -2109,12 +2161,13 @@ ccp PrintUsecByFormatUTC
// returns temporary buffer by GetCircBuf();
ccp format, // format string for strftime()
- time_t time, // seconds since epoch -> time()
+ // 1-6 '@' in row replaced by digits of 'usec'
+ time_t tim, // seconds since epoch
uint usec // micro second of second
)
{
char buf[100];
- struct tm *tm = gmtime(&time);
+ struct tm *tm = gmtime(&tim);
const uint len = strftime(buf,sizeof(buf),format,tm);
char *at = strchr(buf,'@');
if (at)
diff --git a/project/dclib/dclib-ui.c b/project/dclib/dclib-ui.c
index a642431..02f56c9 100644
--- a/project/dclib/dclib-ui.c
+++ b/project/dclib/dclib-ui.c
@@ -260,7 +260,7 @@ enumError CheckEnvOptions ( ccp varname, check_opt_func func )
char * buf = MALLOC(envlen+1);
char * dest = buf;
- int argc = 1; // argv[0] = progname
+ int argc = 1; // argv[0] = ProgInfo.progname
ccp src = env;
while (*src)
{
@@ -279,7 +279,7 @@ enumError CheckEnvOptions ( ccp varname, check_opt_func func )
TRACE("argc = %d\n",argc);
char ** argv = MALLOC((argc+1)*sizeof(*argv));
- argv[0] = (char*)progname;
+ argv[0] = (char*)ProgInfo.progname;
argv[argc] = 0;
dest = buf;
int i;
diff --git a/project/dclib/dclib-xdump.c b/project/dclib/dclib-xdump.c
index ec0e49a..b860b62 100644
--- a/project/dclib/dclib-xdump.c
+++ b/project/dclib/dclib-xdump.c
@@ -680,6 +680,45 @@ void InitializeXDump ( XDump_t *xd )
///////////////////////////////////////////////////////////////////////////////
+ccp hexdump_prefix = "";
+ccp hexdump_eol = "\n";
+bool hexdump_align = false;
+
+//-----------------------------------------------------------------------------
+
+void InitializeXDumpEx
+(
+ XDump_t *xd,
+ FILE *f,
+ int indent,
+ u64 addr,
+ int addr_fw,
+ int row_len
+)
+{
+ DASSERT(xd);
+ InitializeXDump(xd);
+
+ xd->f = f;
+ xd->prefix = hexdump_prefix;
+ xd->eol = hexdump_eol;
+ xd->mode_align = hexdump_align;
+ xd->indent = indent;
+ xd->start_addr = addr;
+ xd->min_addr_fw = addr_fw;
+ xd->min_width = row_len;
+ xd->format = XDUMPF_INT_1;
+ xd->print_format = false;
+ xd->print_summary = false;
+ xd->print_diff_sep = false;
+
+ hexdump_prefix = EmptyString;
+ hexdump_eol = "\n";
+ hexdump_align = false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
void SetupXDump ( XDump_t *xd, XDumpCommand_t cmd )
{
DASSERT(xd);
diff --git a/project/dclib/dclib-xdump.h b/project/dclib/dclib-xdump.h
index 2943cb4..f58ee29 100644
--- a/project/dclib/dclib-xdump.h
+++ b/project/dclib/dclib-xdump.h
@@ -205,9 +205,25 @@ XDump_t;
//-----------------------------------------------------------------------------
+extern ccp hexdump_prefix;
+extern ccp hexdump_eol;
+extern bool hexdump_align;
+
+//-----------------------------------------------------------------------------
+
void InitializeXDump ( XDump_t *xd );
-void SetupXDump ( XDump_t *xd, XDumpCommand_t cmd );
+void InitializeXDumpEx
+(
+ XDump_t *xd,
+ FILE *f,
+ int indent,
+ u64 addr,
+ int addr_fw,
+ int row_len
+);
+
+void SetupXDump ( XDump_t *xd, XDumpCommand_t cmd );
static inline void ResetXDump ( XDump_t *xd ) {}
void PrintXDumpParam
diff --git a/project/gen-template.sh b/project/gen-template.sh
index 7e137dd..7e137dd 100644..100755
--- a/project/gen-template.sh
+++ b/project/gen-template.sh
diff --git a/project/gen-text-file.sh b/project/gen-text-file.sh
index 428a8a9..428a8a9 100644..100755
--- a/project/gen-text-file.sh
+++ b/project/gen-text-file.sh
diff --git a/project/revision.sh b/project/revision.sh
index 194c58a..05c51c7 100644
--- a/project/revision.sh
+++ b/project/revision.sh
@@ -1 +1 @@
-revision=8243
+revision=8267M
diff --git a/project/src/lib-brres.c b/project/src/lib-brres.c
index ea18724..128fb33 100644
--- a/project/src/lib-brres.c
+++ b/project/src/lib-brres.c
@@ -182,7 +182,7 @@ const brsub_info_t brsub_info[] =
{ FF_SRT, 0, 5,5, 2,2, BIMD_OK }, // [[2do]] verify hexdump
{ FF_TEX,
- FF_TEX_CT, 1,3, 1,1, BIMD_HINT },
+ FF_TEX_CT, 1,3, 1,1, BIMD_INFO }, // not BIMD_HINT
{ FF_TEX,
FF_TEX_CT, 2,3, 2,1, BIMD_FAIL },
{ FF_TEX,
diff --git a/project/src/lib-brres.h b/project/src/lib-brres.h
index 1e03edf..120565c 100644
--- a/project/src/lib-brres.h
+++ b/project/src/lib-brres.h
@@ -205,6 +205,7 @@ ccp GetStringBRRES
typedef enum brsub_warn_t
{
BIMD_OK, // original record
+ BIMD_INFO, // hint about wrong version on VERBOSE -> will work
BIMD_HINT, // hint about wrong version -> will work
BIMD_FAIL, // wrong n_sect, but will work (garbage display)
BIMD_FATAL, // wrong n_sect, will freeze
diff --git a/project/src/lib-checksum.c b/project/src/lib-checksum.c
index 4057e31..3be8513 100644
--- a/project/src/lib-checksum.c
+++ b/project/src/lib-checksum.c
@@ -43,6 +43,7 @@
#include "dclib-basics.h"
#include "dclib-numeric.h"
#include "lib-checksum.h"
+#include "lib-szs.h"
//
///////////////////////////////////////////////////////////////////////////////
diff --git a/project/src/lib-checksum.h b/project/src/lib-checksum.h
index 088b2a1..ddde54c 100644
--- a/project/src/lib-checksum.h
+++ b/project/src/lib-checksum.h
@@ -41,7 +41,8 @@
#define _GNU_SOURCE 1
#include "dclib-types.h"
-#include "lib-szs.h"
+
+typedef struct szs_file_t szs_file_t;
//
///////////////////////////////////////////////////////////////////////////////
diff --git a/project/src/lib-ctcode.c b/project/src/lib-ctcode.c
index 6aa43ce..dd954c6 100644
--- a/project/src/lib-ctcode.c
+++ b/project/src/lib-ctcode.c
@@ -2767,6 +2767,7 @@ enumError ScanRawDataCTCODE
if (!raw->data)
return ERR_OK;
+ ctcode->fatt = raw->fatt;
ctcode->fname = raw->fname;
raw->fname = 0;
#if USE_NEW_CONTAINER_CTC
diff --git a/project/src/lib-file.c b/project/src/lib-file.c
index 635baaf..d5a01f2 100644
--- a/project/src/lib-file.c
+++ b/project/src/lib-file.c
@@ -3213,7 +3213,7 @@ int PutScriptVars
break;
case FF_PHP:
- fputs("$d = new stdClass;\n",f);
+ fputs("$d = new \\stdClass;\n",f);
break;
case FF_MAKEDOC:
@@ -3320,6 +3320,7 @@ int PutScriptVars
fputc('\n',f);
break;
}
+ fflush(f);
}
ps->index++;
@@ -3554,7 +3555,8 @@ void AnalyzeSlotAttrib ( slot_info_t *si, bool reset_si, mem_t attrib )
if (!memcmp(src,"31+71",5))
{
si->have_31_71 = true;
- if ( si->race_slot == 31 || si->race_slot == 71 )
+ if ( si->race_mode != SIT_MANDATORY2
+ && (si->race_slot == 31 || si->race_slot == 71 ))
{
si->race_mode = SIT_MANDATORY;
snprintf(si->race_info,sizeof(si->race_info),"%u",si->race_slot);
diff --git a/project/src/lib-kcl.c b/project/src/lib-kcl.c
index 629ced6..86acd6b 100644
--- a/project/src/lib-kcl.c
+++ b/project/src/lib-kcl.c
@@ -4123,6 +4123,7 @@ enumError ScanRawDataKCL
else
ResetKCL(kcl);
+ kcl->fatt = raw->fatt;
kcl->fname = raw->fname;
raw->fname = 0;
diff --git a/project/src/lib-kmp-text.c b/project/src/lib-kmp-text.c
index 0f3e292..98cf31d 100644
--- a/project/src/lib-kmp-text.c
+++ b/project/src/lib-kmp-text.c
@@ -6330,7 +6330,11 @@ enumError SaveTextKMP
DASSERT(kmp);
DASSERT(fname);
- PRINT("SaveTextKMP(%s,%d)\n",fname,set_time);
+ #if USE_NEW_FILEATTRIB
+ PRINT("SaveTextKMP(%s,%d) mtime=%lu\n",fname,set_time,kmp->fatt.mtime.tv_sec);
+ #else
+ PRINT("SaveTextKMP(%s,%d) mtime=%lu\n",fname,set_time,kmp->fatt.mtime);
+ #endif
KMP_ACTION_LOG(false,"SaveTextKMP() %s\n",fname);
char temp_buf[100];
diff --git a/project/src/lib-kmp.c b/project/src/lib-kmp.c
index 239e577..ba31951 100644
--- a/project/src/lib-kmp.c
+++ b/project/src/lib-kmp.c
@@ -2998,6 +2998,7 @@ enumError ScanRawDataKMP
else
ResetKMP(kmp);
+ kmp->fatt = raw->fatt;
kmp->fname = raw->fname;
raw->fname = 0;
@@ -6022,7 +6023,6 @@ void CheckUsedPos ( const kmp_t *kmp, kmp_usedpos_t *up )
}
}
-
#if HAVE_WIIMM_EXT && 0
PrintUsedPosObj(stderr,1,&up->orig);
PrintUsedPosObj(stderr,1,&up->orig_lex);
@@ -6035,6 +6035,46 @@ void CheckUsedPos ( const kmp_t *kmp, kmp_usedpos_t *up )
#endif
}
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+void CheckWarnKMP ( kmp_t *kmp, kmp_usedpos_t *up )
+{
+ kmp_usedpos_t local_up;
+ if (!up)
+ {
+ InitializeUsedPos(&local_up);
+ up = &local_up;
+ }
+
+ CheckUsedPos(kmp,up);
+ if ( up->suggest->max_rating >= WLEVEL_WARN )
+ kmp->warn_bits |= 1 << WARNSZS_ITEMPOS;
+
+ //-------------------------------------------------------------------------
+
+ const uint mask = 1 << WARNSZS_SELF_ITPH;
+ if (!(kmp->warn_bits & mask))
+ {
+ const List_t *phlist = kmp->dlist + KMP_ITPH;
+ const int n_ph = phlist->used;
+
+ if (n_ph)
+ {
+ uint i;
+ for ( i = 0; i < n_ph; i++ )
+ {
+ const kmp_itph_entry_t *ph = (kmp_itph_entry_t*)phlist->list + i;
+ if ( ph->next[0] == i && ph->pt_len == 1 )
+ {
+ kmp->warn_bits |= mask;
+ break;
+ }
+ }
+ }
+ }
+}
+
//
///////////////////////////////////////////////////////////////////////////////
/////////////// DetectSpecialKMP() ///////////////
diff --git a/project/src/lib-kmp.h b/project/src/lib-kmp.h
index c3b583c..65566c0 100644
--- a/project/src/lib-kmp.h
+++ b/project/src/lib-kmp.h
@@ -1277,6 +1277,7 @@ typedef struct kmp_t
u16 value[KMP_N_SECT+1]; // 'value' of section header
IsArena_t battle_mode; // one of ARENA_*
IndexList_t index[KMP_N_SECT]; // named indices
+ warn_bits_t warn_bits; // warning summary
char * info; // string behind last section
const u8 * max_scanned; // raw scanning: max scanned area
@@ -2123,6 +2124,7 @@ kmp_usedpos_t;
void InitializeUsedPos ( kmp_usedpos_t *up );
void CheckUsedPos ( const kmp_t *kmp, kmp_usedpos_t *up );
+void CheckWarnKMP ( kmp_t *kmp, kmp_usedpos_t *up );
//
///////////////////////////////////////////////////////////////////////////////
diff --git a/project/src/lib-lecode.c b/project/src/lib-lecode.c
index b6f52d3..b63909c 100644
--- a/project/src/lib-lecode.c
+++ b/project/src/lib-lecode.c
@@ -2305,8 +2305,15 @@ enumError LoadLPAR
raw_data_t raw;
enumError err = LoadRawData(&raw,true,fname,0,ignore_no_file,0);
- if ( !err && raw.fform == FF_LPAR )
- err = ScanTextLPAR(lpar,false,fname,raw.data,raw.data_size);
+ if (!err)
+ {
+ if ( raw.fform != FF_LPAR )
+ err = ERROR0(ERR_WRONG_FILE_TYPE,
+ "Not a LPAR file: %s:%s\n",
+ GetNameFF(raw.fform,0), raw.fname );
+ else
+ err = ScanTextLPAR(lpar,false,fname,raw.data,raw.data_size);
+ }
if ( err && use_lpar )
opt_lpar = 0;
@@ -3776,6 +3783,7 @@ enumError ScanRawDataLEX
else
ResetLEX(lex);
+ lex->fatt = raw->fatt;
lex->fname = raw->fname;
raw->fname = 0;
diff --git a/project/src/lib-mdl.c b/project/src/lib-mdl.c
index 2473aaf..b05b260 100644
--- a/project/src/lib-mdl.c
+++ b/project/src/lib-mdl.c
@@ -1714,6 +1714,7 @@ enumError ScanRawDataMDL
else
ResetMDL(mdl);
+ mdl->fatt = raw->fatt;
mdl->fname = raw->fname;
raw->fname = 0;
#if USE_NEW_CONTAINER_MDL
diff --git a/project/src/lib-pat.c b/project/src/lib-pat.c
index 62ff78b..ad3131c 100644
--- a/project/src/lib-pat.c
+++ b/project/src/lib-pat.c
@@ -1671,6 +1671,7 @@ enumError ScanRawDataPAT
else
ResetPAT(pat);
+ pat->fatt = raw->fatt;
pat->fname = raw->fname;
raw->fname = 0;
#if USE_NEW_CONTAINER_PAT
diff --git a/project/src/lib-std.c b/project/src/lib-std.c
index 3a845a0..11526cb 100644
--- a/project/src/lib-std.c
+++ b/project/src/lib-std.c
@@ -333,11 +333,31 @@ void SetupColors()
}
///////////////////////////////////////////////////////////////////////////////
+// [[2do]]
-void SetupLib ( int argc, char ** argv, ccp p_progname )
+#if defined(TEST) || defined(DEBUG)
+ #define USE_PROGINFO 2 // 0:off, 1:both, 2:new proginfo only
+ #define LOG_PROGINFO 1 // 0:off, 1:on
+#else
+ #define USE_PROGINFO 2 // 0:off, 1:both, 2:new proginfo only
+ #define LOG_PROGINFO 0 // 0:off, 1:on
+#endif
+
+//-----------------------------------------------------------------------------
+
+void SetupLib ( int argc, char ** argv, ccp tname, ccp tvers, ccp ttitle )
{
- if ( p_progname && *p_progname )
- progname = p_progname;
+ #if USE_PROGINFO
+ SetupProgname(argc,argv,tname,tvers,ttitle);
+ #else
+ if ( tname && *tname )
+ ProgInfo.progname = tname;
+ #endif
+
+ #if LOG_PROGINFO
+ PRINT1("PROG1: %s | %s | %s\n",ProgInfo.progname,ProgInfo.progdir,ProgInfo.progpath);
+ PRINT1("TOOL1: %s | %s | %s\n",ProgInfo.toolname,ProgInfo.toolversion,ProgInfo.tooltitle);
+ #endif
SetupTimezone(true);
GetTimerMSec();
@@ -357,7 +377,7 @@ void SetupLib ( int argc, char ** argv, ccp p_progname )
if (!TRACE_FILE)
{
char fname[100];
- snprintf(fname,sizeof(fname),"_trace-%s.tmp",p_progname);
+ snprintf(fname,sizeof(fname),"_trace-%s.tmp",tname);
TRACE_FILE = fopen(fname,"w");
if (!TRACE_FILE)
fprintf(stderr,"open TRACE_FILE failed: %s\n",fname);
@@ -701,16 +721,20 @@ void SetupLib ( int argc, char ** argv, ccp p_progname )
//----- setup progname
- tool_name = p_progname;
+ #if USE_PROGINFO < 2
+
+ tool_name = tname;
if ( argc > 0 && *argv && **argv )
- p_progname = *argv;
- progname = strrchr(p_progname,'/');
- progname = progname ? progname+1 : p_progname;
- //argv[0] = (char*)progname;
+ tname = *argv;
+ ProgInfo.progname = strrchr(tname,'/');
+ ProgInfo.progname = ProgInfo.progname ? ProgInfo.progname+1 : tname;
+ //argv[0] = (char*)ProgInfo.progname;
if ( !tool_name || !*tool_name )
- tool_name = progname;
+ tool_name = ProgInfo.progname;
- TRACE("##PROG## PROG-NAME=%s\n",progname);
+ TRACE("##PROG## PROG-NAME=%s\n",ProgInfo.progname);
+
+ #endif
//----- setup search_path
@@ -721,17 +745,22 @@ void SetupLib ( int argc, char ** argv, ccp p_progname )
#ifndef WIN_SZS_LIB
// determine program path
+ #if !USE_PROGINFO
char proc_path[30];
snprintf(proc_path,sizeof(proc_path),"/proc/%u/exe",getpid());
TRACE("PROC-PATH: %s\n",proc_path);
-
+ #endif
static char share[] = "/share/szs/";
static char local_share[] = "/usr/local/share/szs/";
#ifndef __CYGWIN__
share_path = local_share;
#endif
+ #if USE_PROGINFO
+ if (GetProgramPath(path,sizeof(path),true,argv[0]))
+ #else
if (readlink(proc_path,path,sizeof(path)))
+ #endif
{
// program path found!
TRACE("PROG-PATH: %s\n",path);
@@ -801,6 +830,11 @@ void SetupLib ( int argc, char ** argv, ccp p_progname )
#endif
SetupStandardSZS();
+
+ #if LOG_PROGINFO
+ PRINT1("PROG2: %s | %s | %s\n",ProgInfo.progname,ProgInfo.progdir,ProgInfo.progpath);
+ PRINT1("TOOL2: %s | %s | %s\n",ProgInfo.toolname,ProgInfo.toolversion,ProgInfo.tooltitle);
+ #endif
}
///////////////////////////////////////////////////////////////////////////////
@@ -866,7 +900,7 @@ void NormalizeOptions
if (print_title_func)
print_title_func(stdout);
- fprintf(stdlog,"PROGRAM_NAME = %s\n",progname);
+ fprintf(stdlog,"PROGRAM_NAME = %s\n",ProgInfo.progname);
if ( compatible != COMPAT_CURRENT )
fprintf(stdlog,"COMPATIBILITY = %s\n",PrintOptCompatible());
@@ -1077,6 +1111,41 @@ void InitializeOutputMode ( output_mode_t * outmode )
//
///////////////////////////////////////////////////////////////////////////////
+/////////////// warn_enum_t / warn_bits_t ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+const ccp warn_szs_name[WARNSZS__N] =
+{
+ "itempos", // WARNSZS_ITEMPOS
+ "self-it", // WARNSZS_SELF_ITPH
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+ccp GetWarnSZSNames ( warn_bits_t ws, char sep )
+{
+ static const int order[] =
+ {
+ WARNSZS_ITEMPOS,
+ WARNSZS_SELF_ITPH,
+ -1
+ };
+
+ char buf[100], *dest = buf;
+
+ const int *op;
+ for ( op = order; *op >= 0; op++ )
+ if ( 1 << *op & ws && dest < buf+sizeof(buf)-1 )
+ {
+ *dest++ = sep;
+ dest = StringCopyE(dest,buf+sizeof(buf),warn_szs_name[*op]);
+ }
+
+ return dest == buf ? EmptyString : CopyCircBuf0(buf+1,dest-buf-1);
+}
+
+//
+///////////////////////////////////////////////////////////////////////////////
/////////////// [[obsolete+]] old_container ///////////////
///////////////////////////////////////////////////////////////////////////////
// old [[container]] will be replaced by Container_t & ContainerData_t
diff --git a/project/src/lib-std.h b/project/src/lib-std.h
index b97fcc9..51e69db 100644
--- a/project/src/lib-std.h
+++ b/project/src/lib-std.h
@@ -94,7 +94,8 @@
///////////////////////////////////////////////////////////////////////////////
void SetupColors();
-void SetupLib ( int argc, char ** argv, ccp p_progname );
+void SetupLib ( int argc, char ** argv, ccp tname, ccp tvers, ccp ttitle );
+
void NormalizeOptions
(
uint log_level // 0: no log
@@ -199,6 +200,26 @@ extern const char WarnLevelNameUp[WLEVEL__N][8]; // upper case
//
///////////////////////////////////////////////////////////////////////////////
+/////////////// warn_enum_t ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[warn_enum_t]] [[warn_bits_t]]
+// order is important, compare warn_szs_name[] and ct.wiimm.de "warning bits"
+
+typedef enum warn_enum_t
+{
+ WARNSZS_ITEMPOS, // item-pos bug
+ WARNSZS_SELF_ITPH, // self linked ITPT route
+ WARNSZS__N
+}
+warn_enum_t;
+
+typedef uint warn_bits_t;
+
+extern const ccp warn_szs_name[WARNSZS__N];
+ccp GetWarnSZSNames ( warn_bits_t ws, char sep );
+
+//
+///////////////////////////////////////////////////////////////////////////////
/////////////// sub file system ///////////////
///////////////////////////////////////////////////////////////////////////////
// [[SubFile_t]]
@@ -2156,7 +2177,6 @@ extern const u8 TestDataLEX[8*1];
///////////////////////////////////////////////////////////////////////////////
extern ccp tool_name;
-extern ccp progname;
extern ccp share_path;
extern ccp search_path[];
extern ccp auto_add_path[6];
diff --git a/project/src/lib-szs-create.c b/project/src/lib-szs-create.c
index 36d8516..1907542 100644
--- a/project/src/lib-szs-create.c
+++ b/project/src/lib-szs-create.c
@@ -808,16 +808,12 @@ enumError CreateSZS
{
StringCopyE( sd.path_rel, sd.path+sizeof(sd.path), *ptr );
struct stat st;
+ #if USE_NEW_FILEATTRIB
+ if ( stat(sd.path,&st) || CompareTimeSpec(&st.st_mtim,&szs.fatt.mtime) < 0 )
+ #else
const time_t mtime = stat(sd.path,&st) ? 0 : st.st_mtime;
-#if 0
- BINGO;
- printf("mtime: %u - %u = %d [%s>%s>] size=%zu,%zu\n",
- (uint)mtime, (uint)szs.fatt.mtime, (int)(mtime-szs.fatt.mtime),
- GetNameFF(setup_param2.fform_file,setup_param2.fform_arch),
- GetNameFF(szs.fform_file,szs.fform_arch),
- szs.size, szs.csize );
-#endif
if ( mtime < szs.fatt.mtime )
+ #endif
{
const bool is_compressed = IsCompressedFF(setup_param2.fform_file);
if (is_compressed)
@@ -1007,7 +1003,8 @@ enumError LoadCreateSZS
}
enumError err = LoadSZS(szs,fname,decompress,ignore_no_file,mark_readonly);
- PatchSZS(szs);
+ if ( err <= ERR_WARNING )
+ PatchSZS(szs);
return err;
}
@@ -3643,6 +3640,10 @@ static int check_brres
print_check_error( chk, CMOD_HINT,
"Unusual %s version %d: %s\n",
GetNameFF(0,fform), version, it->path );
+ else if ( bi->warn >= BIMD_INFO )
+ print_check_error( chk, CMOD_INFO,
+ "Unusual %s version %d: %s\n",
+ GetNameFF(0,fform), version, it->path );
}
return 0;
}
@@ -3710,6 +3711,18 @@ static void set_required_slot
///////////////////////////////////////////////////////////////////////////////
+static void dump_slots ( int stat, int *slot, ccp info )
+{
+ printf(">> stat=%d:",stat);
+ uint i;
+ for ( i = 0; i < 32; i++ )
+ printf("%s%c", i&3 ? "" : " ",
+ slot[i] < 0 ? '-' : slot[i] > 0 ? '+' : '.' );
+ printf(" : %s\n",info);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
int FindSlotsSZS
(
// returns -1, 0 or +1
@@ -3792,7 +3805,6 @@ int FindSlotsSZS
*required_slot = 31;
}
-
//--- analyze slot 4.2
if ( !szs->slot_42 || szs->moonview_mdl_stat < 2 )
@@ -3818,6 +3830,7 @@ int FindSlotsSZS
else if ( !SLOT(6,1) && szs->have_ice_brres )
SLOT(6,1) = 1;
+
//--- analyze slot 6.2
if (szs->slot_62)
@@ -3835,6 +3848,8 @@ int FindSlotsSZS
if (!SLOT(6,1)) SLOT(6,1) = -1;
if (!SLOT(6,2)) SLOT(6,2) = -1;
+
+ //dump_slots(stat,slot,"END");
return stat;
}
@@ -3860,10 +3875,12 @@ void AnalyzeSlot ( slot_ana_t *sa, szs_file_t *szs )
static char buf[500];
char *dest = buf;
- uint i;
+ uint i, allow = 0;
for ( i = 0; i < MKW_N_TRACKS; i++ )
{
const int slot = sa->slot[i];
+ if ( slot >= 0 )
+ allow++;
if ( slot != sa->stat )
{
if ( dest > buf )
@@ -3874,6 +3891,9 @@ void AnalyzeSlot ( slot_ana_t *sa, szs_file_t *szs )
}
}
+ if (!allow)
+ dest = StringCopyS(buf,sizeof(buf),"none");
+
if ( dest == buf )
*dest++ = '%';
*dest = 0;
diff --git a/project/src/lib-szs.c b/project/src/lib-szs.c
index 43b9268..748c9a3 100644
--- a/project/src/lib-szs.c
+++ b/project/src/lib-szs.c
@@ -49,6 +49,7 @@
#include "lib-image.h"
#include "lib-bzip2.h"
#include "lib-checksum.h"
+#include "crypt.h"
//
///////////////////////////////////////////////////////////////////////////////
@@ -2103,7 +2104,7 @@ void PrintVersionSZS ( char *buf, uint buf_size, struct szs_iterator_t *it )
if ( !bi || bi->warn >= BIMD_FAIL )
snprintf(buf,buf_size,"%s%3d!%s",
colout->fatal, vers, colout->reset );
- else if ( bi->warn >= BIMD_HINT )
+ else if ( bi->warn >= BIMD_INFO )
snprintf(buf,buf_size,"%s%3d %s",
colout->hint, vers, colout->reset );
else
@@ -4414,6 +4415,304 @@ enumError DiffSZS
//
///////////////////////////////////////////////////////////////////////////////
+/////////////// analyse_szs_t ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+void InitializeAnalyseSZS ( analyse_szs_t * as )
+{
+ #ifdef DEBUG
+ static bool done = false;
+ if (!done)
+ {
+ done = true;
+ TRACE_SIZEOF(analyse_szs_t);
+ TRACE_SIZEOF(lex_info_t);
+ TRACE_SIZEOF(slot_ana_t);
+ TRACE_SIZEOF(slot_info_t);
+ TRACE_SIZEOF(kmp_finish_t);
+ TRACE_SIZEOF(kmp_usedpos_t);
+ TRACE("-\n");
+ }
+ #endif
+
+ DASSERT(as);
+ memset(as,0,sizeof(*as));
+
+ InitializeLexInfo(&as->lexinfo);
+ InitializeFinishLine(&as->kmp_finish);
+ InitializeUsedPos(&as->used_pos);
+
+ as->ckpt0_count = -1; // number of LC in CKPT
+ as->lap_count = 3; // STGI lap counter
+ as->speed_factor = 1.0; // STGI speed factor
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void ResetAnalyseSZS ( analyse_szs_t * as )
+{
+ if (as)
+ {
+ ResetLexInfo(&as->lexinfo);
+ InitializeAnalyseSZS(as);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void AnalyseSZS
+(
+ analyse_szs_t *as, // result
+ bool init_sa, // true: init 'as', false: reset 'as'
+ szs_file_t *szs, // SZS filre t analysze
+ ccp fname // NULL or fname for slot analysis
+)
+{
+ //--- setup
+
+ const u_usec_t start_usec = GetTimerUSec();
+
+ DASSERT(as);
+ if (init_sa)
+ InitializeAnalyseSZS(as);
+ else
+ ResetAnalyseSZS(as);
+
+ if (!szs)
+ return;
+
+ char *ct_dest = as->ct_attrib;
+ char *ct_end = as->ct_attrib + sizeof(as->ct_attrib);
+
+
+ //--- checksums
+
+ sha1_size_t sha1_data;
+ SHA1(szs->data,szs->size,sha1_data.hash);
+ Sha1Bin2Hex(as->sha1_szs,sha1_data.hash);
+ memcpy(as->sha1_szs_norm,as->sha1_szs,sizeof(as->sha1_szs_norm));
+
+ sha1_data.size = htonl(szs->size);
+ CreateSSChecksumDB(as->db64,sizeof(as->db64),&sha1_data);
+ FindSpecialFilesSZS(szs,false);
+
+
+ //--- scan LEX
+
+ InitializeLexInfo(&as->lexinfo);
+
+ if (szs->course_lex_data)
+ {
+ lex_t lex;
+ InitializeLEX(&lex);
+ ScanLEX(&lex,false,szs->course_lex_data,szs->course_lex_size);
+ szs->have_lex = lex.have_lex;
+ SetupLexInfo(&as->lexinfo,&lex);
+ ResetLEX(&lex);
+ }
+
+
+ //--- scan slots
+
+ AnalyzeSlot(&as->slotana,szs);
+ if (fname)
+ AnalyzeSlotByName(&as->slotinfo,true,MemByString(fname));
+ if (as->slotana.mandatory_slot[0])
+ AnalyzeSlotAttrib(&as->slotinfo,false,MemByString(as->slotana.mandatory_slot));
+ FinalizeSlotInfo(&as->slotinfo,true);
+ if (*as->slotinfo.slot_attrib)
+ ct_dest = StringCat2E(ct_dest,ct_end,",",as->slotinfo.slot_attrib);
+
+
+ //--- scan KMP
+
+ if (szs->course_kmp_data)
+ {
+ SHA1(szs->course_kmp_data,szs->course_kmp_size,sha1_data.hash);
+ Sha1Bin2Hex(as->sha1_kmp,sha1_data.hash);
+ memcpy(as->sha1_kmp_norm,as->sha1_kmp,sizeof(as->sha1_kmp_norm));
+
+ kmp_t kmp;
+ InitializeKMP(&kmp);
+ kmp.lexinfo = &as->lexinfo;
+ const enumError err
+ = ScanKMP(&kmp,false,szs->course_kmp_data,szs->course_kmp_size,0);
+ if ( err <= ERR_WARNING )
+ {
+ if (kmp.stgi)
+ {
+ kmp_stgi_entry_t *stgi = (kmp_stgi_entry_t*)kmp.stgi;
+ as->lap_count = stgi->lap_count;
+ as->speed_mod = stgi->speed_mod;
+ stgi->lap_count = 3;
+ stgi->speed_mod = 0;
+
+ SHA1(szs->data,szs->size,sha1_data.hash);
+ Sha1Bin2Hex(as->sha1_szs_norm,sha1_data.hash);
+
+ SHA1(szs->course_kmp_data,szs->course_kmp_size,sha1_data.hash);
+ Sha1Bin2Hex(as->sha1_kmp_norm,sha1_data.hash);
+
+ stgi->lap_count = as->lap_count;
+ stgi->speed_mod = as->speed_mod;
+ }
+
+ CheckFinishLine(&kmp,&as->kmp_finish);
+ CheckWarnKMP(&kmp,&as->used_pos);
+ szs->warn_bits |= kmp.warn_bits;
+
+ const uint n_ckpt = kmp.dlist[KMP_CKPT].used;
+ if (n_ckpt)
+ {
+ const kmp_ckpt_entry_t *ckpt
+ = (kmp_ckpt_entry_t*)kmp.dlist[KMP_CKPT].list;
+ uint i;
+ as->ckpt0_count = 0;
+ for ( i = 0; i < n_ckpt; i++, ckpt++ )
+ if (!ckpt->mode)
+ as->ckpt0_count++;
+ }
+
+ const kmp_stgi_entry_t *stgi = (kmp_stgi_entry_t*)kmp.dlist[KMP_STGI].list;
+ if ( kmp.dlist[KMP_STGI].used > 0 )
+ {
+ as->lap_count = stgi->lap_count;
+ if (!szs->is_arena)
+ {
+ if ( as->ckpt0_count > 1 )
+ {
+ if ( as->lap_count == 1 )
+ ct_dest = StringCopyE(ct_dest,ct_end,",1lap");
+ ct_dest = snprintfE(ct_dest,ct_end,",%ulc",as->ckpt0_count);
+ }
+ else if ( as->lap_count != 0 && as->lap_count != 3 )
+ ct_dest = snprintfE(ct_dest,ct_end,",%ulap%s",
+ as->lap_count, as->lap_count == 1 ? "" : "s" );
+ }
+
+ if (stgi->speed_mod)
+ {
+ as->speed_mod = stgi->speed_mod;
+ as->speed_factor = SpeedMod2float(stgi->speed_mod);
+ char buf[20];
+ snprintf(buf,sizeof(buf),",x%4.2f",as->speed_factor);
+ char *ptr = buf + strlen(buf) - 1;
+ while ( *ptr == '0' )
+ *ptr-- = 0;
+ if ( *ptr == '.' )
+ *ptr = 0;
+ if ( strcmp(buf,",x0") && strcmp(buf,",x1") )
+ ct_dest = StringCopyE(ct_dest,ct_end,buf);
+ }
+ }
+ else if ( !szs->is_arena && as->ckpt0_count > 1 )
+ ct_dest = snprintfE(ct_dest,ct_end,",%ulc",as->ckpt0_count);
+
+ if ( as->kmp_finish.n_ktpt_m > 1 )
+ ct_dest = StringCopyE(ct_dest,ct_end,",2ktpt");
+
+ kmp_ana_pflag_t ap;
+ AnalysePFlagScenarios(&ap,&kmp,GMD_M_DEFAULT);
+ snprintf(as->gobj_info,sizeof(as->gobj_info),"%d %d %d %d",
+ ap.ag.n_gobj, ap.n_version, ap.n_res_std, ap.n_res_ext );
+ ResetPFlagScenarios(&ap);
+ }
+
+ DetectSpecialKMP(&kmp,szs->kmp_special);
+ if ( szs->kmp_special[HAVEKMP_WOODBOX_HT]
+ || szs->kmp_special[HAVEKMP_MUSHROOM_CAR]
+ || szs->kmp_special[HAVEKMP_PENGUIN_POS]
+ || szs->kmp_special[HAVEKMP_EPROP_SPEED]
+ )
+ {
+ ct_dest = StringCopyE(ct_dest,ct_end,",gobj");
+ }
+
+ if ( szs->kmp_special[HAVEKMP_X_PFLAGS]
+ || szs->kmp_special[HAVEKMP_X_COND]
+ || szs->kmp_special[HAVEKMP_X_DEFOBJ]
+ || szs->kmp_special[HAVEKMP_X_RANDOM]
+ )
+ {
+ ct_dest = StringCopyE(ct_dest,ct_end,",xpf");
+ }
+
+ ResetKMP(&kmp);
+ }
+
+ if ( szs->szs_special[HAVESZS_ITEM_SLOT_TABLE] )
+ ct_dest = StringCopyE(ct_dest,ct_end,",itemslot");
+
+ if ( szs->szs_special[HAVESZS_OBJFLOW] )
+ ct_dest = StringCopyE(ct_dest,ct_end,",objflow");
+
+ if ( szs->szs_special[HAVESZS_GHT_ITEM]
+ || szs->szs_special[HAVESZS_GHT_ITEM_OBJ]
+ || szs->szs_special[HAVESZS_GHT_KART]
+ || szs->szs_special[HAVESZS_GHT_KART_OBJ]
+ )
+ {
+ ct_dest = StringCopyE(ct_dest,ct_end,",geohit");
+ }
+
+ if ( szs->szs_special[HAVESZS_MINIGAME] )
+ ct_dest = StringCopyE(ct_dest,ct_end,",minigame");
+
+
+ //--- scan KCL
+
+ if (szs->course_kcl_data)
+ {
+ SHA1(szs->course_kcl_data,szs->course_kcl_size,sha1_data.hash);
+ Sha1Bin2Hex(as->sha1_kcl,sha1_data.hash);
+ }
+
+
+ //--- course model (course_model.brres, course_d_model.brres)
+
+ if (szs->course_model_data)
+ {
+ SHA1(szs->course_model_data,szs->course_model_size,sha1_data.hash);
+ Sha1Bin2Hex(as->sha1_course,sha1_data.hash);
+ }
+ else if (szs->course_d_model_data)
+ {
+ SHA1(szs->course_d_model_data,szs->course_d_model_size,sha1_data.hash);
+ Sha1Bin2Hex(as->sha1_course,sha1_data.hash);
+ }
+
+
+ //--- vrcorn (vrcorn_model.brres)
+
+ if (szs->vrcorn_model_data)
+ {
+ SHA1(szs->vrcorn_model_data,szs->vrcorn_model_size,sha1_data.hash);
+ Sha1Bin2Hex(as->sha1_vrcorn,sha1_data.hash);
+ }
+
+
+ //--- minimap (map_model.brres)
+
+ if (szs->map_model_data)
+ {
+ SHA1(szs->map_model_data,szs->map_model_size,sha1_data.hash);
+ Sha1Bin2Hex(as->sha1_minimap,sha1_data.hash);
+ }
+
+
+ //--- finalize ct_attrib by "lex" and "warn"
+
+ if (szs->course_lex_data)
+ ct_dest = StringCopyE(ct_dest,ct_end,",lex");
+
+ if (szs->warn_bits)
+ ct_dest = StringCat2E(ct_dest,ct_end,",warn=",GetWarnSZSNames(szs->warn_bits,'+'));
+
+ as->duration_usec = GetTimerUSec() - start_usec;
+}
+
+//
+///////////////////////////////////////////////////////////////////////////////
/////////////// string_pool_t ///////////////
///////////////////////////////////////////////////////////////////////////////
diff --git a/project/src/lib-szs.h b/project/src/lib-szs.h
index 8908bf1..eff7eed 100644
--- a/project/src/lib-szs.h
+++ b/project/src/lib-szs.h
@@ -55,6 +55,8 @@
#include "lib-std.h"
#include "lib-object.h"
#include "lib-lecode.h"
+#include "lib-checksum.h"
+#include "lib-kmp.h"
#include "db-mkw.h"
//
@@ -406,6 +408,7 @@ typedef struct szs_file_t
// 2: all materials found
// 3: all materials found & content ok
+ warn_bits_t warn_bits; // warning summary
bool szs_special[HAVESZS__N]; // true: special file found
kmp_special_t kmp_special; // list: >0: number of special KMP objects found
uint have_lex; // bit field for found lex eleemnts
@@ -1271,6 +1274,65 @@ enumError CompressBZ ( szs_file_t * szs, bool remove_uncompressed );
//
///////////////////////////////////////////////////////////////////////////////
+/////////////// analyse_szs_t ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[analyse_szs_t]]
+
+typedef struct analyse_szs_t
+{
+
+ //--- db+sha1 check sums
+
+ char db64[CHECKSUM_DB_SIZE+1];
+ // DB64 checksum
+ sha1_hex_t sha1_szs; // SHA1 of SZS file
+ sha1_hex_t sha1_szs_norm; // SHA1 of normed SZS file
+ sha1_hex_t sha1_kmp; // SHA1 of KMP file
+ sha1_hex_t sha1_kmp_norm; // SHA1 of normed KMP file
+ sha1_hex_t sha1_kcl; // SHA1 of KCL file
+ sha1_hex_t sha1_course; // SHA1 of course-model
+ sha1_hex_t sha1_vrcorn; // SHA1 of vrcorn
+ sha1_hex_t sha1_minimap; // SHA1 of minimap
+
+
+ //--- sub files
+
+ lex_info_t lexinfo; // LEX info
+ slot_ana_t slotana; // slot data
+ slot_info_t slotinfo; // slot data
+ kmp_finish_t kmp_finish; // finish line
+ kmp_usedpos_t used_pos; // used positions
+
+
+ //--- more stats
+
+ int ckpt0_count; // number of LC in CKPT, -1 unknown
+ int lap_count; // STGI lap counter
+ u16 speed_mod; // STGI speed mod
+ float speed_factor; // STGI speed factor
+
+ char gobj_info[20]; // gobj counters
+ char ct_attrib[300]; // collected ct attributes
+
+ u_usec_t duration_usec; // duration of AnalyseSZS() in usec
+}
+analyse_szs_t;
+
+//-----------------------------------------------------------------------------
+
+void InitializeAnalyseSZS ( analyse_szs_t * as );
+void ResetAnalyseSZS ( analyse_szs_t * as );
+
+void AnalyseSZS
+(
+ analyse_szs_t *as, // result
+ bool init_sa, // true: init 'as', false: reset 'as'
+ szs_file_t *szs, // SZS filre t analysze
+ ccp fname // NULL or fname for slot analysis
+);
+
+//
+///////////////////////////////////////////////////////////////////////////////
/////////////// END ///////////////
///////////////////////////////////////////////////////////////////////////////
diff --git a/project/src/lib-xbmg.c b/project/src/lib-xbmg.c
index 3f5417e..2648091 100644
--- a/project/src/lib-xbmg.c
+++ b/project/src/lib-xbmg.c
@@ -370,6 +370,7 @@ enumError ScanRawDataBMG
ResetBMG(bmg);
if (!raw->data)
return ERR_OK;
+ bmg->fatt = raw->fatt;
if (IsArchiveFF(raw->fform))
{
diff --git a/project/src/wbmgt.c b/project/src/wbmgt.c
index 3750bce..87ba3ce 100644
--- a/project/src/wbmgt.c
+++ b/project/src/wbmgt.c
@@ -154,11 +154,11 @@ static void hint_exit ( enumError stat )
if ( current_command )
fprintf(stderr,
"-> Type '%s help %s' (pipe it to a pager like 'less') for more help.\n\n",
- progname, CommandInfo[current_command->id].name1 );
+ ProgInfo.progname, CommandInfo[current_command->id].name1 );
else
fprintf(stderr,
"-> Type '%s -h' or '%s help' (pipe it to a pager like 'less') for more help.\n\n",
- progname, progname );
+ ProgInfo.progname, ProgInfo.progname );
exit(stat);
}
@@ -862,7 +862,7 @@ static enumError CheckOptions ( int argc, char ** argv, bool is_env )
NormalizeOptions( verbose > 3 && !is_env ? 2 : 0 );
SetupBMG(filter_bmg);
- return !err ? ERR_OK : max_error ? max_error : ERR_SYNTAX;
+ return !err ? ERR_OK : ProgInfo.max_error ? ProgInfo.max_error : ERR_SYNTAX;
}
//
@@ -951,7 +951,7 @@ static enumError CheckCommand ( int argc, char ** argv )
#endif
{
print_title_func = print_title;
- SetupLib(argc,argv,WBMGT_SHORT);
+ SetupLib(argc,argv,WBMGT_SHORT,VERSION,TITLE);
//----- process arguments
diff --git a/project/src/wctct.c b/project/src/wctct.c
index cf34003..6f1db93 100644
--- a/project/src/wctct.c
+++ b/project/src/wctct.c
@@ -144,11 +144,11 @@ static void hint_exit ( enumError stat )
if ( current_command )
fprintf(stderr,
"-> Type '%s help %s' (pipe it to a pager like 'less') for more help.\n\n",
- progname, CommandInfo[current_command->id].name1 );
+ ProgInfo.progname, CommandInfo[current_command->id].name1 );
else
fprintf(stderr,
"-> Type '%s -h' or '%s help' (pipe it to a pager like 'less') for more help.\n\n",
- progname, progname );
+ ProgInfo.progname, ProgInfo.progname );
exit(stat);
}
@@ -866,7 +866,7 @@ static enumError CheckOptions ( int argc, char ** argv, bool is_env )
SetupBMG(filter_bmg);
UsePatchingListBMG(&opt_load_bmg);
- return !err ? ERR_OK : max_error ? max_error : ERR_SYNTAX;
+ return !err ? ERR_OK : ProgInfo.max_error ? ProgInfo.max_error : ERR_SYNTAX;
}
//
@@ -958,7 +958,7 @@ static enumError CheckCommand ( int argc, char ** argv )
#endif
{
print_title_func = print_title;
- SetupLib(argc,argv,WCTCT_SHORT);
+ SetupLib(argc,argv,WCTCT_SHORT,VERSION,TITLE);
ctcode_enabled = true;
//----- process arguments
diff --git a/project/src/wimgt.c b/project/src/wimgt.c
index c4126e1..4acb1c1 100644
--- a/project/src/wimgt.c
+++ b/project/src/wimgt.c
@@ -150,11 +150,11 @@ static void hint_exit ( enumError stat )
if ( current_command )
fprintf(stderr,
"-> Type '%s help %s' (pipe it to a pager like 'less') for more help.\n\n",
- progname, CommandInfo[current_command->id].name1 );
+ ProgInfo.progname, CommandInfo[current_command->id].name1 );
else
fprintf(stderr,
"-> Type '%s -h' or '%s help' (pipe it to a pager like 'less') for more help.\n\n",
- progname, progname );
+ ProgInfo.progname, ProgInfo.progname );
exit(stat);
}
@@ -669,7 +669,7 @@ static enumError CheckOptions ( int argc, char ** argv, bool is_env )
#endif
NormalizeOptions( verbose > 3 && !is_env ? 2 : 0 );
- return !err ? ERR_OK : max_error ? max_error : ERR_SYNTAX;
+ return !err ? ERR_OK : ProgInfo.max_error ? ProgInfo.max_error : ERR_SYNTAX;
}
//
@@ -752,7 +752,7 @@ static enumError CheckCommand ( int argc, char ** argv )
#endif
{
print_title_func = print_title;
- SetupLib(argc,argv,WIMGT_SHORT);
+ SetupLib(argc,argv,WIMGT_SHORT,VERSION,TITLE);
//----- process arguments
diff --git a/project/src/wkclt.c b/project/src/wkclt.c
index bd2b7fe..49f5742 100644
--- a/project/src/wkclt.c
+++ b/project/src/wkclt.c
@@ -144,11 +144,11 @@ static void hint_exit ( enumError stat )
if ( current_command )
fprintf(stderr,
"-> Type '%s help %s' (pipe it to a pager like 'less') for more help.\n\n",
- progname, CommandInfo[current_command->id].name1 );
+ ProgInfo.progname, CommandInfo[current_command->id].name1 );
else
fprintf(stderr,
"-> Type '%s -h' or '%s help' (pipe it to a pager like 'less') for more help.\n\n",
- progname, progname );
+ ProgInfo.progname, ProgInfo.progname );
exit(stat);
}
@@ -1226,7 +1226,7 @@ static enumError CheckOptions ( int argc, char ** argv, bool is_env )
NormalizeOptions( verbose > 3 && !is_env ? 2 : 0 );
SetupKCL();
- return !err ? ERR_OK : max_error ? max_error : ERR_SYNTAX;
+ return !err ? ERR_OK : ProgInfo.max_error ? ProgInfo.max_error : ERR_SYNTAX;
}
//
@@ -1323,7 +1323,7 @@ static enumError CheckCommand ( int argc, char ** argv )
#endif
{
print_title_func = print_title;
- SetupLib(argc,argv,WKCLT_SHORT);
+ SetupLib(argc,argv,WKCLT_SHORT,VERSION,TITLE);
//----- process arguments
diff --git a/project/src/wkmpt.c b/project/src/wkmpt.c
index baf73ec..b2bb4ee 100644
--- a/project/src/wkmpt.c
+++ b/project/src/wkmpt.c
@@ -145,11 +145,11 @@ static void hint_exit ( enumError stat )
if ( current_command )
fprintf(stderr,
"-> Type '%s help %s' (pipe it to a pager like 'less') for more help.\n\n",
- progname, CommandInfo[current_command->id].name1 );
+ ProgInfo.progname, CommandInfo[current_command->id].name1 );
else
fprintf(stderr,
"-> Type '%s -h' or '%s help' (pipe it to a pager like 'less') for more help.\n\n",
- progname, progname );
+ ProgInfo.progname, ProgInfo.progname );
exit(stat);
}
@@ -1705,7 +1705,7 @@ static enumError CheckOptions ( int argc, char ** argv, bool is_env )
SetupKCL();
SetupKMP();
- return !err ? ERR_OK : max_error ? max_error : ERR_SYNTAX;
+ return !err ? ERR_OK : ProgInfo.max_error ? ProgInfo.max_error : ERR_SYNTAX;
}
//
@@ -1802,7 +1802,7 @@ static enumError CheckCommand ( int argc, char ** argv )
#endif
{
print_title_func = print_title;
- SetupLib(argc,argv,WKMPT_SHORT);
+ SetupLib(argc,argv,WKMPT_SHORT,VERSION,TITLE);
//----- process arguments
diff --git a/project/src/wlect.c b/project/src/wlect.c
index 5794e6a..373cd27 100644
--- a/project/src/wlect.c
+++ b/project/src/wlect.c
@@ -146,11 +146,11 @@ static void hint_exit ( enumError stat )
if ( current_command )
fprintf(stderr,
"-> Type '%s help %s' (pipe it to a pager like 'less') for more help.\n\n",
- progname, CommandInfo[current_command->id].name1 );
+ ProgInfo.progname, CommandInfo[current_command->id].name1 );
else
fprintf(stderr,
"-> Type '%s -h' or '%s help' (pipe it to a pager like 'less') for more help.\n\n",
- progname, progname );
+ ProgInfo.progname, ProgInfo.progname );
exit(stat);
}
@@ -377,7 +377,9 @@ static enumError LoadLECODE ( raw_data_t *raw, le_analyse_t *ana, ccp fname )
if ( raw->fform != FF_LE_BIN )
{
- err = ERROR0(ERR_WRONG_FILE_TYPE,"Not a LECODE binary file: %s\n",raw->fname);
+ err = ERROR0(ERR_WRONG_FILE_TYPE,
+ "Not a LECODE binary file: %s:%s\n",
+ GetNameFF(raw->fform,0), raw->fname);
goto abort;
}
@@ -1172,7 +1174,7 @@ static enumError CheckOptions ( int argc, char ** argv, bool is_env )
SetupBMG(0);
UsePatchingListBMG(&opt_load_bmg);
- return !err ? ERR_OK : max_error ? max_error : ERR_SYNTAX;
+ return !err ? ERR_OK : ProgInfo.max_error ? ProgInfo.max_error : ERR_SYNTAX;
}
//
@@ -1264,7 +1266,7 @@ static enumError CheckCommand ( int argc, char ** argv )
#endif
{
print_title_func = print_title;
- SetupLib(argc,argv,WLECT_SHORT);
+ SetupLib(argc,argv,WLECT_SHORT,VERSION,TITLE);
ctcode_enabled = true;
lecode_enabled = true;
diff --git a/project/src/wmdlt.c b/project/src/wmdlt.c
index 892c724..fcfc034 100644
--- a/project/src/wmdlt.c
+++ b/project/src/wmdlt.c
@@ -139,11 +139,11 @@ static void hint_exit ( enumError stat )
if ( current_command )
fprintf(stderr,
"-> Type '%s help %s' (pipe it to a pager like 'less') for more help.\n\n",
- progname, CommandInfo[current_command->id].name1 );
+ ProgInfo.progname, CommandInfo[current_command->id].name1 );
else
fprintf(stderr,
"-> Type '%s -h' or '%s help' (pipe it to a pager like 'less') for more help.\n\n",
- progname, progname );
+ ProgInfo.progname, ProgInfo.progname );
exit(stat);
}
@@ -636,7 +636,7 @@ static enumError CheckOptions ( int argc, char ** argv, bool is_env )
NormalizeOptions( verbose > 3 && !is_env ? 2 : 0 );
SetupMDL();
- return !err ? ERR_OK : max_error ? max_error : ERR_SYNTAX;
+ return !err ? ERR_OK : ProgInfo.max_error ? ProgInfo.max_error : ERR_SYNTAX;
}
//
@@ -724,7 +724,7 @@ static enumError CheckCommand ( int argc, char ** argv )
#endif
{
print_title_func = print_title;
- SetupLib(argc,argv,WMDLT_SHORT);
+ SetupLib(argc,argv,WMDLT_SHORT,VERSION,TITLE);
//----- process arguments
diff --git a/project/src/wpatt.c b/project/src/wpatt.c
index fd65bca..dbcdc7c 100644
--- a/project/src/wpatt.c
+++ b/project/src/wpatt.c
@@ -139,11 +139,11 @@ static void hint_exit ( enumError stat )
if ( current_command )
fprintf(stderr,
"-> Type '%s help %s' (pipe it to a pager like 'less') for more help.\n\n",
- progname, CommandInfo[current_command->id].name1 );
+ ProgInfo.progname, CommandInfo[current_command->id].name1 );
else
fprintf(stderr,
"-> Type '%s -h' or '%s help' (pipe it to a pager like 'less') for more help.\n\n",
- progname, progname );
+ ProgInfo.progname, ProgInfo.progname );
exit(stat);
}
@@ -430,7 +430,7 @@ static enumError CheckOptions ( int argc, char ** argv, bool is_env )
if (!err)
WarnDepractedOptions(&InfoUI_wpatt);
- return !err ? ERR_OK : max_error ? max_error : ERR_SYNTAX;
+ return !err ? ERR_OK : ProgInfo.max_error ? ProgInfo.max_error : ERR_SYNTAX;
}
//
@@ -514,7 +514,7 @@ static enumError CheckCommand ( int argc, char ** argv )
#endif
{
print_title_func = print_title;
- SetupLib(argc,argv,WPATT_SHORT);
+ SetupLib(argc,argv,WPATT_SHORT,VERSION,TITLE);
//----- process arguments
diff --git a/project/src/wstrt.c b/project/src/wstrt.c
index 6901ec3..a384f45 100644
--- a/project/src/wstrt.c
+++ b/project/src/wstrt.c
@@ -151,11 +151,11 @@ static void hint_exit ( enumError stat )
if ( current_command )
fprintf(stderr,
"-> Type '%s help %s' (pipe it to a pager like 'less') for more help.\n\n",
- progname, CommandInfo[current_command->id].name1 );
+ ProgInfo.progname, CommandInfo[current_command->id].name1 );
else
fprintf(stderr,
"-> Type '%s -h' or '%s help' (pipe it to a pager like 'less') for more help.\n\n",
- progname, progname );
+ ProgInfo.progname, ProgInfo.progname );
exit(stat);
}
@@ -1349,7 +1349,7 @@ static enumError CheckOptions ( int argc, char ** argv, bool is_env )
if ( opt_wcode >= WCODE_ON && opt_gct_move < OFFON_FORCE )
opt_gct_move = OFFON_FORCE;
}
- return !err ? ERR_OK : max_error ? max_error : ERR_SYNTAX;
+ return !err ? ERR_OK : ProgInfo.max_error ? ProgInfo.max_error : ERR_SYNTAX;
}
//
@@ -1442,7 +1442,7 @@ static enumError CheckCommand ( int argc, char ** argv )
#endif
{
print_title_func = print_title;
- SetupLib(argc,argv,WSTRT_SHORT);
+ SetupLib(argc,argv,WSTRT_SHORT,VERSION,TITLE);
//----- process arguments
diff --git a/project/src/wszst.c b/project/src/wszst.c
index 895357f..7ca33f1 100644
--- a/project/src/wszst.c
+++ b/project/src/wszst.c
@@ -245,11 +245,11 @@ static void hint_exit ( enumError stat )
if ( current_command )
fprintf(stderr,
"-> Type '%s help %s' (pipe it to a pager like 'less') for more help.\n\n",
- progname, CommandInfo[current_command->id].name1 );
+ ProgInfo.progname, CommandInfo[current_command->id].name1 );
else
fprintf(stderr,
"-> Type '%s -h' or '%s help' (pipe it to a pager like 'less') for more help.\n\n",
- progname, progname );
+ ProgInfo.progname, ProgInfo.progname );
exit(stat);
}
@@ -1066,6 +1066,7 @@ static int check_brsub
"%sOk %s", colout->success, colout->reset );
break;
+ case BIMD_INFO:
case BIMD_HINT:
err = ERR_INVALID_VERSION;
print_status = cb->mode > 0;
@@ -1180,6 +1181,7 @@ enumError cmd_brsub()
fputs("-\n",stdout);
break;
+ case BIMD_INFO:
case BIMD_HINT:
printf("%sUNUSUAL%s\n",colout->hint,colout->reset);
break;
@@ -1804,7 +1806,11 @@ static enumError cmd_sha1()
{
if (long_count>1)
{
+ #if USE_NEW_FILEATTRIB
+ struct tm * tm = localtime(&szs.fatt.mtime.tv_sec);
+ #else
struct tm * tm = localtime(&szs.fatt.mtime);
+ #endif
char timbuf[40];
strftime(timbuf,sizeof(timbuf),"%F %T ",tm);
fputs(timbuf,stdout);
@@ -1885,6 +1891,9 @@ static enumError cmd_analyze()
szs_file_t szs;
InitializeSZS(&szs);
+ analyse_szs_t as;
+ InitializeAnalyseSZS(&as);
+
File_t fo;
InitializeFile(&fo);
@@ -1901,8 +1910,12 @@ static enumError cmd_analyze()
enumError err = LoadCreateSZS(&szs,param->arg,true,opt_ignore>0,true);
if ( err == ERR_NOT_EXISTS || err > ERR_WARNING && opt_ignore )
continue;
- if ( max_err < err )
- max_err = err;
+ if ( err > ERR_WARNING )
+ {
+ if ( max_err < err )
+ max_err = err;
+ continue;
+ }
if (!fo.f)
SubstDest(dest,sizeof(dest),param->arg,opt_dest,def_path,
@@ -1918,246 +1931,9 @@ static enumError cmd_analyze()
}
- //--- checksums
-
- sha1_size_t info;
- SHA1(szs.data,szs.size,info.hash);
- info.size = htonl(szs.size);
- sha1_hex_t sha1, sha1_norm;
- Sha1Bin2Hex(sha1,info.hash);
- memcpy(sha1_norm,sha1,sizeof(sha1_norm));
-
- char db64[CHECKSUM_DB_SIZE+1];
- CreateSSChecksumDB(db64,sizeof(db64),&info);
- FindSpecialFilesSZS(&szs,false);
-
-
- //--- scan LEX
-
- lex_info_t lexinfo;
- InitializeLexInfo(&lexinfo);
-
- if (szs.course_lex_data)
- {
- lex_t lex;
- InitializeLEX(&lex);
- err = ScanLEX(&lex,false,szs.course_lex_data,szs.course_lex_size);
- szs.have_lex = lex.have_lex;
- SetupLexInfo(&lexinfo,&lex);
- ResetLEX(&lex);
- }
-
-
- //--- scan KMP
-
- sha1_hex_t sha1_kmp = {0}, sha1_kmp_norm = {0};
-
- char ct_attrib[300];
- char *ct_dest = ct_attrib;
- char *ct_end = ct_attrib + sizeof(ct_attrib);
- ct_attrib[1] = 0;
+ //--- analyse szs
- int ckpt0_count = -1; // number of LC in CKPT
- int lap_count = 3; // STGI lap counter
- float speed_factor = 1.0; // STGI speed factor
-
- slot_ana_t slotana;
- AnalyzeSlot(&slotana,&szs);
- slot_info_t slotinfo;
- AnalyzeSlotByName(&slotinfo,true,MemByString(param->arg));
- if (slotana.mandatory_slot[0])
- AnalyzeSlotAttrib(&slotinfo,false,MemByString(slotana.mandatory_slot));
- FinalizeSlotInfo(&slotinfo,true);
- if (*slotinfo.slot_attrib)
- ct_dest = StringCat2E(ct_dest,ct_end,",",slotinfo.slot_attrib);
-
- kmp_finish_t kf;
- InitializeFinishLine(&kf);
-
- kmp_usedpos_t up;
- InitializeUsedPos(&up);
-
- char gobj_info[20] = {0};
- if (szs.course_kmp_data)
- {
- SHA1(szs.course_kmp_data,szs.course_kmp_size,info.hash);
- Sha1Bin2Hex(sha1_kmp,info.hash);
- memcpy(sha1_kmp_norm,sha1_kmp,sizeof(sha1_kmp_norm));
-
- kmp_t kmp;
- InitializeKMP(&kmp);
- kmp.lexinfo = &lexinfo;
- err = ScanKMP(&kmp,false,szs.course_kmp_data,szs.course_kmp_size,0);
- if ( err <= ERR_WARNING )
- {
- if (kmp.stgi)
- {
- kmp_stgi_entry_t *stgi = (kmp_stgi_entry_t*)kmp.stgi;
- const u8 lap_count = stgi->lap_count;
- const u16 speed_mod = stgi->speed_mod;
- stgi->lap_count = 3;
- stgi->speed_mod = 0;
-
- SHA1(szs.data,szs.size,info.hash);
- Sha1Bin2Hex(sha1_norm,info.hash);
-
- SHA1(szs.course_kmp_data,szs.course_kmp_size,info.hash);
- Sha1Bin2Hex(sha1_kmp_norm,info.hash);
-
- stgi->lap_count = lap_count;
- stgi->speed_mod = speed_mod;
- }
-
- CheckFinishLine(&kmp,&kf);
- CheckUsedPos(&kmp,&up);
-
- const uint n_ckpt = kmp.dlist[KMP_CKPT].used;
- if (n_ckpt)
- {
- const kmp_ckpt_entry_t *ckpt
- = (kmp_ckpt_entry_t*)kmp.dlist[KMP_CKPT].list;
- uint i;
- ckpt0_count = 0;
- for ( i = 0; i < n_ckpt; i++, ckpt++ )
- if (!ckpt->mode)
- ckpt0_count++;
- }
-
- const kmp_stgi_entry_t *stgi = (kmp_stgi_entry_t*)kmp.dlist[KMP_STGI].list;
- if ( kmp.dlist[KMP_STGI].used > 0 )
- {
- lap_count = stgi->lap_count;
- if (!szs.is_arena)
- {
- if ( ckpt0_count > 1 )
- {
- if ( lap_count == 1 )
- ct_dest = StringCopyE(ct_dest,ct_end,",1lap");
- ct_dest = snprintfE(ct_dest,ct_end,",%ulc",ckpt0_count);
- }
- else if ( lap_count != 0 && lap_count != 3 )
- ct_dest = snprintfE(ct_dest,ct_end,",%ulap%s",
- lap_count, lap_count == 1 ? "" : "s" );
- }
-
- if (stgi->speed_mod)
- {
- speed_factor = SpeedMod2float(stgi->speed_mod);
- char buf[20];
- snprintf(buf,sizeof(buf),",x%4.2f",speed_factor);
- char *ptr = buf + strlen(buf) - 1;
- while ( *ptr == '0' )
- *ptr-- = 0;
- if ( *ptr == '.' )
- *ptr = 0;
- if ( strcmp(buf,",x0") && strcmp(buf,",x1") )
- ct_dest = StringCopyE(ct_dest,ct_end,buf);
- }
- }
- else if ( !szs.is_arena && ckpt0_count > 1 )
- ct_dest = snprintfE(ct_dest,ct_end,",%ulc",ckpt0_count);
-
- if ( kf.n_ktpt_m > 1 )
- ct_dest = StringCopyE(ct_dest,ct_end,",2ktpt");
-
- kmp_ana_pflag_t ap;
- AnalysePFlagScenarios(&ap,&kmp,GMD_M_DEFAULT);
- snprintf(gobj_info,sizeof(gobj_info),"%d %d %d %d",
- ap.ag.n_gobj, ap.n_version, ap.n_res_std, ap.n_res_ext );
- ResetPFlagScenarios(&ap);
- }
-
- DetectSpecialKMP(&kmp,szs.kmp_special);
- if ( szs.kmp_special[HAVEKMP_WOODBOX_HT]
- || szs.kmp_special[HAVEKMP_MUSHROOM_CAR]
- || szs.kmp_special[HAVEKMP_PENGUIN_POS]
- || szs.kmp_special[HAVEKMP_EPROP_SPEED]
- )
- {
- ct_dest = StringCopyE(ct_dest,ct_end,",gobj");
- }
-
- if ( szs.kmp_special[HAVEKMP_X_PFLAGS]
- || szs.kmp_special[HAVEKMP_X_COND]
- || szs.kmp_special[HAVEKMP_X_DEFOBJ]
- || szs.kmp_special[HAVEKMP_X_RANDOM]
- )
- {
- ct_dest = StringCopyE(ct_dest,ct_end,",xpf");
- }
-
- ResetKMP(&kmp);
- }
-
- if ( szs.szs_special[HAVESZS_ITEM_SLOT_TABLE] )
- ct_dest = StringCopyE(ct_dest,ct_end,",itemslot");
-
- if ( szs.szs_special[HAVESZS_OBJFLOW] )
- ct_dest = StringCopyE(ct_dest,ct_end,",objflow");
-
- if ( szs.szs_special[HAVESZS_GHT_ITEM]
- || szs.szs_special[HAVESZS_GHT_ITEM_OBJ]
- || szs.szs_special[HAVESZS_GHT_KART]
- || szs.szs_special[HAVESZS_GHT_KART_OBJ]
- )
- {
- ct_dest = StringCopyE(ct_dest,ct_end,",geohit");
- }
-
- if ( szs.szs_special[HAVESZS_MINIGAME] )
- ct_dest = StringCopyE(ct_dest,ct_end,",minigame");
-
-
- //--- scan KCL
-
- sha1_hex_t sha1_kcl = {0};
- if (szs.course_kcl_data)
- {
- SHA1(szs.course_kcl_data,szs.course_kcl_size,info.hash);
- Sha1Bin2Hex(sha1_kcl,info.hash);
- }
-
-
- //--- add "lex" and terminate 'ct_dest'
-
- if (szs.course_lex_data)
- ct_dest = StringCopyE(ct_dest,ct_end,",lex");
- *ct_dest = 0;
-
-
- //--- course model (course_model.brres, course_d_model.brres)
-
- sha1_hex_t sha1_course = {0};
- if (szs.course_model_data)
- {
- SHA1(szs.course_model_data,szs.course_model_size,info.hash);
- Sha1Bin2Hex(sha1_course,info.hash);
- }
- else if (szs.course_d_model_data)
- {
- SHA1(szs.course_d_model_data,szs.course_d_model_size,info.hash);
- Sha1Bin2Hex(sha1_course,info.hash);
- }
-
-
- //--- vrcorn (vrcorn_model.brres)
-
- sha1_hex_t sha1_vrcorn = {0};
- if (szs.vrcorn_model_data)
- {
- SHA1(szs.vrcorn_model_data,szs.vrcorn_model_size,info.hash);
- Sha1Bin2Hex(sha1_vrcorn,info.hash);
- }
-
-
- //--- minimap (map_model.brres)
-
- sha1_hex_t sha1_minimap = {0};
- if (szs.map_model_data)
- {
- SHA1(szs.map_model_data,szs.map_model_size,info.hash);
- Sha1Bin2Hex(sha1_minimap,info.hash);
- }
+ AnalyseSZS(&as,false,&szs,param->arg);
//--- status
@@ -2230,51 +2006,56 @@ static enumError cmd_analyze()
"special_kmp=\"%s\"\n"
"special_files=\"%s\"\n"
"lex_sections=\"%s\"\n"
+ "warn=\"%u=%s\"\n"
"ct_attributes=\"%s\"\n"
"name_attributes=\"%.*s\"\n"
+ "duration_usec=%llu\n"
,dest
,szs.size
- ,db64
- ,sha1
- ,sha1_norm
- ,sha1_kcl
- ,sha1_kmp
- ,sha1_kmp_norm
- ,sha1_course
- ,sha1_vrcorn
- ,sha1_minimap
+ ,as.db64
+ ,as.sha1_szs
+ ,as.sha1_szs_norm
+ ,as.sha1_kcl
+ ,as.sha1_kmp
+ ,as.sha1_kmp_norm
+ ,as.sha1_course
+ ,as.sha1_vrcorn
+ ,as.sha1_minimap
,szs.is_arena
,is_arena_name[szs.is_arena]
- ,ckpt0_count
- ,lap_count
- ,speed_factor
- ,slotana.slot_info
- ,slotinfo.slot_attrib
- ,slotinfo.race_slot,slotinfo.race_info
- ,slotinfo.arena_slot,slotinfo.arena_info
- ,slotinfo.music_index,slotinfo.music_info
- ,up.orig.rating[0],WarnLevelNameLo[up.orig.rating[0]]
- ,up.orig.min.x,up.orig.max.x
- ,fabsf(up.orig.max.x-up.orig.min.x)
- ,(up.orig.min.x+up.orig.max.x)/2
- ,up.orig.rating[1],WarnLevelNameLo[up.orig.rating[1]]
- ,up.orig.min.y,up.orig.max.y
- ,fabsf(up.orig.max.y-up.orig.min.y)
- ,(up.orig.min.y+up.orig.max.y)/2
- ,up.orig.rating[2],WarnLevelNameLo[up.orig.rating[2]]
- ,up.orig.min.z,up.orig.max.z
- ,fabsf(up.orig.max.z-up.orig.min.z)
- ,(up.orig.min.z+up.orig.max.z)/2
- ,GetUsedPosObjSuggestion(up.suggest,true,"")
- ,kf.warn ? "warn" : kf.hint ? "hint" : "ok"
- ,kf.distance
- ,kf.dir_delta
- ,gobj_info
+ ,as.ckpt0_count
+ ,as.lap_count
+ ,as.speed_factor
+ ,as.slotana.slot_info
+ ,as.slotinfo.slot_attrib
+ ,as.slotinfo.race_slot,as.slotinfo.race_info
+ ,as.slotinfo.arena_slot,as.slotinfo.arena_info
+ ,as.slotinfo.music_index,as.slotinfo.music_info
+ ,as.used_pos.orig.rating[0]
+ ,WarnLevelNameLo[as.used_pos.orig.rating[0]]
+ ,as.used_pos.orig.min.x,as.used_pos.orig.max.x
+ ,fabsf(as.used_pos.orig.max.x-as.used_pos.orig.min.x)
+ ,(as.used_pos.orig.min.x+as.used_pos.orig.max.x)/2
+ ,as.used_pos.orig.rating[1],WarnLevelNameLo[as.used_pos.orig.rating[1]]
+ ,as.used_pos.orig.min.y,as.used_pos.orig.max.y
+ ,fabsf(as.used_pos.orig.max.y-as.used_pos.orig.min.y)
+ ,(as.used_pos.orig.min.y+as.used_pos.orig.max.y)/2
+ ,as.used_pos.orig.rating[2],WarnLevelNameLo[as.used_pos.orig.rating[2]]
+ ,as.used_pos.orig.min.z,as.used_pos.orig.max.z
+ ,fabsf(as.used_pos.orig.max.z-as.used_pos.orig.min.z)
+ ,(as.used_pos.orig.min.z+as.used_pos.orig.max.z)/2
+ ,GetUsedPosObjSuggestion(as.used_pos.suggest,true,"")
+ ,as.kmp_finish.warn ? "warn" : as.kmp_finish.hint ? "hint" : "ok"
+ ,as.kmp_finish.distance
+ ,as.kmp_finish.dir_delta
+ ,as.gobj_info
,CreateSpecialInfoKMP(szs.kmp_special,true,"")
,CreateSpecialFileInfo(&szs,true,"")
,CreateSectionInfoLEX(szs.have_lex,true,"")
- ,ct_attrib+1
+ ,szs.warn_bits,GetWarnSZSNames(szs.warn_bits,' ')
+ ,as.ct_attrib+1
,name_attrib_len,name_attrib
+ ,as.duration_usec
);
if ( long_count > 0 )
@@ -2300,13 +2081,12 @@ static enumError cmd_analyze()
PrintScriptFooter(&ps);
ResetFile(&fo,0);
}
-
- ResetLexInfo(&lexinfo);
}
PrintScriptFooter(&ps);
ResetPrintScript(&ps);
ResetFile(&fo,0);
+ ResetAnalyseSZS(&as);
ResetSZS(&szs);
return max_err;
}
@@ -5413,7 +5193,7 @@ static enumError CheckOptions ( int argc, char ** argv, bool is_env )
return err;
}
- return !err ? ERR_OK : max_error ? max_error : ERR_SYNTAX;
+ return !err ? ERR_OK : ProgInfo.max_error ? ProgInfo.max_error : ERR_SYNTAX;
}
//
@@ -5552,13 +5332,13 @@ static enumError CheckCommand ( int argc, char ** argv )
//
///////////////////////////////////////////////////////////////////////////////
-/////////////// main_wszst() ///////////////
+/////////////// main_wszst(), main() ///////////////
///////////////////////////////////////////////////////////////////////////////
int main_wszst ( int argc, char ** argv )
{
print_title_func = print_title;
- SetupLib(argc,argv,WSZST_SHORT);
+ SetupLib(argc,argv,WSZST_SHORT,VERSION,TITLE);
SetupExtendedSZS();
//----- process arguments
@@ -5657,7 +5437,7 @@ static const wrapper_t * FindWrapper ( int argc, char ** argv )
int main_wrapper ( int argc, char ** argv )
{
- SetupLib(argc,argv,TOOLSET_SHORT);
+ SetupLib(argc,argv,TOOLSET_SHORT,VERSION,TITLE);
enum
{
@@ -5838,7 +5618,7 @@ int main_wrapper ( int argc, char ** argv )
fprintf(stdout,
"\n%s\n%s\n\n Usage: %s TOOLNAME ...\n\n"
"This is a wrapper for the following tools:\n\n",
- text_logo, TOOLSET_TITLE, progname );
+ text_logo, TOOLSET_TITLE, ProgInfo.progname );
const wrapper_t *w, *active = FindWrapper(argc,argv);
DASSERT(active);
diff --git a/project/src/wtest.c b/project/src/wtest.c
index f91feb2..79f45c6 100644
--- a/project/src/wtest.c
+++ b/project/src/wtest.c
@@ -302,8 +302,8 @@ static int test_matrix ( int argc, char ** argv )
}
printf("\nerr=%u, total=%u\n",err_count,total_count);
- if ( err_count && max_error < ERR_DIFFER )
- max_error = ERR_DIFFER;
+ if ( err_count && ProgInfo.max_error < ERR_DIFFER )
+ ProgInfo.max_error = ERR_DIFFER;
return 0;
}
@@ -3353,7 +3353,7 @@ static enumError test_timezone ( int argc, char ** argv )
{
printf("\nEndless timezone test with interval of 30 minutes started (pid=%u)\n",
getpid() );
- printf("Typical usage: nohup ./%s TIMEZONE >>timezone-test.tmp 2>&1 &\n\n",progname);
+ printf("Typical usage: nohup ./%s TIMEZONE >>timezone-test.tmp 2>&1 &\n\n",ProgInfo.progname);
for(;;)
{
@@ -3989,7 +3989,7 @@ int main ( int argc, char ** argv )
{
printf("***** %s *****\n",TITLE);
print_title_func = print_title;
- SetupLib(argc,argv,NAME);
+ SetupLib(argc,argv,NAME,VERSION,TITLE);
fflush(stdout);
//printf(" |" MM1(XXX) "|" MM2(XXX) "\n");
@@ -4079,7 +4079,7 @@ int main ( int argc, char ** argv )
if (SIGINT_level)
ERROR0(ERR_INTERRUPT,"Program interrupted by user.");
- return max_error;
+ return ProgInfo.max_error;
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/project/templates/HISTORY.txt b/project/templates/HISTORY.txt
index be9d5e7..b7cd9e2 100644
--- a/project/templates/HISTORY.txt
+++ b/project/templates/HISTORY.txt
@@ -83,7 +83,7 @@ szs v2.02a r7827 - 2019-05-04
- New command: wszst XCOMMON: Scan archives and extract files from archives,
that are below directory 'common'. Command XCOMMON is a short cut for
EXTRACT --basedir=common.
- - New command: wszst ANALYZE: Analyse track files and print resulta in
+ - New command: wszst ANALYZE: Analyse track files and print result in
machine readable format.
@@ -412,6 +412,11 @@ szs v2.19a r8237 - 2020-08-01
is renamed. This suppresses wrong warnings.
+szs v2.19b r8243 - 2020-08-03
+
+ - Bug fix for wlect LPAR: Message functions are not longer printed twice.
+
+
@@MODULE(last-history.txt)@@
diff --git a/project/templates/module/last-history.txt b/project/templates/module/last-history.txt
index 308942e..c9505ab 100644
--- a/project/templates/module/last-history.txt
+++ b/project/templates/module/last-history.txt
@@ -1,7 +1,12 @@
szs v@@VERSION@@ r@@REV-NEXT@@ - @@@@-@@-@@
- - Bug fix for wlect LPAR: Message functions are not longer printed twice.
-
+ - Time stamps of the files are now managed in nanoseconds instead of seconds.
+ - wszst ANALYSE: New result "warn=": Print warnings about Item Position Bug
+ and self linked item routes with 1 point.
+ - wszst CHECK: Hints about unusual TEX version 1 are suppressed now if option
+ --verbose is not set.
+ - Fewer program crashes when reading faulty SZS files.
+
~ - MDL support: Scanning a MDL file and transferring the data into an internal
~ format was already implemented, but only used for analysis purposes. Now it
~ is possible to create a binary MDL by reading the internal data. This is