diff --git a/check/fixes.frm b/check/fixes.frm index 663bf3c5..ffdb9517 100644 --- a/check/fixes.frm +++ b/check/fixes.frm @@ -1430,3 +1430,67 @@ assert result("F64m6") =~ expr("f(-18446744073709551616)") assert result("F64m7") =~ expr("f(-18446744073709551617)") assert result("F64m8") =~ expr("f(-18446744073709551618)") *--#] Issue139 : +*--#[ Issue149_1 : +* Index matches to -1 but crashes in output +Index mu; +CF f; +L F1 = f(-1); +L F2 = +...+; +id f(mu?) = mu; +P; +.end +assert succeeded? +assert result("F1") =~ expr("f(-1)") +assert result("F2") =~ expr("8256 + f(-2) + f(-1) + f(129) + f(130)") +*--#] Issue149_1 : +*--#[ Issue149_2 : +Index mu; +CF f1(s),f2(a),f3(c),f4(r); +L F1 = +...+; +L F2 = +...+; +L F3 = +...+; +L F4 = +...+; +id f1?(mu?) = mu; +P; +.end +assert succeeded? +assert result("F1") =~ expr("8256 + f1(-2) + f1(-1) + f1(129) + f1(130)") +assert result("F2") =~ expr("8256 + f2(-2) + f2(-1) + f2(129) + f2(130)") +assert result("F3") =~ expr("8256 + f3(-2) + f3(-1) + f3(129) + f3(130)") +assert result("F4") =~ expr("8256 + f4(-2) + f4(-1) + f4(129) + f4(130)") +*--#] Issue149_2 : +*--#[ Issue153_1 : +* Pattern with index and set restriction matches to number +I mu1,...,mu9; +CF f; +Set indices: mu1,...,mu9; +Set indices2: mu1,...,mu9, 127, 128; +L F1 = f(132); +L F2 = +...+; +id f(mu1?indices) = 1; +id f(mu1?indices2) = 0; +P; +.end +assert succeeded? +assert result("F1") =~ expr("f(132)") +assert result("F2") =~ expr("f(126) + f(129) + f(130) + f(131) + f(132)") +*--#] Issue153_1 : +*--#[ Issue153_2 : +I mu1,...,mu9; +CF f1(s),f2(a),f3(c),f4(r); +Set indices: mu1,...,mu9; +Set indices2: mu1,...,mu9, 127, 128; +L F1 = +...+; +L F2 = +...+; +L F3 = +...+; +L F4 = +...+; +id f1?(mu1?indices) = 1; +id f1?(mu1?indices2) = 0; +P; +.end +assert succeeded? +assert result("F1") =~ expr("f1(126) + f1(129) + f1(130) + f1(131) + f1(132)") +assert result("F2") =~ expr("f2(126) + f2(129) + f2(130) + f2(131) + f2(132)") +assert result("F3") =~ expr("f3(126) + f3(129) + f3(130) + f3(131) + f3(132)") +assert result("F4") =~ expr("f4(126) + f4(129) + f4(130) + f4(131) + f4(132)") +*--#] Issue153_2 : diff --git a/configure.ac b/configure.ac index 39bf59da..53051094 100644 --- a/configure.ac +++ b/configure.ac @@ -13,9 +13,22 @@ m4_define([FORM_VERSION], m4_esyscmd_s([ if test -f .version; then cat .version else - scripts/git-version-gen.sh -C . -v || cat <&2 + scripts/git-version-gen.sh -C . -v || { + # As a fallback, try for form3.h. + major_version=`grep MAJORVERSION sources/form3.h | sed -e 's/ *#define *MAJORVERSION *//'` + minor_version=`grep MINORVERSION sources/form3.h | sed -e 's/ *#define *MINORVERSION *//'` + if test "x$major_version" != x && test "x$minor_version" != x; then + # Make the version files. + echo "$major_version.$minor_version" >.version + echo "#define REPO_MAJOR_VERSION $major_version" >sources/version.h.in + echo "#define REPO_MINOR_VERSION $minor_version" >>sources/version.h.in + echo "\\def\\repomajorversion{$major_version}" >doc/manual/version.tex.in + echo "\\def\\repominorversion{$minor_version}" >>doc/manual/version.tex.in + cp doc/manual/version.tex.in doc/devref/version.tex.in + fi + cat <&2 ======================================================================== -Failed to determine the version of the source code. +Failed to determine the revision of the source code. The reason may be - this is neither a source distribution (containing the configure @@ -28,11 +41,20 @@ Source distributions and some binaries can be found in: http://www.nikhef.nl/~form/maindir/binaries/binaries.html https://github.com/vermaseren/form/releases -The latest source code can be obtained as +The latest source code can be cloned by: git clone https://github.com/vermaseren/form.git +END + test -f .version && cat <&2 + +You can continue the build, but binaries will not contain the revision +information. +END + cat <&2 ======================================================================== END + test -f .version && cat .version + } fi ])) @@ -83,6 +105,27 @@ AC_CHECK_HEADERS([unordered_map tr1/unordered_map boost/unordered_map.hpp]) AC_CHECK_HEADERS([unordered_set tr1/unordered_set boost/unordered_set.hpp]) AC_LANG_POP([C++]) +# Checks for builtin functions +ok=no +AS_IF([test $ok != yes], + [AC_MSG_CHECKING([__builtin_popcount]) + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([], [ + int x = __builtin_popcount((unsigned int)(-1)); + ])], + [ok=yes; + AC_DEFINE([HAVE_BUILTIN_POPCOUNT], [1], [Define to 1 if you have __builtin_popcount function.])]) + AC_MSG_RESULT($ok)]) +AS_IF([test $ok != yes], + [AC_MSG_CHECKING([__popcnt]) + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([#include ], [ + unsigned int x = __popcnt((unsigned int)(-1)); + ])], + [ok=yes; + AC_DEFINE([HAVE_POPCNT], [1], [Define to 1 if you have __popcnt function.])]) + AC_MSG_RESULT($ok)]) + # Check for inline AC_C_INLINE diff --git a/doc/devref/Makefile.am b/doc/devref/Makefile.am index bf5ab07c..b58cc488 100644 --- a/doc/devref/Makefile.am +++ b/doc/devref/Makefile.am @@ -39,7 +39,7 @@ if FIXED_VERSION UPDATE_VERSION_TEX = \ [ -f version.tex ] || $(LN_S) "$(srcdir)/version.tex.in" version.tex -DISTHOOK_VERSION_H = \ +DISTHOOK_VERSION_TEX = \ cp "$(srcdir)/version.tex.in" "$(distdir)/version.tex.in" else diff --git a/doc/devref/devref.tex.in b/doc/devref/devref.tex.in index 3121dc90..b941c008 100644 --- a/doc/devref/devref.tex.in +++ b/doc/devref/devref.tex.in @@ -1,5 +1,6 @@ \input{version.tex} \def\formdate{\repodate} +\providecommand{\repodate}{\today} \documentclass[11pt,titlepage]{article} diff --git a/doc/manual/Makefile.am b/doc/manual/Makefile.am index 89bcae94..ba978111 100644 --- a/doc/manual/Makefile.am +++ b/doc/manual/Makefile.am @@ -53,7 +53,7 @@ if FIXED_VERSION UPDATE_VERSION_TEX = \ [ -f version.tex ] || $(LN_S) "$(srcdir)/version.tex.in" version.tex -DISTHOOK_VERSION_H = \ +DISTHOOK_VERSION_TEX = \ cp "$(srcdir)/version.tex.in" "$(distdir)/version.tex.in" else diff --git a/doc/manual/manual.tex.in b/doc/manual/manual.tex.in index a85c8179..d28815c1 100644 --- a/doc/manual/manual.tex.in +++ b/doc/manual/manual.tex.in @@ -2,6 +2,7 @@ \def\formmajorversion{\repomajorversion} \def\formminorversion{\repominorversion} \def\formdate{\repodate} +\providecommand{\repodate}{\today} \documentclass[11pt]{report} diff --git a/sources/checkpoint.c b/sources/checkpoint.c index a186009f..cc3b34df 100644 --- a/sources/checkpoint.c +++ b/sources/checkpoint.c @@ -2393,7 +2393,7 @@ int DoRecovery(int *moduletype) for ( i = 0; i < AO.NumDictionaries; i++ ) { R_SET(l,LONG) AO.Dictionaries[i] = DictFromBytes(p); - p += l; + p = (char *)p + l; } } /*#] AO :*/ diff --git a/sources/form3.h b/sources/form3.h index a2344d75..c355b01e 100644 --- a/sources/form3.h +++ b/sources/form3.h @@ -131,6 +131,27 @@ #endif /* HAVE_CONFIG_H */ +/* Workaround for MSVC. */ +#if defined(_MSC_VER) +/* + * Recent versions of MSVC++ (>= 2012) don't like reserved keywords being + * macroized even when they are not available. This is problematic for + * `alignof`, which is used in legacy `PADXXX` macros. We disable tests in + * xkeycheck.h. + */ +#if _MSC_VER >= 1700 +#define _ALLOW_KEYWORD_MACROS +#endif +/* + * Old versions of MSVC didn't support C99 function `snprintf`, which is used + * in poly.cc. On the other hand, macroizing `snprintf` gives a fatal error + * with MSVC >= 2015. + */ +#if _MSC_VER < 1900 +#define snprintf _snprintf +#endif +#endif + /* * STATIC_ASSERT(condition) will fail to be compiled if the given * condition is false. @@ -155,16 +176,16 @@ /* Undefine/rename conflicted symbols. */ #undef VOID /* WinNT.h */ #undef MAXLONG /* WinNT.h */ -#define WORD WORD__Renamed /* WinDef.h */ -#define LONG LONG__Renamed /* WinNT.h */ -#define ULONG ULONG__Renamed /* WinDef.h */ +#define WORD FORM_WORD /* WinDef.h */ +#define LONG FORM_LONG /* WinNT.h */ +#define ULONG FORM_ULONG /* WinDef.h */ #undef CreateFile /* WinBase.h */ #undef CopyFile /* WinBase.h */ -#define OpenFile OpenFile__Renamed /* WinBase.h */ -#define ReOpenFile ReOpenFile__Renamed /* WinBase.h */ -#define ReadFile ReadFile__Renamed /* WinBase.h */ -#define WriteFile WriteFile__Renamed /* WinBase.h */ -#define DeleteObject DeleteObject__Renamed /* WinGDI.h */ +#define OpenFile FORM_OpenFile /* WinBase.h */ +#define ReOpenFile FORM_ReOpenFile /* WinBase.h */ +#define ReadFile FORM_ReadFile /* WinBase.h */ +#define WriteFile FORM_WriteFile /* WinBase.h */ +#define DeleteObject FORM_DeleteObject /* WinGDI.h */ #else #error UNIX or WINDOWS must be defined! #endif diff --git a/sources/function.c b/sources/function.c index 7ec75dd0..87fc8f02 100644 --- a/sources/function.c +++ b/sources/function.c @@ -1239,7 +1239,8 @@ IndAll: i = m[1] - WILDOFFSET; else if ( *m == -ARGWILD ) goto ArgAll; else if ( *m == -INDEX && m[1] >= AM.OffsetIndex+WILDOFFSET && m[1] < AM.OffsetIndex+(WILDOFFSET<<1) ) { - if ( *t == -VECTOR || *t == -SNUMBER ) goto IndAll; + if ( *t == -VECTOR ) goto IndAll; + if ( *t == -SNUMBER && t[1] >= 0 && t[1] < AM.OffsetIndex ) goto IndAll; if ( *t == -MINVECTOR ) { i = m[1] - WILDOFFSET; AN.argaddress = AT.MinVecArg; diff --git a/sources/mytime.cc b/sources/mytime.cc index b69c5bcc..87643a59 100644 --- a/sources/mytime.cc +++ b/sources/mytime.cc @@ -1,3 +1,10 @@ +#ifdef HAVE_CONFIG_H +#include +#endif + +// A timing routine for debugging. Only on Unix (where sys/time.h is available). +#ifdef UNIX + #include #include #include @@ -37,3 +44,5 @@ std::string thetime_str() { sprintf (res,"%.4lf", thetime()); return res; } + +#endif // UNIX diff --git a/sources/optimize.cc b/sources/optimize.cc index 26a6f553..d27500ad 100644 --- a/sources/optimize.cc +++ b/sources/optimize.cc @@ -77,6 +77,26 @@ using std::tr1::unordered_set; #endif +#if defined(HAVE_BUILTIN_POPCOUNT) + static inline int popcount(unsigned int x) { + return __builtin_popcount(x); + } +#elif defined(HAVE_POPCNT) + #include + static inline int popcount(unsigned int x) { + return __popcnt(x); + } +#else + static inline int popcount(unsigned int x) { + int count = 0; + while (x > 0) { + if ((x & 1) == 1) count++; + x >>= 1; + } + return count; + } +#endif + extern "C" { #include "form3.h" } @@ -399,7 +419,7 @@ int count_operators (const WORD *expr, bool print=false) { } if (t[i+1]>2) { // (extra)symbol power>2 cntpow++; - sumpow += (int)floor(log(t[i+1])/log(2.0)) + __builtin_popcount(t[i+1]) - 1; + sumpow += (int)floor(log(t[i+1])/log(2.0)) + popcount(t[i+1]) - 1; } if (t[i+1]==2) cntmul++; // (extra)symbol squared cntsym++; @@ -445,7 +465,7 @@ int count_operators (const vector &instr, bool print=false) { if (*(t+4)==2) cntmul++; // (extra)symbol squared if (*(t+4)>2) { // (extra)symbol power>2 cntpow++; - sumpow += (int)floor(log(*(t+4))/log(2.0)) + __builtin_popcount(*(t+4)) - 1; + sumpow += (int)floor(log(*(t+4))/log(2.0)) + popcount(*(t+4)) - 1; } } if (ABS(*(t+*t-1))!=3 || *(t+*t-2)!=1 || *(t+*t-3)!=1) cntmul++; // non +/-1 coefficient @@ -1317,7 +1337,7 @@ int count_operators_cse (const vector &tree) { if (tree[i + 3] == 2) numinstr++; else - numinstr += (int)floor(log(tree[i+3])/log(2.0)) + __builtin_popcount(tree[i+3]) - 1; + numinstr += (int)floor(log(tree[i+3])/log(2.0)) + popcount(tree[i+3]) - 1; ID[x] = numinstr; s.push(1); @@ -1408,7 +1428,7 @@ int count_operators_cse (const vector &tree) { } } - MesPrint ("*** [%s] Stopping CSEE", thetime_str().c_str()); + //MesPrint ("*** [%s] Stopping CSEE", thetime_str().c_str()); return numinstr - numcommas; } @@ -1573,7 +1593,7 @@ int count_operators_cse_topdown (vector &tree) { if (c->data[3] == 2) numinstr++; else - numinstr += (int)floor(log(c->data[3])/log(2.0)) + __builtin_popcount(c->data[3]) - 1; + numinstr += (int)floor(log(c->data[3])/log(2.0)) + popcount(c->data[3]) - 1; } } } else { diff --git a/sources/proces.c b/sources/proces.c index b2bab9ff..ad8ccd51 100644 --- a/sources/proces.c +++ b/sources/proces.c @@ -2525,7 +2525,11 @@ ComAct: if ( t < u ) do { *m++ = *t++; } while ( t < u ); } } *termout = WORDDIF(m,termout); - if ( (*termout)*((LONG)sizeof(WORD)) > AM.MaxTer ) goto InsCall; + if ( (*termout)*((LONG)sizeof(WORD)) > AM.MaxTer ) { + MLOCK(ErrorMessageLock); + MesPrint("Term too complex during substitution. MaxTermSize of %l is too small",AM.MaxTer); + goto InsCall2; + } AT.WorkPointer = coef; return(0); } @@ -2552,6 +2556,7 @@ ComAct: if ( t < u ) do { *m++ = *t++; } while ( t < u ); InsCall: MLOCK(ErrorMessageLock); +InsCall2: MesCall("InsertTerm"); MUNLOCK(ErrorMessageLock); SETERROR(-1) diff --git a/sources/startup.c b/sources/startup.c index 25a5ed10..eb19ca76 100644 --- a/sources/startup.c +++ b/sources/startup.c @@ -67,7 +67,18 @@ #ifdef HAVE_CONFIG_H /* We have also version.h. */ #include "version.h" - #define VERSIONSTR FORMNAME " " REPO_VERSION " (" REPO_DATE ", " REPO_REVISION ")" + #ifndef REPO_VERSION + #define REPO_VERSION STRINGIFY(REPO_MAJOR_VERSION) "." STRINGIFY(REPO_MINOR_VERSION) + #endif + #ifndef REPO_DATE + /* The build date, instead of the repo date. */ + #define REPO_DATE __DATE__ + #endif + #ifdef REPO_REVISION + #define VERSIONSTR FORMNAME " " REPO_VERSION " (" REPO_DATE ", " REPO_REVISION ")" + #else + #define VERSIONSTR FORMNAME " " REPO_VERSION " (" REPO_DATE ")" + #endif #define MAJORVERSION REPO_MAJOR_VERSION #define MINORVERSION REPO_MINOR_VERSION #else @@ -1229,10 +1240,14 @@ WORD IniVars() #endif WORD *fi, i, one = 1; CBUF *C = cbuf+AC.cbufnum; - UBYTE buf[32]; +#ifdef WITHPTHREADS + UBYTE buf[32]; sprintf((char*)buf,"%d",AM.totalnumberofthreads); PutPreVar((UBYTE *)"NTHREADS_",buf,0,1); +#else + PutPreVar((UBYTE *)"NTHREADS_",(UBYTE *)"1",0,1); +#endif AC.ShortStats = 0; AC.WarnFlag = 1; diff --git a/sources/symmetr.c b/sources/symmetr.c index deacef95..5f1995db 100644 --- a/sources/symmetr.c +++ b/sources/symmetr.c @@ -2082,7 +2082,8 @@ IndAll: i = m[1] - WILDOFFSET; } else if ( *m == -INDEX && m[1] >= AM.OffsetIndex+WILDOFFSET && m[1] < AM.OffsetIndex+(WILDOFFSET<<1) ) { - if ( *t == -VECTOR || *t == -SNUMBER ) goto IndAll; + if ( *t == -VECTOR ) goto IndAll; + if ( *t == -SNUMBER && t[1] >= 0 && t[1] < AM.OffsetIndex ) goto IndAll; if ( *t == -MINVECTOR ) { i = m[1] - WILDOFFSET; AN.argaddress = AT.MinVecArg;