Exemple #1
0
CString CreateDataFieldFromItemList (const TArray<CItem> &List)

//	CreateDataFieldFromItemList
//
//	Creates a data field string from a list of items

	{
	int i;
	CCodeChain &CC = g_pUniverse->GetCC();

	CMemoryWriteStream Output(10000);
	if (Output.Create() != NOERROR)
		return NULL_STR;

	Output.Write("='(", 3);
	for (i = 0; i < List.GetCount(); i++)
		{
		ICCItem *pItem = List[i].WriteToCCItem(CC);
		if (pItem->IsError())
			{
			pItem->Discard(&CC);
			return NULL_STR;
			}

		CString sItem = pItem->Print(&CC);
		Output.Write(sItem.GetASCIIZPointer(), sItem.GetLength());
		Output.Write(" ", 1);

		pItem->Discard(&CC);
		}
	Output.Write(")", 1);
	Output.Close();

	return CString(Output.GetPointer(), Output.GetLength());
	}
Exemple #2
0
ICCItem *CCPrimitive::Execute (CEvalContext *pCtx, ICCItem *pArgs)

//	Execute
//
//	Executes the function and returns a result

	{
	bool bCustomArgEval = ((m_dwFlags & PPFLAG_CUSTOM_ARG_EVAL) ? true : false);

	//	Evaluate args, if necessary

	ICCItem *pEvalArgs;
	if (!bCustomArgEval)
		{
		pEvalArgs = pCtx->pCC->EvaluateArgs(pCtx, pArgs, m_sArgPattern);
		if (pEvalArgs->IsError())
			return pEvalArgs;
		}
	else
		pEvalArgs = pArgs;

	//	Invoke the function

	ICCItem *pResult;
	bool bReportError = false;
	try
		{
		pResult = m_pfFunction(pCtx, pEvalArgs, m_dwData);
		}
	catch (...)
		{
		bReportError = true;
		}

	//	Report error

	if (bReportError)
		{
		CString sArgs;
		try
			{
			sArgs = pEvalArgs->Print(pCtx->pCC);
			}
		catch (...)
			{
			sArgs = CONSTLIT("[invalid arg item]");
			}

		CString sError = strPatternSubst(CONSTLIT("Exception in %s; arg = %s"), m_sName, sArgs);
		pResult = pCtx->pCC->CreateError(sError, pEvalArgs);
		kernelDebugLogMessage(sError.GetASCIIZPointer());
		}

	//	Done

	if (!bCustomArgEval)
		pEvalArgs->Discard(pCtx->pCC);

	return pResult;
	}
Exemple #3
0
void OutputTable (SItemTableCtx &Ctx, const SItemTypeList &ItemList)
	{
	int i, j;

	if (ItemList.GetCount() == 0)
		return;

	//	Output each row

	for (i = 0; i < ItemList.GetCount(); i++)
		{
		CItemType *pType = ItemList[i];

		for (j = 0; j < Ctx.Cols.GetCount(); j++)
			{
			if (j != 0)
				printf("\t");

			const CString &sField = Ctx.Cols[j];

			//	Get the field value

			CString sValue;
			CItem Item(pType, 1);
			CItemCtx ItemCtx(Item);
			CCodeChainCtx CCCtx;

			ICCItem *pResult = Item.GetProperty(&CCCtx, ItemCtx, sField);

			if (pResult->IsNil())
				sValue = NULL_STR;
			else
				sValue = pResult->Print(&g_pUniverse->GetCC(), PRFLAG_NO_QUOTES | PRFLAG_ENCODE_FOR_DISPLAY);

			pResult->Discard(&g_pUniverse->GetCC());

			//	Format the value

			if (strEquals(sField, FIELD_AVERAGE_DAMAGE) || strEquals(sField, FIELD_POWER_PER_SHOT))
				printf("%.2f", strToInt(sValue, 0, NULL) / 1000.0);
			else if (strEquals(sField, FIELD_POWER))
				printf("%.1f", strToInt(sValue, 0, NULL) / 1000.0);
			else if (strEquals(sField, FIELD_TOTAL_COUNT))
				{
				SDesignTypeInfo *pInfo = Ctx.TotalCount.GetAt(pType->GetUNID());
				double rCount = (pInfo ? pInfo->rPerGameMeanCount : 0.0);
				printf("%.2f", rCount);
				}
			else
				printf(sValue.GetASCIIZPointer());
			}

		printf("\n");
		}
	}
