NCBI C++ ToolKit
Classes | Macros | Typedefs | Functions | Variables
dbpivot.c File Reference
#include <config.h>
#include <stdarg.h>
#include <freetds/time.h>
#include <assert.h>
#include <stdio.h>
#include <freetds/tds.h>
#include <freetds/thread.h>
#include <freetds/convert.h>
#include <freetds/string.h>
#include <replacements.h>
#include <sybfront.h>
#include <sybdb.h>
#include <syberror.h>
#include <dblib.h>
+ Include dependency graph for dbpivot.c:

Go to the source code of this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

Classes

struct  col_t
 
struct  KEY_T
 
struct  agg_t
 
struct  metadata_t
 
struct  pivot_t
 
struct  name_t
 

Macros

#define TDS_FIND(k, b, c)   tds_find(k, b, sizeof(b)/sizeof(b[0]), sizeof(b[0]), c)
 
#define TEST_MALLOC(dest, type)    {if (!(dest = (type*)calloc(1, sizeof(type)))) goto Cleanup;}
 
#define TEST_CALLOC(dest, type, n)    {if (!(dest = (type*)calloc((n), sizeof(type)))) goto Cleanup;}
 
#define tds_alloc_column()   ((TDSCOLUMN*) calloc(1, sizeof(TDSCOLUMN)))
 

Typedefs

typedef bool(* compare_func) (const void *, const void *)
 
typedef struct KEY_T KEY_T
 
typedef struct agg_t AGG_T
 
typedef struct pivot_t PIVOT_T
 

Functions

static void * tds_find (const void *key, const void *base, size_t nelem, size_t width, compare_func compar)
 
static TDS_SERVER_TYPE infer_col_type (int sybtype)
 
static struct col_tcol_init (struct col_t *pcol, int sybtype, size_t collen)
 
static void col_free (struct col_t *p)
 
static bool col_equal (const struct col_t *pc1, const struct col_t *pc2)
 
static void * col_buffer (struct col_t *pcol)
 
static struct col_tcol_cpy (struct col_t *pdest, const struct col_t *psrc)
 
static bool col_null (const struct col_t *pcol)
 
static char * string_value (const struct col_t *pcol)
 
static char * join (int argc, char *argv[], const char sep[])
 
static int bind_type (int sybtype)
 
static bool key_equal (const KEY_T *a, const KEY_T *b)
 
static void key_free (KEY_T *p)
 
static KEY_Tkey_cpy (KEY_T *pdest, const KEY_T *psrc)
 
static char * make_col_name (DBPROCESS *dbproc, const KEY_T *k)
 
static bool agg_next (const AGG_T *p1, const AGG_T *p2)
 
static void agg_free (AGG_T *p)
 
static bool agg_equal (const AGG_T *p1, const AGG_T *p2)
 
static TDSRESULTINFOalloc_results (TDS_USMALLINT num_cols)
 
static TDSRET set_result_column (TDSSOCKET *tds, TDSCOLUMN *curcol, const char name[], const struct col_t *pvalue)
 
static bool reinit_results (TDSSOCKET *tds, TDS_USMALLINT num_cols, const struct metadata_t meta[])
 
static bool pivot_key_equal (const PIVOT_T *a, const PIVOT_T *b)
 
PIVOT_Tdbrows_pivoted (DBPROCESS *dbproc)
 
STATUS dbnextrow_pivoted (DBPROCESS *dbproc, PIVOT_T *pp)
 
RETCODE dbpivot (DBPROCESS *dbproc, int nkeys, int *keys, int ncols, int *cols, DBPIVOT_FUNC func, int val)
 Pivot the rows, creating a new resultset. More...
 
void dbpivot_count (struct col_t *tgt, const struct col_t *src)
 
void dbpivot_sum (struct col_t *tgt, const struct col_t *src)
 
void dbpivot_min (struct col_t *tgt, const struct col_t *src)
 
void dbpivot_max (struct col_t *tgt, const struct col_t *src)
 
static bool name_equal (const struct name_t *n1, const struct name_t *n2)
 
DBPIVOT_FUNC dbpivot_lookup_name (const char name[])
 

Variables

static PIVOT_Tpivots = NULL
 
static size_t npivots = 0
 
static const struct name_t names []
 

Macro Definition Documentation

◆ tds_alloc_column

