mirror of
https://github.com/leonelquinteros/php-toml.git
synced 2025-01-17 12:28:16 +01:00
Add support for TOML version 0.4.0
This commit is contained in:
parent
1c3eafd203
commit
2fb5908103
@ -7,7 +7,7 @@ PHP parser for TOML language ( https://github.com/toml-lang/toml )
|
|||||||
Support
|
Support
|
||||||
-------
|
-------
|
||||||
|
|
||||||
TOML version: 0.2.0
|
TOML version: [v0.4.0](https://github.com/mojombo/toml/blob/master/versions/en/toml-v0.4.0.md)
|
||||||
|
|
||||||
|
|
||||||
Requirements
|
Requirements
|
||||||
|
152
src/Toml.php
152
src/Toml.php
@ -77,10 +77,12 @@ class Toml
|
|||||||
|
|
||||||
// Split lines
|
// Split lines
|
||||||
$aToml = explode("\n", $toml);
|
$aToml = explode("\n", $toml);
|
||||||
|
print_r($aToml);
|
||||||
|
|
||||||
foreach($aToml as $line)
|
//foreach($aToml as $line)
|
||||||
|
for($ln = 0; $ln < count($aToml); $ln++)
|
||||||
{
|
{
|
||||||
$line = trim($line);
|
$line = trim($aToml[$ln]);
|
||||||
|
|
||||||
// Skip commented and empty lines
|
// Skip commented and empty lines
|
||||||
if(empty($line) || $line[0] == '#')
|
if(empty($line) || $line[0] == '#')
|
||||||
@ -148,7 +150,35 @@ class Toml
|
|||||||
$kv = explode('=', $line, 2);
|
$kv = explode('=', $line, 2);
|
||||||
if(!isset($pointer[ trim($kv[0]) ]))
|
if(!isset($pointer[ trim($kv[0]) ]))
|
||||||
{
|
{
|
||||||
$pointer[ trim($kv[0]) ] = self::parseValue( $kv[1] );
|
// Multi-line strings
|
||||||
|
if(substr(trim($kv[1]), 0, 3) == '"""')
|
||||||
|
{
|
||||||
|
if(strlen(trim($kv[1])) > 3 && substr(trim($kv[1]), -3) != '"""' || strlen(trim($kv[1])) == 3)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
$ln++;
|
||||||
|
$kv[1] .= "\n" . $aToml[$ln];
|
||||||
|
}
|
||||||
|
while(strpos($aToml[$ln], '"""') === false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Multi-line literal strings
|
||||||
|
if(substr(trim($kv[1]), 0, 3) == "'''")
|
||||||
|
{
|
||||||
|
if(strlen(trim($kv[1])) > 3 && substr(trim($kv[1]), -3) != "'''" || strlen(trim($kv[1])) == 3)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
$ln++;
|
||||||
|
$kv[1] .= "\n" . $aToml[$ln];
|
||||||
|
}
|
||||||
|
while(strpos($aToml[$ln], "'''") === false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$pointer[ trim($kv[0]) ] = self::parseValue( trim($kv[1]) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -188,6 +218,9 @@ class Toml
|
|||||||
// Run, char by char.
|
// Run, char by char.
|
||||||
$normalized = '';
|
$normalized = '';
|
||||||
$openString = false;
|
$openString = false;
|
||||||
|
$openLString = false;
|
||||||
|
$openMString = false;
|
||||||
|
$openMLString = false;
|
||||||
$openBrackets = 0;
|
$openBrackets = 0;
|
||||||
$openKeygroup = false;
|
$openKeygroup = false;
|
||||||
$lineBuffer = '';
|
$lineBuffer = '';
|
||||||
@ -241,15 +274,59 @@ class Toml
|
|||||||
// EOLs inside string should throw error.
|
// EOLs inside string should throw error.
|
||||||
throw new Exception("Multi-line strings are not allowed on: " . $lineBuffer);
|
throw new Exception("Multi-line strings are not allowed on: " . $lineBuffer);
|
||||||
}
|
}
|
||||||
elseif($toml[$i] == '"' && $toml[$i - 1] != "\\")
|
elseif($toml[$i] == '"' && $toml[$i - 1] != "\\") // String handling, allow escaped quotes.
|
||||||
{
|
{
|
||||||
// String handling, allow escaped quotes.
|
// Check multi-line strings
|
||||||
$openString = !$openString;
|
if($toml[$i+1] == '"' && $toml[$i+2] == '"')
|
||||||
|
{
|
||||||
|
// Include the token inmediately.
|
||||||
|
$i += 2;
|
||||||
|
$normalized .= '"""';
|
||||||
|
$lineBuffer .= '"""';;
|
||||||
|
$keep = false;
|
||||||
|
|
||||||
|
$openMString = !$openMString;
|
||||||
|
}
|
||||||
|
else // Simple strings
|
||||||
|
{
|
||||||
|
$openString = !$openString;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
elseif($toml[$i] == "\\" && !in_array($toml[$i+1], array('0', 't', 'n', 'r', '"', "\\")))
|
elseif($toml[$i] == "'") // Literal string handling.
|
||||||
{
|
{
|
||||||
// Reserved special characters should produce error
|
// Check multi-line strings
|
||||||
throw new Exception('Reserved special characters inside strings are not allowed: ' . $toml[$i] . $toml[$i+1]);
|
if($toml[$i+1] == "'" && $toml[$i+2] == "'")
|
||||||
|
{
|
||||||
|
// Include the token inmediately.
|
||||||
|
$i += 2;
|
||||||
|
$normalized .= "'''";
|
||||||
|
$lineBuffer .= "'''";
|
||||||
|
$keep = false;
|
||||||
|
|
||||||
|
$openMLString = !$openMLString;
|
||||||
|
}
|
||||||
|
else // Simple strings
|
||||||
|
{
|
||||||
|
$openLString = !$openLString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elseif($toml[$i] == "\\" && !in_array($toml[$i+1], array('0', 't', 'n', 'r', "u", '"', "\\")))
|
||||||
|
{
|
||||||
|
// Reserved special characters inside strings should produce error
|
||||||
|
if($openString)
|
||||||
|
{
|
||||||
|
throw new Exception('Reserved special characters inside strings are not allowed: ' . $toml[$i] . $toml[$i+1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup escaped new lines and whitespaces from multi-line strings
|
||||||
|
if($openMString)
|
||||||
|
{
|
||||||
|
while($toml[$i+1] == "\n" || $toml[$i+1] == " ")
|
||||||
|
{
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
$keep = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
elseif($toml[$i] == '#' && !$openString && !$openKeygroup)
|
elseif($toml[$i] == '#' && !$openString && !$openKeygroup)
|
||||||
{
|
{
|
||||||
@ -277,7 +354,7 @@ class Toml
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Something went wrong.
|
// Something went wrong.
|
||||||
if($openBrackets || $openString || $openKeygroup)
|
if($openBrackets || $openString || $openLString || $openMString || $openMLString || $openKeygroup)
|
||||||
{
|
{
|
||||||
throw new Exception('Syntax error found on TOML document.');
|
throw new Exception('Syntax error found on TOML document.');
|
||||||
}
|
}
|
||||||
@ -300,7 +377,7 @@ class Toml
|
|||||||
// Cleanup
|
// Cleanup
|
||||||
$val = trim($val);
|
$val = trim($val);
|
||||||
|
|
||||||
if(empty($val))
|
if($val === '')
|
||||||
{
|
{
|
||||||
throw new Exception('Empty value not allowed');
|
throw new Exception('Empty value not allowed');
|
||||||
}
|
}
|
||||||
@ -310,6 +387,42 @@ class Toml
|
|||||||
{
|
{
|
||||||
$parsedVal = (bool) $val;
|
$parsedVal = (bool) $val;
|
||||||
}
|
}
|
||||||
|
// Literal multi-line string
|
||||||
|
elseif(substr($val, 0, 3) == "'''" && substr($val, -3) == "'''")
|
||||||
|
{
|
||||||
|
$parsedVal = substr($val, 3, -3);
|
||||||
|
|
||||||
|
// Trim first newline on multi-line string definition
|
||||||
|
if($parsedVal[0] == "\n")
|
||||||
|
{
|
||||||
|
$parsedVal = substr($parsedVal, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Literal string
|
||||||
|
elseif($val[0] == "'" && substr($val, -1) == "'")
|
||||||
|
{
|
||||||
|
// No newlines allowed
|
||||||
|
if(strpos($val, "\n") !== false)
|
||||||
|
{
|
||||||
|
throw new Exception('New lines not allowed on single line string literals.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$parsedVal = substr($val, 1, -1);
|
||||||
|
}
|
||||||
|
// Multi-line string
|
||||||
|
elseif(substr($val, 0, 3) == '"""' && substr($val, -3) == '"""')
|
||||||
|
{
|
||||||
|
$parsedVal = substr($val, 3, -3);
|
||||||
|
|
||||||
|
// Trim first newline on multi-line string definition
|
||||||
|
if($parsedVal[0] == "\n")
|
||||||
|
{
|
||||||
|
$parsedVal = substr($parsedVal, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use json_decode to finally parse the string.
|
||||||
|
$parsedVal = json_decode('"' . str_replace("\n", '\n', $parsedVal) . '"');
|
||||||
|
}
|
||||||
// String
|
// String
|
||||||
elseif($val[0] == '"' && substr($val, -1) == '"')
|
elseif($val[0] == '"' && substr($val, -1) == '"')
|
||||||
{
|
{
|
||||||
@ -317,8 +430,10 @@ class Toml
|
|||||||
$parsedVal = json_decode($val);
|
$parsedVal = json_decode($val);
|
||||||
}
|
}
|
||||||
// Numbers
|
// Numbers
|
||||||
elseif(is_numeric($val))
|
elseif(is_numeric(str_replace('_', '', $val)))
|
||||||
{
|
{
|
||||||
|
$val = str_replace('_', '', $val);
|
||||||
|
|
||||||
if(is_int($val))
|
if(is_int($val))
|
||||||
{
|
{
|
||||||
$parsedVal = (int) $val;
|
$parsedVal = (int) $val;
|
||||||
@ -338,6 +453,11 @@ class Toml
|
|||||||
{
|
{
|
||||||
$parsedVal = self::parseArray($val);
|
$parsedVal = self::parseArray($val);
|
||||||
}
|
}
|
||||||
|
// Inline table (normalized)
|
||||||
|
elseif($val[0] == '{' && substr($val, -1) == '}')
|
||||||
|
{
|
||||||
|
$parsedVal = self::parseInlineTable($val);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new Exception('Unknown value type: ' . $val);
|
throw new Exception('Unknown value type: ' . $val);
|
||||||
@ -419,6 +539,14 @@ class Toml
|
|||||||
throw new Exception('Wrong array definition: ' . $val);
|
throw new Exception('Wrong array definition: ' . $val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse inline tables into common table array
|
||||||
|
*/
|
||||||
|
private static function parseInlineTable($val)
|
||||||
|
{
|
||||||
|
return $val;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function that checks the data type of the first and last elements of an array,
|
* Function that checks the data type of the first and last elements of an array,
|
||||||
* and returns false if they don't match
|
* and returns false if they don't match
|
||||||
|
Loading…
x
Reference in New Issue
Block a user