CString CCSymbolTable::Print (CCodeChain *pCC, DWORD dwFlags)

//	Print
//
//	Render as text

	{
	int i;

	CMemoryWriteStream Stream;
	if (Stream.Create() != NOERROR)
		return CONSTLIT("ERROR-OUT-OF-MEMORY");

	//	Open paren

	Stream.Write("{ ", 2);

	//	Write items

	for (i = 0; i < m_Symbols.GetCount(); i++)
		{
		CString sKey = CCString::Print(m_Symbols.GetKey(i));
		Stream.Write(sKey.GetASCIIZPointer(), sKey.GetLength());
		Stream.Write(":", 1);

		ICCItem *pValue = dynamic_cast<ICCItem *>(m_Symbols.GetValue(i));
		CString sValue = pValue->Print(pCC);
		Stream.Write(sValue.GetASCIIZPointer(), sValue.GetLength());

		Stream.Write(" ", 1);
		}

	//	Close paren

	Stream.Write("}", 1);
	return CString(Stream.GetPointer(), Stream.GetLength());
	}
Exemple #5
0
void OutputTable (SItemTableCtx &Ctx, const SItemTypeList &ItemList)
	{
	int i, j;

	if (ItemList.GetCount() == 0)
		return;

	//	Output each row

	for (i = 0; i < ItemList.GetCount(); i++)
		{
		CItemType *pType = ItemList[i];
		CItem Item(pType, 1);
		CItemCtx ItemCtx(Item);

		for (j = 0; j < Ctx.Cols.GetCount(); j++)
			{
			if (j != 0)
				printf("\t");

			const CString &sField = Ctx.Cols[j];

            //  Handle some special fields

            if (strEquals(sField, FIELD_BENCHMARK))
                {
                CWeaponBenchmarkCtx::SStats Stats;
                if (!Ctx.WeaponBenchmarks.GetStats(pType, Stats))
                    {
                    printf("\t\t\t\t");
                    }
                else
                    {
                    CString sBestArmor;
                    if (Stats.pBestArmor)
                        {
                        CItem BestArmor(Stats.pBestArmor, 1);
                        sBestArmor = BestArmor.GetNounPhrase(nounShort);
                        }

                    CString sWorstArmor;
                    if (Stats.pWorstArmor)
                        {
                        CItem WorstArmor(Stats.pWorstArmor, 1);
                        sWorstArmor = WorstArmor.GetNounPhrase(nounShort);
                        }

                    printf("%d\t%s\t%d\t%s\t%d",
                            Stats.iAverageTime,
                            (LPSTR)sBestArmor,
                            Stats.iBestTime,
                            (LPSTR)sWorstArmor,
                            Stats.iWorstTime);
                    }
                }

            else if (strEquals(sField, FIELD_BALANCE_STATS))
                {
                CDeviceClass *pDevice = pType->GetDeviceClass();
                CWeaponClass *pWeapon = NULL;

                if (pDevice)
                    pWeapon = pDevice->AsWeaponClass();
                else if (pType->IsMissile() && ItemCtx.ResolveVariant())
                    {
                    pDevice = ItemCtx.GetVariantDevice();
                    pWeapon = pDevice->AsWeaponClass();
                    }

                if (pWeapon)
                    {
                    CWeaponClass::SBalance Balance;
                    pWeapon->CalcBalance(ItemCtx, Balance);
                    printf("%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f",
                            Balance.rBalance,
                            Balance.rBalance - Balance.rCost,
                            Balance.rDamage,
                            Balance.rDamageType,
                            Balance.rAmmo,
                            Balance.rOmni,
                            Balance.rTracking,
                            Balance.rRange,
                            Balance.rSpeed,
                            Balance.rWMD,
                            Balance.rRadiation,
                            Balance.rMining,
                            Balance.rShatter,
                            Balance.rDeviceDisrupt,
                            Balance.rDeviceDamage,
                            Balance.rDisintegration,
                            Balance.rShieldPenetrate,
                            Balance.rArmor,
                            Balance.rShield,
                            Balance.rProjectileHP,
                            Balance.rPower,
                            Balance.rCost,
                            Balance.rSlots,
                            Balance.rExternal,
                            Balance.rLinkedFire,
                            Balance.rRecoil
                            );
                    }
                else
                    printf("\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t");
                }

			//	Get the field value

            else
                {
			    CString sValue;
			    CCodeChainCtx CCCtx;

			    ICCItem *pResult = Item.GetProperty(&CCCtx, ItemCtx, sField);

			    if (pResult->IsNil())
				    sValue = NULL_STR;
			    else
				    sValue = pResult->Print(&g_pUniverse->GetCC(), PRFLAG_NO_QUOTES | PRFLAG_ENCODE_FOR_DISPLAY);

			    pResult->Discard(&g_pUniverse->GetCC());

			    //	Format the value

			    if (strEquals(sField, FIELD_POWER_PER_SHOT))
				    printf("%.2f", strToInt(sValue, 0, NULL) / 1000.0);
			    else if (strEquals(sField, FIELD_POWER))
				    printf("%.1f", strToInt(sValue, 0, NULL) / 1000.0);
			    else if (strEquals(sField, FIELD_TOTAL_COUNT))
				    {
				    SDesignTypeInfo *pInfo = Ctx.TotalCount.GetAt(pType->GetUNID());
				    double rCount = (pInfo ? pInfo->rPerGameMeanCount : 0.0);
				    printf("%.2f", rCount);
				    }
			    else
				    printf(sValue.GetASCIIZPointer());
                }
			}

		printf("\n");
		}
	}