#define tds_alloc_column (   void)    ((TDSCOLUMN*) calloc(1, sizeof(TDSCOLUMN)))

Definition at line 654 of file dbpivot.c.

◆ TDS_FIND

#define TDS_FIND (   k,
  b,
 
)    tds_find(k, b, sizeof(b)/sizeof(b[0]), sizeof(b[0]), c)

Definition at line 56 of file dbpivot.c.

◆ TEST_CALLOC

#define TEST_CALLOC (   dest,
  type,
  n 
)     {if (!(dest = (type*)calloc((n), sizeof(type)))) goto Cleanup;}

Definition at line 651 of file dbpivot.c.

◆ TEST_MALLOC

#define TEST_MALLOC (   dest,
  type 
)     {if (!(dest = (type*)calloc(1, sizeof(type)))) goto Cleanup;}

Definition at line 647 of file dbpivot.c.

Typedef Documentation

◆ AGG_T

typedef struct agg_t AGG_T

◆ compare_func

typedef bool(* compare_func) (const void *, const void *)

Definition at line 58 of file dbpivot.c.

◆ KEY_T

typedef struct KEY_T KEY_T

◆ PIVOT_T

typedef struct pivot_t PIVOT_T

Function Documentation

◆ agg_equal()

static bool agg_equal ( const AGG_T p1,
const AGG_T p2 
)
static

Definition at line 623 of file dbpivot.c.

References assert, col_equal(), agg_t::col_key, i, KEY_T::keys, KEY_T::nkeys, and agg_t::row_key.

Referenced by dbpivot().

◆ agg_free()

static void agg_free ( AGG_T p)
static

Definition at line 615 of file dbpivot.c.

References col_free(), agg_t::col_key, key_free(), agg_t::row_key, and agg_t::value.

Referenced by dbpivot().

◆ agg_next()

static bool agg_next ( const AGG_T p1,
const AGG_T p2 
)
static

Definition at line 574 of file dbpivot.c.

References assert, col_equal(), agg_t::col_key, i, KEY_T::keys, KEY_T::nkeys, NULL, agg_t::row_key, and col_t::type.

Referenced by dbnextrow_pivoted().

◆ alloc_results()

static TDSRESULTINFO* alloc_results ( TDS_USMALLINT  num_cols)
static

◆ bind_type()

static int bind_type ( int  sybtype)
static

◆ col_buffer()

static void* col_buffer ( struct col_t pcol)
static

◆ col_cpy()

static struct col_t* col_cpy ( struct col_t pdest,
const struct col_t psrc 
)
static

Definition at line 276 of file dbpivot.c.

References assert, col_t::len, NULL, col_t::null_indicator, col_t::s, and tds_new.

Referenced by dbpivot(), and key_cpy().

◆ col_equal()

static bool col_equal ( const struct col_t pc1,
const struct col_t pc2 
)
static

◆ col_free()

static void col_free ( struct col_t p)
static

Definition at line 125 of file dbpivot.c.

References free(), and col_t::s.

Referenced by agg_free(), and key_free().

◆ col_init()

static struct col_t* col_init ( struct col_t pcol,
int  sybtype,
size_t  collen 
)
static

◆ col_null()

static bool col_null ( const struct col_t pcol)
static

Definition at line 295 of file dbpivot.c.

References assert, col_t::null_indicator, and true.

Referenced by dbnextrow_pivoted(), dbpivot_count(), dbpivot_max(), dbpivot_min(), and dbpivot_sum().

◆ dbnextrow_pivoted()

STATUS dbnextrow_pivoted ( DBPROCESS dbproc,
PIVOT_T pp 
)

◆ dbpivot()

RETCODE dbpivot ( DBPROCESS dbproc,
int  nkeys,
int keys,
int  ncols,
int cols,
DBPIVOT_FUNC  func,
int  val 
)

Pivot the rows, creating a new resultset.

Call dbpivot() immediately after dbresults(). It calls dbnextrow() as long as it returns REG_ROW, transforming the results into a cross-tab report. dbpivot() modifies the metadata such that DB-Library can be used tranparently: retrieve the rows as usual with dbnumcols(), dbnextrow(), etc.

@dbproc, our old friend @nkeys the number of left-edge columns to group by @keys an array of left-edge columns to group by @ncols the number of top-edge columns to group by @cols an array of top-edge columns to group by @func the aggregation function to use @val the number of the column to which @func is applied

