Fix array of tables parsing. Fixes issue #6

This commit is contained in:
Leonel Quinteros 2016-12-05 18:34:00 -03:00
parent 97f44b50cd
commit fbd93fd889
6 changed files with 57 additions and 142 deletions

View File

@ -72,6 +72,7 @@ class Toml
{
$result = array();
$pointer = & $result;
$isTableArray = false;
// Pre-compile
$toml = self::normalize($toml);
@ -93,23 +94,25 @@ class Toml
// Array of Tables
if(substr($line, 0, 2) == '[[' && substr($line, -2) == ']]')
{
// Set pointer at first level.
// Mark table array
$isTableArray = true;
// Set pointer at top level.
$pointer = & $result;
$tableName = substr($line, 2, -2);
$aTable = explode('.', $tableName);
$last = count($aTable) - 1;
foreach($aTable as $i => $tableName)
foreach($aTable as $tableName)
{
$tableName = trim($tableName);
if($tableName == "")
{
// Empty table name
throw new Exception("Empty table keys aren't allowed");
}
$tableName = trim($tableName);
// Allow quoted table names
if($tableName[0] == '"' && substr($tableName,-1) == '"')
{
@ -124,21 +127,19 @@ class Toml
if( !isset($pointer[$tableName]) )
{
// Create array of tables
$pointer[$tableName] = array(array());
}
else
{
// Add new
$pointer[$tableName][] = array();
$pointer[$tableName] = array();
}
// Move pointer forward
$pointer = & $pointer[$tableName][count($pointer[$tableName]) -1];
$pointer = & $pointer[$tableName];
}
}
// Single Tables
elseif($line[0] == '[' && substr($line, -1) == ']')
{
// Unmark table array
$isTableArray = false;
// Set pointer at first level.
$pointer = & $result;
@ -186,6 +187,19 @@ class Toml
elseif(strpos($line, '='))
{
$kv = explode('=', $line, 2);
// Handle table array
if($isTableArray)
{
// Create new item and point it
$pointer[] = array();
end($pointer);
$pointer = & $pointer[key($pointer)];
// Unmark table array
$isTableArray = false;
}
if(!isset($pointer[ trim($kv[0]) ]))
{
// Multi-line strings
@ -216,6 +230,7 @@ class Toml
}
}
// Set key=value
$pointer[ trim($kv[0]) ] = self::parseValue( trim($kv[1]) );
}
else
@ -642,6 +657,10 @@ class Toml
*/
public static function isISODate($val)
{
if(!is_string($val)) {
return false;
}
// Use DateTime support to check for valid dates.
try
{

View File

@ -1,66 +0,0 @@
<?php
require('../src/Toml.php');
$toml = '[a]
[a.b]
';
$result = Toml::parse($toml);
print_r($result);
echo json_encode($result);
echo "\n";
// Format response values into test suite object
function walk(&$a) {
foreach($a as $i => $v)
{
if(is_array($v) && array_values($v) !== $v)
{
walk($a[$i]);
}
else
{
// Get type
$t = gettype($v);
// Parse type name
$t = str_replace(array('boolean', 'double'), array('bool', 'float'), $t);
// Check date type
if(Toml::isISODate($v))
{
$t = 'datetime';
}
// Fix double vs integer type
if($t == 'float' && $v == intval($v))
{
$t = 'integer';
}
// Parse array type
if($t == 'array')
{
walk($v);
}
else
{
$v = "$v";
}
$a[$i] = array(
'type' => $t,
'value' => $v,
);
}
}
}
walk($result);
print_r($result);
echo json_encode($result);
echo "\n";

View File

@ -1,62 +0,0 @@
#!/usr/bin/php
<?php
require('../src/Toml.php');
try
{
$result = Toml::parse(file_get_contents("php://stdin"));
}
catch(Exception $e)
{
exit(1);
}
// Format response values into test suite object
function walk(&$a) {
foreach($a as $i => $v)
{
if(is_array($v) && array_values($v) !== $v)
{
walk($a[$i]);
}
else
{
// Get type
$t = gettype($v);
// Parse type name
$t = str_replace(array('boolean', 'double'), array('bool', 'float'), $t);
// Check date type
if(Toml::isISODate($v))
{
$t = 'datetime';
}
// Fix double vs integer type
if($t == 'float' && $v == intval($v))
{
$t = 'integer';
}
// Parse array type
if($t == 'array')
{
walk($v);
}
else
{
$v = "$v";
}
$a[$i] = array(
'type' => $t,
'value' => $v,
);
}
}
}
walk($result);
echo json_encode($result);

20
travis-test/debug.php Normal file
View File

@ -0,0 +1,20 @@
<?php
require("../src/Toml.php");
$str = <<<STR
[[fruit]]
name = "apple"
[fruit.physical]
color = "red"
shape = "round"
[[fruit]]
name = "banana"
STR;
$toml = Toml::parse($str);
print_r($toml);

View File

@ -242,4 +242,4 @@ color = "gray"
[[fruit.variety]]
name = "plantain"

View File

@ -1,4 +1,8 @@
<?php
require("../src/Toml.php");
Toml::parseFile('example.toml');
$toml = Toml::parseFile('example.toml');
if(count($argv) > 1 && $argv[1] == 'dump') {
print_r($toml);
}