Exemple #6
0
void Run (CUniverse &Universe, CXMLElement *pCmdLine)
	{
	ALERROR error;
	int i;
	CCodeChain &CC = g_pUniverse->GetCC();
	bool bNoLogo = pCmdLine->GetAttributeBool(NO_LOGO_SWITCH);

	//	Prepare the universe

	CTopologyNode *pNode = g_pUniverse->GetFirstTopologyNode();
	if (pNode == NULL)
		{
		printf("ERROR: No topology node found.\n");
		return;
		}

	CSystem *pSystem;
	if (error = g_pUniverse->CreateStarSystem(pNode, &pSystem))
		{
		printf("ERROR: Unable to create star system.\n");
		return;
		}

	//	Set the POV

	CSpaceObject *pPOV = pSystem->GetObject(0);
	g_pUniverse->SetPOV(pPOV);
	pSystem->SetPOVLRS(pPOV);

	//	Prepare system

	g_pUniverse->UpdateExtended();
	g_pUniverse->GarbageCollectLibraryBitmaps();

	CString sCommand = pCmdLine->GetAttribute(RUN_SWITCH);
	CString sRunFile = pCmdLine->GetAttribute(RUN_FILE_SWITCH);

	//	If this is a run file, then we parse it and run it

	if (!sRunFile.IsBlank() && !strEquals(sRunFile, CONSTLIT("true")))
		{
		TArray<CString> Files;
		ParseStringList(sRunFile, PSL_FLAG_ALLOW_WHITESPACE, &Files);
		for (i = 0; i < Files.GetCount(); i++)
			RunFile(Files[i], bNoLogo);
		}

	//	If we have a command, invoke it

	else if (!sCommand.IsBlank() && !strEquals(sCommand, CONSTLIT("True")))
		{
		CCodeChainCtx Ctx;
		ICCItem *pCode = Ctx.Link(sCommand, 0, NULL);
		ICCItem *pResult = Ctx.Run(pCode);

		CString sOutput;
		if (pResult->IsIdentifier())
			sOutput = pResult->Print(&CC, PRFLAG_NO_QUOTES | PRFLAG_ENCODE_FOR_DISPLAY);
		else
			sOutput = CC.Unlink(pResult);

		Ctx.Discard(pResult);
		Ctx.Discard(pCode);

		//	Output result

		printf("%s\n", sOutput.GetASCIIZPointer());
		}

	//	Otherwise, we enter a command loop

	else
		{
		//	Welcome

		if (!bNoLogo)
			{
			printf("(help) for function help.\n");
			printf("\\q to quit.\n\n");
			}

		//	Loop

		while (true)
			{
			char szBuffer[1024];
			if (!bNoLogo)
				printf(": ");
			gets_s(szBuffer, sizeof(szBuffer)-1);
			CString sCommand(szBuffer);

			//	Escape codes

			if (*sCommand.GetASCIIZPointer() == '\\')
				{
				//	Quit command

				if (strStartsWith(sCommand, CONSTLIT("\\q")))
					break;
				else if (strStartsWith(sCommand, CONSTLIT("\\?"))
						|| strStartsWith(sCommand, CONSTLIT("\\h")))
					{
					printf("TLisp Shell\n\n");
					printf("\\h      Show this help\n");
					printf("\\q      Quit\n");

					printf("\n(help) for function help.\n");
					}
				}

			//	Null command

			else if (sCommand.IsBlank())
				NULL;

			//	Command

			else
				{
				CCodeChainCtx Ctx;
				ICCItem *pCode = Ctx.Link(sCommand, 0, NULL);
				ICCItem *pResult = Ctx.Run(pCode);

				CString sOutput;
				if (pResult->IsIdentifier())
					sOutput = pResult->Print(&CC, PRFLAG_NO_QUOTES | PRFLAG_ENCODE_FOR_DISPLAY);
				else
					sOutput = CC.Unlink(pResult);

				Ctx.Discard(pResult);
				Ctx.Discard(pCode);

				//	Output result

				printf("%s\n", sOutput.GetASCIIZPointer());
				}
			}
		}
	}