Returns
the return code from the final call to dbnextrow(). Success is normally indicated by NO_MORE_ROWS.

Definition at line 926 of file dbpivot.c.

References _DB_RES_RESULTSET_EMPTY, _DB_RES_RESULTSET_ROWS, pivot_t::across, agg_equal(), agg_free(), assert, bind_type(), buffer, metadata_t::col, col_buffer(), col_cpy(), col_init(), agg_t::col_key, dbbind(), dbcollen(), dbcolname(), dbcoltype(), dbnextrow(), dbnullbind(), dbperror, pivot_t::dbproc, dbproc, tds_dblib_dbprocess::dbresults_state, pivot_t::dbresults_state, exit(), FAIL, i, input(), key_cpy(), key_equal(), key_free(), KEY_T::keys, len, make_col_name(), pivot_t::nacross, metadata_t::name, names, pivot_t::nout, npivots, NULL, pivot_t::output, P, metadata_t::pacross, pivot_key_equal(), pivots, REG_ROW, reinit_results(), agg_t::row_key, pivot_t::status, strdup, SUCCEED, SYBEMEM, SYBFLT8, TDS_DBG_FUNC, tds_find(), tds_new0, TDS_RESIZE, tds_dblib_dbprocess::tds_socket, tdsdump_log, val, and agg_t::value.

◆ dbpivot_count()

void dbpivot_count ( struct col_t tgt,
const struct col_t src 
)

Definition at line 1120 of file dbpivot.c.

References assert, col_null(), col_t::data, col_t::i, SYBINT4, and col_t::type.

◆ dbpivot_lookup_name()

DBPIVOT_FUNC dbpivot_lookup_name ( const char  name[])

Definition at line 1317 of file dbpivot.c.

References n, name_t::name, name_equal(), names, NULL, and TDS_FIND.

◆ dbpivot_max()

void dbpivot_max ( struct col_t tgt,
const struct col_t src 
)

◆ dbpivot_min()

void dbpivot_min ( struct col_t tgt,
const struct col_t src 
)

◆ dbpivot_sum()

void dbpivot_sum ( struct col_t tgt,
const struct col_t src 
)

◆ dbrows_pivoted()

PIVOT_T* dbrows_pivoted ( DBPROCESS dbproc)

Definition at line 799 of file dbpivot.c.

References assert, dbproc, npivots, P, pivot_key_equal(), pivots, and tds_find().

Referenced by dbnextrow().

◆ infer_col_type()

static TDS_SERVER_TYPE infer_col_type ( int  sybtype)
static

◆ join()

static char* join ( int  argc,
char *  argv[],
const char  sep[] 
)
static

◆ key_cpy()

static KEY_T* key_cpy ( KEY_T pdest,
const KEY_T psrc 
)
static

Definition at line 497 of file dbpivot.c.

References assert, col_cpy(), i, KEY_T::keys, KEY_T::nkeys, NULL, and tds_new0.

Referenced by dbnextrow_pivoted(), and dbpivot().

◆ key_equal()

static bool key_equal ( const KEY_T a,
const KEY_T b 
)
static

Definition at line 472 of file dbpivot.c.

References a, assert, b, col_equal(), and i.

Referenced by __WORKAROUND_RENAME(), dbpivot(), and CSourceModParser::GetModAllowedValues().

◆ key_free()

static void key_free ( KEY_T p)
static

Definition at line 489 of file dbpivot.c.

References col_free(), free(), and KEY_T::keys.

Referenced by agg_free(), and dbpivot().

◆ make_col_name()

static char* make_col_name ( DBPROCESS dbproc,
const KEY_T k 
)
static

Definition at line 518 of file dbpivot.c.

References assert, dbperror, dbproc, free(), join(), KEY_T::keys, names, KEY_T::nkeys, NULL, output, col_t::s, string_value(), SYBEMEM, and tds_new0.

Referenced by dbpivot().

◆ name_equal()

static bool name_equal ( const struct name_t n1,
const struct name_t n2 
)
static

Definition at line 1310 of file dbpivot.c.

References assert, name_t::name, and util::strcmp().

Referenced by dbpivot_lookup_name().

◆ pivot_key_equal()

