Exemplo n.º 1
0
static int
Script_LOG(lua_State* state)
{
	Script script(state);
	Script::Object obj = script.GetObject(script.GetTop());

	printf("%s\n", obj.GetString());

	return 0;
}
Exemplo n.º 2
0
/**
	Demonstrates walking an array table.
**/
void
TestScript::DoScriptArrayTest()
{
	Script script;
	script.DoFile("ScriptArrayTest.scr");
	Script::Object testTableObj = script.GetGlobals().GetByName("TestArray");
	// or							script.GetGlobal("TestArray");
	for (int i = 1; ; ++i)
	{
		Script::AutoBlock block(script);	// Automatic stack fixups.
		Script::Object entryObj = testTableObj.GetByIndex(i);
		if (entryObj.IsNil())
			break;
		if (entryObj.IsNumber())		// IsNumber() must ALWAYS come first.
			printf("%f\n", entryObj.GetNumber());
		else if (entryObj.IsString())	// IsString() returns true for a number or string.
			printf("%s\n", entryObj.GetString());
	}
}
Exemplo n.º 3
0
/**
	Writes a Lua object to a text file.
**/
static void
WriteObject(Script& script, FILE* file, const char* name,
						Script::Object value, unsigned int indentLevel)
{
	// If there is nothing in the variable, then don't write it.
	if (value.IsNil())
		return;

	// If the variable is user data or a function, then don't write it.
	if (value.IsUserData()	||	value.IsFunction())
	{
		return;
	}

	// Indent the line the number of spaces for the current indentation level.
	const unsigned int INDENT_SIZE = 4;
	const unsigned int indentSpaces = indentLevel * INDENT_SIZE;
	IndentFile(file, indentSpaces);
	
	// If the object has a name, write it out.
	if (name)
		fprintf(file, "%s = ", name);

	// If the object's value is a number, write it as a number.
	if (value.IsNumber())
		fprintf(file, "%.16g", value.GetNumber());

	// Or if the object's value is a string, write it as a quoted string.
	else if (value.IsString())
		fprintf(file, "\"%s\"", value.GetString());

	// Otherwise, see if the object's value is a table.
	else if (value.IsTable())
	{
		// Write the table header.
		fputs("\n", file);
		IndentFile(file, indentSpaces);
		fputs("{\n", file);

		// Rename, just for ease of reading.
		Script::Object table = value;

		// upperIndex is the upper index value of a sequential numerical array
		// items.
		int upperIndex = 1;
		bool wroteSemi = false;
		bool hasSequential = false;

		// Block to search for array items.
		{
			// Pop the stack state when done.
			Script::AutoBlock block (script);

			// Grab index 1 and index 2 of the table.
			Script::Object value1 = table.GetByIndex(1);
			Script::Object value2 = table.GetByIndex(2);

			// If they both exist, then there is a sequential list.
			if (!value1.IsNil()	&&	!value2.IsNil())
			{
				// Cycle through the list.
				bool firstSequential = true;
				for (; ; ++upperIndex)
				{
					// Restore the stack state each iteration.
					Script::AutoBlock block_ (script);

					// Try retrieving the table entry at upperIndex.
					Script::Object value = table.GetByIndex(upperIndex);

					// If it doesn't exist, then exit the loop.
					if (value.IsNil())
						break;

					// Only add the comma and return if not on the first item.
					if (!firstSequential)
						fputs(",\n", file);
					
					// Write the object as an unnamed entry.
					WriteObject(script, file, NULL, value, indentLevel + 1);

					// We've definitely passed the first item now.
					firstSequential = false;
				}
			}
		}

		// Did we find any sequential table values?
		if (upperIndex > 1)
		{
			hasSequential = true;
		}
		
		// Cycle through the table.
		int i;
		script.PushNil();
		while ((i = script.Next(table.GetStackIndex())) != 0)
		{
			char keyName[255];

			// Retrieve the table entry's key and value.
			Script::Object key = script.GetObject(script.GetTop() - 1);
			Script::Object value = script.GetObject(script.GetTop());

			// Is the key a number?
			if (key.IsNumber())
			{
				// Yes, were there sequential array items in this table?
				if (hasSequential)
				{
					// Is the array item's key an integer?
					float realNum = key.GetNumber();
					int intNum = (int)realNum;
					if (realNum == (float)intNum)
					{
						// Yes.	Is it between 1 and upperIndex?
						if (intNum >= 1	&&	intNum < upperIndex)
						{
							// We already wrote it as part of the sequential
							// list.
							script.Pop();
							continue;
						}
					}
				}

				// Build the table entry name for the number.
				sprintf(keyName, "[%.16g]", key.GetNumber());
			}
			else
			{
				// Build the table entry name for the string key name.
				strcpy(keyName, key.GetString());
			}

			// If we wrote a sequential list, the value we're about to write
			// is not nil, and we haven't written the semicolon to separate
			// the sequential table entries from the keyed table entries...
			if (hasSequential	&&	!value.IsNil()	&&	!wroteSemi)
			{
				// Then add a comma (for good measure) and the semicolon.
				fputs(", ;\n", file);
				wroteSemi = true;
			}

			// Write the table entry.
			WriteObject(script, file, keyName, value, indentLevel + 1);

			// Add a comma after the table entry.
			fputs(",\n", file);

			// Go to the next item.
			script.Pop();
		}

		// If we wrote a sequential list and haven't written a semicolon, then
		// there were no keyed table entries.	Just write the final comma.
		if (hasSequential	&&	!wroteSemi)
		{
			fputs(",\n", file);
		}
		
		// Indent, with the intent of closing up the table.
		IndentFile(file, indentSpaces);

		// If the indentation level is 0, then we're at the root position.
		if (indentLevel == 0)
		{
			// Add a couple extra returns for readability's sake.
			fputs("}\n\n", file);
		}
		else
		{
			// Close the table.	The comma is written when WriteObject()
			// returns from the recursive call.
			fputs("}", file);
		}
	}

	// If the indentation level is at the root, then add a return to separate
	// the lines.
	if (indentLevel == 0)
	{
		fputs("\n", file);
	}
}