Exemple #7
0
void RunFile (const CString &sFilespec, bool bNoLogo)
	{
	ALERROR error;
	CCodeChain &CC = g_pUniverse->GetCC();
	CCodeChainCtx Ctx;

	//	Verify the file

	CString sRunFile = sFilespec;
	if (!strEndsWith(sRunFile, CONSTLIT("."))
			&& pathGetExtension(sRunFile).IsBlank())
		sRunFile.Append(CONSTLIT(".tlisp"));

	//	Open the file

	CFileReadBlock InputFile(sRunFile);
	if (error = InputFile.Open())
		{
		printf("error : Unable to open file '%s'.\n", sRunFile.GetASCIIZPointer());
		return;
		}

	if (!bNoLogo)
		printf("%s\n", sRunFile.GetASCIIZPointer());

	//	Parse

	CString sInputFile(InputFile.GetPointer(0), InputFile.GetLength(), TRUE);
	CString sOutput;
	int iOffset = 0;

	while (true)
		{
		int iCharCount;
		ICCItem *pCode = Ctx.Link(sInputFile, iOffset, &iCharCount);
		if (pCode->IsNil())
			break;
		else if (pCode->IsError())
			{
			printf("error : %s\n", pCode->GetStringValue().GetASCIIZPointer());
			Ctx.Discard(pCode);
			return;
			}

		iOffset += iCharCount;

		//	Execute

		ICCItem *pResult = Ctx.Run(pCode);

		//	Compose output

		if (pResult->IsIdentifier())
			sOutput = pResult->Print(&CC, PRFLAG_NO_QUOTES | PRFLAG_ENCODE_FOR_DISPLAY);
		else
			sOutput = CC.Unlink(pResult);

		//	Free

		Ctx.Discard(pResult);
		Ctx.Discard(pCode);
		}

	//	Output result

	printf("%s\n", sOutput.GetASCIIZPointer());
	}