static bool pivot_key_equal ( const PIVOT_T a,
const PIVOT_T b 
)
static

Definition at line 788 of file dbpivot.c.

References a, assert, b, and true.

Referenced by dbpivot(), and dbrows_pivoted().

◆ reinit_results()

static bool reinit_results ( TDSSOCKET tds,
TDS_USMALLINT  num_cols,
const struct metadata_t  meta[] 
)
static

◆ set_result_column()

static TDSRET set_result_column ( TDSSOCKET tds,
TDSCOLUMN curcol,
const char  name[],
const struct col_t pvalue 
)
static

◆ string_value()

static char* string_value ( const struct col_t pcol)
static

◆ tds_find()

static void* tds_find ( const void *  key,
const void *  base,
size_t  nelem,
size_t  width,
compare_func  compar 
)
static

Definition at line 61 of file dbpivot.c.

References i, ncbi::grid::netcache::search::fields::key, and NULL.

Referenced by dbnextrow_pivoted(), dbpivot(), and dbrows_pivoted().

Variable Documentation

◆ names

const struct name_t names[]
static
Initial value:
=
{ { "count", dbpivot_count }
, { "sum", dbpivot_sum }
, { "min", dbpivot_min }
, { "max", dbpivot_max }
}
void dbpivot_count(struct col_t *tgt, const struct col_t *src)
Definition: dbpivot.c:1120
void dbpivot_min(struct col_t *tgt, const struct col_t *src)
Definition: dbpivot.c:1188
void dbpivot_max(struct col_t *tgt, const struct col_t *src)
Definition: dbpivot.c:1244
void dbpivot_sum(struct col_t *tgt, const struct col_t *src)
Definition: dbpivot.c:1132

