diff options
| author | Wiimm <none> | 2020-09-30 13:20:16 +0200 |
|---|---|---|
| committer | Wiimm <none> | 2020-09-30 13:20:16 +0200 |
| commit | 646b95d113309378591b75a290ee6c62a04f3772 (patch) | |
| tree | a94864e8cef5fc0fbffb7e69d46d688e7caaae3d | |
| parent | eaf1f8f8ce68b80ebdcefb45896461a89b47e1e1 (diff) | |
SZS v2.20a.beta1: Test Mac build
Diffstat (limited to '')
51 files changed, 1941 insertions, 1344 deletions
@@ -1,6 +1,42 @@ # Wiimms SZS Tools -»Wiimms SZS Tools« is a set of command line tools to extract, modify and create different files of game *Mario Kart Wii* and of other Nintendo games. Development started in 2011. See https://szs.wiimm.de/ for more details, documentation and downloads. -<dl><dt>Note:</dt><dd>This is only a copy of Wiimms private SVN repository. Only official releases are exported to <i>GitHub</i>. Therefor merge requests can not imported directly and must be included manually.</dd></dl> + ********************************* + * _______ _______ _______ * + * | ___ |____ | ___ | * + * | | |_| / /| | |_| * + * | |_____ / / | |_____ * + * |_____ | / / |_____ | * + * _ | | / / _ | | * + * | |___| |/ /____| |___| | * + * |_______|_______|_______| * + * * + * Wiimms SZS Tools * + * https://szs.wiimm.de/ * + * * + ********************************* + +»Wiimms SZS Tools« is a set of command line tools to extract, modify and create +different files of game *Mario Kart Wii* and of other Nintendo games. +Development started in 2011. See https://szs.wiimm.de/ for more details, +documentation and downloads. -Wiimm, 2020-07-28 +<dl> +<dt>Note:</dt> +<dd> +This is only a copy of Wiimms private SVN repository. +Only official releases are exported to <i>GitHub</i>. +Therefor merge requests can not imported directly and must be included manually. +</dd> + +<dt>License:</dt> +<dd> +This program is free software; +you can redistribute it and/or modify it under the terms of the +GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +See file project/gpl-2.0.txt or http://www.gnu.org/licenses/gpl-2.0.txt for details. +</dd> +</dl> + +*Wiimm, 2020-08-22* 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 |