Exemple #8
0
void GenerateShipTable (CUniverse &Universe, CXMLElement *pCmdLine)
	{
	int i, j;

	//	Some options

	bool bAllClasses = (pCmdLine->GetAttributeBool(CONSTLIT("allClasses")) || pCmdLine->GetAttributeBool(CONSTLIT("all")));

	//	Get the criteria from the command line. Always append 's' because we
	//	want ship classes.

	CString sCriteria = strPatternSubst(CONSTLIT("%s s"), pCmdLine->GetAttribute(CONSTLIT("criteria")));
	CDesignTypeCriteria Criteria;
	if (CDesignTypeCriteria::ParseCriteria(sCriteria, &Criteria) != NOERROR)
		{
		printf("ERROR: Unable to parse criteria.\n");
		return;
		}

	//	Generate a list of columns to display

	TArray<CString> Cols;
	Cols.Insert(FIELD_LEVEL);
	Cols.Insert(FIELD_NAME);

	for (i = 0; i < pCmdLine->GetAttributeCount(); i++)
		{
		CString sAttrib = pCmdLine->GetAttributeName(i);

		if (strEquals(sAttrib, FIELD_BALANCE))
			{
			Cols.Insert(CONSTLIT("balanceType"));
			Cols.Insert(CONSTLIT("combatStrength"));
			Cols.Insert(CONSTLIT("damage"));
			Cols.Insert(CONSTLIT("defenseStrength"));
			}
		else if (!IsMainCommandParam(sAttrib)
				&& !strEquals(sAttrib, CONSTLIT("shiptable")))
			{
			CString sValue = pCmdLine->GetAttribute(i);
			
			if (!strEquals(sValue, CONSTLIT("true")))
				Cols.Insert(strPatternSubst(CONSTLIT("%s:%s"), sAttrib, sValue));
			else
				Cols.Insert(sAttrib);
			}
		}

	//	Output the header

	for (j = 0; j < Cols.GetCount(); j++)
		{
		if (j != 0)
			printf("\t");

		printf(Cols[j].GetASCIIZPointer());
		}

	printf("\n");

	//	Generate a table

	CSymbolTable Table(FALSE, TRUE);

	//	Loop over all items that match and add them to
	//	a sorted table.

	for (i = 0; i < Universe.GetShipClassCount(); i++)
		{
		CShipClass *pClass = Universe.GetShipClass(i);

		//	Only include generic classes unless otherwise specified

		if (!bAllClasses && !pClass->HasLiteralAttribute(CONSTLIT("genericClass")))
			continue;

		if (!pClass->MatchesCriteria(Criteria))
			continue;

		//	Figure out the sort order

		char szBuffer[1024];
		wsprintf(szBuffer, "%04d%s%d", 
				pClass->GetLevel(),
				pClass->GetNounPhrase(0).GetASCIIZPointer(),
				pClass->GetUNID());
		Table.AddEntry(CString(szBuffer), (CObject *)pClass);
		}

	//	Output table

	CCodeChainCtx CCCtx;
	for (i = 0; i < Table.GetCount(); i++)
		{
		CShipClass *pClass = (CShipClass *)Table.GetValue(i);

		//	Output each row

		for (j = 0; j < Cols.GetCount(); j++)
			{
			if (j != 0)
				printf("\t");

			const CString &sField = Cols[j];
			ICCItem *pResult = pClass->GetProperty(CCCtx, sField);

			if (strEquals(sField, FIELD_MANEUVER) 
					|| strEquals(sField, FIELD_THRUST_TO_WEIGHT))
				printf("%.1f", pResult->GetIntegerValue() / 1000.0);
			else if (strEquals(sField, FIELD_SCORE_CALC))
				printf("%d", pClass->CalcScore());
			else
				{
				CString sValue = pResult->Print(&g_pUniverse->GetCC(), PRFLAG_NO_QUOTES | PRFLAG_ENCODE_FOR_DISPLAY);
				printf(sValue.GetASCIIZPointer());
				}
			}

		printf("\n");
		}

	printf("\n");
	}
Exemple #9
0
int AlchemyMain (CXMLElement *pCmdLine)

