- BORLAND/: Borland C++ 4.52 (chosen over 4.5 by byte-match: CODE/RP/CW32.LIB
is identical to 4.52's install lib). BCC32/TLINK32/TLIB/MAKE run natively on
Win11; CODE/BT/OPT.MAK is the shipped BTL4OPT.EXE's exact flag recipe
(extender = Borland PowerPack DPMI32, not Phar Lap TNT).
- restoration/source410/: the literal 1995-form reconstruction of the missing
BT game source (never mixed into CODE/). Round 1-3 state:
* 6 of 10 surviving original TUs COMPILE CLEAN under the period toolchain
(BTMSSN, BTCNSL, BTSCNRL, BTTEAM, BTL4MODE, BTL4ARND) - first builds
since 1996.
* BT_L4/BTL4APP.CPP pilot reconstruction: 12/12 functions, Fail() lands on
its binary-recorded line 400 exactly.
* BT/BTCNSL.HPP: console wire IDs recovered from the binary's ctors
(Killed=9, Damaged=10, ScoreUpdate=13, DeathWithoutHonor=15 [T1];
TeamScore=12 flagged [T4]).
* MUNGA/: 8 engine-header backfills back-dated from the BT412 WinTesla tree
(VDATA numbering decomp-verified; AUDREND's OpenAL-era virtual removed -
the period compiler is the drift detector).
* Tooling: backdate.py (WinTesla->1995 header transform), compile410.sh
(per-TU verification sweep under authentic OPT.MAK flags).
* README: corrected roadmap - MECH.HPP is the capstone grown with the mech
TU reconstructions; BTREG.CPP green = the header-family milestone.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
318 lines
12 KiB
C++
318 lines
12 KiB
C++
// BDE - (C) Copyright 1995 by Borland International
|
|
|
|
// optparam.c
|
|
#include "snipit.h"
|
|
|
|
static const char szTblName[] = "OPTPARAM";
|
|
static const char szTblType[] = szPARADOX;
|
|
|
|
#define NAMELEN 10 // Length of the name field
|
|
|
|
// Field descriptor used in creating a table.
|
|
static SNIPFAR FLDDesc fldDesc[] = {
|
|
{ // Field 1 - AUTOINC
|
|
1, // Field number
|
|
"NUMBER", // Field name
|
|
fldFLOAT, // Field type
|
|
fldUNKNOWN, // Field subtype
|
|
0, // Field size (1 or 0, except
|
|
// BLOB or CHAR field)
|
|
0, // Decimal places ( 0 )
|
|
// computed
|
|
0, // Offset in record ( 0 )
|
|
0, // Length in bytes ( 0 )
|
|
0, // For NULL bits ( 0 )
|
|
fldvNOCHECKS, // Validity checks ( 0 )
|
|
fldrREADWRITE // Rights
|
|
},
|
|
{ // Field 2 - ALPHA
|
|
2, "ALPHA", fldZSTRING, fldUNKNOWN,
|
|
NAMELEN, 0, 0, 0, 0,
|
|
fldvNOCHECKS, fldrREADWRITE
|
|
}
|
|
}; // Array of field descriptors.
|
|
|
|
// The number of fields in the table.
|
|
static const unsigned uNumFields = sizeof(fldDesc) / sizeof (fldDesc[0]);
|
|
|
|
static DBIResult GetOptionalParams(pCHAR szDriver, UINT16 *iFields,
|
|
pFLDDesc pfldDesc, pCHAR szData);
|
|
|
|
//=====================================================================
|
|
// Function:
|
|
// OptParam();
|
|
//
|
|
// Description:
|
|
// This function shows how to use the optional parameters
|
|
// on some of the BDE functions.
|
|
//=====================================================================
|
|
void
|
|
OptParam (void)
|
|
{
|
|
DBIResult rslt; // Return value from IDAPI functions
|
|
hDBIDb hDb; // Handle to the database
|
|
hDBICur hCur; // Handle to the table
|
|
CRTblDesc TblDesc; // Create table descriptor
|
|
UINT16 uDispNumRecs = 10 ; // Number of records to add and
|
|
// display
|
|
CURProps curProps; // Cursor properties
|
|
pFLDDesc pfldDesc; // Field descriptor for optional
|
|
// parameters
|
|
UINT16 iFields; // Number of fields (optional
|
|
// parameters)
|
|
UINT16 i; // Loop counter
|
|
UINT16 iOffset; // Offset in the default values buffer
|
|
CHAR szFieldName[DBIMAXSCRECSIZE]; // Field name
|
|
CHAR szDefault[DBIMAXSCRECSIZE]; // Default values for
|
|
// optional parameters
|
|
pCHAR szTemp; // Temporary buffer
|
|
pCHAR szData; // Data to display
|
|
|
|
Screen("*** Using Optional Parameters ***\r\n");
|
|
|
|
BREAK_IN_DEBUGGER();
|
|
|
|
Screen(" Initializing IDAPI...");
|
|
if (InitAndConnect(&hDb) != DBIERR_NONE)
|
|
{
|
|
Screen("\r\n*** End of Example ***");
|
|
return;
|
|
}
|
|
|
|
Screen(" Setting the database directory...");
|
|
rslt = DbiSetDirectory(hDb, (pCHAR) szTblDirectory);
|
|
ChkRslt(rslt, "SetDirectory");
|
|
|
|
szTemp = (pCHAR) malloc(DBIMAXSCFLDLEN);
|
|
szData = (pCHAR) malloc(DBIMAXSCRECSIZE);
|
|
pfldDesc = (pFLDDesc) malloc(DBIMAXSCFIELDS * sizeof(FLDDesc));
|
|
if ((szTemp == NULL) || (szData == NULL) || (pfldDesc == NULL))
|
|
{
|
|
Screen(" Error - Out of Memory!");
|
|
if (szTemp) free(szTemp);
|
|
if (szData) free(szData);
|
|
if (pfldDesc) free(pfldDesc);
|
|
CloseDbAndExit(&hDb);
|
|
Screen("\r\n*** End of Example ***");
|
|
return;
|
|
}
|
|
|
|
// Initialize the pfldDesc variable to all zeroes.
|
|
memset((void*) pfldDesc , 0, sizeof(FLDDesc) * DBIMAXSCFIELDS);
|
|
|
|
// Get the field types and default values of the optional
|
|
// parameters available when creating a Paradox table.
|
|
GetOptionalParams("PARADOX", &iFields, pfldDesc, szData);
|
|
|
|
Screen("\r\n Default values for optional parameters...\r\n");
|
|
strcpy(szFieldName, " ");
|
|
strcpy(szDefault, " ");
|
|
iOffset = 0;
|
|
for (i = 0; i < iFields; i++)
|
|
{
|
|
// Note: Fields are formatted to be 20 characters wide
|
|
// in order to better fit on the screen (Field widths
|
|
// default to 128).
|
|
sprintf(szTemp, "%-*s\t", 20, pfldDesc[i].szName);
|
|
strcat(szFieldName, szTemp);
|
|
sprintf(szTemp, " %-*s\t", 20, &szData[iOffset]);
|
|
strcat(szDefault, szTemp);
|
|
|
|
// Create the table as a 3.5 table.
|
|
if (! strcmp(pfldDesc[i].szName, "LEVEL"))
|
|
{
|
|
strcpy(&szData[iOffset], "3");
|
|
}
|
|
|
|
// Set the maximum size of the table to 256MB.
|
|
if (! strcmp(pfldDesc[i].szName, "BLOCK SIZE"))
|
|
{
|
|
strcpy(&szData[iOffset], "4096");
|
|
}
|
|
|
|
// Increment to point to the next field within the
|
|
// array of default values.
|
|
iOffset += pfldDesc[i].iLen;
|
|
}
|
|
|
|
Screen(szFieldName);
|
|
Screen(szDefault);
|
|
|
|
Screen("\r\n Change optional parameters to...\r\n");
|
|
strcpy(szFieldName, " ");
|
|
strcpy(szDefault, " ");
|
|
iOffset = 0;
|
|
for (i = 0; i < iFields; i++)
|
|
{
|
|
// Note: Fields are formatted to be 20 characters wide
|
|
// in order to better fit on the screen (field widths
|
|
// default to 128).
|
|
sprintf(szTemp, "%-*s\t", 20, pfldDesc[i].szName);
|
|
strcat(szFieldName, szTemp);
|
|
sprintf(szTemp, " %-*s\t", 20, &szData[iOffset]);
|
|
strcat(szDefault, szTemp);
|
|
|
|
// Increment to point to the next field within the
|
|
// array of default values.
|
|
iOffset += pfldDesc[i].iLen;
|
|
}
|
|
|
|
Screen(szFieldName);
|
|
Screen(szDefault);
|
|
|
|
Screen("\r\n Initializing the table descriptor...");
|
|
memset((void *) &TblDesc, 0, sizeof(CRTblDesc));
|
|
lstrcpy(TblDesc.szTblName, szTblName);
|
|
lstrcpy(TblDesc.szTblType, szTblType);
|
|
TblDesc.iFldCount = uNumFields;
|
|
TblDesc.pfldDesc = fldDesc;
|
|
TblDesc.iOptParams = iFields;
|
|
TblDesc.pfldOptParams = pfldDesc;
|
|
TblDesc.pOptData = (pBYTE) szData;
|
|
|
|
Screen("\r\n Creating the Paradox table...");
|
|
rslt = DbiCreateTable(hDb, TRUE, &TblDesc);
|
|
if (ChkRslt(rslt, "CreateTable") != DBIERR_NONE)
|
|
{
|
|
free(szTemp);
|
|
free(szData);
|
|
free(pfldDesc);
|
|
CloseDbAndExit(&hDb);
|
|
Screen("\r\n*** End of Example ***");
|
|
return;
|
|
}
|
|
|
|
free(pfldDesc);
|
|
|
|
Screen(" Fill the table with random data...");
|
|
FillTable(hDb, (pCHAR) szTblName, (pCHAR) szTblType, uDispNumRecs);
|
|
|
|
Screen(" Open the %s table...", szTblName);
|
|
rslt = DbiOpenTable(hDb, (pCHAR) szTblName, (pCHAR) szTblType,
|
|
NULL, NULL, 0, dbiREADWRITE, dbiOPENSHARED,
|
|
xltFIELD, FALSE, NULL, &hCur);
|
|
if (ChkRslt(rslt, "OpenTable") != DBIERR_NONE)
|
|
{
|
|
rslt = DbiDeleteTable(hDb, (pCHAR) szTblName, (pCHAR) szTblType);
|
|
ChkRslt(rslt, "DeleteTable");
|
|
CloseDbAndExit(&hDb);
|
|
Screen("\r\n*** End of Example ***");
|
|
return;
|
|
}
|
|
|
|
Screen("\r\n Determine the properties of the table:");
|
|
rslt = DbiGetCursorProps(hCur, &curProps);
|
|
ChkRslt(rslt, "GetCursorProps");
|
|
|
|
Screen(" Table Level: %d", curProps.iTblLevel);
|
|
Screen(" Table block size: %d", (curProps.iBlockSize * 1024));
|
|
|
|
Screen("\r\n Display the %s table which we just created...", szTblName);
|
|
DisplayTable(hCur, uDispNumRecs);
|
|
|
|
Screen("\r\n Close the table...");
|
|
rslt = DbiCloseCursor(&hCur);
|
|
ChkRslt(rslt, "CloseCursor");
|
|
|
|
Screen(" Deleting the table...");
|
|
rslt = DbiDeleteTable(hDb, (pCHAR) szTblName, (pCHAR) szTblType);
|
|
ChkRslt(rslt, "DeleteTable");
|
|
|
|
Screen("\r\n Close the database and exit IDAPI...");
|
|
CloseDbAndExit(&hDb);
|
|
|
|
free(szTemp);
|
|
free(szData);
|
|
Screen("\r\n*** End of Example ***");
|
|
}
|
|
|
|
//=====================================================================
|
|
// Function:
|
|
// GetOptionalParams(pCHAR szDriver, UINT16 *iFields,
|
|
// pFLDDesc pfldDesc, pCHAR szData);
|
|
//
|
|
// Input: szDriver - Name of the driver
|
|
// iFields - Used to return the number of fields
|
|
// pfldDesc - Returns the descriptors of the fields
|
|
// Memory for this variable must be allocated by
|
|
// the calling function
|
|
// szData - Contains the values of the fields. Memory for
|
|
// this variable must be allocated by the calling
|
|
// function
|
|
//
|
|
// Return: DBIResult - success of the function
|
|
//
|
|
// Description:
|
|
// This function is used to return the available optional
|
|
// parameters when creating a table of the given type. This
|
|
// information includes the number of optional parameters
|
|
// (iFields), an array of field descriptors describing those
|
|
// parameters, and the default values for the parameters.
|
|
// Optional parameters are available only for dBASE and
|
|
// Paradox tables.
|
|
//=====================================================================
|
|
DBIResult
|
|
GetOptionalParams(pCHAR szDriver, UINT16 *iFields,
|
|
pFLDDesc pfldDesc, pCHAR szData)
|
|
{
|
|
DBIResult rslt; // Return value from IDAPI functions
|
|
hDBICur hCur; // Handle to the cursor
|
|
pCHAR szNode; // String which contains the name of the node
|
|
pCFGDesc CfgDesc; // Configuration descriptor
|
|
DBIPATH szCfgPath; // Maximum length of the path
|
|
// in the configuration file
|
|
UINT16 iOffset = 0; // Offset in the buffer
|
|
|
|
*iFields = 0;
|
|
|
|
// Set up the option to get from the configuration file.
|
|
strcpy(szCfgPath, "\\DRIVERS\\");
|
|
strcat(szCfgPath, szDriver);
|
|
strcat(szCfgPath, "\\TABLE CREATE\\");
|
|
|
|
rslt = DbiOpenCfgInfoList(NULL, dbiREADONLY, cfgPersistent, szCfgPath,
|
|
&hCur);
|
|
if (ChkRslt(rslt, "OpenCfgInfoList") != DBIERR_NONE)
|
|
{
|
|
return rslt;
|
|
}
|
|
|
|
// Allocate resources.
|
|
szNode = (pCHAR) malloc((DBIMAXPATHLEN * sizeof(CHAR)) + 1);
|
|
CfgDesc = (pCFGDesc) malloc(sizeof(CFGDesc));
|
|
if ((szNode == NULL) || (CfgDesc == NULL))
|
|
{
|
|
if (szNode) free(szNode);
|
|
if (CfgDesc) free(CfgDesc);
|
|
rslt = DbiCloseCursor(&hCur);
|
|
ChkRslt(rslt, "CloseCursor");
|
|
}
|
|
|
|
// Process all nodes.
|
|
// Get the next record in the table - contains the next option
|
|
// of the given level in the tree.
|
|
while (DbiGetNextRecord(hCur, dbiNOLOCK, (pBYTE)CfgDesc, NULL)
|
|
== DBIERR_NONE)
|
|
{
|
|
pfldDesc[*iFields].iFldNum = *iFields + 1;
|
|
pfldDesc[*iFields].iFldType = CfgDesc->iDataType;
|
|
pfldDesc[*iFields].iUnits1 = DBIMAXSCFLDLEN - 1;
|
|
pfldDesc[*iFields].iLen = DBIMAXSCFLDLEN;
|
|
strcpy(pfldDesc[*iFields].szName, CfgDesc->szNodeName);
|
|
|
|
sprintf(szNode, "%s", CfgDesc->szValue);
|
|
strcpy(&szData[iOffset], szNode);
|
|
iOffset += pfldDesc[*iFields].iLen;
|
|
(*iFields)++;
|
|
}
|
|
|
|
// Clean up.
|
|
free(szNode);
|
|
free((pCHAR) CfgDesc);
|
|
rslt = DbiCloseCursor(&hCur);
|
|
ChkRslt(rslt, "CloseCursor");
|
|
|
|
return rslt;
|
|
}
|
|
|