Referenced by CTabDelimitedValidator::_MakeColumns(), CTableNames::AllTableNames(), AppendNamesParameter(), CExplodeRNAFeats::apply(), NMacroUtil::ApplyAuthorNames(), CRemoveSeqFromAlignDlg::ApplyToCSeq_entry(), BOOST_AUTO_TEST_CASE(), CHugeMacroContext::CacheTaxnames(), CCgiEnvHolder::CCgiEnvHolder(), CheckDelGbblockSource(), CheckDelGbblockSourceFromDescrs(), CCodeGenerator::CheckFileNames(), CInvalidChoiceSelection::CInvalidChoiceSelection(), CCleanup::CleanupAuthList(), CSubjectsSequenceCoverage::Create(), CDriverManager::CreateDsFrom(), dbpivot(), dbpivot_lookup_name(), pub_report::DoHydraSearch(), CNcbiEnvironment::Enumerate(), CNSTDatabase::ExecSP_GetClients(), fix_pub::ExtractConsortiums(), FindOrgNames(), pub_report::FirstOrLastAuthorMatches(), fta_fix_affil(), CClassTypeStrings::GenerateClassCode(), CChoiceTypeStrings::GenerateClassCode(), CEnumTypeStrings::GenerateTypeCode(), CSynRegistry::Get(), CSGFeatureJob::GetAnnotNames(), CSGAlignmentJob::GetAnnotNames(), CSGSeqGraphJob::GetAnnotNames(), CSGFeatureDS::GetAnnotNames(), CSGSegmentMapDS::GetAnnotNames(), CSGAlignmentDS::GetAnnotNames(), CSGGraphDS::GetAnnotNames(), CSGFeatureJob::GetAnnotNames_var(), CSGFeatureDS::GetAnnotNames_var(), SNetStorageObjectRPC::GetAttributeList(), CCgiSession_NetCache::GetAttributeNames(), CReferenceItem::GetAuthNames(), GetAuthorMatchStrings(), pub_report::GetAuthorsFromList(), CColumnarVCFReader::GetChromosomeNames(), CRawSeqDBSource::GetColumnNames(), CClusterDBSource::GetColumnNames(), CRemoveSeqFromAlignDlg::GetCommand(), CProjectViewBase::GetCompatibleToolBars(), CTableView::GetCompatibleToolBars(), CFeatTableView::GetCompatibleToolBars(), CViewGraphic::GetCompatibleToolBars(), CSequinDesktopView::GetCompatibleToolBars(), CTextView::GetCompatibleToolBars(), CVcfTableView::GetCompatibleToolBars(), CTableViewWithTextViewNav::GetCompatibleToolBars(), CDDTypedAnnotDialog::GetData(), CEntrezDB::GetDbNames(), GetDiscrepancyNames(), GetDiscrepancyTests(), CAppEnvHolder::GetEnv(), CMacroEditorContext::GetFeatQualifiers(), CSeqGraphicPane::GetFeatureNames(), fix_pub::GetFirstTenNames(), CAuth_list::GetLabelV1(), CAuth_list::GetLabelV2(), CTypeStrings::GetModuleName(), CFileCode::GetModuleNames(), CInvalidChoiceSelection::GetName(), CGBDataLoader_Native::GetNamedAnnotAccessions(), CPSGDataLoader::GetNamedAnnotAccessions(), SRequestBuilder::SReader< CJson_ConstObject >::GetNamedAnnots(), CWithdrawSequences::GetNames(), CCSRAFileInfo::GetPossibleAnnotNames(), CSNPFileInfo::GetPossibleAnnotNames(), CBAMDataLoader_Impl::GetPossibleAnnotNames(), CCSRADataLoader_Impl::GetPossibleAnnotNames(), CSNPDataLoader_Impl::GetPossibleAnnotNames(), CVDBGraphDataLoader_Impl::GetPossibleAnnotNames(), GetPrimerSetNameValues(), GetProtRefAnnot(), CQueueDataBase::GetQueueNames(), CClassTypeInfoBase::GetRegisteredClassNames(), CObjectManager::GetRegisteredNames(), CPhyloTreeWidget::GetRenderersNames(), CVariantDescriptors::GetSampleNames(), CHitMatrixDataSource::GetScoreNames(), CSGSeqGraphJob::GetSeqtableAnnots(), CSGGraphDS::GetSeqtableAnnots(), ShowHideManager::GetShowHideInfo(), CCdDbPriority::GetSourceNames(), CCSraDb_Impl::GetSpotGroups(), GetTaxnameName(), GetTaxnameNameFromDescrs(), CProjectViewToolBatFactory::GetToolBarNames(), CFrameworkDemoToolBarFactory::GetToolBarNames(), CDataMiningService::GetToolNames(), CUIToolRegistry::GetToolNames(), CBinsDS::GetTrackNames(), CSGHapmapDS::GetTrackNames(), CLDBlockDS::GetTrackNames(), CFeatTableDS::GetTypeNames(), GetVDBScope(), CAlnMultiRenderer::GetVisibleColumns(), CSynRegistry::Has(), CValidError_imp::HasName(), CTextTableModel::Init(), SRemoteCgi::Input(), CStdAnnotTypes::IsPredefinedDescr(), CStdAnnotTypes::IsPredefinedDescrForType(), CCompoundRWRegistry::LoadBaseRegistries(), CProcessor_AnnotInfo::LoadBlob(), CReader::LoadBlobs(), CDataTool::LoadDefinitions(), CUIToolRegistry::LoadSettings(), CWidgetDisplayStyle::LoadSettings(), CStdAnnotTypes::LoadTypes(), CCgiApplication::LogRequest(), make_col_name(), MaybeCutGbblockSource(), mdb_txn_end(), CDataMiningPanel::OnAutorun(), CHitMatrixWidget::OnColorByScore(), CProjectTreeViewDropTarget::OnData(), CMultiFileInput::CDropTarget::OnData(), CFrameworkDemoGUIDropTarget::OnData(), CPubseqGatewayApp::OnGetNA(), StructureWindow::OnSelect(), OrderQual(), CColumnValidatorRegistry::PrintSupported(), CDiscRepArgDescriptions::PrintUsage(), CCgiSampleApplication::ProcessPrintEnvironment(), CCgiSessionSampleApplication::ProcessRequest(), CDistanceMatrix::Read(), RemoveConsortium(), CWindowManagerService::RemoveToolBarContext(), CCleanup::ResetAuthorNames(), CExplodeRNAFeats::RNAWordsFromString(), CNcbiApplogApp::Run(), CDemoApp::Run(), s_AddLatencyOptions(), s_AddPrimers(), s_AppendPrimerNames(), s_AuthListEmpty(), s_CreateNAChunk(), CFeatureFieldNamePanel::s_FillFeatQualList(), s_GetNameForDescription(), CMacroFunction_PubFields::s_GetObjectsFromAuthListNames(), CMacroFunction_PubFields::s_GetObjectsFromPersonID(), s_GetPrimerInfo(), CMacroFunction_AuthorFix::s_MoveMiddleToFirst(), s_NamesNotSet(), s_NumAuthors(), s_ParseEnabledFlags(), s_SetLogFilesDir(), s_SetPrimerNames(), CCacheWriter::SaveSeq_idBlob_ids(), CWidgetDisplayStyle::SaveSettings(), CDataMiningPanel::SelectToolByName(), CCassNamedAnnotFetch::Serialize(), SPSGS_AnnotRequest::Serialize(), SetAuthorNames(), CDataMiningPanel::SetService(), CHttpCookies::sx_RevertDomain(), tds7_get_instance_ports(), tds_iconv_open(), tds_process_colinfo(), tds_process_tabname(), tds_set_server(), CSynRegistry::TGet(), CMacroFunction_ReplaceStopWithSelenocysteine::TheFunction(), CIndexedDb_New::TraceNames(), CDiscrepancyContext::TypeName(), CValidError_imp::ValidateAuthorList(), CValidError_imp::ValidateAuthorsInPubequiv(), CValidError_imp::ValidateSubmitBlock(), CSequenceEditingEventHandler::WithdrawSequences(), WriteEnvironment(), CMacroFunction_AddPubAuthor::x_AddAuthor(), CReferenceItem::x_AddAuthors(), CFeatureItem::x_AddQualCdsProduct(), CFeatureItem::x_AddQualsProt(), CMakeBlastDBApp::x_BuildDatabase(), CSubmitBlockDlg::x_CopyAuthors(), CSubmitBlockDlg::x_CreateBlock(), CQueueDataBase::x_DumpQueueOrClass(), CPSGS_AnnotProcessor::x_FilterNames(), CAnnot_Collector::x_GetAnnotNames(), CPubseqGatewayApp::x_GetNames(), CEditingActionBiosourceTaxnameAfterBinomial::x_GetTextAfterNomial(), CSrcTaxnameAfterBinomialColumn::x_GetTextAfterNomial(), CRequestContext::x_LoadEnvContextProperties(), CMacroFunction_AuthorFix::x_MakeAuthorChanges(), CPSGDataLoader_Impl::x_MakeLoadLocalCDDEntryRequest(), CSettingsSet::x_MakeUniqueStyleName(), CPSGS_CDDProcessor::x_NameIncluded(), CTable2AsnValidator::x_PopulateDiscrepancy(), CNetStorageHandler::x_ProcessGetAttrList(), CMakeBlastDBApp::x_ProcessInputData(), CFastCgiApplicationMT::x_ProcessThreadedRequest(), CQueueDataBase::x_ReadDumpQueueDesrc(), CWindowManagerService::x_ShowToolBar(), CAlignTabExportPage2::x_StartAlignNamesJob(), CAlignTabExportPage2::x_StartNAAlignNamesJob(), CDescrModApply::x_TryPCRPrimerMod(), CFeatModApply::x_TryProtRefMod(), CWindowsDlg::x_UpdateTable(), CGff2Writer::xAssignFeatureAttributeProduct(), CSrcWriter::xGather(), and CSrcWriter::xPrimerSetNames().

◆ npivots

size_t npivots = 0
static

Definition at line 796 of file dbpivot.c.

Referenced by dbpivot(), and dbrows_pivoted().

◆ pivots

PIVOT_T* pivots = NULL
static

Definition at line 795 of file dbpivot.c.

Referenced by dbpivot(), and dbrows_pivoted().

Modified on Tue Apr 09 07:59:29 2024 by modify_doxy.py rev. 669887
Modified on Wed Apr 10 07:34:48 2024 by modify_doxy.py rev. 669887
Modified on Thu Apr 11 15:16:28 2024 by modify_doxy.py rev. 669887
Modified on Fri Apr 12 17:21:28 2024 by modify_doxy.py rev. 669887
Modified on Sat Apr 13 11:49:01 2024 by modify_doxy.py rev. 669887
Modified on Sun Apr 14 05:28:33 2024 by modify_doxy.py rev. 669887
Modified on Tue Apr 16 20:13:25 2024 by modify_doxy.py rev. 669887
Modified on Wed Apr 17 13:10:25 2024 by modify_doxy.py rev. 669887