//	AlchemyMain
//
//	Main entry-point after kernel initialization

	{
	ALERROR error;
	bool bLogo = !pCmdLine->GetAttributeBool(NO_LOGO_SWITCH);

	if (bLogo)
		{
		printf("CCShell v1.0\n");
		printf("Copyright (c) 2010 by George Moromisato. All Rights Reserved.\n\n");
		}

	//	Initialize CodeChain environment

	CCodeChain CC;
	if (error = CC.Boot())
		{
		PrintError(ERR_UNABLE_TO_INIT_CODECHAIN);
		return 1;
		}

	//	Load some functions

	if (error = RegisterShellPrimitives(CC))
		{
		PrintError(ERR_UNABLE_TO_REGISTER_PRIMITIVES);
		return 1;
		}

	//	Prepare context

	SExecuteCtx Ctx;
	Ctx.bQuit = false;

	//	Interpreter loop

	while (!Ctx.bQuit)
		{
		//	Prompt

		printf(": ");

		//	Read a line

		CString sInput;
		char *pDest = sInput.GetWritePointer(65536);
		if (fgets(pDest, 65536, stdin) == NULL)
			{
			PrintError(ERR_INVALID_INPUT);
			continue;
			}
		sInput.Truncate(strlen(sInput.GetASCIIZPointer()));

		//	Parse the line

		ICCItem *pCode = CC.Link(sInput, 0, NULL);
		if (pCode->IsError())
			{
			printf("codechain: %s\n", pCode->Print(&CC).GetASCIIZPointer());
			pCode->Discard(&CC);
			continue;
			}

		//	Execute

		ICCItem *pResult = CC.TopLevel(pCode, &Ctx);

		//	Output

		if (pResult->IsError())
			printf("codechain: %s\n", pResult->Print(&CC).GetASCIIZPointer());
		else
			printf("%s\n", pResult->Print(&CC).GetASCIIZPointer());

		//	Done

		pCode->Discard(&CC);
		pResult->Discard(&CC);
		}

	return 0;
	}
Exemple #10
0
void GenerateTypeTable (CUniverse &Universe, CXMLElement *pCmdLine)
	{
	int i, j;

	//	Get the criteria from the command line.

	CString sCriteria = pCmdLine->GetAttribute(CRITERIA_ATTRIB);

	//	Parse it

	CDesignTypeCriteria Criteria;
	if (CDesignTypeCriteria::ParseCriteria(sCriteria, &Criteria) != NOERROR)
		{
		printf("ERROR: Unable to parse criteria.\n");
		return;
		}

	//	Generate a table of all matching types

	TSortMap<CString, CDesignType *> Table;

	//	Loop over all items for this level and add them to
	//	a sorted table.

	for (i = 0; i < Universe.GetDesignTypeCount(); i++)
		{
		CDesignType *pType = Universe.GetDesignType(i);
		int iLevel = pType->GetLevel();

		if (!pType->MatchesCriteria(Criteria))
			continue;

		//	Get the name

		CString sName = pType->GetDataField(FIELD_NAME);
		if (*sName.GetASCIIZPointer() == '(')
			sName = strSubString(sName, 1, -1);

		//	Figure out the sort order

		char szBuffer[1024];
		wsprintf(szBuffer, "%02d%s%08x", 
				iLevel,
				sName.GetASCIIZPointer(),
				pType->GetUNID());
		Table.Insert(CString(szBuffer), pType);
		}

	//	Generate a list of columns to display

	TArray<CString> Cols;
	Cols.Insert(FIELD_LEVEL);
	Cols.Insert(FIELD_NAME);

	for (i = 0; i < pCmdLine->GetAttributeCount(); i++)
		{
		CString sAttrib = pCmdLine->GetAttributeName(i);

		if (!IsMainCommandParam(sAttrib)
				&& !strEquals(sAttrib, CONSTLIT("typetable")))
			{
			CString sValue = pCmdLine->GetAttribute(i);
			
			if (!strEquals(sValue, CONSTLIT("true")))
				Cols.Insert(strPatternSubst(CONSTLIT("%s:%s"), sAttrib, sValue));
			else
				Cols.Insert(sAttrib);
			}
		}

	//	If we need to output total count, then load the table

	CDesignTypeStats TotalCount;
	if (pCmdLine->GetAttributeBool(FIELD_TOTAL_COUNT)
			|| pCmdLine->GetAttributeBool(FIELD_COUNT_DISTRIBUTION))
		{
		if (LoadDesignTypeStats(Universe.GetDesignCollection().GetAdventureUNID(), &TotalCount) != NOERROR)
			{
			printf("ERROR: Unable to load type count table.\n");
			return;
			}
		}

	//	If we've got any entries in the table, output now

	if (Table.GetCount())
		{
		//	Output the header

		for (j = 0; j < Cols.GetCount(); j++)
			{
			if (j != 0)
				printf("\t");

			printf(Cols[j].GetASCIIZPointer());
			}

		printf("\n");

		//	Output each row

		CCodeChainCtx CCCtx;
		for (i = 0; i < Table.GetCount(); i++)
			{
			CDesignType *pType = Table[i];

			for (j = 0; j < Cols.GetCount(); j++)
				{
				if (j != 0)
					printf("\t");

				const CString &sField = Cols[j];

				//	Format and output

				if (strEquals(sField, FIELD_TOTAL_COUNT))
					{
					SDesignTypeInfo *pInfo = TotalCount.GetAt(pType->GetUNID());
					double rCount = (pInfo ? pInfo->rPerGameMeanCount : 0.0);
					printf("%.2f", rCount);
					}
				else if (strEquals(sField, FIELD_COUNT_DISTRIBUTION))
					{
					SDesignTypeInfo *pInfo = TotalCount.GetAt(pType->GetUNID());
					printf("%s", (pInfo ? pInfo->sDistribution : NULL_STR).GetASCIIZPointer());
					}
				else
					{
					ICCItem *pResult = pType->GetProperty(CCCtx, sField);
					CString sValue = pResult->Print(&g_pUniverse->GetCC(), PRFLAG_NO_QUOTES | PRFLAG_ENCODE_FOR_DISPLAY);
					pResult->Discard(&g_pUniverse->GetCC());

					printf(sValue.GetASCIIZPointer());
					}
				}

			printf("\n");
			}

		printf("\n");
		}
	else
		printf("No entries match criteria.\n");
	}
