aboutsummaryrefslogtreecommitdiff
path: root/project/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--project/src/lib-brres.c2
-rw-r--r--project/src/lib-brres.h1
-rw-r--r--project/src/lib-checksum.c1
-rw-r--r--project/src/lib-checksum.h3
-rw-r--r--project/src/lib-ctcode.c1
-rw-r--r--project/src/lib-file.c6
-rw-r--r--project/src/lib-kcl.c1
-rw-r--r--project/src/lib-kmp-text.c6
-rw-r--r--project/src/lib-kmp.c42
-rw-r--r--project/src/lib-kmp.h2
-rw-r--r--project/src/lib-lecode.c12
-rw-r--r--project/src/lib-mdl.c1
-rw-r--r--project/src/lib-pat.c1
-rw-r--r--project/src/lib-std.c95
-rw-r--r--project/src/lib-std.h24
-rw-r--r--project/src/lib-szs-create.c42
-rw-r--r--project/src/lib-szs.c301
-rw-r--r--project/src/lib-szs.h62
-rw-r--r--project/src/lib-xbmg.c1
-rw-r--r--project/src/wbmgt.c8
-rw-r--r--project/src/wctct.c8
-rw-r--r--project/src/wimgt.c8
-rw-r--r--project/src/wkclt.c8
-rw-r--r--project/src/wkmpt.c8
-rw-r--r--project/src/wlect.c12
-rw-r--r--project/src/wmdlt.c8
-rw-r--r--project/src/wpatt.c8
-rw-r--r--project/src/wstrt.c8
-rw-r--r--project/src/wszst.c350
-rw-r--r--project/src/wtest.c10
30 files changed, 678 insertions, 362 deletions
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;
}
///////////////////////////////////////////////////////////////////////////////