Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ jobs:
exit 1
fi
fi
./sources/$binname -vv

- name: Upload binary as artifact
if: steps.check-portability.outcome == 'success' && steps.check-portability.conclusion == 'success'
Expand Down
3 changes: 3 additions & 0 deletions doc/form.1
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ the program.
.BR "-v"
Only the version will be printed. The program terminates immediately after it.
.TP
.BR "-vv"
Same as \fB-v\fR, but prints verbose version information.
.TP
.BR "-w"
This should be followed immediately by a number without any space. The number
indicates the number of worker threads for \fBtform\fR. All other versions of
Expand Down
1 change: 1 addition & 0 deletions doc/manual/startup.tex
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ \chapter{Running FORM}
information see the "On TotalSize;" statement~\ref{ontotalsize}.
\item[-v] Only the version will be printed. The program terminates
immediately after it.
\item[-vv] Same as -v, but prints verbose version information.
\item[-w] This should be followed immediately by a number. The
number indicates the number of worker threads for \TFORM\@. All other
versions of \FORM\ ignore this parameter. It should be noted that \TFORM\
Expand Down
1 change: 1 addition & 0 deletions sources/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ SRCBASE = \
execute.c \
extcmd.c \
factor.c \
features.cc \
findpat.c \
form3.h \
fsizes.h \
Expand Down
1 change: 1 addition & 0 deletions sources/declare.h
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,7 @@ extern int Product(UWORD *,WORD *,WORD);
extern void PrtLong(UWORD *,WORD,UBYTE *);
extern void PrtTerms(void);
extern void PrintDeprecation(const char *,const char *);
extern void PrintFeatureList(void);
extern void PrintRunningTime(void);
extern LONG GetRunningTime(void);
extern int PutBracket(PHEAD WORD *);
Expand Down
212 changes: 212 additions & 0 deletions sources/features.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
/** @file features.cc
*
* Utility code for printing available features.
*/
/* #[ License : */
/*
* Copyright (C) 1984-2026 J.A.M. Vermaseren
* When using this file you are requested to refer to the publication
* J.A.M.Vermaseren "New features of FORM" math-ph/0010025
* This is considered a matter of courtesy as the development was paid
* for by FOM the Dutch physics granting agency and we would like to
* be able to track its scientific use to convince FOM of its value
* for the community.
*
* This file is part of FORM.
*
* FORM 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 3 of the License, or (at your option) any later
* version.
*
* FORM is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along
* with FORM. If not, see <http://www.gnu.org/licenses/>.
*/
/* #] License : */
// #[ Includes :

extern "C" {
#include "form3.h"
}

#include <algorithm>
#include <string>
#include <vector>

#ifdef WITHFLINT
#include <flint/flint.h>
#endif

#ifdef WITHGMP
#include <gmp.h>
#endif

#ifdef WITHMPFR
#include <mpfr.h>
#endif

#ifdef WITHZLIB
#include <zlib.h>
#endif

#ifdef WITHZSTD
#include <zstd.h>
#endif

// #] Includes :
// #[ PrintFeatureList :

/**
* Prints a list of strings in multiple columns to fit within the line length.
*
* @param lines List of strings to print.
*/
static void PrintMulticolumn(const std::vector<std::string>& lines)
{
const std::size_t n_lines = lines.size();

if ( n_lines == 0 ) return;

const std::size_t line_len = AC.LineLength > 0 ? AC.LineLength : 79;
constexpr std::size_t max_cols = 6;
constexpr std::size_t col_spacing = 2;

std::vector<std::size_t> col_lens(max_cols);

for ( std::size_t n_cols = max_cols; n_cols >= 2; n_cols-- ) {
const std::size_t n_rows = (n_lines - 1) / n_cols + 1;

// Check whether `n_cols` columns fit within the line length.
// Columns are filled top-to-bottom, then left-to-right.

std::fill(col_lens.begin(),col_lens.begin()+n_cols,0);

std::size_t total_len = 0;
for ( std::size_t j = 0; j < n_cols; j++ ) {
for ( std::size_t i = 0; i < n_rows; i++ ) {
const std::size_t k = i + j * n_rows;
if ( k >= n_lines ) break;
col_lens[j] = std::max(col_lens[j],lines[k].size());
}
total_len += col_lens[j];
}
total_len += (n_cols - 1) * col_spacing;

if ( total_len > line_len ) continue;

// Output using `n_cols` columns.

std::string line;
line.reserve(line_len);
for ( std::size_t i = 0; i < n_rows; i++ ) {
line.clear();
for ( std::size_t j = 0; j < n_cols; j++ ) {
const std::size_t k = i + j * n_rows;
if ( k >= n_lines ) break;
line += lines[k];
if ( j < n_cols - 1 ) {
line += std::string(col_lens[j]-lines[k].size()+col_spacing,' ');
}
}
MesPrint("%s",line.c_str());
}
return;
}

// Fallback to a single column.

for ( const auto& f : lines ) {
MesPrint("%s",f.c_str());
}
}