void CCommandLineDisplay::OnKeyDown (int iVirtKey, DWORD dwKeyState)

//	OnKeyDown
//
//	Handle WM_KEYDOWN

	{
	switch (iVirtKey)
		{
		case VK_BACK:
			InputBackspace();
			break;

		case VK_DELETE:
			InputDelete();
			break;

		case VK_RETURN:
			{
			CString sInput = GetInput();
			if (!sInput.IsBlank())
				{
				CCodeChain &CC = g_pUniverse->GetCC();

				InputEnter();

				CCodeChainCtx Ctx;
				ICCItem *pCode = Ctx.Link(sInput, 0, NULL);
				ICCItem *pResult = Ctx.Run(pCode);

				CString sOutput;
				if (pResult->IsIdentifier())
					sOutput = pResult->Print(&CC, PRFLAG_NO_QUOTES | PRFLAG_ENCODE_FOR_DISPLAY);
				else
					sOutput = CC.Unlink(pResult);

				Ctx.Discard(pResult);
				Ctx.Discard(pCode);

				Output(sOutput);
				}
			break;
			}

		case VK_TAB:
			{
			AutoCompleteSearch();
			break;
			}

		case VK_UP:
			InputHistoryUp();
			break;

		case VK_DOWN:
			InputHistoryDown();
			break;

		case VK_LEFT:
			if (m_iCursorPos > 0) m_iCursorPos--;
			m_bInvalid = true;
			break;

		case VK_RIGHT:
			if (m_iCursorPos < m_sInput.GetLength()) m_iCursorPos++;
			m_bInvalid = true;
			break;

		case VK_HOME:
			m_iCursorPos = 0;
			m_bInvalid = true;
			break;

		case VK_END:
			m_iCursorPos = m_sInput.GetLength();
			m_bInvalid = true;
			break;

		case VK_PRIOR:
			if (m_iScrollPos < 2*MAX_LINES) m_iScrollPos++;
			m_bInvalid = true;
			break;

		case VK_NEXT:
			if (m_iScrollPos > 0) m_iScrollPos--;
			m_bInvalid = true;
			break;
		}
	}