/**
* Prints the list of available features.
*/
void PrintFeatureList(void)
{
std::vector<std::string> feature_list = {

#ifdef ENABLE_BACKTRACE
"+backtrace",
#else
"-backtrace",
#endif

#ifdef DEBUGGING
"+debugging",
#else
"-debugging",
#endif

#ifdef WITHFLINT
"+flint=" + std::string(flint_version),
#else
"-flint",
#endif

#ifdef WITHFLOAT
"+float",
#else
"-float",
#endif

#ifdef WITHGMP
"+gmp=" + std::string(gmp_version),
#else
"-gmp",
#endif

#ifdef WITHMPFR
"+mpfr=" + std::string(mpfr_get_version()),
#else
"-mpfr",
#endif

#ifdef WITHMPI
"+mpi",
#else
"-mpi",
#endif

#ifdef UNIX
"+posix",
#else
"-posix",
#endif

#ifdef WITHPTHREADS
"+pthreads",
#else
"-pthreads",
#endif

#ifdef WINDOWS
"+windows",
#else
"-windows",
#endif

#ifdef WITHZLIB
"+zlib=" + std::string(zlibVersion()),
#else
"-zlib",
#endif

#ifdef WITHZSTD
"+zstd=" + std::string(ZSTD_versionString()),
#else
"-zstd",
#endif

};

PrintMulticolumn(feature_list);
}

// #] PrintFeatureList :
62 changes: 54 additions & 8 deletions sources/startup.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,51 @@
#[ PrintHeader :
*/

/**
* Prints build information.
*
* @note As a configure-time assumption, the C and C++ compilers are from
* the same vendor and have the same version.
*/
static void PrintBuildInfo(void) {
#if defined(__INTEL_LLVM_COMPILER)
MesPrint("Compiler: Intel LLVM oneAPI %d",__INTEL_LLVM_COMPILER);
#elif defined(__INTEL_COMPILER)
MesPrint("Compiler: Intel Classic %d",__INTEL_COMPILER);
#elif defined(__clang__) && defined(__apple_build_version__)
MesPrint("Compiler: Apple Clang %d.%d.%d (build %d)",__clang_major__,__clang_minor__,__clang_patchlevel__,__apple_build_version__);
#elif defined(__clang__)
MesPrint("Compiler: Clang %d.%d.%d",__clang_major__,__clang_minor__,__clang_patchlevel__);
#elif defined(__GNUC__)
MesPrint("Compiler: GCC %d.%d.%d",__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__);
#elif defined(_MSC_VER)
MesPrint("Compiler: MSVC %d",_MSC_VER);
#else
MesPrint("Compiler: Unknown");
#endif

#if defined(__x86_64__) || defined(_M_X64)
MesPrint("Architecture: x86_64");
#elif defined(__i386__) || defined(_M_IX86)
MesPrint("Architecture: x86 (32-bit)");
#elif defined(__aarch64__) || defined(_M_ARM64)
MesPrint("Architecture: arm64");
#elif defined(__arm__) || defined(_M_ARM)
MesPrint("Architecture: arm (32-bit)");
#else
MesPrint("Architecture: Unknown");
#endif
}

/**
* Prints the header line of the output.
*
* @param with_full_info True for printing also runtime information.
* @param par Controls the output mode
* (0: default,
* 1: including runtime information,
* 2: including verbose version information).
*/
static void PrintHeader(int with_full_info)
static void PrintHeader(int par)
{
#ifdef WITHMPI
if ( PF.me == MASTER && !AM.silent ) {
Expand Down Expand Up @@ -147,7 +186,7 @@ static void PrintHeader(int with_full_info)
s += snprintf(s,250-(s-buffer1)," %d-bits",(WORD)(sizeof(WORD)*16));
*s = 0;
*/
if ( with_full_info ) {
if ( par == 1 ) {
#if defined(WITHPTHREADS) || defined(WITHMPI)
#if defined(WITHPTHREADS)
int nworkers = AM.totalnumberofthreads-1;
Expand Down Expand Up @@ -200,6 +239,11 @@ static void PrintHeader(int with_full_info)
MesPrint("%s",buffer1);
AC.LineLength = oldLineLength;
}

if ( par == 2 ) {
PrintFeatureList();
PrintBuildInfo();
}
}
#ifdef WINDOWS
PrintDeprecation("the native Windows version", "issues/623");
Expand Down Expand Up @@ -414,12 +458,14 @@ int DoTail(int argc, UBYTE **argv)
break;
case 'T': /* Print the total size used at end of job */
AM.PrintTotalSize = 1; break;
case 'v':
case 'v': /* Print version information */
AC.FinalStats = 0;
if ( s[1] == 'v' ) { /* verbose version information */
PrintHeader(2);
return(1);
}
printversion:;
#ifdef WITHMPI
if ( PF.me == MASTER )
#endif
PrintHeader(0);
PrintHeader(0);
if ( onlyversion ) return(1);
goto NoFile;
case 'y': /* Preprocessor dumps output. No compilation. */
Expand Down
Loading