├── CREDITS ├── tests ├── bug_74799.yaml ├── yaml_parse_file_003.yaml ├── yaml_parse_file_003.phpt ├── yaml_parse_spec_str.phpt ├── bug_61770.phpt ├── bug_72540.phpt ├── bug_69617.phpt ├── bug_79567.phpt ├── yaml_emit_004.phpt ├── yaml_emit_005.phpt ├── yaml_parse_spec_bool.phpt ├── bug_76309.phpt ├── yaml_parse_wiki_YtsBlockMapping_001.phpt ├── yaml_parse_spec_set.phpt ├── yaml_parse_wiki_YtsStrangeKeys_001.phpt ├── bug_21995.phpt ├── bug_69616.phpt ├── bug_72204.phpt ├── yaml_emit_007.phpt ├── bug_64694.phpt ├── bug_75029.phpt ├── bug_80324.phpt ├── yaml_parse_004.phpt ├── yaml_parse_007.phpt ├── yaml_parse_wiki_YtsMapInSeq_002.phpt ├── yaml_parse_wiki_YtsMapInSeq_003.phpt ├── yaml_parse_wiki_YtsStrangeKeys_002.phpt ├── yaml_parse_wiki_YtsMapInSeq_001.phpt ├── yaml_parse_wiki_YtsBlockMapping_002.phpt ├── yaml_parse_wiki_YtsBlockMapping_004.phpt ├── yaml_parse_wiki_YtsBasicTests_006.phpt ├── yaml_parse_spec_int.phpt ├── yaml_parse_wiki_YtsBasicTests_001.phpt ├── yaml_parse_wiki_YtsBlockMapping_003.phpt ├── yaml_parse_spec_float.phpt ├── yaml_parse_wiki_YtsBasicTests_002.phpt ├── yaml_parse_wiki_YtsBasicTests_004.phpt ├── yaml_parse_wiki_YtsBasicTests_009.phpt ├── yaml_parse_wiki_YtsBasicTests_005.phpt ├── yaml_parse_wiki_YtsBasicTests_007.phpt ├── bug_79494.phpt ├── yaml_parse_file_001.yaml ├── yaml_parse_003.phpt ├── yaml_parse_wiki_YtsBasicTests_003.phpt ├── yaml_parse_spec_map.phpt ├── yaml_parse_002.phpt ├── yaml_parse_spec_timestamp.phpt ├── bug_parsing_alias.phpt ├── bug_74886.phpt ├── bug_74799.phpt ├── bug_64019.phpt ├── bug_69465.phpt ├── bug_79866.phpt ├── yaml_parse_wiki_YtsBasicTests_008.phpt ├── yaml_parse_spec_binary.phpt ├── yaml_parse_spec_pairs.phpt ├── yaml_parse_spec_null.phpt ├── yaml_002.phpt ├── yaml_parse_spec_omap.phpt ├── yaml_001.phpt ├── yaml_emit_009.phpt ├── yaml_parse_file_002.phpt ├── bug_61923.phpt ├── yaml_parse_spec_seq.phpt ├── yaml_emit_008.phpt ├── yaml_parse_006.phpt ├── bug_60628.phpt ├── yaml_parse_spec_merge.phpt ├── yaml_parse_file_001.phpt ├── yaml_parse_url_001.phpt ├── yaml_emit_003.phpt ├── bug_59860.phpt ├── yaml_parse_005.phpt ├── yaml_emit_file_basic.phpt ├── yaml_emit_002.phpt ├── yaml_parse_008.phpt ├── yaml_emit_001.phpt ├── yaml_parse_001.phpt ├── yaml_emit_006.phpt └── bug_77720.phpt ├── docs └── phpdoc │ ├── entities.functions.xml │ ├── reference.xml │ ├── versions.xml │ ├── configure.xml │ ├── book.xml │ ├── setup.xml │ ├── examples.xml │ ├── functions │ ├── yaml-parse-file.xml │ ├── yaml-emit-file.xml │ ├── yaml-emit.xml │ ├── yaml-parse-url.xml │ └── yaml-parse.xml │ ├── ini.xml │ └── constants.xml ├── .appveyor ├── test.ps1 ├── build.ps1 └── install.ps1 ├── TODO ├── dev-tools ├── test-all.sh ├── test.sh ├── README.packaging ├── test-build.sh ├── sync-upstream.sh ├── pull-request.sh ├── test-coverage.sh └── maintainer-clean.sh ├── composer.json ├── config.w32 ├── .gitignore ├── .appveyor.yml ├── LICENSE ├── config.m4 ├── README ├── php_yaml.h ├── .github └── workflows │ └── main.yml ├── php_yaml_int.h ├── detect.c └── yaml.c /CREDITS: -------------------------------------------------------------------------------- 1 | yaml 2 | Bryan Davis, Ryusuke Sekiyama 3 | -------------------------------------------------------------------------------- /tests/bug_74799.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | key: 3 | !value 4 | ... -------------------------------------------------------------------------------- /tests/yaml_parse_file_003.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | This is a front-matter 3 | --- 4 | doc: 5 | - prop1: val1 6 | prop2: val2 7 | ... 8 | -------------------------------------------------------------------------------- /docs/phpdoc/entities.functions.xml: -------------------------------------------------------------------------------- 1 | &reference.yaml.functions.yaml-emit-file; 2 | &reference.yaml.functions.yaml-emit; 3 | &reference.yaml.functions.yaml-parse-file; 4 | &reference.yaml.functions.yaml-parse-url; 5 | &reference.yaml.functions.yaml-parse; 6 | -------------------------------------------------------------------------------- /.appveyor/test.ps1: -------------------------------------------------------------------------------- 1 | cd c:\projects\yaml 2 | 3 | $env:TEST_PHP_EXECUTABLE = $env:PHP_PATH + '\php.exe' 4 | $runner = $env:TEST_PHP_EXECUTABLE 5 | & $runner 'run-tests.php' --show-diff tests 6 | if (-not $?) { 7 | throw "testing failed with errorlevel $LastExitCode" 8 | } 9 | -------------------------------------------------------------------------------- /tests/yaml_parse_file_003.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | yaml_parse_file - ndocs 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 5 | --FILE-- 6 | 11 | --EXPECT-- 12 | array(1) { 13 | ["string"]=> 14 | string(4) "abcd" 15 | } 16 | -------------------------------------------------------------------------------- /tests/bug_61770.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Test PECL bug #61770 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 9 | --EXPECTF-- 10 | Warning: yaml_emit(): Invalid UTF-8 sequence in argument in %sbug_61770.php on line 2 11 | bool(false) 12 | -------------------------------------------------------------------------------- /tests/bug_72540.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Test PECL bug #72540 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 11 | --EXPECT-- 12 | bool(false) 13 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | FUTURE FEATURES 2 | =============== 3 | 4 | Document merge support. 5 | 6 | More tests for proper string emits 7 | tests for yaml_parse_file 8 | tests for yaml_parse_url 9 | tests for yaml_emit_file 10 | tests for parse callbacks 11 | 12 | Add php ini setting to turn y/n boolean treatment on/off. 13 | see http://www.kuwata-lab.com/materials/php_yaml-0.3.0.patch 14 | -------------------------------------------------------------------------------- /tests/bug_69617.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Test PECL bug #69617 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 15 | --EXPECT-- 16 | array(1) { 17 | ["a"]=> 18 | string(26) "O:1:"A":1:{s:3:"one";i:1;}" 19 | } 20 | -------------------------------------------------------------------------------- /dev-tools/test-all.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | rm .rbenv-version 2>/dev/null 4 | 5 | VERSIONS=$(phpenv versions --bare | grep -E '^(7.[^0]|8|master)' | sort -V) 6 | SCRIPT_DIR=$(dirname $0) 7 | 8 | for v in $VERSIONS; do 9 | echo -n "$v: " 10 | if ${SCRIPT_DIR}/test-build.sh $v >$v.log 2>&1; then 11 | echo -e "\033[1;32mPASS\033[0m" 12 | else 13 | echo -e "\033[1;31mFAIL\033[0m" 14 | fi 15 | done 16 | -------------------------------------------------------------------------------- /tests/bug_79567.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Test PECL bug #79567 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | [ 9 | 0 => 132317787432502136, 10 | 1 => 0, 11 | ], 12 | ]; 13 | $yaml = yaml_emit($data); 14 | $result = yaml_parse($yaml); 15 | print $result == $data ? "Yes!\n" : "No...\n"; 16 | ?> 17 | --EXPECT-- 18 | Yes! 19 | -------------------------------------------------------------------------------- /tests/yaml_emit_004.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | yaml_emit - datetime 3 | --SKIPIF-- 4 | 8 | --INI-- 9 | date.timezone=GMT 10 | --FILE-- 11 | 15 | --EXPECT-- 16 | string(41) "--- 2008-08-03T14:52:10.000000+00:00 17 | ... 18 | " 19 | -------------------------------------------------------------------------------- /tests/yaml_emit_005.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | yaml_emit - serializable 3 | --SKIPIF-- 4 | 7 | --FILE-- 8 | one; 14 | } 15 | } 16 | $a = new A; 17 | 18 | var_dump(yaml_emit(array('a' => $a))); 19 | ?> 20 | --EXPECT-- 21 | string(56) "--- 22 | a: !php/object "O:1:\"A\":1:{s:3:\"one\";i:1;}" 23 | ... 24 | " 25 | -------------------------------------------------------------------------------- /tests/yaml_parse_spec_bool.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Yaml 1.1 Spec - bool 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 14 | --EXPECT-- 15 | array(4) { 16 | ["canonical"]=> 17 | bool(true) 18 | ["answer"]=> 19 | bool(false) 20 | ["logical"]=> 21 | bool(true) 22 | ["option"]=> 23 | bool(true) 24 | } 25 | -------------------------------------------------------------------------------- /tests/bug_76309.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Test PECL bug #76309 3 | --SKIPIF-- 4 | 5 | --INI-- 6 | serialize_precision=-1 7 | --FILE-- 8 | '1.0', 11 | 'b' => '2.', 12 | 'c' => '3', 13 | 'd' => '.', 14 | 'e' => 1.0, 15 | 'f' => 2., 16 | 'g' => 3, 17 | ] ); 18 | ?> 19 | --EXPECT-- 20 | --- 21 | a: "1.0" 22 | b: "2." 23 | c: "3" 24 | d: . 25 | e: 1 26 | f: 2 27 | g: 3 28 | ... 29 | -------------------------------------------------------------------------------- /tests/yaml_parse_wiki_YtsBlockMapping_001.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Yaml YtsBlockMapping - One Element Mapping 3 | --DESCRIPTION-- 4 | A mapping with one key/value pair 5 | --CREDITS-- 6 | Bryan Davis bd808@bd808.com 7 | # yaml.kwiki.org import/conversion 8 | --SKIPIF-- 9 | 10 | --FILE-- 11 | 16 | --EXPECT-- 17 | array(1) { 18 | ["foo"]=> 19 | string(3) "bar" 20 | } 21 | -------------------------------------------------------------------------------- /tests/yaml_parse_spec_set.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Yaml 1.1 Spec - set 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 13 | --EXPECT-- 14 | array(1) { 15 | ["baseball players"]=> 16 | array(3) { 17 | ["Mark McGwire"]=> 18 | NULL 19 | ["Sammy Sosa"]=> 20 | NULL 21 | ["Ken Griffey"]=> 22 | NULL 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/yaml_parse_wiki_YtsStrangeKeys_001.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Yaml YtsStrangeKeys - Quoted line noise key 3 | --DESCRIPTION-- 4 | Check that quoted line noise parses as key. 5 | --CREDITS-- 6 | Bryan Davis bd808@bd808.com 7 | # yaml.kwiki.org import/conversion 8 | --SKIPIF-- 9 | 10 | --FILE-- 11 | 16 | --EXPECT-- 17 | array(1) { 18 | ["!@#%"]=> 19 | string(7) "bar baz" 20 | } 21 | -------------------------------------------------------------------------------- /dev-tools/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Run phpt tests 3 | # 4 | 5 | set -e 6 | set -u 7 | 8 | BASENAME=${0} 9 | TOOLS_DIR=$(dirname ${BASENAME}) 10 | WORK_DIR="${TOOLS_DIR}/.." 11 | 12 | cd "${WORK_DIR}" 13 | 14 | TEST=${1:-tests/} 15 | 16 | USE_PHP=${TEST_PHP_EXECUTABLE:-$(which php)} 17 | 18 | TEST_PHP_EXECUTABLE=${USE_PHP} \ 19 | REPORT_EXIT_STATUS=1 \ 20 | ${USE_PHP} \ 21 | -n -d open_basedir= -d output_buffering=0 -d memory_limit=-1 \ 22 | run-tests.php -n -d extension_dir=modules -d extension=yaml.so ${TEST} 23 | -------------------------------------------------------------------------------- /tests/bug_21995.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Test PECL bug #21995 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | "yaml_cbk", 20 | )); 21 | ?> 22 | --EXPECT-- 23 | string(3) "boo" 24 | string(3) "doo" 25 | string(1) "a" 26 | string(1) "d" 27 | -------------------------------------------------------------------------------- /tests/bug_69616.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Test PECL bug #69616 3 | --SKIPIF-- 4 | 5 | --INI-- 6 | yaml.decode_php=1 7 | --FILE-- 8 | 19 | --EXPECTF-- 20 | Notice: yaml_parse(): Failed to unserialize class in %sbug_69616.php on line 10 21 | 22 | Notice: yaml_parse(): Failed to unserialize class in %sbug_69616.php on line 10 23 | -------------------------------------------------------------------------------- /tests/bug_72204.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Test PECL bug #72204 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 17 | --EXPECT-- 18 | array(2) { 19 | ["foo"]=> 20 | array(1) { 21 | ["bar"]=> 22 | bool(true) 23 | } 24 | ["baz"]=> 25 | array(1) { 26 | ["bar"]=> 27 | bool(false) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/yaml_emit_007.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | yaml_emit - recursive structures 3 | --SKIPIF-- 4 | 7 | --FILE-- 8 | "a", 11 | "b" => "b", 12 | "c" => &$recursive, 13 | ); 14 | var_dump(yaml_emit($recursive)); 15 | 16 | // clean up a little or we may see false memory leak reports 17 | unset($recursive['c']); 18 | ?> 19 | --EXPECT-- 20 | string(56) "--- 21 | a: a 22 | b: b 23 | c: &refid1 24 | a: a 25 | b: b 26 | c: *refid1 27 | ... 28 | " 29 | -------------------------------------------------------------------------------- /tests/bug_64694.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Test PECL bug #64694 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 19 | --EXPECTF-- 20 | array(1) { 21 | ["[a]"]=> 22 | int(1) 23 | } 24 | 25 | Warning: yaml_parse(): Illegal offset type array (line 1, column 7) in %sbug_64694.php on line 12 26 | array(0) { 27 | } 28 | -------------------------------------------------------------------------------- /tests/bug_75029.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Test PECL bug #75029 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 18 | --EXPECT-- 19 | NULL 20 | array(1) { 21 | [0]=> 22 | NULL 23 | } 24 | array(3) { 25 | [0]=> 26 | string(3) "doc" 27 | [1]=> 28 | NULL 29 | [2]=> 30 | string(3) "doc" 31 | } 32 | NULL 33 | -------------------------------------------------------------------------------- /tests/bug_80324.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Bug #80324 (Segfault in YAML with anonymous functions) 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | function ($str) {return $str;}, 14 | '!path' => function ($str) {return $str;}, 15 | )); 16 | 17 | var_dump($result); 18 | ?> 19 | --EXPECT-- 20 | array(2) { 21 | [0]=> 22 | string(3) "ENV" 23 | [1]=> 24 | string(4) "PATH" 25 | } 26 | -------------------------------------------------------------------------------- /tests/yaml_parse_004.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | yaml_parse - syck bug #11585 3 | --CREDITS-- 4 | From syck bug #11585 5 | http://pecl.php.net/bugs/bug.php?id=11585 6 | --SKIPIF-- 7 | 8 | --FILE-- 9 | 18 | --EXPECTF-- 19 | Warning: yaml_parse(): alias broken_pointer_to_define is not registered (line 6, column 37) in %syaml_parse_004.php on line %d 20 | bool(false) 21 | -------------------------------------------------------------------------------- /tests/yaml_parse_007.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | yaml_parse - serializable 3 | --SKIPIF-- 4 | 7 | --INI-- 8 | yaml.decode_php=1 9 | --FILE-- 10 | one; 16 | } 17 | } 18 | 19 | var_dump(yaml_parse(' 20 | --- 21 | a: !php/object "O:1:\"A\":1:{s:3:\"one\";i:1;}" 22 | ... 23 | ')); 24 | ?> 25 | --EXPECTF-- 26 | array(1) { 27 | ["a"]=> 28 | object(A)#%d (1) { 29 | ["one"]=> 30 | int(1) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/yaml_parse_wiki_YtsMapInSeq_002.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Yaml YtsMapInSeq - Multiple keys 3 | --DESCRIPTION-- 4 | Test a map with multiple keys. 5 | --CREDITS-- 6 | Bryan Davis bd808@bd808.com 7 | # yaml.kwiki.org import/conversion 8 | --SKIPIF-- 9 | 10 | --FILE-- 11 | 17 | --EXPECT-- 18 | array(1) { 19 | [0]=> 20 | array(2) { 21 | ["foo"]=> 22 | string(3) "bar" 23 | ["baz"]=> 24 | string(3) "bug" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pecl/yaml", 3 | "type": "php-ext", 4 | "license": "MIT", 5 | "description": "YAML-1.1 parser and emitter", 6 | "require": { 7 | "php": ">= 7.1.0", 8 | "ext-date": "*" 9 | }, 10 | "php-ext": { 11 | "extension-name": "yaml", 12 | "configure-options": [ 13 | { 14 | "name": "with-yaml", 15 | "description": "Enable LibYAML support. DIR is the path to LibYAML install prefix", 16 | "needs-value": true 17 | } 18 | ] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/yaml_parse_wiki_YtsMapInSeq_003.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Yaml YtsMapInSeq - Strange keys 3 | --DESCRIPTION-- 4 | Test a map with "line noise" keys. 5 | --CREDITS-- 6 | Bryan Davis bd808@bd808.com 7 | # yaml.kwiki.org import/conversion 8 | --SKIPIF-- 9 | 10 | --FILE-- 11 | 17 | --EXPECT-- 18 | array(1) { 19 | [0]=> 20 | array(2) { 21 | ["!@#$"]=> 22 | string(3) "foo" 23 | ["-+!@"]=> 24 | string(3) "bar" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /config.w32: -------------------------------------------------------------------------------- 1 | // vim:ft=javascript 2 | 3 | ARG_WITH("yaml", "The YAML parser and emitter PHP extension", "no"); 4 | 5 | if (PHP_YAML != "no") { 6 | if ((lib=CHECK_LIB("libyaml_a.lib;libyaml.lib;yaml.lib", "yaml", PHP_YAML)) && CHECK_HEADER_ADD_INCLUDE("yaml.h", "CFLAGS_YAML")) { 7 | AC_DEFINE("HAVE_YAML", 1, "Yaml support"); 8 | 9 | if (lib.substr(lib.length - 6, 6) == '_a.lib') { 10 | ADD_FLAG("CFLAGS_YAML", "/D YAML_DECLARE_STATIC"); 11 | } 12 | EXTENSION("yaml", "yaml.c parse.c emit.c detect.c"); 13 | } else { 14 | WARNING("yaml not enabled; library or header not found"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/yaml_parse_wiki_YtsStrangeKeys_002.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Yaml YtsStrangeKeys - Unquoted line noise key 3 | --DESCRIPTION-- 4 | Check that unquoted line noise parses as key. 5 | This requires the line noise be tame enough 6 | to pass as an implicit plain key. 7 | --CREDITS-- 8 | Bryan Davis bd808@bd808.com 9 | # yaml.kwiki.org import/conversion 10 | --SKIPIF-- 11 | 12 | --FILE-- 13 | 18 | --EXPECT-- 19 | array(1) { 20 | ["-+!@#%"]=> 21 | string(7) "bar baz" 22 | } 23 | -------------------------------------------------------------------------------- /tests/yaml_parse_wiki_YtsMapInSeq_001.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Yaml YtsMapInSeq - Single key 3 | --DESCRIPTION-- 4 | Test maps with just one key. 5 | --CREDITS-- 6 | Bryan Davis bd808@bd808.com 7 | # yaml.kwiki.org import/conversion 8 | --SKIPIF-- 9 | 10 | --FILE-- 11 | 17 | --EXPECT-- 18 | array(2) { 19 | [0]=> 20 | array(1) { 21 | ["foo"]=> 22 | string(3) "bar" 23 | } 24 | [1]=> 25 | array(1) { 26 | ["baz"]=> 27 | string(3) "bug" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/yaml_parse_wiki_YtsBlockMapping_002.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Yaml YtsBlockMapping - Multi Element Mapping 3 | --DESCRIPTION-- 4 | More than one key/value pair 5 | --CREDITS-- 6 | Bryan Davis bd808@bd808.com 7 | # yaml.kwiki.org import/conversion 8 | --SKIPIF-- 9 | 10 | --FILE-- 11 | 18 | --EXPECT-- 19 | array(3) { 20 | ["red"]=> 21 | string(5) "baron" 22 | ["white"]=> 23 | string(5) "walls" 24 | ["blue"]=> 25 | string(7) "berries" 26 | } 27 | -------------------------------------------------------------------------------- /tests/yaml_parse_wiki_YtsBlockMapping_004.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Yaml YtsBlockMapping - Colons aligned 3 | --DESCRIPTION-- 4 | Spaces can come before the ': ' key/value separator. 5 | --CREDITS-- 6 | Bryan Davis bd808@bd808.com 7 | # yaml.kwiki.org import/conversion 8 | --SKIPIF-- 9 | 10 | --FILE-- 11 | 18 | --EXPECT-- 19 | array(3) { 20 | ["red"]=> 21 | string(5) "baron" 22 | ["white"]=> 23 | string(5) "walls" 24 | ["blue"]=> 25 | string(7) "berries" 26 | } 27 | -------------------------------------------------------------------------------- /tests/yaml_parse_wiki_YtsBasicTests_006.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Yaml YtsBasicTests - Sequence in a Mapping 3 | --DESCRIPTION-- 4 | A value in a mapping can be a sequence. 5 | --CREDITS-- 6 | Bryan Davis bd808@bd808.com 7 | # yaml.kwiki.org import/conversion 8 | --SKIPIF-- 9 | 10 | --FILE-- 11 | 18 | --EXPECT-- 19 | array(2) { 20 | ["foo"]=> 21 | string(8) "whatever" 22 | ["bar"]=> 23 | array(2) { 24 | [0]=> 25 | string(3) "uno" 26 | [1]=> 27 | string(3) "dos" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/yaml_parse_spec_int.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Yaml 1.1 Spec - int 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 16 | --EXPECT-- 17 | array(6) { 18 | ["canonical"]=> 19 | int(685230) 20 | ["decimal"]=> 21 | int(685230) 22 | ["octal"]=> 23 | int(685230) 24 | ["hexadecimal"]=> 25 | int(685230) 26 | ["binary"]=> 27 | int(685230) 28 | ["sexagesimal"]=> 29 | int(685230) 30 | } 31 | -------------------------------------------------------------------------------- /tests/yaml_parse_wiki_YtsBasicTests_001.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Yaml YtsBasicTests - Simple Sequence 3 | --DESCRIPTION-- 4 | You can specify a list in YAML by placing each 5 | member of the list on a new line with an opening 6 | dash. These lists are called sequences. 7 | --CREDITS-- 8 | Bryan Davis bd808@bd808.com 9 | # yaml.kwiki.org import/conversion 10 | --SKIPIF-- 11 | 12 | --FILE-- 13 | 19 | --EXPECT-- 20 | array(3) { 21 | [0]=> 22 | string(5) "apple" 23 | [1]=> 24 | string(6) "banana" 25 | [2]=> 26 | string(6) "carrot" 27 | } 28 | -------------------------------------------------------------------------------- /tests/yaml_parse_wiki_YtsBlockMapping_003.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Yaml YtsBlockMapping - Values aligned 3 | --DESCRIPTION-- 4 | Often times human editors of documents will align the values even 5 | though YAML emitters generally don't. 6 | --CREDITS-- 7 | Bryan Davis bd808@bd808.com 8 | # yaml.kwiki.org import/conversion 9 | --SKIPIF-- 10 | 11 | --FILE-- 12 | 19 | --EXPECT-- 20 | array(3) { 21 | ["red"]=> 22 | string(5) "baron" 23 | ["white"]=> 24 | string(5) "walls" 25 | ["blue"]=> 26 | string(7) "berries" 27 | } 28 | -------------------------------------------------------------------------------- /tests/yaml_parse_spec_float.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Yaml 1.1 Spec - float 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 16 | --EXPECT-- 17 | array(6) { 18 | ["canonical"]=> 19 | float(685230.15) 20 | ["exponentioal"]=> 21 | float(685230.15) 22 | ["fixed"]=> 23 | float(685230.15) 24 | ["sexagesimal"]=> 25 | float(685230.15) 26 | ["negative infinity"]=> 27 | float(-INF) 28 | ["not a number"]=> 29 | float(NAN) 30 | } 31 | -------------------------------------------------------------------------------- /tests/yaml_parse_wiki_YtsBasicTests_002.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Yaml YtsBasicTests - Nested Sequences 3 | --DESCRIPTION-- 4 | You can include a sequence within another 5 | sequence by giving the sequence an empty 6 | dash, followed by an indented list. 7 | --CREDITS-- 8 | Bryan Davis bd808@bd808.com 9 | # yaml.kwiki.org import/conversion 10 | --SKIPIF-- 11 | 12 | --FILE-- 13 | 20 | --EXPECT-- 21 | array(1) { 22 | [0]=> 23 | array(3) { 24 | [0]=> 25 | string(3) "foo" 26 | [1]=> 27 | string(3) "bar" 28 | [2]=> 29 | string(3) "baz" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/yaml_parse_wiki_YtsBasicTests_004.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Yaml YtsBasicTests - Deeply Nested Sequences 3 | --DESCRIPTION-- 4 | Sequences can be nested even deeper, with each 5 | level of indentation representing a level of 6 | depth. 7 | --CREDITS-- 8 | Bryan Davis bd808@bd808.com 9 | # yaml.kwiki.org import/conversion 10 | --SKIPIF-- 11 | 12 | --FILE-- 13 | 20 | --EXPECT-- 21 | array(1) { 22 | [0]=> 23 | array(1) { 24 | [0]=> 25 | array(2) { 26 | [0]=> 27 | string(3) "uno" 28 | [1]=> 29 | string(3) "dos" 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/yaml_parse_wiki_YtsBasicTests_009.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Yaml YtsBasicTests - Sequence-Mapping Shortcut 3 | --DESCRIPTION-- 4 | If you are adding a mapping to a sequence, you 5 | can place the mapping on the same line as the 6 | dash as a shortcut. 7 | --CREDITS-- 8 | Bryan Davis bd808@bd808.com 9 | # yaml.kwiki.org import/conversion 10 | --SKIPIF-- 11 | 12 | --FILE-- 13 | 18 | --EXPECT-- 19 | array(1) { 20 | [0]=> 21 | array(1) { 22 | ["work on YAML.py"]=> 23 | array(1) { 24 | [0]=> 25 | string(13) "work on Store" 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /tests/yaml_parse_wiki_YtsBasicTests_005.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Yaml YtsBasicTests - Simple Mapping 3 | --DESCRIPTION-- 4 | You can add a keyed list "also known as a dictionary or 5 | hash" to your document by placing each member of the 6 | list on a new line, with a colon seperating the key 7 | from its value. In YAML, this type of list is called 8 | a mapping. 9 | --CREDITS-- 10 | Bryan Davis bd808@bd808.com 11 | # yaml.kwiki.org import/conversion 12 | --SKIPIF-- 13 | 14 | --FILE-- 15 | 20 | --EXPECT-- 21 | array(2) { 22 | ["foo"]=> 23 | string(8) "whatever" 24 | ["bar"]=> 25 | string(5) "stuff" 26 | } 27 | -------------------------------------------------------------------------------- /tests/yaml_parse_wiki_YtsBasicTests_007.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Yaml YtsBasicTests - Nested Mappings 3 | --DESCRIPTION-- 4 | A value in a mapping can be another mapping. 5 | --CREDITS-- 6 | Bryan Davis bd808@bd808.com 7 | # yaml.kwiki.org import/conversion 8 | --SKIPIF-- 9 | 10 | --FILE-- 11 | 19 | --EXPECT-- 20 | array(2) { 21 | ["foo"]=> 22 | string(8) "whatever" 23 | ["bar"]=> 24 | array(3) { 25 | ["fruit"]=> 26 | string(5) "apple" 27 | ["name"]=> 28 | string(5) "steve" 29 | ["sport"]=> 30 | string(8) "baseball" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /dev-tools/README.packaging: -------------------------------------------------------------------------------- 1 | To package a new distribution: 2 | 3 | Edit package.xml: 4 | - copy current into 5 | - edit for today's date, version, etc 6 | `pear package` 7 | 8 | To create a .deb: 9 | `pear package` 10 | copy package somewhere 11 | `dh-make-pecl \ 12 | --depends libyaml-0-1 \ 13 | --build-depends libyaml-dev \ 14 | --only 5 \ 15 | yaml-.tgz` 16 | 17 | To add to pecl channel: 18 | `cd extras/pear` 19 | `php ~/bin/pearscs.phar release ../../yaml-.tgz ` 20 | add new files to svn 21 | `find . -name '*.xml' | xargs svn propset svn:mime-type application/xml` 22 | 23 | Versioning: 24 | https://wiki.php.net/rfc/peclversioning/solution2 25 | -------------------------------------------------------------------------------- /dev-tools/test-build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # build and test against a phpenv managed php version 3 | 4 | set -euo pipefail 5 | 6 | SCRIPT_DIR=$(dirname $0) 7 | 8 | hash phpenv &>/dev/null || { 9 | echo >&2 "phpenv not found in path" 10 | echo >&2 "Install from https://github.com/CHH/phpenv" 11 | exit 1 12 | } 13 | 14 | [[ -n $1 ]] || { 15 | echo >&2 "usage: $0 " 16 | echo >&2 "versions: " 17 | phpenv versions >&2 18 | exit 2 19 | } 20 | 21 | make distclean &>/dev/null || true 22 | phpenv local $1 && 23 | phpize && 24 | CC=colorgcc CFLAGS="-Wall -fno-strict-aliasing -g3" \ 25 | ./configure --with-yaml=${LIBYAML:=} --enable-debug && 26 | make clean all && 27 | TEST_PHP_EXECUTABLE=$(command -v php) ${SCRIPT_DIR}/test.sh || exit $? 28 | -------------------------------------------------------------------------------- /tests/bug_79494.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Test PECL bug #74949 3 | --SKIPIF-- 4 | 5 | --INI-- 6 | serialize_precision=-1 7 | --FILE-- 8 | 11 | array ( 12 | 'audioEnabled' => 13 | array ( 14 | 0 => 132317787432502136, 15 | 1 => 0, 16 | ), 17 | 'eveampGain' => 18 | array ( 19 | 0 => 132316833510704299, 20 | 1 => 0.25, 21 | ), 22 | ), 23 | ); 24 | 25 | print yaml_emit($data); 26 | ?> 27 | --EXPECTF-- 28 | --- 29 | audio: 30 | audioEnabled: 31 | - %r(132317787432502136|1\.3231778743250214E\+17)%r 32 | - 0 33 | eveampGain: 34 | - %r(132316833510704299|1\.323168335107043E\+17)%r 35 | - 0.25 36 | ... 37 | -------------------------------------------------------------------------------- /tests/yaml_parse_file_001.yaml: -------------------------------------------------------------------------------- 1 | --- ! 2 | invoice: 34843 3 | date : 2001-01-23 4 | bill-to: &id001 5 | given : Chris 6 | family : Dumars 7 | address: 8 | lines: | 9 | 458 Walkman Dr. 10 | Suite #292 11 | city : Royal Oak 12 | state : MI 13 | postal : 48046 14 | ship-to: *id001 15 | product: 16 | - sku : BL394D 17 | quantity : 4 18 | description : Basketball 19 | price : 450.00 20 | - sku : BL4438H 21 | quantity : 1 22 | description : Super Hoop 23 | price : 2392.00 24 | tax : 251.42 25 | total: 4443.52 26 | comments: 27 | Late afternoon is best. 28 | Backup contact is Nancy 29 | Billsmer @ 338-4338. 30 | -------------------------------------------------------------------------------- /tests/yaml_parse_003.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | yaml_parse - parse errors 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 14 | --EXPECTF-- 15 | Warning: yaml_parse(): scanning error encountered during parsing: found character that cannot start any token (line 2, column 16), context while scanning for the next token (line 2, column 16) in %syaml_parse_003.php on line %d 16 | bool(false) 17 | 18 | Warning: yaml_parse(): scanning error encountered during parsing: found character that cannot start any token (line 2, column 15), context while scanning for the next token (line 2, column 15) in %syaml_parse_003.php on line %d 19 | bool(false) 20 | -------------------------------------------------------------------------------- /tests/yaml_parse_wiki_YtsBasicTests_003.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Yaml YtsBasicTests - Mixed Sequences 3 | --DESCRIPTION-- 4 | Sequences can contain any YAML data, 5 | including strings and other sequences. 6 | --CREDITS-- 7 | Bryan Davis bd808@bd808.com 8 | # yaml.kwiki.org import/conversion 9 | --SKIPIF-- 10 | 11 | --FILE-- 12 | 22 | --EXPECT-- 23 | array(4) { 24 | [0]=> 25 | string(5) "apple" 26 | [1]=> 27 | array(3) { 28 | [0]=> 29 | string(3) "foo" 30 | [1]=> 31 | string(3) "bar" 32 | [2]=> 33 | string(4) "x123" 34 | } 35 | [2]=> 36 | string(6) "banana" 37 | [3]=> 38 | string(6) "carrot" 39 | } 40 | -------------------------------------------------------------------------------- /tests/yaml_parse_spec_map.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Yaml 1.1 Spec - map 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 16 | --EXPECT-- 17 | array(2) { 18 | ["Block style"]=> 19 | array(3) { 20 | ["Clark"]=> 21 | string(5) "Evans" 22 | ["Brian"]=> 23 | string(8) "Ingerson" 24 | ["Oren"]=> 25 | string(8) "Ben-Kiki" 26 | } 27 | ["Flow style"]=> 28 | array(3) { 29 | ["Clark"]=> 30 | string(5) "Evans" 31 | ["Brian"]=> 32 | string(8) "Ingerson" 33 | ["Oren"]=> 34 | string(8) "Ben-Kiki" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/yaml_parse_002.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | yaml_parse - multiple documents 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 22 | --EXPECT-- 23 | array(2) { 24 | [0]=> 25 | array(3) { 26 | ["time"]=> 27 | string(8) "20:03:20" 28 | ["player"]=> 29 | string(10) "Sammy Sosa" 30 | ["action"]=> 31 | string(13) "strike (miss)" 32 | } 33 | [1]=> 34 | array(3) { 35 | ["time"]=> 36 | string(8) "20:03:47" 37 | ["player"]=> 38 | string(10) "Sammy Sosa" 39 | ["action"]=> 40 | string(10) "grand slam" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /docs/phpdoc/reference.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Yaml &Functions; 6 | 7 | &reference.yaml.entities.functions; 8 | 9 | 10 | 11 | 31 | -------------------------------------------------------------------------------- /dev-tools/sync-upstream.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Sync master of github clone with canonical upstream. 3 | # 4 | 5 | set -e 6 | set -u 7 | 8 | UPSTREAM_URL="https://github.com/php/pecl-file_formats-yaml.git" 9 | UPSTREAM=upstream 10 | MASTER=php7 11 | 12 | MY_UPSTREAM=$(git remote show ${UPSTREAM} 2>/dev/null | 13 | grep "Fetch URL"|awk '{print $3}') 14 | 15 | if [[ -z ${MY_UPSTREAM} ]]; then 16 | echo "Adding remote ${UPSTREAM} ${UPSTREAM_URL}" 17 | git remote add ${UPSTREAM} ${UPSTREAM_URL} 18 | MY_UPSTREAM=${UPSTREAM_URL} 19 | fi 20 | 21 | if [[ ${MY_UPSTREAM} != ${UPSTREAM_URL} ]]; then 22 | echo "Remote ${UPSTREAM} not tracking expected ${UPSTREAM_URL}" 23 | echo "Cowardly refusing to continue" 24 | exit 1 25 | fi 26 | 27 | set -x 28 | 29 | git fetch ${UPSTREAM} -pv 30 | git checkout ${MASTER} 31 | git merge --ff-only ${UPSTREAM}/${MASTER} 32 | -------------------------------------------------------------------------------- /tests/yaml_parse_spec_timestamp.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Yaml 1.1 Spec - timestamp 3 | --SKIPIF-- 4 | 5 | --INI-- 6 | yaml.decode_timestamp=1 7 | date.timezone=GMT 8 | --FILE-- 9 | 19 | --EXPECT-- 20 | array(6) { 21 | ["canonical"]=> 22 | int(1008385183) 23 | ["valid iso8601"]=> 24 | int(1008385183) 25 | ["alternate iso8601"]=> 26 | int(1008385183) 27 | ["space separated"]=> 28 | int(1008385183) 29 | ["no time zone (Z)"]=> 30 | int(1008385183) 31 | ["date (00:00:00Z)"]=> 32 | int(1039824000) 33 | } 34 | -------------------------------------------------------------------------------- /tests/bug_parsing_alias.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Test PECL strange alias bug 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 21 | --EXPECT-- 22 | array(2) { 23 | ["basic"]=> 24 | array(1) { 25 | [0]=> 26 | array(1) { 27 | ["value"]=> 28 | int(22) 29 | } 30 | } 31 | ["keylevel0"]=> 32 | array(2) { 33 | ["keylevel1"]=> 34 | array(1) { 35 | ["value"]=> 36 | int(1) 37 | } 38 | ["keylevel1.1"]=> 39 | array(1) { 40 | ["keylevel2"]=> 41 | array(1) { 42 | ["value"]=> 43 | int(2) 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tests/bug_74886.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Test PECL bug #74886 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 17 | --EXPECTF-- 18 | Warning: yaml_parse(): expected a mapping for merging, but found scalar (line 6, column 22) in %sbug_74886.php on line 2 19 | 20 | Warning: yaml_parse(): expected a mapping for merging, but found scalar (line 8, column 28) in %sbug_74886.php on line 2 21 | array(4) { 22 | [0]=> 23 | array(1) { 24 | ["x"]=> 25 | int(1) 26 | } 27 | [1]=> 28 | array(1) { 29 | ["<<"]=> 30 | int(2147483647) 31 | } 32 | [2]=> 33 | array(0) { 34 | } 35 | [3]=> 36 | array(1) { 37 | ["x"]=> 38 | int(1) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tests/bug_74799.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Memory leak check 3 | --CREDITS-- 4 | Gleb Svitelskiy 5 | --SKIPIF-- 6 | 7 | --FILE-- 8 | 'tag_callback']); 18 | unset($yamlString, $ndocs); 19 | 20 | $ndocs = null; 21 | yaml_parse_file(__DIR__.'/bug_74799.yaml', 0, $ndocs, ['!value' => 'tag_callback']); 22 | unset($ndocs); 23 | 24 | $array = ['key' => 'value']; 25 | yaml_emit($array); 26 | unset($array); 27 | 28 | $array = ['key' => 'value']; 29 | yaml_emit_file(__DIR__.'/bug_74799.tmp', $array); 30 | unset($array); 31 | 32 | var_dump($base_memory == memory_get_usage()); 33 | ?> 34 | --CLEAN-- 35 | 38 | --EXPECT-- 39 | bool(true) 40 | -------------------------------------------------------------------------------- /tests/bug_64019.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Test PECL bug #64019 3 | --SKIPIF-- 4 | 5 | --INI-- 6 | ; Ignore Deprecated: Using null as an array offset is deprecated... 7 | error_reporting = E_ALL & ~E_DEPRECATED 8 | --FILE-- 9 | 28 | --EXPECT-- 29 | array(2) { 30 | ["configAnchors"]=> 31 | array(1) { 32 | [0]=> 33 | array(2) { 34 | [""]=> 35 | NULL 36 | ["configKey"]=> 37 | string(11) "configValue" 38 | } 39 | } 40 | ["config"]=> 41 | array(1) { 42 | ["<<"]=> 43 | NULL 44 | } 45 | } 46 | array(1) { 47 | ["config"]=> 48 | array(1) { 49 | ["<<"]=> 50 | NULL 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # from svn:ignore 2 | .deps 3 | .libs 4 | .php-version 5 | .rbenv-version 6 | acinclude.m4 7 | aclocal.m4 8 | autom4te.cache 9 | build 10 | config.guess 11 | config.h 12 | config.h.in 13 | config.log 14 | config.nice 15 | config.status 16 | config.sub 17 | configure 18 | configure.in 19 | configure.ac 20 | extras 21 | include 22 | install-sh 23 | libtool 24 | ltmain.sh 25 | ltmain.sh.backup 26 | Makefile 27 | Makefile.fragments 28 | Makefile.global 29 | Makefile.objects 30 | missing 31 | mkinstalldirs 32 | modules 33 | run-tests.php 34 | tmp-php.ini 35 | yaml.loT 36 | 37 | # General Ignores 38 | *~ 39 | .#* 40 | *. 41 | *.slo 42 | *.mk 43 | *.mem 44 | *.gcda 45 | *.gcno 46 | *.la 47 | *.lo 48 | *.o 49 | *.a 50 | *.ncb 51 | *.opt 52 | *.plg 53 | *.dep 54 | *swp 55 | *.patch 56 | *.tgz 57 | *.tar.gz 58 | *.tar.bz2 59 | .FBCIndex 60 | .FBCLockFolder 61 | core 62 | 63 | # Test specific Ignores 64 | tests/*.diff 65 | tests/*.exp 66 | tests/*.log 67 | tests/*.out 68 | tests/*.php 69 | tests/*.sh 70 | 71 | # coverage 72 | /coverage.info 73 | /reports 74 | -------------------------------------------------------------------------------- /tests/bug_69465.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Test PECL bug #69465 3 | --SKIPIF-- 4 | 5 | --INI-- 6 | yaml.decode_timestamp=1 7 | date.timezone=UTC 8 | --FILE-- 9 | 27 | --EXPECT-- 28 | array(12) { 29 | ["date1"]=> 30 | int(1431648000) 31 | ["date2"]=> 32 | string(10) "2015-05-15" 33 | ["date3"]=> 34 | string(10) "2015-05-15" 35 | ["bool1"]=> 36 | bool(true) 37 | ["bool2"]=> 38 | string(4) "true" 39 | ["bool3"]=> 40 | string(4) "true" 41 | ["int1"]=> 42 | int(1) 43 | ["int2"]=> 44 | string(1) "1" 45 | ["int3"]=> 46 | string(1) "1" 47 | ["float1"]=> 48 | float(1.5) 49 | ["float2"]=> 50 | string(3) "1.5" 51 | ["float3"]=> 52 | string(3) "1.5" 53 | } 54 | -------------------------------------------------------------------------------- /docs/phpdoc/versions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 36 | -------------------------------------------------------------------------------- /dev-tools/pull-request.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Apply a github pull request. 3 | # 4 | #/ usage: pull-request.sh PULL-REQUEST-ID [BRANCH] 5 | #/ - PULL-REQUEST-ID : Pull request number 6 | #/ - BRANCH : Branch to land to (default: "master") 7 | # 8 | 9 | set -e 10 | set -u 11 | 12 | REQ=${1:?PULL-REQUEST-ID required} 13 | GITHUB_REPO="php/pecl-file_formats-yaml" 14 | BRANCH=${2:-php7} 15 | 16 | # switch to main branch 17 | git checkout ${BRANCH} 18 | 19 | # fetch the pull request into a local branch 20 | git fetch git://github.com/${GITHUB_REPO}.git \ 21 | pull/${REQ}/head:pull-request/${REQ} 22 | 23 | # review changes 24 | git log --patch-with-stat ${BRANCH}..pull-request/${REQ} 25 | 26 | printf "Accept changes? (y/N) " 27 | read -e APPLY 28 | if [[ "y" = $APPLY || "Y" = $APPLY ]]; then 29 | # merge into working copy 30 | git merge --no-ff --no-commit pull-request/${REQ} 31 | 32 | echo "Changes staged for commit." 33 | echo " - Don't forget to make a good commit message!" 34 | echo " - This might be a good time to update package.xml too." 35 | fi 36 | -------------------------------------------------------------------------------- /.appveyor.yml: -------------------------------------------------------------------------------- 1 | image: Visual Studio 2017 2 | version: '{branch}.{build}' 3 | 4 | clone_folder: c:\projects\yaml 5 | 6 | install: 7 | - ps: .appveyor\install.ps1 8 | 9 | cache: 10 | - c:\build-cache -> .appveyor.yml, .appveyor\install.ps1 11 | 12 | environment: 13 | BIN_SDK_VER: 2.3.0 14 | matrix: 15 | - PHP_VER: 7.2.34 16 | ARCH: x64 17 | TS: 1 18 | VC: vc15 19 | DEP: libyaml-0.1.7 20 | - PHP_VER: 7.2.34 21 | ARCH: x86 22 | TS: 0 23 | VC: vc15 24 | DEP: libyaml-0.1.7 25 | - PHP_VER: 7.3.33 26 | ARCH: x64 27 | TS: 1 28 | VC: vc15 29 | DEP: libyaml-0.1.7 30 | - PHP_VER: 7.3.33 31 | ARCH: x86 32 | TS: 0 33 | VC: vc15 34 | DEP: libyaml-0.1.7 35 | - PHP_VER: 7.4.33 36 | ARCH: x64 37 | TS: 1 38 | VC: vc15 39 | DEP: libyaml-0.1.7 40 | - PHP_VER: 7.4.33 41 | ARCH: x86 42 | TS: 0 43 | VC: vc15 44 | DEP: libyaml-0.1.7 45 | 46 | build_script: 47 | - ps: .appveyor\build.ps1 48 | 49 | test_script: 50 | - ps: .appveyor\test.ps1 51 | -------------------------------------------------------------------------------- /docs/phpdoc/configure.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | &reftitle.install; 6 | 7 | 8 | &pecl.info; 9 | &url.pecl.package;yaml 10 | 11 | 12 | 13 | The latest PECL/yaml Win32 DLL is available here: 14 | php_yaml.dll 15 | 16 | 17 |
18 | 19 | 20 | 40 | -------------------------------------------------------------------------------- /dev-tools/test-coverage.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # build and test against a phpenv managed php version 3 | 4 | set -e 5 | 6 | SCRIPT_DIR=$(dirname $0) 7 | 8 | hash phpenv &>/dev/null || { 9 | echo >&2 "phpenv not found in path" 10 | echo >&2 "Install from https://github.com/CHH/phpenv" 11 | exit 1 12 | } 13 | 14 | [[ -n $1 ]] || { 15 | echo >&2 "usage: $0 " 16 | echo >&2 "versions: " 17 | phpenv versions >&2 18 | exit 2 19 | } 20 | 21 | make distclean &>/dev/null || true 22 | phpenv local $1 && 23 | phpize && 24 | CC=colorgcc \ 25 | CFLAGS="-Wall -fno-strict-aliasing -g -O0 --coverage -fprofile-arcs -ftest-coverage" \ 26 | LDFLAGS="--coverage" \ 27 | ./configure --with-yaml && 28 | make clean all && 29 | lcov --directory . --zerocounters && 30 | lcov --directory . --capture --initial --output-file coverage.info 31 | TEST_PHP_EXECUTABLE=$(command -v php) ${SCRIPT_DIR}/test.sh || exit $? 32 | [[ -f .libs/yaml.gcno ]] || touch .libs/yaml.gcno # HACK 33 | lcov --no-checksum --directory . --capture --output-file coverage.info 34 | genhtml --highlight --legend --output-directory reports coverage.info 35 | -------------------------------------------------------------------------------- /tests/bug_79866.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Test PECL bug #79866 3 | --SKIPIF-- 4 | 5 | --INI-- 6 | precision=14 7 | serialize_precision=-1 8 | --FILE-- 9 | 0, 12 | "1" => 1, 13 | "-1" => -1, 14 | "2." => 2., 15 | "2.0" => 2.0, 16 | "2.00" => 2.00, 17 | "2.000" => 2.000, 18 | "0.123456789" => 0.123456789, 19 | "-0.123456789" => -0.123456789, 20 | "2.3e6" => 2.3e6, 21 | "-2.3e6" => -2.3e6, 22 | "2.3e-6" => 2.3e-6, 23 | "-2.3e-6" => -2.3e-6, 24 | "INF" => INF, 25 | "NAN" => NAN, 26 | "0.000021" => 0.000021, 27 | ]; 28 | 29 | foreach( $floats as $idx => $float ) { 30 | $float = floatval($float); 31 | ob_start(); 32 | @print_r($float); 33 | $native = ob_get_clean(); 34 | 35 | $expect = "--- {$native}\n...\n"; 36 | $got = yaml_emit($float); 37 | if ( $got !== $expect ) { 38 | echo "== FAIL! {$idx} ==\n"; 39 | echo "expected:\n{$expect}\n"; 40 | echo "got:{$got}\n"; 41 | } 42 | } 43 | ?> 44 | --EXPECT-- 45 | -------------------------------------------------------------------------------- /tests/yaml_parse_wiki_YtsBasicTests_008.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Yaml YtsBasicTests - Mixed Mapping 3 | --DESCRIPTION-- 4 | A mapping can contain any assortment 5 | of mappings and sequences as values. 6 | --CREDITS-- 7 | Bryan Davis bd808@bd808.com 8 | # yaml.kwiki.org import/conversion 9 | --SKIPIF-- 10 | 11 | --FILE-- 12 | 26 | --EXPECT-- 27 | array(2) { 28 | ["foo"]=> 29 | string(8) "whatever" 30 | ["bar"]=> 31 | array(3) { 32 | [0]=> 33 | array(3) { 34 | ["fruit"]=> 35 | string(5) "apple" 36 | ["name"]=> 37 | string(5) "steve" 38 | ["sport"]=> 39 | string(8) "baseball" 40 | } 41 | [1]=> 42 | string(4) "more" 43 | [2]=> 44 | array(3) { 45 | ["python"]=> 46 | string(5) "rocks" 47 | ["perl"]=> 48 | string(6) "papers" 49 | ["ruby"]=> 50 | string(10) "scissorses" 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /.appveyor/build.ps1: -------------------------------------------------------------------------------- 1 | cd c:\projects\yaml 2 | echo "" | Out-File -Encoding "ASCII" task.bat 3 | echo "call phpize 2>&1" | Out-File -Encoding "ASCII" -Append task.bat 4 | echo "call configure --with-php-build=c:\build-cache\deps --with-yaml --enable-debug-pack 2>&1" | Out-File -Encoding "ASCII" -Append task.bat 5 | echo "nmake /nologo 2>&1" | Out-File -Encoding "ASCII" -Append task.bat 6 | echo "exit %errorlevel%" | Out-File -Encoding "ASCII" -Append task.bat 7 | $here = (Get-Item -Path "." -Verbose).FullName 8 | $runner = 'c:\build-cache\php-sdk-' + $env:BIN_SDK_VER + '\phpsdk' + '-' + $env:VC + '-' + $env:ARCH + '.bat' 9 | $task = $here + '\task.bat' 10 | & $runner -t $task 11 | if (-not $?) { 12 | throw "building failed with errorlevel $LastExitCode" 13 | } 14 | $dname = '' 15 | if ('x64' -eq $env:ARCH) { $dname = $dname + 'x64\'} 16 | $dname = $dname + 'Release'; 17 | if ('1' -eq $env:TS) { $dname = $dname + '_TS'} 18 | copy $dname\php_yaml.dll $env:PHP_PATH\ext\php_yaml.dll 19 | 20 | New-Item -Path $env:PHP_PATH\php.ini -Force 21 | Add-Content -Path $env:PHP_PATH\php.ini -Value 'extension_dir=ext' 22 | Add-Content -Path $env:PHP_PATH\php.ini -Value 'extension=php_yaml.dll' 23 | -------------------------------------------------------------------------------- /tests/yaml_parse_spec_binary.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Yaml 1.1 Spec - binary 3 | --SKIPIF-- 4 | 8 | --INI-- 9 | yaml.decode_binary=1 10 | --FILE-- 11 | 29 | --EXPECT-- 30 | bool(true) 31 | string(32) "a8363b3d0e4e39d9e77e244e216c7840" 32 | -------------------------------------------------------------------------------- /tests/yaml_parse_spec_pairs.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Yaml 1.1 Spec - pairs 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 17 | --EXPECT-- 18 | array(2) { 19 | ["Block tasks"]=> 20 | array(4) { 21 | [0]=> 22 | array(1) { 23 | ["meeting"]=> 24 | string(10) "with team." 25 | } 26 | [1]=> 27 | array(1) { 28 | ["meeting"]=> 29 | string(10) "with boss." 30 | } 31 | [2]=> 32 | array(1) { 33 | ["break"]=> 34 | string(6) "lunch." 35 | } 36 | [3]=> 37 | array(1) { 38 | ["meeting"]=> 39 | string(12) "with client." 40 | } 41 | } 42 | ["Flow tasks"]=> 43 | array(2) { 44 | [0]=> 45 | array(1) { 46 | ["meeting"]=> 47 | string(9) "with team" 48 | } 49 | [1]=> 50 | array(1) { 51 | ["meeting"]=> 52 | string(9) "with boss" 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /tests/yaml_parse_spec_null.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Yaml 1.1 Spec - null 3 | --SKIPIF-- 4 | 5 | --INI-- 6 | ; Ignore Deprecated: Using null as an array offset is deprecated... 7 | error_reporting = E_ALL & ~E_DEPRECATED 8 | --FILE-- 9 | 31 | --EXPECT-- 32 | array(3) { 33 | [0]=> 34 | NULL 35 | [1]=> 36 | array(4) { 37 | ["empty"]=> 38 | NULL 39 | ["canonical"]=> 40 | NULL 41 | ["english"]=> 42 | NULL 43 | [""]=> 44 | string(8) "null key" 45 | } 46 | [2]=> 47 | array(1) { 48 | ["sparse"]=> 49 | array(5) { 50 | [0]=> 51 | NULL 52 | [1]=> 53 | string(9) "2nd entry" 54 | [2]=> 55 | NULL 56 | [3]=> 57 | string(9) "4th entry" 58 | [4]=> 59 | NULL 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2007 Ryusuke SEKIYAMA 4 | Copyright (c) 2009 Keynetics Inc 5 | Copyright (c) 2015 Bryan Davis and contributors 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a 8 | copy of this software and associated documentation files (the "Software"), 9 | to deal in the Software without restriction, including without limitation 10 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 | and/or sell copies of the Software, and to permit persons to whom the 12 | Software is furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /tests/yaml_002.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | yaml - emit -> parse roundtrip with datetime 3 | --SKIPIF-- 4 | 8 | --INI-- 9 | date.timezone=GMT 10 | yaml.decode_timestamp=2 11 | --FILE-- 12 | new DateTime("2001-12-15T02:59:43.1Z"), 15 | "valid iso8601" => new DateTime("2001-12-14t21:59:43.10-05:00"), 16 | "alternate iso8601" => new DateTime("2001-12-14T21:59:43.10-0500"), 17 | "space separated" => new DateTime("2001-12-14 21:59:43.10 -5"), 18 | "no time zone (Z)" => new DateTime("2001-12-15 2:59:43.10"), 19 | "date (0000:00Z)" => new DateTime("2002-12-14"), 20 | ); 21 | 22 | $yaml = yaml_emit($original); 23 | var_dump($yaml); 24 | $parsed = yaml_parse($yaml); 25 | var_dump($parsed == $original); 26 | ?> 27 | --EXPECT-- 28 | string(303) "--- 29 | canonical: 2001-12-15T02:59:43.100000+00:00 30 | valid iso8601: 2001-12-14T21:59:43.100000-05:00 31 | alternate iso8601: 2001-12-14T21:59:43.100000-05:00 32 | space separated: 2001-12-14T21:59:43.100000-05:00 33 | no time zone (Z): 2001-12-15T02:59:43.100000+00:00 34 | date (0000:00Z): 2002-12-14T00:00:00.000000+00:00 35 | ... 36 | " 37 | bool(true) 38 | -------------------------------------------------------------------------------- /config.m4: -------------------------------------------------------------------------------- 1 | PHP_ARG_WITH(yaml, [whether to enable LibYAML support], 2 | [ --with-yaml[[=DIR]] Enable LibYAML support. 3 | DIR is the path to LibYAML install prefix]) 4 | 5 | if test "$PHP_YAML" != "no"; then 6 | 7 | AC_MSG_CHECKING([for yaml headers]) 8 | for i in "$PHP_YAML" "$prefix" /usr /usr/local; do 9 | if test -r "$i/include/yaml.h"; then 10 | PHP_YAML_DIR=$i 11 | AC_MSG_RESULT([found in $i]) 12 | break 13 | fi 14 | done 15 | if test -z "$PHP_YAML_DIR"; then 16 | AC_MSG_RESULT([not found]) 17 | AC_MSG_ERROR([Please install libyaml]) 18 | fi 19 | 20 | PHP_ADD_INCLUDE($PHP_YAML_DIR/include) 21 | dnl recommended flags for compilation with gcc 22 | dnl CFLAGS="$CFLAGS -Wall -fno-strict-aliasing" 23 | 24 | export OLD_CPPFLAGS="$CPPFLAGS" 25 | export CPPFLAGS="$CPPFLAGS $INCLUDES -DHAVE_YAML" 26 | AC_CHECK_HEADER([yaml.h], [], AC_MSG_ERROR(['yaml.h' header not found])) 27 | PHP_SUBST(YAML_SHARED_LIBADD) 28 | 29 | PHP_ADD_LIBRARY_WITH_PATH(yaml, $PHP_YAML_DIR/$PHP_LIBDIR, YAML_SHARED_LIBADD) 30 | export CPPFLAGS="$OLD_CPPFLAGS" 31 | 32 | PHP_SUBST(YAML_SHARED_LIBADD) 33 | AC_DEFINE(HAVE_YAML, 1, [ ]) 34 | PHP_NEW_EXTENSION(yaml, yaml.c parse.c emit.c detect.c , $ext_shared) 35 | fi 36 | -------------------------------------------------------------------------------- /tests/yaml_parse_spec_omap.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Yaml 1.1 Spec - omap 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 18 | --EXPECT-- 19 | array(2) { 20 | ["Bestiary"]=> 21 | array(3) { 22 | [0]=> 23 | array(1) { 24 | ["aardvark"]=> 25 | string(33) "African pig-like ant eater. Ugly." 26 | } 27 | [1]=> 28 | array(1) { 29 | ["anteater"]=> 30 | string(38) "South-American ant eater. Two species." 31 | } 32 | [2]=> 33 | array(1) { 34 | ["anaconda"]=> 35 | string(40) "South-American constrictor snake. Scaly." 36 | } 37 | } 38 | ["Numbers"]=> 39 | array(3) { 40 | [0]=> 41 | array(1) { 42 | ["one"]=> 43 | int(1) 44 | } 45 | [1]=> 46 | array(1) { 47 | ["two"]=> 48 | int(2) 49 | } 50 | [2]=> 51 | array(1) { 52 | ["three"]=> 53 | int(3) 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /tests/yaml_001.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | yaml - emit -> parse roundtrip 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | "Chris", 9 | "family"=> "Dumars", 10 | "address"=> array( 11 | "lines"=> "458 Walkman Dr. 12 | Suite #292", 13 | "city"=> "Royal Oak", 14 | "state"=> "MI", 15 | "postal"=> 48046, 16 | ), 17 | ); 18 | $invoice = array ( 19 | "invoice"=> 34843, 20 | "date"=> 980208000, 21 | "bill-to"=> $addr, 22 | "ship-to"=> $addr, 23 | "product"=> array( 24 | array( 25 | "sku"=> "BL394D", 26 | "quantity"=> 4, 27 | "description"=> "Basketball", 28 | "price"=> 450, 29 | ), 30 | array( 31 | "sku"=> "BL4438H", 32 | "quantity"=> 1, 33 | "description"=> "Super Hoop", 34 | "price"=> 2392, 35 | ), 36 | ), 37 | "tax"=> 251.42, 38 | "total"=> 4443.52, 39 | "comments"=> "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338.", 40 | "tags" => array("a","b","c"), 41 | ); 42 | $yaml = yaml_emit($invoice); 43 | $parsed = yaml_parse($yaml); 44 | var_dump($parsed == $invoice); 45 | ?> 46 | --EXPECT-- 47 | bool(true) 48 | -------------------------------------------------------------------------------- /docs/phpdoc/book.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | YAML Data Serialization 8 | Yaml 9 | 10 | 11 | 12 | &reftitle.intro; 13 | 14 | This extension implements the YAML Ain't 15 | Markup Language (YAML) data serialization standard. Parsing and 16 | emiting are handled by the LibYAML 17 | library. 18 | 19 | 20 | 21 | 22 | &reference.yaml.setup; 23 | &reference.yaml.constants; 24 | &reference.yaml.examples; 25 | &reference.yaml.reference; 26 | 27 | 28 | 29 | 49 | -------------------------------------------------------------------------------- /tests/yaml_emit_009.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | yaml_emit - custom tags with closures 3 | --SKIPIF-- 4 | 8 | --FILE-- 9 | function ($o) { 12 | return array( 13 | 'tag' => '!emit009', 14 | 'data' => $o->data, 15 | ); 16 | }, 17 | ); 18 | 19 | class Emit009Example { 20 | public $data; // data may be in any pecl/yaml suitable type 21 | } 22 | 23 | $t = new Emit009Example(); 24 | $t->data = array ('a','b','c'); 25 | $yaml = yaml_emit( 26 | array( 27 | 'callback' => $t, 28 | ), 29 | YAML_ANY_ENCODING, 30 | YAML_ANY_BREAK, 31 | $emit_callbacks 32 | ); 33 | var_dump($yaml); 34 | 35 | /* make sure you can undo the custome serialization */ 36 | function parse_009 ($value, $tag, $flags) { 37 | $ret = new Emit009Example(); 38 | $ret->data = $value; 39 | return $ret; 40 | } 41 | $parse_callbacks = array( 42 | '!emit009' => 'parse_009', 43 | ); 44 | $array = yaml_parse($yaml, 0, $cnt, $parse_callbacks); 45 | var_dump($array['callback'] == $t); 46 | 47 | /* roundtrip with raw object */ 48 | var_dump($t == yaml_parse( 49 | yaml_emit($t, YAML_ANY_ENCODING, YAML_ANY_BREAK, $emit_callbacks), 50 | 0, $cnt, $parse_callbacks)); 51 | ?> 52 | --EXPECT-- 53 | string(39) "--- 54 | callback: !emit009 55 | - a 56 | - b 57 | - c 58 | ... 59 | " 60 | bool(true) 61 | bool(true) 62 | -------------------------------------------------------------------------------- /tests/yaml_parse_file_002.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | yaml_parse_file - error cases 3 | --SKIPIF-- 4 | 5 | --INI-- 6 | yaml.decode_timestamp=1 7 | date.timezone=GMT 8 | ; Ignore Deprecated: yaml_parse_file(): Passing null to parameter #1... 9 | error_reporting = E_ALL & ~E_DEPRECATED 10 | --FILE-- 11 | getMessage()} in " . __FILE__ . " on line 4\n"; 18 | } 19 | try { 20 | // PHP7 emits a Warning here 21 | yaml_parse_file(''); 22 | } catch (ValueError $e) { 23 | // PHP8 raises this exception 24 | echo "\nWarning: yaml_parse_file(): {$e->getMessage()} in " . __FILE__ . " on line 11\n"; 25 | } 26 | yaml_parse_file('invalid'); 27 | try { 28 | // PHP7 emits a Warning here 29 | yaml_parse_file(); 30 | } catch (ArgumentCountError $e) { 31 | // PHP8 raises this exception 32 | echo "\nWarning: {$e->getMessage()} in " . __FILE__ . " on line 19\n"; 33 | } 34 | --EXPECTF-- 35 | Warning: yaml_parse_file(): %r(Filename|Path)%r %r(cannot|must not)%r be empty in %s on line %d 36 | 37 | Warning: yaml_parse_file(): %r(Filename|Path)%r %r(cannot|must not)%r be empty in %s on line %d 38 | 39 | Warning: yaml_parse_file(invalid): %r[Ff]%railed to open stream: No such file or directory in %s on line %d 40 | 41 | Warning: yaml_parse_file() expects at least 1 %r(argument|parameter)%r, 0 given in %s on line %d 42 | -------------------------------------------------------------------------------- /docs/phpdoc/setup.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | &reftitle.setup; 6 | 7 |
8 | &reftitle.required; 9 | 10 | This extension requires the LibYAML C 11 | library version 0.1.0 or higher to be installed. 12 | 13 |
14 | 15 |
16 | &reftitle.install; 17 | 18 | &pecl.moved; 19 | 20 | 21 | &pecl.info; 22 | &url.pecl.package;yaml. 23 | 24 | 25 | &pecl.windows.download; 26 | 27 |
28 | 29 | 30 | &reference.yaml.ini; 31 | 32 | 33 |
34 | &reftitle.resources; 35 | 36 | 37 | 38 |
39 | 40 |
41 | 42 | 62 | -------------------------------------------------------------------------------- /tests/bug_61923.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Test PECL bug #61923 3 | --SKIPIF-- 4 | 5 | --INI-- 6 | serialize_precision=-1 7 | --FILE-- 8 | 35 | --EXPECT-- 36 | array(2) { 37 | ["strings"]=> 38 | array(8) { 39 | [0]=> 40 | string(3) "1:0" 41 | [1]=> 42 | string(3) "0:1" 43 | [2]=> 44 | string(5) "1:0:0" 45 | [3]=> 46 | string(6) "+1:0:0" 47 | [4]=> 48 | string(6) "-1:0:0" 49 | [5]=> 50 | string(3) ":01" 51 | [6]=> 52 | string(2) ":1" 53 | [7]=> 54 | string(14) "18:53:17.00037" 55 | } 56 | ["numbers"]=> 57 | array(8) { 58 | [0]=> 59 | int(60) 60 | [1]=> 61 | int(1) 62 | [2]=> 63 | int(3600) 64 | [3]=> 65 | int(3600) 66 | [4]=> 67 | int(-3600) 68 | [5]=> 69 | int(1) 70 | [6]=> 71 | int(1) 72 | [7]=> 73 | float(67997.00037) 74 | } 75 | } 76 | string(161) "--- 77 | strings: 78 | - "1:0" 79 | - "0:1" 80 | - "1:0:0" 81 | - "+1:0:0" 82 | - "-1:0:0" 83 | - ":01" 84 | - ":1" 85 | - "18:53:17.00037" 86 | numbers: 87 | - 60 88 | - 1 89 | - 3600 90 | - 3600 91 | - -3600 92 | - 1 93 | - 1 94 | - 67997.00037 95 | ... 96 | " 97 | -------------------------------------------------------------------------------- /tests/yaml_parse_spec_seq.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Yaml 1.1 Spec - seq 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 24 | --EXPECT-- 25 | array(2) { 26 | ["Block style"]=> 27 | array(9) { 28 | [0]=> 29 | string(7) "Mercury" 30 | [1]=> 31 | string(5) "Venus" 32 | [2]=> 33 | string(5) "Earth" 34 | [3]=> 35 | string(4) "Mars" 36 | [4]=> 37 | string(7) "Jupiter" 38 | [5]=> 39 | string(6) "Saturn" 40 | [6]=> 41 | string(6) "Uranus" 42 | [7]=> 43 | string(7) "Neptune" 44 | [8]=> 45 | string(5) "Pluto" 46 | } 47 | ["Flow style"]=> 48 | array(9) { 49 | [0]=> 50 | string(7) "Mercury" 51 | [1]=> 52 | string(5) "Venus" 53 | [2]=> 54 | string(5) "Earth" 55 | [3]=> 56 | string(4) "Mars" 57 | [4]=> 58 | string(7) "Jupiter" 59 | [5]=> 60 | string(6) "Saturn" 61 | [6]=> 62 | string(6) "Uranus" 63 | [7]=> 64 | string(7) "Neptune" 65 | [8]=> 66 | string(5) "Pluto" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /tests/yaml_emit_008.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | yaml_emit - custom tags 3 | --SKIPIF-- 4 | 7 | --FILE-- 8 | '!emit008', 24 | 'data' => $obj->data, 25 | ); 26 | } 27 | } 28 | 29 | $emit_callbacks = array( 30 | 'Emit008Example' => array('Emit008Example', 'yamlEmit') 31 | ); 32 | 33 | $t = new Emit008Example(); 34 | $t->data = array ('a','b','c'); 35 | $yaml = yaml_emit( 36 | array( 37 | 'callback' => $t, 38 | ), 39 | YAML_ANY_ENCODING, 40 | YAML_ANY_BREAK, 41 | $emit_callbacks 42 | ); 43 | var_dump($yaml); 44 | 45 | /* make sure you can undo the custome serialization */ 46 | function parse_008 ($value, $tag, $flags) { 47 | $ret = new Emit008Example(); 48 | $ret->data = $value; 49 | return $ret; 50 | } 51 | $parse_callbacks = array( 52 | '!emit008' => 'parse_008', 53 | ); 54 | $array = yaml_parse($yaml, 0, $cnt, $parse_callbacks); 55 | var_dump($array['callback'] == $t); 56 | 57 | /* roundtrip with raw object */ 58 | var_dump($t == yaml_parse( 59 | yaml_emit($t, YAML_ANY_ENCODING, YAML_ANY_BREAK, $emit_callbacks), 60 | 0, $cnt, $parse_callbacks)); 61 | ?> 62 | --EXPECT-- 63 | string(39) "--- 64 | callback: !emit008 65 | - a 66 | - b 67 | - c 68 | ... 69 | " 70 | bool(true) 71 | bool(true) 72 | -------------------------------------------------------------------------------- /tests/yaml_parse_006.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | yaml_parse - syck bug #14384 3 | --CREDITS-- 4 | From syck bug #14384 5 | http://pecl.php.net/bugs/bug.php?id=14384 6 | --SKIPIF-- 7 | 8 | --FILE-- 9 | 35 | --EXPECTF-- 36 | Warning: yaml_parse(): scanning error encountered during parsing: found character that cannot start any token (line 2, column 1), context while scanning for the next token (line 2, column 1) in %syaml_parse_006.php on line %d 37 | bool(false) 38 | 39 | Warning: yaml_parse(): scanning error encountered during parsing: found character that cannot start any token (line 2, column 3), context while scanning for the next token (line 2, column 3) in %syaml_parse_006.php on line %d 40 | bool(false) 41 | array(1) { 42 | ["key"]=> 43 | string(16) "tab before value" 44 | } 45 | array(1) { 46 | ["key"]=> 47 | string(26) "space and tab before value" 48 | } 49 | 50 | Warning: yaml_parse(): scanning error encountered during parsing: found character that cannot start any token (line 2, column 2), context while scanning for the next token (line 2, column 2) in %syaml_parse_006.php on line %d 51 | bool(false) 52 | 53 | Warning: yaml_parse(): scanning error encountered during parsing: found character that cannot start any token (line 2, column 4), context while scanning for the next token (line 2, column 4) in %syaml_parse_006.php on line %d 54 | bool(false) 55 | -------------------------------------------------------------------------------- /tests/bug_60628.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Test PECL bug #260628 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | $value, 23 | 'another' => 'test', 24 | ); 25 | } 26 | 27 | /* baseline. do like operation in native php. */ 28 | $native = array( 29 | "data" => array("look upper"), 30 | ); 31 | $native["data"] = tag_callback($native["data"], "!mytag", 0); 32 | 33 | echo "-- native value --\n"; 34 | var_dump($native); 35 | echo "-- end native value --\n"; 36 | 37 | $cnt = null; 38 | $array = yaml_parse($data, 0, $cnt, array( 39 | '!mytag' => 'tag_callback', 40 | )); 41 | 42 | echo "-- parsed value --\n"; 43 | var_dump($array); 44 | echo "-- end parsed value --\n"; 45 | ?> 46 | --EXPECT-- 47 | -- callback value -- 48 | array(1) { 49 | [0]=> 50 | string(10) "look upper" 51 | } 52 | string(6) "!mytag" 53 | int(0) 54 | -- end callback value -- 55 | -- native value -- 56 | array(1) { 57 | ["data"]=> 58 | array(2) { 59 | ["data"]=> 60 | array(1) { 61 | [0]=> 62 | string(10) "look upper" 63 | } 64 | ["another"]=> 65 | string(4) "test" 66 | } 67 | } 68 | -- end native value -- 69 | -- callback value -- 70 | array(1) { 71 | [0]=> 72 | string(10) "look upper" 73 | } 74 | string(6) "!mytag" 75 | int(0) 76 | -- end callback value -- 77 | -- parsed value -- 78 | array(1) { 79 | ["data"]=> 80 | array(2) { 81 | ["data"]=> 82 | array(1) { 83 | [0]=> 84 | string(10) "look upper" 85 | } 86 | ["another"]=> 87 | string(4) "test" 88 | } 89 | } 90 | -- end parsed value -- 91 | -------------------------------------------------------------------------------- /tests/yaml_parse_spec_merge.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Yaml 1.1 Spec - merge 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 37 | --EXPECT-- 38 | array(8) { 39 | [0]=> 40 | array(2) { 41 | ["x"]=> 42 | int(1) 43 | ["y"]=> 44 | int(2) 45 | } 46 | [1]=> 47 | array(2) { 48 | ["x"]=> 49 | int(0) 50 | ["y"]=> 51 | int(2) 52 | } 53 | [2]=> 54 | array(1) { 55 | ["r"]=> 56 | int(10) 57 | } 58 | [3]=> 59 | array(1) { 60 | ["r"]=> 61 | int(1) 62 | } 63 | [4]=> 64 | array(4) { 65 | ["x"]=> 66 | int(1) 67 | ["y"]=> 68 | int(2) 69 | ["r"]=> 70 | int(10) 71 | ["label"]=> 72 | string(10) "center/big" 73 | } 74 | [5]=> 75 | array(4) { 76 | ["x"]=> 77 | int(1) 78 | ["y"]=> 79 | int(2) 80 | ["r"]=> 81 | int(10) 82 | ["label"]=> 83 | string(10) "center/big" 84 | } 85 | [6]=> 86 | array(4) { 87 | ["x"]=> 88 | int(1) 89 | ["y"]=> 90 | int(2) 91 | ["r"]=> 92 | int(10) 93 | ["label"]=> 94 | string(10) "center/big" 95 | } 96 | [7]=> 97 | array(4) { 98 | ["r"]=> 99 | int(10) 100 | ["x"]=> 101 | int(1) 102 | ["y"]=> 103 | int(2) 104 | ["label"]=> 105 | string(10) "center/big" 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /tests/yaml_parse_file_001.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | yaml_parse_file - general 3 | --SKIPIF-- 4 | 5 | --INI-- 6 | yaml.decode_timestamp=1 7 | date.timezone=GMT 8 | --FILE-- 9 | 14 | int(34843) 15 | ["date"]=> 16 | int(980208000) 17 | ["bill-to"]=> 18 | &array(3) { 19 | ["given"]=> 20 | string(5) "Chris" 21 | ["family"]=> 22 | string(6) "Dumars" 23 | ["address"]=> 24 | array(4) { 25 | ["lines"]=> 26 | string(27) "458 Walkman Dr. 27 | Suite #292 28 | " 29 | ["city"]=> 30 | string(9) "Royal Oak" 31 | ["state"]=> 32 | string(2) "MI" 33 | ["postal"]=> 34 | int(48046) 35 | } 36 | } 37 | ["ship-to"]=> 38 | &array(3) { 39 | ["given"]=> 40 | string(5) "Chris" 41 | ["family"]=> 42 | string(6) "Dumars" 43 | ["address"]=> 44 | array(4) { 45 | ["lines"]=> 46 | string(27) "458 Walkman Dr. 47 | Suite #292 48 | " 49 | ["city"]=> 50 | string(9) "Royal Oak" 51 | ["state"]=> 52 | string(2) "MI" 53 | ["postal"]=> 54 | int(48046) 55 | } 56 | } 57 | ["product"]=> 58 | array(2) { 59 | [0]=> 60 | array(4) { 61 | ["sku"]=> 62 | string(6) "BL394D" 63 | ["quantity"]=> 64 | int(4) 65 | ["description"]=> 66 | string(10) "Basketball" 67 | ["price"]=> 68 | float(450) 69 | } 70 | [1]=> 71 | array(4) { 72 | ["sku"]=> 73 | string(7) "BL4438H" 74 | ["quantity"]=> 75 | int(1) 76 | ["description"]=> 77 | string(10) "Super Hoop" 78 | ["price"]=> 79 | float(2392) 80 | } 81 | } 82 | ["tax"]=> 83 | float(251.42) 84 | ["total"]=> 85 | float(4443.52) 86 | ["comments"]=> 87 | string(68) "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338." 88 | } 89 | -------------------------------------------------------------------------------- /tests/yaml_parse_url_001.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | yaml_parse_url - general 3 | --SKIPIF-- 4 | 5 | --INI-- 6 | yaml.decode_timestamp=1 7 | date.timezone=GMT 8 | --FILE-- 9 | 12 | --EXPECT-- 13 | array(8) { 14 | ["invoice"]=> 15 | int(34843) 16 | ["date"]=> 17 | int(980208000) 18 | ["bill-to"]=> 19 | &array(3) { 20 | ["given"]=> 21 | string(5) "Chris" 22 | ["family"]=> 23 | string(6) "Dumars" 24 | ["address"]=> 25 | array(4) { 26 | ["lines"]=> 27 | string(27) "458 Walkman Dr. 28 | Suite #292 29 | " 30 | ["city"]=> 31 | string(9) "Royal Oak" 32 | ["state"]=> 33 | string(2) "MI" 34 | ["postal"]=> 35 | int(48046) 36 | } 37 | } 38 | ["ship-to"]=> 39 | &array(3) { 40 | ["given"]=> 41 | string(5) "Chris" 42 | ["family"]=> 43 | string(6) "Dumars" 44 | ["address"]=> 45 | array(4) { 46 | ["lines"]=> 47 | string(27) "458 Walkman Dr. 48 | Suite #292 49 | " 50 | ["city"]=> 51 | string(9) "Royal Oak" 52 | ["state"]=> 53 | string(2) "MI" 54 | ["postal"]=> 55 | int(48046) 56 | } 57 | } 58 | ["product"]=> 59 | array(2) { 60 | [0]=> 61 | array(4) { 62 | ["sku"]=> 63 | string(6) "BL394D" 64 | ["quantity"]=> 65 | int(4) 66 | ["description"]=> 67 | string(10) "Basketball" 68 | ["price"]=> 69 | float(450) 70 | } 71 | [1]=> 72 | array(4) { 73 | ["sku"]=> 74 | string(7) "BL4438H" 75 | ["quantity"]=> 76 | int(1) 77 | ["description"]=> 78 | string(10) "Super Hoop" 79 | ["price"]=> 80 | float(2392) 81 | } 82 | } 83 | ["tax"]=> 84 | float(251.42) 85 | ["total"]=> 86 | float(4443.52) 87 | ["comments"]=> 88 | string(68) "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338." 89 | } 90 | -------------------------------------------------------------------------------- /tests/yaml_emit_003.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | yaml_emit - mappings 3 | --SKIPIF-- 4 | 5 | --INI-- 6 | serialize_precision=-1 7 | --FILE-- 8 | "Chris", 11 | "family"=> "Dumars", 12 | "address"=> array( 13 | "lines"=> "458 Walkman Dr. 14 | Suite #292", 15 | "city"=> "Royal Oak", 16 | "state"=> "MI", 17 | "postal"=> 48046, 18 | ), 19 | ); 20 | $invoice = array ( 21 | "invoice"=> 34843, 22 | "date"=> 980208000, 23 | "bill-to"=> $addr, 24 | "ship-to"=> $addr, 25 | "product"=> array( 26 | array( 27 | "sku"=> "BL394D", 28 | "quantity"=> 4, 29 | "description"=> "Basketball", 30 | "price"=> 450, 31 | ), 32 | array( 33 | "sku"=> "BL4438H", 34 | "quantity"=> 1, 35 | "description"=> "Super Hoop", 36 | "price"=> 2392, 37 | ), 38 | ), 39 | "tax"=> 251.42, 40 | "total"=> 4443.52, 41 | "comments"=> "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338.", 42 | ); 43 | var_dump(yaml_emit($invoice)); 44 | ?> 45 | --EXPECT-- 46 | string(620) "--- 47 | invoice: 34843 48 | date: 980208000 49 | bill-to: 50 | given: Chris 51 | family: Dumars 52 | address: 53 | lines: |- 54 | 458 Walkman Dr. 55 | Suite #292 56 | city: Royal Oak 57 | state: MI 58 | postal: 48046 59 | ship-to: 60 | given: Chris 61 | family: Dumars 62 | address: 63 | lines: |- 64 | 458 Walkman Dr. 65 | Suite #292 66 | city: Royal Oak 67 | state: MI 68 | postal: 48046 69 | product: 70 | - sku: BL394D 71 | quantity: 4 72 | description: Basketball 73 | price: 450 74 | - sku: BL4438H 75 | quantity: 1 76 | description: Super Hoop 77 | price: 2392 78 | tax: 251.42 79 | total: 4443.52 80 | comments: Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338. 81 | ... 82 | " 83 | -------------------------------------------------------------------------------- /tests/bug_59860.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Test PECL bug #59860 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 'tag_callback', 30 | YAML_SEQ_TAG => 'tag_callback', 31 | )); 32 | ?> 33 | --EXPECT-- 34 | array(3) { 35 | [0]=> 36 | array(1) { 37 | ["a"]=> 38 | string(1) "b" 39 | } 40 | [1]=> 41 | string(21) "tag:yaml.org,2002:map" 42 | [2]=> 43 | int(0) 44 | } 45 | array(3) { 46 | [0]=> 47 | array(1) { 48 | ["c"]=> 49 | string(1) "d" 50 | } 51 | [1]=> 52 | string(21) "tag:yaml.org,2002:map" 53 | [2]=> 54 | int(0) 55 | } 56 | array(3) { 57 | [0]=> 58 | array(2) { 59 | [0]=> 60 | string(1) "e" 61 | [1]=> 62 | string(1) "f" 63 | } 64 | [1]=> 65 | string(21) "tag:yaml.org,2002:seq" 66 | [2]=> 67 | int(0) 68 | } 69 | array(3) { 70 | [0]=> 71 | array(2) { 72 | [0]=> 73 | string(1) "g" 74 | [1]=> 75 | string(1) "h" 76 | } 77 | [1]=> 78 | string(21) "tag:yaml.org,2002:seq" 79 | [2]=> 80 | int(0) 81 | } 82 | array(3) { 83 | [0]=> 84 | array(4) { 85 | ["implicit_map"]=> 86 | string(21) "tag:yaml.org,2002:map" 87 | ["explicit_map"]=> 88 | string(21) "tag:yaml.org,2002:map" 89 | ["implicit_seq"]=> 90 | string(21) "tag:yaml.org,2002:seq" 91 | ["explicit_seq"]=> 92 | string(21) "tag:yaml.org,2002:seq" 93 | } 94 | [1]=> 95 | string(21) "tag:yaml.org,2002:map" 96 | [2]=> 97 | int(0) 98 | } 99 | -------------------------------------------------------------------------------- /dev-tools/maintainer-clean.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | BASENAME=${0} 4 | TOOLS_DIR=$(dirname ${BASENAME}) 5 | WORK_DIR="${TOOLS_DIR}/.." 6 | 7 | cd "${WORK_DIR}" 8 | 9 | ## what `make distclean` does 10 | find . -name \*.gcno -o -name \*.gcda | xargs rm -f 11 | find . -name \*.lo -o -name \*.o -o -name \*.dep | xargs rm -f 12 | find . -name \*.la -o -name \*.a | xargs rm -f 13 | find . -name \*.so | xargs rm -f 14 | find . -name .libs -a -type d|xargs rm -rf 15 | rm -f libphp.la modules/* libs/* 16 | rm -f ext/opcache/jit/ir/gen_ir_fold_hash 17 | rm -f ext/opcache/jit/ir/minilua 18 | rm -f ext/opcache/jit/ir/ir_fold_hash.h 19 | rm -f ext/opcache/jit/ir/ir_emit_x86.h 20 | rm -f ext/opcache/jit/ir/ir_emit_aarch64.h 21 | rm -f Makefile config.cache config.log config.status Makefile.objects Makefile.fragments libtool main/php_config.h main/internal_functions_cli.c main/internal_functions.c Zend/zend_dtrace_gen.h Zend/zend_dtrace_gen.h.bak Zend/zend_config.h 22 | rm -f main/build-defs.h scripts/phpize 23 | rm -f ext/date/lib/timelib_config.h ext/mbstring/libmbfl/config.h 24 | rm -f scripts/man1/phpize.1 scripts/php-config scripts/man1/php-config.1 sapi/cli/php.1 sapi/cgi/php-cgi.1 sapi/phpdbg/phpdbg.1 ext/phar/phar.1 ext/phar/phar.phar.1 25 | rm -f sapi/fpm/php-fpm.conf sapi/fpm/init.d.php-fpm sapi/fpm/php-fpm.service sapi/fpm/php-fpm.8 sapi/fpm/status.html 26 | rm -f ext/phar/phar.phar ext/phar/phar.php 27 | 28 | ## get rid of anything that phpize and configure made as well 29 | rm -rf .deps \ 30 | .libs \ 31 | Makefile \ 32 | Makefile.fragments \ 33 | Makefile.global \ 34 | Makefile.objects \ 35 | acinclude.m4 \ 36 | aclocal.m4 \ 37 | autom4te.cache \ 38 | build \ 39 | config.guess \ 40 | config.h \ 41 | config.h.in* \ 42 | config.log \ 43 | config.nice \ 44 | config.status \ 45 | config.sub \ 46 | configure \ 47 | configure.ac \ 48 | configure.in \ 49 | configure~ \ 50 | include \ 51 | install-sh \ 52 | libtool \ 53 | ltmain.sh \ 54 | missing \ 55 | mkinstalldirs \ 56 | modules \ 57 | run-tests.php \ 58 | 59 | ## coverage stuff 60 | rm -rf coverage.info reports 61 | 62 | ## failed tests 63 | rm -f tests/*.{diff,exp,log,out,php,sh} 64 | -------------------------------------------------------------------------------- /tests/yaml_parse_005.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | yaml_parse - syck bug #12656 3 | --CREDITS-- 4 | From syck bug #12656 5 | http://pecl.php.net/bugs/bug.php?id=12656 6 | --SKIPIF-- 7 | 8 | --FILE-- 9 | 28 | --EXPECT-- 29 | array(9) { 30 | ["models"]=> 31 | array(1) { 32 | [0]=> 33 | string(53) "/usr/home/enovodk/data/core/easyworks/current/models/" 34 | } 35 | ["behaviors"]=> 36 | array(1) { 37 | [0]=> 38 | string(63) "/usr/home/enovodk/data/core/easyworks/current/models/behaviors/" 39 | } 40 | ["controllers"]=> 41 | array(1) { 42 | [0]=> 43 | string(58) "/usr/home/enovodk/data/core/easyworks/current/controllers/" 44 | } 45 | ["components"]=> 46 | array(1) { 47 | [0]=> 48 | string(69) "/usr/home/enovodk/data/core/easyworks/current/controllers/components/" 49 | } 50 | ["apis"]=> 51 | array(1) { 52 | [0]=> 53 | string(62) "/usr/home/enovodk/data/core/easyworks/current/controllers/api/" 54 | } 55 | ["views"]=> 56 | array(1) { 57 | [0]=> 58 | string(52) "/usr/home/enovodk/data/core/easyworks/current/views/" 59 | } 60 | ["helpers"]=> 61 | array(1) { 62 | [0]=> 63 | string(60) "/usr/home/enovodk/data/core/easyworks/current/views/helpers/" 64 | } 65 | ["libs"]=> 66 | array(1) { 67 | [0]=> 68 | string(51) "/usr/home/enovodk/data/core/easyworks/current/libs/" 69 | } 70 | ["plugins"]=> 71 | array(1) { 72 | [0]=> 73 | string(54) "/usr/home/enovodk/data/core/easyworks/current/plugins/" 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /tests/yaml_emit_file_basic.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Test Github pull request #1 3 | --SKIPIF-- 4 | 5 | --INI-- 6 | serialize_precision=-1 7 | --FILE-- 8 | "Chris", 11 | "family"=> "Dumars", 12 | "address"=> array( 13 | "lines"=> "458 Walkman Dr. 14 | Suite #292", 15 | "city"=> "Royal Oak", 16 | "state"=> "MI", 17 | "postal"=> 48046, 18 | ), 19 | ); 20 | $invoice = array ( 21 | "invoice"=> 34843, 22 | "date"=> 980208000, 23 | "bill-to"=> $addr, 24 | "ship-to"=> $addr, 25 | "product"=> array( 26 | array( 27 | "sku"=> "BL394D", 28 | "quantity"=> 4, 29 | "description"=> "Basketball", 30 | "price"=> 450, 31 | ), 32 | array( 33 | "sku"=> "BL4438H", 34 | "quantity"=> 1, 35 | "description"=> "Super Hoop", 36 | "price"=> 2392, 37 | ), 38 | ), 39 | "tax"=> 251.42, 40 | "total"=> 4443.52, 41 | "comments"=> "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338.", 42 | ); 43 | 44 | $temp_filename = dirname(__FILE__) . 'yaml_emit_file_basic.tmp'; 45 | var_dump(yaml_emit_file($temp_filename, $invoice)); 46 | var_dump(file_get_contents($temp_filename)); 47 | ?> 48 | --CLEAN-- 49 | 53 | --EXPECT-- 54 | bool(true) 55 | string(620) "--- 56 | invoice: 34843 57 | date: 980208000 58 | bill-to: 59 | given: Chris 60 | family: Dumars 61 | address: 62 | lines: |- 63 | 458 Walkman Dr. 64 | Suite #292 65 | city: Royal Oak 66 | state: MI 67 | postal: 48046 68 | ship-to: 69 | given: Chris 70 | family: Dumars 71 | address: 72 | lines: |- 73 | 458 Walkman Dr. 74 | Suite #292 75 | city: Royal Oak 76 | state: MI 77 | postal: 48046 78 | product: 79 | - sku: BL394D 80 | quantity: 4 81 | description: Basketball 82 | price: 450 83 | - sku: BL4438H 84 | quantity: 1 85 | description: Super Hoop 86 | price: 2392 87 | tax: 251.42 88 | total: 4443.52 89 | comments: Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338. 90 | ... 91 | " 92 | -------------------------------------------------------------------------------- /tests/yaml_emit_002.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | yaml_emit - sequences 3 | --SKIPIF-- 4 | 5 | --INI-- 6 | serialize_precision=-1 7 | --FILE-- 8 | ,.?/ 17 | 18 | These are extended characters: Iñtërnâtiônàlizætiøn 19 | 20 | 21 | EOD; 22 | $doc = array( 23 | null, 24 | true, 25 | false, 26 | 10, 27 | -10, 28 | 123.456, 29 | -123.456, 30 | "yes", 31 | "no", 32 | "~", 33 | "-", 34 | "'", 35 | '"', 36 | "I\\xF1t\\xEBrn\\xE2ti\\xF4n\\xE0liz\\xE6ti\\xF8n", 37 | "# looks like a comment", 38 | "@looks_like_a_ref", 39 | "&looks_like_a_alias", 40 | "!!str", 41 | "%TAG ! tag:looks.like.one,999:", 42 | "!something", 43 | "Hello world!", 44 | "This is a string with\nan embedded newline.", 45 | $str, 46 | ); 47 | echo "=== Array of scalars ===\n"; 48 | var_dump(yaml_emit($doc)); 49 | 50 | echo "=== Nested ===\n"; 51 | var_dump(yaml_emit(array( 52 | "top level", 53 | array( 54 | "in array", 55 | ), 56 | array( 57 | "in array", 58 | array( 59 | "in array", 60 | ), 61 | ), 62 | ))); 63 | 64 | echo "=== Degenerate ===\n"; 65 | var_dump(yaml_emit(array())); 66 | 67 | ?> 68 | --EXPECT-- 69 | === Array of scalars === 70 | string(604) "--- 71 | - ~ 72 | - true 73 | - false 74 | - 10 75 | - -10 76 | - 123.456 77 | - -123.456 78 | - "yes" 79 | - "no" 80 | - "~" 81 | - '-' 82 | - '''' 83 | - '"' 84 | - I\xF1t\xEBrn\xE2ti\xF4n\xE0liz\xE6ti\xF8n 85 | - '# looks like a comment' 86 | - '@looks_like_a_ref' 87 | - '&looks_like_a_alias' 88 | - '!!str' 89 | - '%TAG ! tag:looks.like.one,999:' 90 | - '!something' 91 | - Hello world! 92 | - |- 93 | This is a string with 94 | an embedded newline. 95 | - "This string was made with a here doc.\n\nIt contains embedded newlines.\n \t\tIt 96 | also has some embedded tabs.\n\nHere are some symbols:\n`~!@#$%^&*()_-+={}[]|\\:\";'<>,.?/\n\nThese 97 | are extended characters: I\xF1t\xEBrn\xE2ti\xF4n\xE0liz\xE6ti\xF8n\n\n" 98 | ... 99 | " 100 | === Nested === 101 | string(61) "--- 102 | - top level 103 | - - in array 104 | - - in array 105 | - - in array 106 | ... 107 | " 108 | === Degenerate === 109 | string(11) "--- [] 110 | ... 111 | " 112 | -------------------------------------------------------------------------------- /tests/yaml_parse_008.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | yaml_parse - callbacks 3 | --SKIPIF-- 4 | 7 | --FILE-- 8 | $v) { 20 | $new_value .= "'{$k}' => '{$v}', "; 21 | } 22 | $value = trim($new_value, ', '); 23 | } 24 | return ""; 25 | } 26 | 27 | // yaml with some custom tags 28 | $yaml_str = << "value_c" 35 | key_d : !tag_d | 36 | some 37 | text 38 | key_e : !tag_e > 39 | some 40 | text 41 | key_f : !tag_f [ one, two ] 42 | key_g : !tag_g { sky: blue, sea: green } 43 | key_h : !tag_h 44 | - one 45 | - two 46 | key_i : !tag_i 47 | sky: blue 48 | sea: green 49 | ... 50 | YAML; 51 | 52 | 53 | $yaml = yaml_parse($yaml_str, 0, $ndocs, array( 54 | "test-tag_a" => "tag_callback", 55 | "test2-tag_b" => "tag_callback", 56 | "tag:example.com,2011:test/tag_c" => "tag_callback", 57 | "test-tag_d" => "tag_callback", 58 | "test-tag_e" => "tag_callback", 59 | "test-tag_f" => "tag_callback", 60 | "test-tag_g" => "tag_callback", 61 | "test-tag_h" => "tag_callback", 62 | "test-tag_i" => "tag_callback", 63 | )); 64 | 65 | var_dump($yaml); 66 | var_dump($ndocs); 67 | ?> 68 | --EXPECT-- 69 | array(9) { 70 | ["key_a"]=> 71 | string(46) "" 72 | ["key_b"]=> 73 | string(47) "" 74 | ["key_c"]=> 75 | string(67) "" 76 | ["key_d"]=> 77 | string(49) "" 80 | ["key_e"]=> 81 | string(49) "" 83 | ["key_f"]=> 84 | string(65) " 'one', '1' => 'two'], tag=[test-tag_f], flags=[0]>" 85 | ["key_g"]=> 86 | string(72) " 'blue', 'sea' => 'green'], tag=[test-tag_g], flags=[0]>" 87 | ["key_h"]=> 88 | string(65) " 'one', '1' => 'two'], tag=[test-tag_h], flags=[0]>" 89 | ["key_i"]=> 90 | string(72) " 'blue', 'sea' => 'green'], tag=[test-tag_i], flags=[0]>" 91 | } 92 | int(1) 93 | -------------------------------------------------------------------------------- /.appveyor/install.ps1: -------------------------------------------------------------------------------- 1 | if (-not (Test-Path c:\build-cache)) { 2 | mkdir c:\build-cache 3 | } 4 | 5 | if ($env:PHP_VER -lt "7.4") { 6 | $vc = $env:VC.toUpper() 7 | } else { 8 | $vc = $env:VC 9 | } 10 | 11 | $bname = 'php-sdk-' + $env:BIN_SDK_VER + '.zip' 12 | if (-not (Test-Path c:\build-cache\$bname)) { 13 | Invoke-WebRequest "https://github.com/php/php-sdk-binary-tools/archive/$bname" -OutFile "c:\build-cache\$bname" 14 | } 15 | $dname0 = 'php-sdk-binary-tools-php-sdk-' + $env:BIN_SDK_VER 16 | $dname1 = 'php-sdk-' + $env:BIN_SDK_VER 17 | if (-not (Test-Path c:\build-cache\$dname1)) { 18 | 7z x c:\build-cache\$bname -oc:\build-cache 19 | move c:\build-cache\$dname0 c:\build-cache\$dname1 20 | } 21 | $ts_part = '' 22 | if ('0' -eq $env:TS) { $ts_part = '-nts' } 23 | $bname = 'php-devel-pack-' + $env:PHP_VER + $ts_part + '-Win32-' + $vc + '-' + $env:ARCH + '.zip' 24 | if (-not (Test-Path c:\build-cache\$bname)) { 25 | Invoke-WebRequest "https://downloads.php.net/~windows/releases/archives/$bname" -OutFile "c:\build-cache\$bname" 26 | if (-not (Test-Path c:\build-cache\$bname)) { 27 | Invoke-WebRequest "hhttps://downloads.php.net/~windows/releases/$bname" -OutFile "c:\build-cache\$bname" 28 | } 29 | } 30 | $dname0 = 'php-' + $env:PHP_VER + '-devel-' + $vc + '-' + $env:ARCH 31 | $dname1 = 'php-' + $env:PHP_VER + $ts_part + '-devel-' + $vc + '-' + $env:ARCH 32 | if (-not (Test-Path c:\build-cache\$dname1)) { 33 | 7z x c:\build-cache\$bname -oc:\build-cache 34 | if ($dname0 -ne $dname1) { 35 | move c:\build-cache\$dname0 c:\build-cache\$dname1 36 | } 37 | } 38 | $env:PHP_DEVEL_PATH = 'c:\build-cache\' + $dname1 39 | $env:PATH = $env:PHP_DEVEL_PATH + ';' + $env:PATH 40 | 41 | $bname = 'php-' + $env:PHP_VER + $ts_part + '-Win32-' + $vc + '-' + $env:ARCH + '.zip' 42 | if (-not (Test-Path c:\build-cache\$bname)) { 43 | Invoke-WebRequest "https://downloads.php.net/~windows/releases/archives/$bname" -OutFile "c:\build-cache\$bname" 44 | if (-not (Test-Path c:\build-cache\$bname)) { 45 | Invoke-WebRequest "https://downloads.php.net/~windows/releases/$bname" -OutFile "c:\build-cache\$bname" 46 | } 47 | } 48 | $dname = 'php-' + $env:PHP_VER + $ts_part + '-Win32-' + $vc + '-' + $env:ARCH 49 | if (-not (Test-Path c:\build-cache\$dname)) { 50 | 7z x c:\build-cache\$bname -oc:\build-cache\$dname 51 | } 52 | $env:PHP_PATH = 'c:\build-cache\' + $dname 53 | $env:PATH = $env:PHP_PATH + ';' + $env:PATH 54 | 55 | $bname = $env:DEP + '-' + $env:VC.toLower() + '-' + $env:ARCH + '.zip' 56 | if (-not (Test-Path c:\build-cache\$bname)) { 57 | Invoke-WebRequest "http://downloads.php.net/~windows/pecl/deps/$bname" -OutFile "c:\build-cache\$bname" 58 | 7z x c:\build-cache\$bname -oc:\build-cache\deps 59 | } 60 | -------------------------------------------------------------------------------- /tests/yaml_emit_001.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | yaml_emit - scalars 3 | --SKIPIF-- 4 | 5 | --INI-- 6 | serialize_precision=-1 7 | --FILE-- 8 | ,.?/ 39 | 40 | These are extended characters: Iñtërnâtiônàlizætiøn 41 | 42 | 43 | EOD; 44 | var_dump(yaml_emit($str)); 45 | ?> 46 | --EXPECT-- 47 | string(10) "--- ~ 48 | ... 49 | " 50 | string(13) "--- true 51 | ... 52 | " 53 | string(14) "--- false 54 | ... 55 | " 56 | string(11) "--- 10 57 | ... 58 | " 59 | string(12) "--- -10 60 | ... 61 | " 62 | string(16) "--- 123.456 63 | ... 64 | " 65 | string(17) "--- -123.456 66 | ... 67 | " 68 | string(14) "--- "yes" 69 | ... 70 | " 71 | string(13) "--- "no" 72 | ... 73 | " 74 | string(12) "--- "~" 75 | ... 76 | " 77 | string(12) "--- '-' 78 | ... 79 | " 80 | string(13) "--- '''' 81 | ... 82 | " 83 | string(12) "--- '"' 84 | ... 85 | " 86 | string(50) "--- I\xF1t\xEBrn\xE2ti\xF4n\xE0liz\xE6ti\xF8n 87 | ... 88 | " 89 | string(33) "--- '# looks like a comment' 90 | ... 91 | " 92 | string(28) "--- '@looks_like_a_ref' 93 | ... 94 | " 95 | string(30) "--- '&looks_like_a_alias' 96 | ... 97 | " 98 | string(16) "--- '!!str' 99 | ... 100 | " 101 | string(41) "--- '%TAG ! tag:looks.like.one,999:' 102 | ... 103 | " 104 | string(21) "--- '!something' 105 | ... 106 | " 107 | string(21) "--- Hello world! 108 | ... 109 | " 110 | string(58) "--- |- 111 | This is a string with 112 | an embedded newline. 113 | ... 114 | " 115 | string(267) "--- "This string was made with a here doc.\n\nIt contains embedded newlines.\n \t\tIt 116 | also has some embedded tabs.\n\nHere are some symbols:\n`~!@#$%^&*()_-+={}[]|\\:\";'<>,.?/\n\nThese 117 | are extended characters: I\xF1t\xEBrn\xE2ti\xF4n\xE0liz\xE6ti\xF8n\n\n" 118 | ... 119 | " 120 | -------------------------------------------------------------------------------- /docs/phpdoc/examples.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | &reftitle.examples; 6 | 7 | Yaml Example 8 | 9 | "Chris", 13 | "family"=> "Dumars", 14 | "address"=> array( 15 | "lines"=> "458 Walkman Dr. 16 | Suite #292", 17 | "city"=> "Royal Oak", 18 | "state"=> "MI", 19 | "postal"=> 48046, 20 | ), 21 | ); 22 | $invoice = array ( 23 | "invoice"=> 34843, 24 | "date"=> "2001-01-23", 25 | "bill-to"=> $addr, 26 | "ship-to"=> $addr, 27 | "product"=> array( 28 | array( 29 | "sku"=> "BL394D", 30 | "quantity"=> 4, 31 | "description"=> "Basketball", 32 | "price"=> 450, 33 | ), 34 | array( 35 | "sku"=> "BL4438H", 36 | "quantity"=> 1, 37 | "description"=> "Super Hoop", 38 | "price"=> 2392, 39 | ), 40 | ), 41 | "tax"=> 251.42, 42 | "total"=> 4443.52, 43 | "comments"=> "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338.", 44 | ); 45 | 46 | // generate a YAML representation of the invoice 47 | $yaml = yaml_emit($invoice); 48 | var_dump($yaml); 49 | 50 | // convert the YAML back into a PHP variable 51 | $parsed = yaml_parse($yaml); 52 | 53 | // check that roundtrip conversion produced an equivalent structure 54 | var_dump($parsed == $invoice); 55 | ?> 56 | ]]> 57 | 58 | &example.outputs.similar; 59 | 60 | 100 | 101 | 102 | 103 | 104 | 124 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | The Yaml PHP Extension provides a wrapper to the LibYAML library. 2 | 3 | It gives the user the ability to parse YAML document streams into PHP 4 | constructs and emit PHP constructs as valid YAML 1.1 documents. 5 | 6 | For more information about LibYAML see http://pyyaml.org/wiki/LibYAML. 7 | For more information about YAML see http://yaml.org/ 8 | 9 | Requirements: 10 | * libyaml 0.1.x 11 | 12 | 13 | BUILDING ON UNIX etc. 14 | ===================== 15 | 16 | To compile your new extension, you will have to execute the following steps: 17 | 18 | 1. $ phpize 19 | 2. $ ./configure [--with-yaml] 20 | 3. $ make 21 | 4. $ sudo make install 22 | 23 | 24 | BUILDING ON WINDOWS 25 | =================== 26 | 27 | The extension provides the VisualStudio V6 project file 28 | 29 | yaml.dsp 30 | To compile the extension you open this file using VisualStudio, 31 | select the apropriate configuration for your installation 32 | (either "Release_TS" or "Debug_TS") and create "php_yaml.dll" 33 | 34 | After successfull compilation you have to copy the newly 35 | created "php_yaml.dll" to the PHP 36 | extension directory (default: C:\PHP\extensions). 37 | 38 | 39 | TESTING 40 | ======== 41 | 42 | You can now load the extension using a php.ini directive 43 | 44 | extension="php_yaml.[so|dll]" 45 | 46 | or load it at runtime using the dl() function 47 | 48 | dl("php_yaml.[so|dll]"); 49 | 50 | The extension should now be available, you can test this 51 | using the extension_loaded() function: 52 | 53 | if (extension_loaded(yaml)) 54 | echo "yaml loaded :)"; 55 | else 56 | echo "something is wrong :("; 57 | 58 | The extension will also add its own block to the output 59 | of phpinfo(); 60 | 61 | 62 | CONFIGURATION 63 | ============= 64 | ini settings: 65 | yaml.decode_timestamp=0 for no timestamp parsing 66 | yaml.decode_timestamp=1 for strtotime parsing 67 | yaml.decode_timestamp=2 for date_create parsing 68 | 69 | yaml.decode_binary=0 for no binary decoding 70 | yaml.decode_binary=1 for base64 binary decoding 71 | 72 | yaml.decode_php=0 for no serialized object parsing 73 | yaml.decode_php=1 for serialized object parsing 74 | 75 | /** 76 | * @param string $input String to parse as YAML document stream 77 | * @param int $pos Document to extract from stream (-1 for all, 0 for first, ...) 78 | * @param int $ndocs Number of documents found in stream 79 | * @param array $callbacks Content handlers for YAML nodes. Array of tag => handler 80 | * @return mixed Parsed data 81 | */ 82 | yaml_parse ($input, $pos=0, &$ndocs=null, $callbacks=null) 83 | 84 | /** 85 | * @param mixed $data Data to encode 86 | * @param int $encoding Output encoding 87 | * @param int $linebreak Output linebreak 88 | * @return string Encoded data 89 | */ 90 | yaml_emit ($data, $encoding=YAML_ANY_ENCODING, $linebreak=YAML_ANY_BREAK) 91 | 92 | 93 | CREDITS 94 | ======== 95 | 96 | php-yaml v0.1.0 through v0.3.0 was developed by Ryusuke Sekiyama. 97 | 98 | Starting with v0.4.0 the extension has been maintained by Bryan Davis. 99 | Development of versions v0.4.0 - v1.1.0 funded by Keynetics Inc 100 | [http://keynetics.com/]. 101 | 102 | Inspiration and some implementation details have been taken from: 103 | * php-syck [http://pecl.php.net/package/syck] 104 | * MacRuby's libyaml wrapper 105 | [http://www.macruby.org/trac/browser/MacRuby/trunk/ext/libyaml] 106 | * LibYAML's examples [http://pyyaml.org/wiki/LibYAML] 107 | -------------------------------------------------------------------------------- /php_yaml.h: -------------------------------------------------------------------------------- 1 | /** 2 | * YAML parser and emitter PHP extension 3 | * 4 | * Copyright (c) 2007 Ryusuke SEKIYAMA. All rights reserved. 5 | * Copyright (c) 2009 Keynetics Inc. All rights reserved. 6 | * Copyright (c) 2015 Bryan Davis and contributors. All rights reserved. 7 | * 8 | * Permission is hereby granted, free of charge, to any personobtaining a 9 | * copy of this software and associated documentation files (the "Software"), 10 | * to deal in the Software without restriction, including without limitation 11 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | * and/or sell copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included 16 | * in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | * DEALINGS IN THE SOFTWARE. 25 | * 26 | * @package php_yaml 27 | * @author Ryusuke SEKIYAMA 28 | * @author Bryan Davis 29 | * @copyright 2007 Ryusuke SEKIYAMA 30 | * @copyright 2009 Keynetics Inc 31 | * @copyright 2015 Bryan Davis and contributors 32 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 33 | */ 34 | 35 | #ifndef PHP_YAML_H 36 | #define PHP_YAML_H 37 | 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | #ifdef HAVE_CONFIG_H 43 | # include "config.h" 44 | #endif 45 | 46 | #include 47 | #include 48 | #include 49 | #ifdef ZTS 50 | # include "TSRM.h" 51 | #endif 52 | #include 53 | #include 54 | #include 55 | #include 56 | #if PHP_VERSION_ID < 70200 57 | #include 58 | #else 59 | #include 60 | #endif 61 | #include 62 | #include 63 | #include 64 | #include 65 | #include 66 | #include 67 | #ifdef __cplusplus 68 | } /* extern "C" */ 69 | #endif 70 | 71 | #include 72 | 73 | #ifdef __cplusplus 74 | extern "C" { 75 | #endif 76 | 77 | #define PHP_YAML_VERSION "2.3.0" 78 | 79 | extern zend_module_entry yaml_module_entry; 80 | #define phpext_yaml_ptr &yaml_module_entry 81 | 82 | /* {{{ module globals */ 83 | 84 | ZEND_BEGIN_MODULE_GLOBALS(yaml) 85 | zend_bool decode_binary; 86 | zend_long decode_timestamp; 87 | zend_bool decode_php; 88 | zval *timestamp_decoder; 89 | zend_bool output_canonical; 90 | zend_long output_indent; 91 | zend_long output_width; 92 | ZEND_END_MODULE_GLOBALS(yaml) 93 | 94 | ZEND_EXTERN_MODULE_GLOBALS(yaml) 95 | #ifdef ZTS 96 | # define YAML_G(v) TSRMG(yaml_globals_id, zend_yaml_globals *, v) 97 | #else 98 | # define YAML_G(v) (yaml_globals.v) 99 | #endif 100 | /* }}} */ 101 | 102 | #ifdef __cplusplus 103 | } /* extern "C" */ 104 | #endif 105 | 106 | #endif /* PHP_YAML_H */ 107 | 108 | /* 109 | * Local variables: 110 | * tab-width: 4 111 | * c-basic-offset: 4 112 | * End: 113 | * vim600: noet sw=4 ts=4 fdm=marker 114 | * vim<600: noet sw=4 ts=4 115 | */ 116 | -------------------------------------------------------------------------------- /docs/phpdoc/functions/yaml-parse-file.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | yaml_parse_file 7 | Parse a YAML stream from a file 8 | 9 | 10 | 11 | &reftitle.description; 12 | 13 | mixedyaml_parse_file 14 | stringfilename 15 | intpos0 16 | intndocs 17 | arraycallbacks 18 | 19 | 20 | Convert all or part of a YAML document stream read from a file to a PHP variable. 21 | 22 | 23 | 24 | 25 | &reftitle.parameters; 26 | 27 | 28 | 29 | filename 30 | 31 | 32 | Path to the file. 33 | 34 | 35 | 36 | 37 | pos 38 | 39 | 40 | Document to extract from stream (-1 for all 41 | documents, 0 for first document, ...). 42 | 43 | 44 | 45 | 46 | ndocs 47 | 48 | 49 | If ndocs is provided, then it is filled with the 50 | number of documents found in stream. 51 | 52 | 53 | 54 | 55 | callbacks 56 | 57 | 58 | Content handlers for YAML nodes. Associative array of YAML 59 | tag => callback mappings. 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | &reftitle.returnvalues; 69 | 70 | Returns the value encoded in input in appropriate 71 | PHP type. &null; is returned if the input cannot be 72 | decoded. If pos is -1 an 73 | array will be returned with one entry for each document found 74 | in the stream. 75 | 76 | 77 | 78 | 79 | &reftitle.seealso; 80 | 81 | 82 | yaml_parse 83 | yaml_parse_url 84 | yaml_emit 85 | 86 | 87 | 88 | 89 | 90 | 91 | 111 | -------------------------------------------------------------------------------- /docs/phpdoc/functions/yaml-emit-file.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | yaml_emit_file 7 | Send the YAML representation of a value to a file 8 | 9 | 10 | 11 | &reftitle.description; 12 | 13 | boolyaml_emit_file 14 | stringfilename 15 | mixeddata 16 | intencodingYAML_ANY_ENCODING 17 | intlinebreakYAML_ANY_BREAK 18 | 19 | 20 | Generate a YAML representation of the provided data 21 | in the filename. 22 | 23 | 24 | 25 | 26 | &reftitle.parameters; 27 | 28 | 29 | 30 | filename 31 | 32 | 33 | Path to the file. 34 | 35 | 36 | 37 | 38 | data 39 | 40 | 41 | The data being encoded. Can be any type except 42 | a resource. 43 | 44 | 45 | 46 | 47 | encoding 48 | 49 | 50 | Output character encoding chosen from 51 | YAML_ANY_ENCODING, 52 | YAML_UTF8_ENCODING, 53 | YAML_UTF16LE_ENCODING, 54 | YAML_UTF16BE_ENCODING. Defaults to 55 | YAML_ANY_ENCODING. 56 | 57 | 58 | 59 | 60 | linebreak 61 | 62 | 63 | Output linebreak style chosen from 64 | YAML_ANY_BREAK, 65 | YAML_CR_BREAK, 66 | YAML_LN_BREAK, 67 | YAML_CRLN_BREAK. Defaults to 68 | YAML_ANY_BREAK. 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | &reftitle.returnvalues; 78 | 79 | Returns TRUE on success. 80 | 81 | 82 | 83 | 84 | 85 | &reftitle.seealso; 86 | 87 | 88 | yaml_emit 89 | yaml_parse 90 | 91 | 92 | 93 | 94 | 95 | 96 | 116 | -------------------------------------------------------------------------------- /docs/phpdoc/functions/yaml-emit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | yaml_emit 7 | Returns the YAML representation of a value 8 | 9 | 10 | 11 | &reftitle.description; 12 | 13 | stringyaml_emit 14 | mixeddata 15 | intencodingYAML_ANY_ENCODING 16 | intlinebreakYAML_ANY_BREAK 17 | 18 | 19 | Generate a YAML representation of the provided data. 20 | 21 | 22 | 23 | 24 | &reftitle.parameters; 25 | 26 | 27 | 28 | data 29 | 30 | 31 | The data being encoded. Can be any type except 32 | a resource. 33 | 34 | 35 | 36 | 37 | encoding 38 | 39 | 40 | Output character encoding chosen from 41 | YAML_ANY_ENCODING, 42 | YAML_UTF8_ENCODING, 43 | YAML_UTF16LE_ENCODING, 44 | YAML_UTF16BE_ENCODING. Defaults to 45 | YAML_ANY_ENCODING. 46 | 47 | 48 | 49 | 50 | linebreak 51 | 52 | 53 | Output linebreak style chosen from 54 | YAML_ANY_BREAK, 55 | YAML_CR_BREAK, 56 | YAML_LN_BREAK, 57 | YAML_CRLN_BREAK. Defaults to 58 | YAML_ANY_BREAK. 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | &reftitle.returnvalues; 68 | 69 | Returns a YAML encoded string on success. 70 | 71 | 72 | 73 | 74 | &reftitle.examples; 75 | 76 | 77 | <function>yaml_emit</function> example 78 | 79 | 85 | ]]> 86 | 87 | &example.outputs.similar; 88 | 89 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | &reftitle.seealso; 99 | 100 | 101 | yaml_emit_file 102 | yaml_parse 103 | 104 | 105 | 106 | 107 | 108 | 109 | 129 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - php7 7 | pull_request: 8 | branches: 9 | - php7 10 | workflow_dispatch: 11 | 12 | jobs: 13 | ubuntu: 14 | name: Ubuntu 15 | runs-on: ubuntu-latest 16 | 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | php-version: 21 | - "8.0" 22 | - "8.1" 23 | - "8.2" 24 | - "8.3" 25 | - "8.4" 26 | - "8.5" 27 | 28 | steps: 29 | - name: Install dependencies 30 | run: | 31 | sudo apt-get update 32 | sudo apt-get install -y libyaml-dev 33 | - name: Checkout repo 34 | uses: actions/checkout@v3 35 | - name: Setup PHP 36 | uses: "shivammathur/setup-php@v2" 37 | with: 38 | php-version: "${{ matrix.php-version }}" 39 | coverage: "none" 40 | tools: "phpize, php-config" 41 | - name: Generate build files 42 | run: phpize 43 | - name: Configure build 44 | run: CFLAGS="-Werror -Wall -fno-strict-aliasing" ./configure --with-yaml 45 | - name: Report gcc problems 46 | uses: ammaraskar/gcc-problem-matcher@master 47 | - name: Build 48 | run: make all 49 | - name: Run tests 50 | run: >- 51 | REPORT_EXIT_STATUS=1 52 | NO_INTERACTION=1 53 | TEST_PHP_EXECUTABLE=$(which php) 54 | php -n 55 | -d open_basedir= 56 | -d output_buffering=0 57 | -d memory_limit=-1 58 | run-tests.php -n 59 | -d extension_dir=modules 60 | -d extension=yaml.so 61 | --show-diff 62 | tests 63 | - name: Upload artifacts 64 | uses: actions/upload-artifact@v4 65 | with: 66 | name: "yaml_${{ matrix.php-version }}_linux" 67 | path: .libs/yaml.so 68 | 69 | windows: 70 | name: Windows 71 | runs-on: windows-2022 72 | 73 | defaults: 74 | run: 75 | shell: cmd 76 | 77 | strategy: 78 | fail-fast: false 79 | matrix: 80 | php-version: 81 | - "8.0" 82 | - "8.1" 83 | - "8.2" 84 | - "8.3" 85 | - "8.4" 86 | arch: 87 | - "x64" 88 | ts: 89 | - nts 90 | - ts 91 | libyaml: 92 | - libyaml-0.1.7-vs16 93 | 94 | steps: 95 | - name: Configure git 96 | run: git config --system core.autocrlf false 97 | - name: Checkout repo 98 | uses: actions/checkout@v3 99 | - name: Setup PHP 100 | id: setup-php 101 | uses: php/setup-php-sdk@v0.10 102 | with: 103 | version: "${{ matrix.php-version }}" 104 | arch: "${{ matrix.arch }}" 105 | ts: "${{ matrix.ts }}" 106 | cache: true 107 | - name: Download deps 108 | run: | 109 | curl -LO https://windows.php.net/downloads/pecl/deps/${{ matrix.libyaml }}-${{ matrix.arch }}.zip 110 | 7z x ${{ matrix.libyaml }}-${{ matrix.arch }}.zip -o..\deps 111 | dir ..\deps 112 | - name: Enable developer cli 113 | uses: ilammy/msvc-dev-cmd@v1 114 | with: 115 | arch: "${{ matrix.arch }}" 116 | toolset: "${{ steps.setup-php.outputs.toolset }}" 117 | - name: Generate build files 118 | run: phpize 119 | - name: Configure build 120 | run: configure --with-yaml --with-php-build=..\deps --with-prefix=${{ steps.setup-php.outputs.prefix }} 121 | - name: Report msvc problems 122 | uses: ammaraskar/msvc-problem-matcher@master 123 | - name: Build 124 | run: nmake /D /P 125 | - name: Run tests 126 | run: nmake test TESTS="-n --show-diff tests" 127 | - name: Upload artifacts 128 | uses: actions/upload-artifact@v4 129 | with: 130 | name: "yaml_${{ matrix.php-version }}_win32_${{ matrix.ts }}_${{ matrix.arch }}" 131 | path: x64/ 132 | -------------------------------------------------------------------------------- /docs/phpdoc/functions/yaml-parse-url.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | yaml_parse_url 7 | Parse a Yaml stream from a URL 8 | 9 | 10 | 11 | &reftitle.description; 12 | 13 | mixedyaml_parse_url 14 | stringurl 15 | intpos0 16 | intndocs 17 | arraycallbacks 18 | 19 | 20 | Convert all or part of a YAML document stream read from a URL to a PHP variable. 21 | 22 | 23 | 24 | 25 | &reftitle.parameters; 26 | 27 | 28 | 29 | url 30 | 31 | 32 | url should be of the form "scheme://...". PHP 33 | will search for a protocol handler (also known as a wrapper) for that 34 | scheme. If no wrappers for that protocol are registered, PHP will emit 35 | a notice to help you track potential problems in your script and then 36 | continue as though filename specifies a regular file. 37 | 38 | 39 | 40 | 41 | pos 42 | 43 | 44 | Document to extract from stream (-1 for all 45 | documents, 0 for first document, ...). 46 | 47 | 48 | 49 | 50 | ndocs 51 | 52 | 53 | If ndocs is provided, then it is filled with the 54 | number of documents found in stream. 55 | 56 | 57 | 58 | 59 | callbacks 60 | 61 | 62 | Content handlers for YAML nodes. Associative array of YAML 63 | tag => callback mappings. 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | &reftitle.returnvalues; 73 | 74 | Returns the value encoded in input in appropriate 75 | PHP type. &null; is returned if the input cannot be 76 | decoded. If pos is -1 an 77 | array will be returned with one entry for each document found 78 | in the stream. 79 | 80 | 81 | 82 | 83 | &reftitle.seealso; 84 | 85 | 86 | yaml_parse 87 | yaml_parse_file 88 | yaml_emit 89 | 90 | 91 | 92 | 93 | 94 | 95 | 115 | -------------------------------------------------------------------------------- /tests/yaml_parse_001.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | yaml_parse - general 3 | --SKIPIF-- 4 | 5 | --INI-- 6 | yaml.decode_timestamp=1 7 | date.timezone=GMT 8 | --FILE-- 9 | 12 | invoice: 34843 13 | date : 2001-01-23 14 | bill-to: &id001 15 | given : Chris 16 | family : Dumars 17 | address: 18 | lines: | 19 | 458 Walkman Dr. 20 | Suite #292 21 | city : Royal Oak 22 | state : MI 23 | postal : 48046 24 | ship-to: *id001 25 | product: 26 | - sku : BL394D 27 | quantity : 4 28 | description : Basketball 29 | price : 450.00 30 | - sku : BL4438H 31 | quantity : 1 32 | description : Super Hoop 33 | price : 2392.00 34 | tax : 251.42 35 | total: 4443.52 36 | comments: 37 | Late afternoon is best. 38 | Backup contact is Nancy 39 | Billsmer @ 338-4338. 40 | ')); 41 | var_dump(yaml_parse(' 42 | --- 43 | Time: 2001-11-23 15:01:42 -5 44 | User: ed 45 | Warning: 46 | This is an error message 47 | for the log file 48 | --- 49 | Time: 2001-11-23 15:02:31 -5 50 | User: ed 51 | Warning: 52 | A slightly different error 53 | message. 54 | --- 55 | Date: 2001-11-23 15:03:17 -5 56 | User: ed 57 | Fatal: 58 | Unknown variable "bar" 59 | Stack: 60 | - file: TopClass.py 61 | line: 23 62 | code: | 63 | x = MoreObject("345\n") 64 | - file: MoreClass.py 65 | line: 58 66 | code: |- 67 | foo = bar 68 | ', -1)); 69 | ?> 70 | --EXPECT-- 71 | array(8) { 72 | ["invoice"]=> 73 | int(34843) 74 | ["date"]=> 75 | int(980208000) 76 | ["bill-to"]=> 77 | &array(3) { 78 | ["given"]=> 79 | string(5) "Chris" 80 | ["family"]=> 81 | string(6) "Dumars" 82 | ["address"]=> 83 | array(4) { 84 | ["lines"]=> 85 | string(27) "458 Walkman Dr. 86 | Suite #292 87 | " 88 | ["city"]=> 89 | string(9) "Royal Oak" 90 | ["state"]=> 91 | string(2) "MI" 92 | ["postal"]=> 93 | int(48046) 94 | } 95 | } 96 | ["ship-to"]=> 97 | &array(3) { 98 | ["given"]=> 99 | string(5) "Chris" 100 | ["family"]=> 101 | string(6) "Dumars" 102 | ["address"]=> 103 | array(4) { 104 | ["lines"]=> 105 | string(27) "458 Walkman Dr. 106 | Suite #292 107 | " 108 | ["city"]=> 109 | string(9) "Royal Oak" 110 | ["state"]=> 111 | string(2) "MI" 112 | ["postal"]=> 113 | int(48046) 114 | } 115 | } 116 | ["product"]=> 117 | array(2) { 118 | [0]=> 119 | array(4) { 120 | ["sku"]=> 121 | string(6) "BL394D" 122 | ["quantity"]=> 123 | int(4) 124 | ["description"]=> 125 | string(10) "Basketball" 126 | ["price"]=> 127 | float(450) 128 | } 129 | [1]=> 130 | array(4) { 131 | ["sku"]=> 132 | string(7) "BL4438H" 133 | ["quantity"]=> 134 | int(1) 135 | ["description"]=> 136 | string(10) "Super Hoop" 137 | ["price"]=> 138 | float(2392) 139 | } 140 | } 141 | ["tax"]=> 142 | float(251.42) 143 | ["total"]=> 144 | float(4443.52) 145 | ["comments"]=> 146 | string(68) "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338." 147 | } 148 | array(3) { 149 | [0]=> 150 | array(3) { 151 | ["Time"]=> 152 | int(1006545702) 153 | ["User"]=> 154 | string(2) "ed" 155 | ["Warning"]=> 156 | string(41) "This is an error message for the log file" 157 | } 158 | [1]=> 159 | array(3) { 160 | ["Time"]=> 161 | int(1006545751) 162 | ["User"]=> 163 | string(2) "ed" 164 | ["Warning"]=> 165 | string(35) "A slightly different error message." 166 | } 167 | [2]=> 168 | array(4) { 169 | ["Date"]=> 170 | int(1006545797) 171 | ["User"]=> 172 | string(2) "ed" 173 | ["Fatal"]=> 174 | string(22) "Unknown variable "bar"" 175 | ["Stack"]=> 176 | array(2) { 177 | [0]=> 178 | array(3) { 179 | ["file"]=> 180 | string(11) "TopClass.py" 181 | ["line"]=> 182 | int(23) 183 | ["code"]=> 184 | string(24) "x = MoreObject("345\n") 185 | " 186 | } 187 | [1]=> 188 | array(3) { 189 | ["file"]=> 190 | string(12) "MoreClass.py" 191 | ["line"]=> 192 | int(58) 193 | ["code"]=> 194 | string(9) "foo = bar" 195 | } 196 | } 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /tests/yaml_emit_006.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | yaml_emit - ini settings 3 | --SKIPIF-- 4 | 7 | --INI-- 8 | yaml.output_canonical=0 9 | yaml.output_indent=2 10 | yaml.output_width=80 11 | serialize_precision=-1 12 | --FILE-- 13 | "Chris", 16 | "family"=> "Dumars", 17 | "address"=> array( 18 | "lines"=> "458 Walkman Dr. 19 | Suite #292", 20 | "city"=> "Royal Oak", 21 | "state"=> "MI", 22 | "postal"=> 48046, 23 | ), 24 | ); 25 | $invoice = array ( 26 | "invoice"=> 34843, 27 | "date"=> 980208000, 28 | "bill-to"=> $addr, 29 | "ship-to"=> $addr, 30 | "product"=> array( 31 | array( 32 | "sku"=> "BL394D", 33 | "quantity"=> 4, 34 | "description"=> "Basketball", 35 | "price"=> 450, 36 | ), 37 | array( 38 | "sku"=> "BL4438H", 39 | "quantity"=> 1, 40 | "description"=> "Super Hoop", 41 | "price"=> 2392, 42 | ), 43 | ), 44 | "tax"=> 251.42, 45 | "total"=> 4443.52, 46 | "comments"=> "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338.", 47 | ); 48 | var_dump(yaml_emit($invoice)); 49 | 50 | ini_set("yaml.output_canonical", "1"); 51 | ini_set("yaml.output_indent", "4"); 52 | ini_set("yaml.output_width", "40"); 53 | echo "== CANONICAL ==\n"; 54 | var_dump(yaml_emit($invoice)); 55 | 56 | ?> 57 | --EXPECT-- 58 | string(620) "--- 59 | invoice: 34843 60 | date: 980208000 61 | bill-to: 62 | given: Chris 63 | family: Dumars 64 | address: 65 | lines: |- 66 | 458 Walkman Dr. 67 | Suite #292 68 | city: Royal Oak 69 | state: MI 70 | postal: 48046 71 | ship-to: 72 | given: Chris 73 | family: Dumars 74 | address: 75 | lines: |- 76 | 458 Walkman Dr. 77 | Suite #292 78 | city: Royal Oak 79 | state: MI 80 | postal: 48046 81 | product: 82 | - sku: BL394D 83 | quantity: 4 84 | description: Basketball 85 | price: 450 86 | - sku: BL4438H 87 | quantity: 1 88 | description: Super Hoop 89 | price: 2392 90 | tax: 251.42 91 | total: 4443.52 92 | comments: Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338. 93 | ... 94 | " 95 | == CANONICAL == 96 | string(1822) "--- 97 | !!map { 98 | ? !!str "invoice" 99 | : !!int "34843", 100 | ? !!str "date" 101 | : !!int "980208000", 102 | ? !!str "bill-to" 103 | : !!map { 104 | ? !!str "given" 105 | : !!str "Chris", 106 | ? !!str "family" 107 | : !!str "Dumars", 108 | ? !!str "address" 109 | : !!map { 110 | ? !!str "lines" 111 | : !!str "458 Walkman Dr.\n Suite 112 | #292", 113 | ? !!str "city" 114 | : !!str "Royal Oak", 115 | ? !!str "state" 116 | : !!str "MI", 117 | ? !!str "postal" 118 | : !!int "48046", 119 | }, 120 | }, 121 | ? !!str "ship-to" 122 | : !!map { 123 | ? !!str "given" 124 | : !!str "Chris", 125 | ? !!str "family" 126 | : !!str "Dumars", 127 | ? !!str "address" 128 | : !!map { 129 | ? !!str "lines" 130 | : !!str "458 Walkman Dr.\n Suite 131 | #292", 132 | ? !!str "city" 133 | : !!str "Royal Oak", 134 | ? !!str "state" 135 | : !!str "MI", 136 | ? !!str "postal" 137 | : !!int "48046", 138 | }, 139 | }, 140 | ? !!str "product" 141 | : !!seq [ 142 | !!map { 143 | ? !!str "sku" 144 | : !!str "BL394D", 145 | ? !!str "quantity" 146 | : !!int "4", 147 | ? !!str "description" 148 | : !!str "Basketball", 149 | ? !!str "price" 150 | : !!int "450", 151 | }, 152 | !!map { 153 | ? !!str "sku" 154 | : !!str "BL4438H", 155 | ? !!str "quantity" 156 | : !!int "1", 157 | ? !!str "description" 158 | : !!str "Super Hoop", 159 | ? !!str "price" 160 | : !!int "2392", 161 | }, 162 | ], 163 | ? !!str "tax" 164 | : !!float "251.42", 165 | ? !!str "total" 166 | : !!float "4443.52", 167 | ? !!str "comments" 168 | : !!str "Late afternoon is best. Backup 169 | contact is Nancy Billsmer @ 338-4338.", 170 | } 171 | ... 172 | " 173 | -------------------------------------------------------------------------------- /docs/phpdoc/ini.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | &reftitle.runtime; 6 | &extension.runtime; 7 | 8 | 9 | Yaml &ConfigureOptions; 10 | 11 | 12 | 13 | &Name; 14 | &Default; 15 | &Changeable; 16 | &Changelog; 17 | 18 | 19 | 20 | 21 | yaml.decode_binary 22 | 0 23 | PHP_INI_ALL 24 | 25 | 26 | 27 | yaml.decode_timestamp 28 | 0 29 | php_ini_all 30 | 31 | 32 | 33 | yaml.output_canonical 34 | 0 35 | php_ini_all 36 | 37 | 38 | 39 | yaml.output_indent 40 | 2 41 | php_ini_all 42 | 43 | 44 | 45 | yaml.output_width 46 | 80 47 | php_ini_all 48 | 49 | 50 | 51 | 52 |
53 |
54 | 55 | &ini.descriptions.title; 56 | 57 | 58 | 59 | 60 | 61 | yaml.decode_binary 62 | boolean 63 | 64 | 65 | 66 | Off by default, but can be set to on to cause base64 binary encoded entities which have the explicit tag "tag:yaml.org,2002:binary" to be decoded. 67 | 68 | 69 | 70 | 71 | 72 | yaml.decode_timestamp 73 | integer 74 | 75 | 76 | 77 | Controls the decoding of both implicit and explict "tag:yaml.org,2002:timestamp" scalars in the YAML document stream. The default setting of 0 will not apply any decoding. A setting of 1 will use strtotime to parse the timestamp value as a Unix timestamp. A setting of 2 will use date_create to parse the timestamp value as DateTime object. 78 | 79 | 80 | 81 | 82 | 83 | yaml.output_canonical 84 | boolean 85 | 86 | 87 | 88 | Off by default, but can be set to on to cause canonical form output. 89 | 90 | 91 | 92 | 93 | 94 | yaml.output_indent 95 | integer 96 | 97 | 98 | 99 | Number of spaces to indent sections. Value should be between 100 | 1 and 10. 101 | 102 | 103 | 104 | 105 | 106 | yaml.output_width 107 | integer 108 | 109 | 110 | 111 | Set the preferred line width. -1 means unlimited. 112 | 113 | 114 | 115 | 116 | 117 |
118 | -------------------------------------------------------------------------------- /php_yaml_int.h: -------------------------------------------------------------------------------- 1 | /** 2 | * YAML parser and emitter PHP extension 3 | * 4 | * Copyright (c) 2007 Ryusuke SEKIYAMA. All rights reserved. 5 | * Copyright (c) 2009 Keynetics Inc. All rights reserved. 6 | * Copyright (c) 2015 Bryan Davis and contributors. All rights reserved. 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a 9 | * copy of this software and associated documentation files (the "Software"), 10 | * to deal in the Software without restriction, including without limitation 11 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | * and/or sell copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included 16 | * in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | * DEALINGS IN THE SOFTWARE. 25 | * 26 | * @package php_yaml 27 | * @author Ryusuke SEKIYAMA 28 | * @author Bryan Davis 29 | * @copyright 2007 Ryusuke SEKIYAMA 30 | * @copyright 2009 Keynetics Inc 31 | * @copyright 2015 Bryan Davis and contributors 32 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 33 | */ 34 | 35 | 36 | #ifndef PHP_YAML_INT_H 37 | #define PHP_YAML_INT_H 38 | 39 | #ifdef __cplusplus 40 | extern "C" { 41 | #endif 42 | 43 | /* {{{ backcompat macros 44 | */ 45 | #ifndef ZVAL_OPT_DEREF 46 | /* Taken from php-src/Zend/zend_types.h @ 95ff285 */ 47 | #define Z_OPT_ISREF(zval) (Z_OPT_TYPE(zval) == IS_REFERENCE) 48 | #define Z_OPT_ISREF_P(zval_p) Z_OPT_ISREF(*(zval_p)) 49 | #define ZVAL_OPT_DEREF(z) do { \ 50 | if (UNEXPECTED(Z_OPT_ISREF_P(z))) { \ 51 | (z) = Z_REFVAL_P(z); \ 52 | } \ 53 | } while (0) 54 | #endif 55 | /* }}} */ 56 | 57 | /* {{{ ext/yaml types 58 | */ 59 | typedef void (*eval_scalar_func_t)(yaml_event_t event, HashTable *callbacks, zval *retval); 60 | 61 | typedef struct parser_state_s { 62 | yaml_parser_t parser; 63 | yaml_event_t event; 64 | int have_event; 65 | zval aliases; 66 | eval_scalar_func_t eval_func; 67 | HashTable *callbacks; 68 | } parser_state_t; 69 | 70 | typedef struct y_emit_state_s { 71 | yaml_emitter_t *emitter; 72 | HashTable *recursive; 73 | HashTable *callbacks; 74 | } y_emit_state_t; 75 | 76 | /* }}} */ 77 | 78 | 79 | /* {{{ ext/yaml macros 80 | */ 81 | #define YAML_BINARY_TAG "tag:yaml.org,2002:binary" 82 | #define YAML_MERGE_TAG "tag:yaml.org,2002:merge" 83 | #define YAML_PHP_TAG "!php/object" 84 | #define YAML_NONSPECIFIC_TAG "!" 85 | 86 | #define Y_SCALAR_IS_NOT_NUMERIC 0x00 87 | #define Y_SCALAR_IS_INT 0x10 88 | #define Y_SCALAR_IS_FLOAT 0x20 89 | #define Y_SCALAR_IS_ZERO 0x00 90 | #define Y_SCALAR_IS_BINARY 0x01 91 | #define Y_SCALAR_IS_OCTAL 0x02 92 | #define Y_SCALAR_IS_DECIMAL 0x03 93 | #define Y_SCALAR_IS_HEXADECIMAL 0x04 94 | #define Y_SCALAR_IS_SEXAGECIMAL 0x05 95 | #define Y_SCALAR_IS_INFINITY_P 0x06 96 | #define Y_SCALAR_IS_INFINITY_N 0x07 97 | #define Y_SCALAR_IS_NAN 0x08 98 | #define Y_SCALAR_FORMAT_MASK 0x0F 99 | 100 | #define STR_EQ(a, b)\ 101 | (a != NULL && b != NULL && 0 == strcmp(a, b)) 102 | 103 | #define SCALAR_TAG_IS(event, name) \ 104 | STR_EQ(name, (const char *)event.data.scalar.tag) 105 | 106 | #define IS_NOT_IMPLICIT(event) \ 107 | (!event.data.scalar.quoted_implicit && !event.data.scalar.plain_implicit) 108 | 109 | #define IS_NOT_IMPLICIT_AND_TAG_IS(event, name) \ 110 | (IS_NOT_IMPLICIT(event) && SCALAR_TAG_IS(event, name)) 111 | 112 | #define IS_NOT_QUOTED(event) \ 113 | (YAML_PLAIN_SCALAR_STYLE == event.data.scalar.style || YAML_ANY_SCALAR_STYLE == event.data.scalar.style) 114 | 115 | #define IS_NOT_QUOTED_OR_TAG_IS(event, name) \ 116 | (IS_NOT_QUOTED(event) && (event.data.scalar.plain_implicit || SCALAR_TAG_IS(event, name))) 117 | 118 | #define SCALAR_IS_QUOTED(event) \ 119 | (YAML_SINGLE_QUOTED_SCALAR_STYLE == event.data.scalar.style || YAML_DOUBLE_QUOTED_SCALAR_STYLE == event.data.scalar.style) 120 | 121 | /* }}} */ 122 | 123 | /* {{{ ext/yaml prototypes 124 | */ 125 | void php_yaml_read_all(parser_state_t *state, zend_long *ndocs, zval *retval); 126 | 127 | void php_yaml_read_partial( 128 | parser_state_t *state, zend_long pos, zend_long *ndocs, zval *retval); 129 | 130 | void eval_scalar(yaml_event_t event, 131 | HashTable * callbacks, zval *retval); 132 | 133 | void eval_scalar_with_callbacks( 134 | yaml_event_t event, HashTable *callbacks, zval *retval); 135 | 136 | const char *detect_scalar_type( 137 | const char *value, size_t length, const yaml_event_t *event); 138 | 139 | int scalar_is_null( 140 | const char *value, size_t length, const yaml_event_t *event); 141 | 142 | int scalar_is_bool( 143 | const char *value, size_t length, const yaml_event_t *event); 144 | 145 | int scalar_is_numeric( 146 | const char *value, size_t length, zend_long *lval, double *dval, char **str); 147 | 148 | int scalar_is_timestamp(const char *value, size_t length); 149 | 150 | int php_yaml_write_impl(yaml_emitter_t *emitter, zval *data, 151 | yaml_encoding_t encoding, HashTable *callbacks); 152 | 153 | int php_yaml_write_to_buffer( 154 | void *data, unsigned char *buffer, size_t size); 155 | 156 | /* }}} */ 157 | 158 | #ifdef __cplusplus 159 | } /* extern "C" */ 160 | #endif 161 | #endif /* PHP_YAML_INT_H */ 162 | 163 | /* 164 | * Local variables: 165 | * tab-width: 4 166 | * c-basic-offset: 4 167 | * End: 168 | * vim600: noet sw=4 ts=4 fdm=marker 169 | * vim<600: noet sw=4 ts=4 170 | */ 171 | -------------------------------------------------------------------------------- /docs/phpdoc/functions/yaml-parse.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | yaml_parse 7 | Parse a YAML stream 8 | 9 | 10 | 11 | &reftitle.description; 12 | 13 | mixedyaml_parse 14 | stringinput 15 | intpos0 16 | intndocs 17 | arraycallbacks 18 | 19 | 20 | Convert all or part of a YAML document stream to a PHP variable. 21 | 22 | 23 | 24 | 25 | &reftitle.parameters; 26 | 27 | 28 | 29 | input 30 | 31 | 32 | The string to parse as a YAML document stream. 33 | 34 | 35 | 36 | 37 | pos 38 | 39 | 40 | Document to extract from stream (-1 for all 41 | documents, 0 for first document, ...). 42 | 43 | 44 | 45 | 46 | ndocs 47 | 48 | 49 | If ndocs is provided, then it is filled with the 50 | number of documents found in stream. 51 | 52 | 53 | 54 | 55 | callbacks 56 | 57 | 58 | Content handlers for YAML nodes. Associative array of YAML 59 | tag => callback mappings. 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | &reftitle.returnvalues; 69 | 70 | Returns the value encoded in input in appropriate 71 | PHP type. &null; is returned if the input cannot be 72 | decoded. If pos is -1 an 73 | array will be returned with one entry for each document found 74 | in the stream. 75 | 76 | 77 | 78 | 79 | &reftitle.examples; 80 | 81 | 82 | <function>yaml_parse</function> example 83 | 84 | 119 | ]]> 120 | 121 | &example.outputs.similar; 122 | 123 | 126 | int(34843) 127 | ["date"]=> 128 | string(10) "2001-01-23" 129 | ["bill-to"]=> 130 | &array(3) { 131 | ["given"]=> 132 | string(5) "Chris" 133 | ["family"]=> 134 | string(6) "Dumars" 135 | ["address"]=> 136 | array(4) { 137 | ["lines"]=> 138 | string(34) "458 Walkman Dr. 139 | Suite #292" 140 | ["city"]=> 141 | string(9) "Royal Oak" 142 | ["state"]=> 143 | string(2) "MI" 144 | ["postal"]=> 145 | int(48046) 146 | } 147 | } 148 | ["ship-to"]=> 149 | &array(3) { 150 | ["given"]=> 151 | string(5) "Chris" 152 | ["family"]=> 153 | string(6) "Dumars" 154 | ["address"]=> 155 | array(4) { 156 | ["lines"]=> 157 | string(34) "458 Walkman Dr. 158 | Suite #292" 159 | ["city"]=> 160 | string(9) "Royal Oak" 161 | ["state"]=> 162 | string(2) "MI" 163 | ["postal"]=> 164 | int(48046) 165 | } 166 | } 167 | ["product"]=> 168 | array(2) { 169 | [0]=> 170 | array(4) { 171 | ["sku"]=> 172 | string(6) "BL394D" 173 | ["quantity"]=> 174 | int(4) 175 | ["description"]=> 176 | string(10) "Basketball" 177 | ["price"]=> 178 | int(450) 179 | } 180 | [1]=> 181 | array(4) { 182 | ["sku"]=> 183 | string(7) "BL4438H" 184 | ["quantity"]=> 185 | int(1) 186 | ["description"]=> 187 | string(10) "Super Hoop" 188 | ["price"]=> 189 | int(2392) 190 | } 191 | } 192 | ["tax"]=> 193 | float(251.42) 194 | ["total"]=> 195 | float(4443.52) 196 | ["comments"]=> 197 | string(68) "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338." 198 | } 199 | ]]> 200 | 201 | 202 | 203 | 204 | 205 | 206 | &reftitle.seealso; 207 | 208 | 209 | yaml_parse_file 210 | yaml_parse_url 211 | yaml_emit 212 | 213 | 214 | 215 | 216 | 217 | 218 | 238 | -------------------------------------------------------------------------------- /docs/phpdoc/constants.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | &reftitle.constants; 6 | &extension.constants; 7 | 8 | 9 | 10 | 11 | Scalar entity styles usable by <function>yaml_parse</function> 12 | callback methods. 13 | 14 | 15 | YAML_ANY_SCALAR_STYLE 16 | (integer) 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | YAML_PLAIN_SCALAR_STYLE 26 | (integer) 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | YAML_SINGLE_QUOTED_SCALAR_STYLE 36 | (integer) 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | YAML_DOUBLE_QUOTED_SCALAR_STYLE 46 | (integer) 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | YAML_LITERAL_SCALAR_STYLE 56 | (integer) 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | YAML_FOLDED_SCALAR_STYLE 66 | (integer) 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | Common tags usable by <function>yaml_parse</function> 77 | callback methods. 78 | 79 | 80 | YAML_NULL_TAG 81 | (string) 82 | 83 | 84 | 85 | "tag:yaml.org,2002:null" 86 | 87 | 88 | 89 | 90 | 91 | YAML_BOOL_TAG 92 | (string) 93 | 94 | 95 | 96 | "tag:yaml.org,2002:bool" 97 | 98 | 99 | 100 | 101 | 102 | YAML_STR_TAG 103 | (string) 104 | 105 | 106 | 107 | "tag:yaml.org,2002:str" 108 | 109 | 110 | 111 | 112 | 113 | YAML_INT_TAG 114 | (string) 115 | 116 | 117 | 118 | "tag:yaml.org,2002:int" 119 | 120 | 121 | 122 | 123 | 124 | YAML_FLOAT_TAG 125 | (string) 126 | 127 | 128 | 129 | "tag:yaml.org,2002:float" 130 | 131 | 132 | 133 | 134 | 135 | YAML_TIMESTAMP_TAG 136 | (string) 137 | 138 | 139 | 140 | "tag:yaml.org,2002:timestamp" 141 | 142 | 143 | 144 | 145 | 146 | YAML_SEQ_TAG 147 | (string) 148 | 149 | 150 | 151 | "tag:yaml.org,2002:seq" 152 | 153 | 154 | 155 | 156 | 157 | YAML_MAP_TAG 158 | (string) 159 | 160 | 161 | 162 | "tag:yaml.org,2002:map" 163 | 164 | 165 | 166 | 167 | 168 | YAML_PHP_TAG 169 | (string) 170 | 171 | 172 | 173 | "!php/object" 174 | 175 | 176 | 177 | 178 | 179 | 180 | Encoding types for <function>yaml_emit</function> 181 | 182 | 183 | YAML_ANY_ENCODING 184 | (integer) 185 | 186 | 187 | 188 | Let the emitter choose an encoding. 189 | 190 | 191 | 192 | 193 | 194 | YAML_UTF8_ENCODING 195 | (integer) 196 | 197 | 198 | 199 | Encode as UTF8. 200 | 201 | 202 | 203 | 204 | 205 | YAML_UTF16LE_ENCODING 206 | (integer) 207 | 208 | 209 | 210 | Encode as UTF16LE. 211 | 212 | 213 | 214 | 215 | 216 | YAML_UTF16BE_ENCODING 217 | (integer) 218 | 219 | 220 | 221 | Encode as UTF16BE. 222 | 223 | 224 | 225 | 226 | 227 | 228 | Linebreak types for <function>yaml_emit</function> 229 | 230 | 231 | YAML_ANY_BREAK 232 | (integer) 233 | 234 | 235 | 236 | Let emitter choose linebreak character. 237 | 238 | 239 | 240 | 241 | 242 | YAML_CR_BREAK 243 | (integer) 244 | 245 | 246 | 247 | Use \r as break character (Mac style). 248 | 249 | 250 | 251 | 252 | 253 | YAML_LN_BREAK 254 | (integer) 255 | 256 | 257 | 258 | Use \n as break character (Unix style). 259 | 260 | 261 | 262 | 263 | 264 | YAML_CRLN_BREAK 265 | (integer) 266 | 267 | 268 | 269 | Use \r\n as break character (DOS style). 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 297 | -------------------------------------------------------------------------------- /tests/bug_77720.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Test PECL bug #77720 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 22 | --EXPECTF-- 23 | 24 | Warning: yaml_parse(): Illegal offset type array (line 2, column 73) in %sbug_77720.php on line 15 25 | 26 | Warning: yaml_parse(): Illegal offset type array (line 2, column 73) in %sbug_77720.php on line 15 27 | 28 | Warning: yaml_parse(): Illegal offset type array (line 2, column 73) in %sbug_77720.php on line 15 29 | 30 | Warning: yaml_parse(): Illegal offset type array (line 2, column 73) in %sbug_77720.php on line 15 31 | 32 | Warning: yaml_parse(): Illegal offset type array (line 2, column 73) in %sbug_77720.php on line 15 33 | 34 | Warning: yaml_parse(): Illegal offset type array (line 2, column 73) in %sbug_77720.php on line 15 35 | 36 | Warning: yaml_parse(): Illegal offset type array (line 2, column 73) in %sbug_77720.php on line 15 37 | 38 | Warning: yaml_parse(): Illegal offset type array (line 2, column 73) in %sbug_77720.php on line 15 39 | 40 | Warning: yaml_parse(): Illegal offset type array (line 2, column 73) in %sbug_77720.php on line 15 41 | 42 | Warning: yaml_parse(): Illegal offset type array (line 2, column 79) in %sbug_77720.php on line 15 43 | 44 | Warning: yaml_parse(): Illegal offset type array (line 3, column 2) in %sbug_77720.php on line 15 45 | 46 | Warning: yaml_parse(): Illegal offset type array (line 3, column 73) in %sbug_77720.php on line 15 47 | 48 | Warning: yaml_parse(): Illegal offset type array (line 3, column 73) in %sbug_77720.php on line 15 49 | 50 | Warning: yaml_parse(): Illegal offset type array (line 3, column 73) in %sbug_77720.php on line 15 51 | 52 | Warning: yaml_parse(): Illegal offset type array (line 3, column 73) in %sbug_77720.php on line 15 53 | 54 | Warning: yaml_parse(): Illegal offset type array (line 3, column 73) in %sbug_77720.php on line 15 55 | 56 | Warning: yaml_parse(): Illegal offset type array (line 3, column 73) in %sbug_77720.php on line 15 57 | 58 | Warning: yaml_parse(): Illegal offset type array (line 3, column 73) in %sbug_77720.php on line 15 59 | 60 | Warning: yaml_parse(): Illegal offset type array (line 3, column 73) in %sbug_77720.php on line 15 61 | 62 | Warning: yaml_parse(): Illegal offset type array (line 3, column 73) in %sbug_77720.php on line 15 63 | 64 | Warning: yaml_parse(): Illegal offset type array (line 3, column 79) in %sbug_77720.php on line 15 65 | 66 | Warning: yaml_parse(): Illegal offset type array (line 4, column 2) in %sbug_77720.php on line 15 67 | 68 | Warning: yaml_parse(): Illegal offset type array (line 4, column 73) in %sbug_77720.php on line 15 69 | 70 | Warning: yaml_parse(): Illegal offset type array (line 4, column 73) in %sbug_77720.php on line 15 71 | 72 | Warning: yaml_parse(): Illegal offset type array (line 4, column 73) in %sbug_77720.php on line 15 73 | 74 | Warning: yaml_parse(): Illegal offset type array (line 4, column 73) in %sbug_77720.php on line 15 75 | 76 | Warning: yaml_parse(): Illegal offset type array (line 4, column 73) in %sbug_77720.php on line 15 77 | 78 | Warning: yaml_parse(): Illegal offset type array (line 4, column 73) in %sbug_77720.php on line 15 79 | 80 | Warning: yaml_parse(): Illegal offset type array (line 4, column 73) in %sbug_77720.php on line 15 81 | 82 | Warning: yaml_parse(): Illegal offset type array (line 4, column 73) in %sbug_77720.php on line 15 83 | 84 | Warning: yaml_parse(): Illegal offset type array (line 4, column 73) in %sbug_77720.php on line 15 85 | 86 | Warning: yaml_parse(): Illegal offset type array (line 4, column 79) in %sbug_77720.php on line 15 87 | 88 | Warning: yaml_parse(): Illegal offset type array (line 5, column 2) in %sbug_77720.php on line 15 89 | 90 | Warning: yaml_parse(): Illegal offset type array (line 5, column 73) in %sbug_77720.php on line 15 91 | 92 | Warning: yaml_parse(): Illegal offset type array (line 5, column 73) in %sbug_77720.php on line 15 93 | 94 | Warning: yaml_parse(): Illegal offset type array (line 5, column 73) in %sbug_77720.php on line 15 95 | 96 | Warning: yaml_parse(): Illegal offset type array (line 5, column 73) in %sbug_77720.php on line 15 97 | 98 | Warning: yaml_parse(): Illegal offset type array (line 5, column 73) in %sbug_77720.php on line 15 99 | 100 | Warning: yaml_parse(): Illegal offset type array (line 5, column 73) in %sbug_77720.php on line 15 101 | 102 | Warning: yaml_parse(): Illegal offset type array (line 5, column 73) in %sbug_77720.php on line 15 103 | 104 | Warning: yaml_parse(): Illegal offset type array (line 5, column 73) in %sbug_77720.php on line 15 105 | 106 | Warning: yaml_parse(): Illegal offset type array (line 5, column 73) in %sbug_77720.php on line 15 107 | 108 | Warning: yaml_parse(): Illegal offset type array (line 5, column 79) in %sbug_77720.php on line 15 109 | 110 | Warning: yaml_parse(): Illegal offset type array (line 6, column 2) in %sbug_77720.php on line 15 111 | 112 | Warning: yaml_parse(): Illegal offset type array (line 6, column 73) in %sbug_77720.php on line 15 113 | 114 | Warning: yaml_parse(): Illegal offset type array (line 6, column 73) in %sbug_77720.php on line 15 115 | 116 | Warning: yaml_parse(): Illegal offset type array (line 6, column 73) in %sbug_77720.php on line 15 117 | 118 | Warning: yaml_parse(): Illegal offset type array (line 6, column 73) in %sbug_77720.php on line 15 119 | 120 | Warning: yaml_parse(): Illegal offset type array (line 6, column 73) in %sbug_77720.php on line 15 121 | 122 | Warning: yaml_parse(): Illegal offset type array (line 6, column 73) in %sbug_77720.php on line 15 123 | 124 | Warning: yaml_parse(): Illegal offset type array (line 6, column 73) in %sbug_77720.php on line 15 125 | 126 | Warning: yaml_parse(): Illegal offset type array (line 6, column 73) in %sbug_77720.php on line 15 127 | 128 | Warning: yaml_parse(): Illegal offset type array (line 6, column 73) in %sbug_77720.php on line 15 129 | 130 | Warning: yaml_parse(): Illegal offset type array (line 6, column 79) in %sbug_77720.php on line 15 131 | 132 | Warning: yaml_parse(): Illegal offset type array (line 7, column 2) in %sbug_77720.php on line 15 133 | 134 | Warning: yaml_parse(): Illegal offset type array (line 7, column 73) in %sbug_77720.php on line 15 135 | 136 | Warning: yaml_parse(): Illegal offset type array (line 7, column 73) in %sbug_77720.php on line 15 137 | 138 | Warning: yaml_parse(): Illegal offset type array (line 7, column 73) in %sbug_77720.php on line 15 139 | 140 | Warning: yaml_parse(): Illegal offset type array (line 7, column 73) in %sbug_77720.php on line 15 141 | 142 | Warning: yaml_parse(): Illegal offset type array (line 7, column 73) in %sbug_77720.php on line 15 143 | 144 | Warning: yaml_parse(): Illegal offset type array (line 7, column 73) in %sbug_77720.php on line 15 145 | 146 | Warning: yaml_parse(): Illegal offset type array (line 7, column 73) in %sbug_77720.php on line 15 147 | 148 | Warning: yaml_parse(): Illegal offset type array (line 7, column 73) in %sbug_77720.php on line 15 149 | 150 | Warning: yaml_parse(): Illegal offset type array (line 7, column 73) in %sbug_77720.php on line 15 151 | 152 | Warning: yaml_parse(): Illegal offset type array (line 7, column 79) in %sbug_77720.php on line 15 153 | 154 | Warning: yaml_parse(): Illegal offset type array (line 8, column 2) in %sbug_77720.php on line 15 155 | 156 | Warning: yaml_parse(): Illegal offset type array (line 8, column 73) in %sbug_77720.php on line 15 157 | 158 | Warning: yaml_parse(): Illegal offset type array (line 8, column 73) in %sbug_77720.php on line 15 159 | 160 | Warning: yaml_parse(): Illegal offset type array (line 8, column 73) in %sbug_77720.php on line 15 161 | 162 | Warning: yaml_parse(): Illegal offset type array (line 8, column 73) in %sbug_77720.php on line 15 163 | 164 | Warning: yaml_parse(): Illegal offset type array (line 8, column 73) in %sbug_77720.php on line 15 165 | 166 | Warning: yaml_parse(): Illegal offset type array (line 8, column 73) in %sbug_77720.php on line 15 167 | 168 | Warning: yaml_parse(): Illegal offset type array (line 8, column 73) in %sbug_77720.php on line 15 169 | 170 | Warning: yaml_parse(): Illegal offset type array (line 8, column 73) in %sbug_77720.php on line 15 171 | 172 | Warning: yaml_parse(): Illegal offset type array (line 8, column 73) in %sbug_77720.php on line 15 173 | 174 | Warning: yaml_parse(): Illegal offset type array (line 8, column 79) in %sbug_77720.php on line 15 175 | 176 | Warning: yaml_parse(): Illegal offset type array (line 9, column 2) in %sbug_77720.php on line 15 177 | 178 | Warning: yaml_parse(): Illegal offset type array (line 9, column 73) in %sbug_77720.php on line 15 179 | 180 | Warning: yaml_parse(): Illegal offset type array (line 9, column 73) in %sbug_77720.php on line 15 181 | 182 | Warning: yaml_parse(): Illegal offset type array (line 9, column 73) in %sbug_77720.php on line 15 183 | 184 | Warning: yaml_parse(): Illegal offset type array (line 9, column 73) in %sbug_77720.php on line 15 185 | 186 | Warning: yaml_parse(): Illegal offset type array (line 9, column 73) in %sbug_77720.php on line 15 187 | 188 | Warning: yaml_parse(): Illegal offset type array (line 9, column 73) in %sbug_77720.php on line 15 189 | 190 | Warning: yaml_parse(): Illegal offset type array (line 9, column 73) in %sbug_77720.php on line 15 191 | 192 | Warning: yaml_parse(): Illegal offset type array (line 9, column 73) in %sbug_77720.php on line 15 193 | 194 | Warning: yaml_parse(): Illegal offset type array (line 9, column 73) in %sbug_77720.php on line 15 195 | 196 | Warning: yaml_parse(): Illegal offset type array (line 9, column 79) in %sbug_77720.php on line 15 197 | 198 | Warning: yaml_parse(): Illegal offset type array (line 10, column 2) in %sbug_77720.php on line 15 199 | 200 | Warning: yaml_parse(): Illegal offset type array (line 10, column 73) in %sbug_77720.php on line 15 201 | 202 | Warning: yaml_parse(): Illegal offset type array (line 10, column 73) in %sbug_77720.php on line 15 203 | 204 | Warning: yaml_parse(): Illegal offset type array (line 10, column 73) in %sbug_77720.php on line 15 205 | 206 | Warning: yaml_parse(): Illegal offset type array (line 10, column 73) in %sbug_77720.php on line 15 207 | 208 | Warning: yaml_parse(): Illegal offset type array (line 10, column 73) in %sbug_77720.php on line 15 209 | 210 | Warning: yaml_parse(): Illegal offset type array (line 10, column 73) in %sbug_77720.php on line 15 211 | 212 | Warning: yaml_parse(): Illegal offset type array (line 10, column 73) in %sbug_77720.php on line 15 213 | 214 | Warning: yaml_parse(): Illegal offset type array (line 10, column 73) in %sbug_77720.php on line 15 215 | 216 | Warning: yaml_parse(): Illegal offset type array (line 10, column 73) in %sbug_77720.php on line 15 217 | 218 | Warning: yaml_parse(): Illegal offset type array (line 10, column 79) in %sbug_77720.php on line 15 219 | 220 | Warning: yaml_parse(): Illegal offset type array (line 11, column 2) in %sbug_77720.php on line 15 221 | 222 | Warning: yaml_parse(): Illegal offset type array (line 11, column 73) in %sbug_77720.php on line 15 223 | 224 | Warning: yaml_parse(): Illegal offset type array (line 11, column 73) in %sbug_77720.php on line 15 225 | 226 | Warning: yaml_parse(): Illegal offset type array (line 11, column 73) in %sbug_77720.php on line 15 227 | 228 | Warning: yaml_parse(): Illegal offset type array (line 11, column 73) in %sbug_77720.php on line 15 229 | 230 | Warning: yaml_parse(): Illegal offset type array (line 11, column 73) in %sbug_77720.php on line 15 231 | 232 | Warning: yaml_parse(): Illegal offset type array (line 11, column 73) in %sbug_77720.php on line 15 233 | 234 | Warning: yaml_parse(): Illegal offset type array (line 11, column 73) in %sbug_77720.php on line 15 235 | 236 | Warning: yaml_parse(): Illegal offset type array (line 11, column 73) in %sbug_77720.php on line 15 237 | 238 | Warning: yaml_parse(): Illegal offset type array (line 11, column 73) in %sbug_77720.php on line 15 239 | 240 | Warning: yaml_parse(): Illegal offset type array (line 11, column 79) in %sbug_77720.php on line 15 241 | 242 | Warning: yaml_parse(): Illegal offset type array (line 12, column 1) in %sbug_77720.php on line 15 243 | array(11) { 244 | [0]=> 245 | array(9) { 246 | [0]=> 247 | string(3) "lol" 248 | [1]=> 249 | string(3) "lol" 250 | [2]=> 251 | string(3) "lol" 252 | [3]=> 253 | string(3) "lol" 254 | [4]=> 255 | string(3) "lol" 256 | [5]=> 257 | string(3) "lol" 258 | [6]=> 259 | string(3) "lol" 260 | [7]=> 261 | string(3) "lol" 262 | [8]=> 263 | string(3) "lol" 264 | } 265 | [1]=> 266 | array(0) { 267 | } 268 | [2]=> 269 | array(0) { 270 | } 271 | [3]=> 272 | array(0) { 273 | } 274 | [4]=> 275 | array(0) { 276 | } 277 | [5]=> 278 | array(0) { 279 | } 280 | [6]=> 281 | array(0) { 282 | } 283 | [7]=> 284 | array(0) { 285 | } 286 | [8]=> 287 | array(0) { 288 | } 289 | [9]=> 290 | array(0) { 291 | } 292 | [10]=> 293 | array(0) { 294 | } 295 | } 296 | -------------------------------------------------------------------------------- /detect.c: -------------------------------------------------------------------------------- 1 | /** 2 | * YAML parser and emitter PHP extension 3 | * 4 | * Copyright (c) 2007 Ryusuke SEKIYAMA. All rights reserved. 5 | * Copyright (c) 2009 Keynetics Inc. All rights reserved. 6 | * Copyright (c) 2015 Bryan Davis and contributors. All rights reserved. 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a 9 | * copy of this software and associated documentation files (the "Software"), 10 | * to deal in the Software without restriction, including without limitation 11 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | * and/or sell copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included 16 | * in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | * DEALINGS IN THE SOFTWARE. 25 | * 26 | * @package php_yaml 27 | * @author Ryusuke SEKIYAMA 28 | * @author Bryan Davis 29 | * @copyright 2007 Ryusuke SEKIYAMA 30 | * @copyright 2009 Keynetics Inc 31 | * @copyright 2015 Bryan Davis and contributors 32 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 33 | */ 34 | 35 | 36 | #include "php_yaml.h" 37 | #include "php_yaml_int.h" 38 | 39 | 40 | /* {{{ local macros 41 | */ 42 | #define ts_skip_space() \ 43 | while (ptr < end && (*ptr == ' ' || *ptr == '\t')) { \ 44 | ptr++; \ 45 | } 46 | 47 | #define ts_skip_number() \ 48 | while (ptr < end && *ptr >= '0' && *ptr <= '9') { \ 49 | ptr++; \ 50 | } 51 | 52 | /* }}} */ 53 | 54 | 55 | /* {{{ local prototypes 56 | */ 57 | static zend_long eval_sexagesimal_l(zend_long lval, const char *sg, const char *eos); 58 | 59 | static double eval_sexagesimal_d(double dval, const char *sg, const char *eos); 60 | 61 | /* }}} */ 62 | 63 | 64 | /* {{{ detect_scalar_type(const char *, size_t, yaml_event_t) 65 | * Guess what datatype the scalar encodes 66 | */ 67 | const char *detect_scalar_type(const char *value, size_t length, 68 | const yaml_event_t *event) 69 | { 70 | int flags = 0; 71 | zend_long lval = 0; 72 | double dval = 0.0; 73 | 74 | /* is value a null? */ 75 | if (0 == length || scalar_is_null(value, length, event)) { 76 | return YAML_NULL_TAG; 77 | } 78 | 79 | /* is value numeric? */ 80 | flags = scalar_is_numeric(value, length, &lval, &dval, NULL); 81 | if (flags != Y_SCALAR_IS_NOT_NUMERIC) { 82 | return (flags & Y_SCALAR_IS_FLOAT) ? YAML_FLOAT_TAG : YAML_INT_TAG; 83 | } 84 | 85 | /* is value boolean? */ 86 | flags = scalar_is_bool(value, length, event); 87 | if (-1 != flags) { 88 | return YAML_BOOL_TAG; 89 | } 90 | 91 | /* is value a timestamp? */ 92 | if (scalar_is_timestamp(value, length)) { 93 | return YAML_TIMESTAMP_TAG; 94 | } 95 | 96 | /* no guess */ 97 | return NULL; 98 | } 99 | /* }}} */ 100 | 101 | 102 | /* {{{ scalar_is_null(const char *,size_t,yaml_event_t) 103 | * Does this scalar encode a NULL value? 104 | * 105 | * specification is found at http://yaml.org/type/null.html. 106 | */ 107 | int 108 | scalar_is_null(const char *value, size_t length, const yaml_event_t *event) 109 | { 110 | if (NULL != event && event->data.scalar.quoted_implicit) { 111 | return 0; 112 | } 113 | 114 | if (NULL == event || event->data.scalar.plain_implicit) { 115 | if (length == 0 || 116 | (length == 1 && *value == '~') || 117 | STR_EQ("NULL", value) || 118 | STR_EQ("Null", value) || 119 | STR_EQ("null", value)) { 120 | return 1; 121 | } 122 | 123 | } else if (NULL != event && SCALAR_TAG_IS((*event), YAML_NULL_TAG)) { 124 | return 1; 125 | } 126 | 127 | return 0; 128 | } 129 | /* }}} */ 130 | 131 | 132 | /* {{{ scalar_is_bool(const char *,size_t,yaml_event_t) 133 | * Does this scalar encode a BOOL value? 134 | * 135 | * specification is found at http://yaml.org/type/bool.html. 136 | */ 137 | int 138 | scalar_is_bool(const char *value, size_t length, const yaml_event_t *event) 139 | { 140 | /* TODO: add ini setting to turn 'y'/'n' checks on/off */ 141 | if (NULL == event || IS_NOT_QUOTED_OR_TAG_IS((*event), YAML_BOOL_TAG)) { 142 | if ((length == 1 && (*value == 'Y' || *value == 'y')) || 143 | STR_EQ("YES", value) || 144 | STR_EQ("Yes", value) || 145 | STR_EQ("yes", value) || 146 | STR_EQ("TRUE", value) || 147 | STR_EQ("True", value) || 148 | STR_EQ("true", value) || 149 | STR_EQ("ON", value) || 150 | STR_EQ("On", value) || 151 | STR_EQ("on", value)) { 152 | return 1; 153 | } 154 | 155 | if ((length == 1 && (*value == 'N' || *value == 'n')) || 156 | STR_EQ("NO", value) || 157 | STR_EQ("No", value) || 158 | STR_EQ("no", value) || 159 | STR_EQ("FALSE", value) || 160 | STR_EQ("False", value) || 161 | STR_EQ("false", value) || 162 | STR_EQ("OFF", value) || 163 | STR_EQ("Off", value) || 164 | STR_EQ("off", value)) { 165 | return 0; 166 | } 167 | 168 | } else if (NULL != event && 169 | IS_NOT_IMPLICIT_AND_TAG_IS((*event), YAML_BOOL_TAG)) { 170 | if (0 == length || (1 == length && '0' == *value)) { 171 | return 0; 172 | } else { 173 | return 1; 174 | } 175 | } 176 | 177 | return -1; 178 | } 179 | /* }}} */ 180 | 181 | 182 | /* {{{ scalar_is_numeric() 183 | * Does this scalar encode a NUMERIC value? 184 | * 185 | * specification is found at http://yaml.org/type/float.html. 186 | * specification is found at http://yaml.org/type/int.html. 187 | */ 188 | int 189 | scalar_is_numeric(const char *value, size_t length, zend_long *lval, 190 | double *dval, char **str) 191 | { 192 | const char *end = value + length; 193 | char *buf = { 0 }, *ptr = { 0 }; 194 | int negative = 0; 195 | int type = 0; 196 | 197 | if (0 == length) { 198 | goto not_numeric; 199 | } 200 | 201 | /* trim */ 202 | while (value < end && (*(end - 1) == ' ' || *(end - 1) == '\t')) { 203 | end--; 204 | } 205 | 206 | while (value < end && (*value == ' ' || *value == '\t')) { 207 | value++; 208 | } 209 | 210 | if (value == end) { 211 | goto not_numeric; 212 | } 213 | 214 | /* not a number */ 215 | if (STR_EQ(".NAN", value) || 216 | STR_EQ(".NaN", value) || 217 | STR_EQ(".nan", value)) { 218 | type = Y_SCALAR_IS_FLOAT | Y_SCALAR_IS_NAN; 219 | goto finish; 220 | } 221 | 222 | /* catch the degenerate case of `.` as input */ 223 | if (STR_EQ(".", value)) { 224 | goto not_numeric; 225 | } 226 | 227 | /* sign */ 228 | if (*value == '+') { 229 | value++; 230 | 231 | } else if (*value == '-') { 232 | negative = 1; 233 | value++; 234 | } 235 | 236 | if (value == end) { 237 | goto not_numeric; 238 | } 239 | 240 | /* infinity */ 241 | if (STR_EQ(".INF", value) || 242 | STR_EQ(".Inf", value) || 243 | STR_EQ(".inf", value)) { 244 | type = Y_SCALAR_IS_FLOAT; 245 | type |= (negative ? Y_SCALAR_IS_INFINITY_N : Y_SCALAR_IS_INFINITY_P); 246 | goto finish; 247 | } 248 | 249 | /* alloc */ 250 | buf = (char *) emalloc(length + 3); 251 | ptr = buf; 252 | if (negative) { 253 | *ptr++ = '-'; 254 | } 255 | 256 | /* parse */ 257 | if (*value == '0') { 258 | *ptr++ = *value++; 259 | if (value == end) { 260 | goto return_zero; 261 | } 262 | 263 | if (*value == 'b') { 264 | /* binary integer */ 265 | *ptr++ = *value++; 266 | if (value == end) { 267 | goto not_numeric; 268 | } 269 | 270 | while (value < end && (*value == '_' || *value == '0')) { 271 | value++; 272 | } 273 | 274 | if (value == end) { 275 | goto return_zero; 276 | } 277 | 278 | /* check the sequence */ 279 | while (value < end) { 280 | if (*value == '_') { 281 | value++; 282 | 283 | } else if (*value == '0' || *value == '1') { 284 | *ptr++ = *value++; 285 | 286 | } else { 287 | goto not_numeric; 288 | } 289 | } 290 | 291 | type = Y_SCALAR_IS_INT | Y_SCALAR_IS_BINARY; 292 | 293 | } else if (*value == 'x') { 294 | /* hexadecimal integer */ 295 | *ptr++ = *value++; 296 | 297 | if (value == end) { 298 | goto not_numeric; 299 | } 300 | 301 | while (value < end && (*value == '_' || *value == '0')) { 302 | value++; 303 | } 304 | 305 | if (value == end) { 306 | goto return_zero; 307 | } 308 | 309 | /* check the sequence */ 310 | while (value < end) { 311 | if (*value == '_') { 312 | value++; 313 | 314 | } else if ((*value >= '0' && *value <= '9') || 315 | (*value >= 'A' && *value <= 'F') || 316 | (*value >= 'a' && *value <= 'f')) { 317 | *ptr++ = *value++; 318 | 319 | } else { 320 | goto not_numeric; 321 | } 322 | } 323 | 324 | type = Y_SCALAR_IS_INT | Y_SCALAR_IS_HEXADECIMAL; 325 | 326 | } else if (*value == '_' || (*value >= '0' && *value <= '7')) { 327 | /* octal integer */ 328 | while (value < end) { 329 | if (*value == '_') { 330 | value++; 331 | 332 | } else if (*value >= '0' && *value <= '7') { 333 | *ptr++ = *value++; 334 | 335 | } else { 336 | goto not_numeric; 337 | } 338 | } 339 | 340 | type = Y_SCALAR_IS_INT | Y_SCALAR_IS_OCTAL; 341 | 342 | } else if (*value == '.') { 343 | goto check_float; 344 | 345 | } else if (*value == ':') { 346 | goto check_sexa; 347 | 348 | } else { 349 | goto not_numeric; 350 | } 351 | 352 | } else if (*value >= '1' && *value <= '9') { 353 | /* integer */ 354 | *ptr++ = *value++; 355 | while (value < end) { 356 | if (*value == '_' || *value == ',') { 357 | value++; 358 | 359 | } else if (*value >= '0' && *value <= '9') { 360 | *ptr++ = *value++; 361 | 362 | } else if (*value == ':') { 363 | goto check_sexa; 364 | 365 | } else if (*value == '.') { 366 | goto check_float; 367 | 368 | } else { 369 | goto not_numeric; 370 | 371 | } 372 | } 373 | 374 | type = Y_SCALAR_IS_INT | Y_SCALAR_IS_DECIMAL; 375 | 376 | } else if (*value == ':') { 377 | /* sexagecimal */ 378 | 379 | check_sexa: 380 | while (value < end) { 381 | if (*value == '.') { 382 | type = Y_SCALAR_IS_FLOAT | Y_SCALAR_IS_SEXAGECIMAL; 383 | goto check_float; 384 | } 385 | 386 | if (*value != ':') { 387 | goto not_numeric; 388 | } 389 | 390 | *ptr++ = *value++; 391 | if (*(value + 1) == ':' || *(value + 1) == '.' || 392 | (value + 1) == end) { 393 | if (*value >= '0' && *value <= '9') { 394 | *ptr++ = *value++; 395 | 396 | } else { 397 | goto not_numeric; 398 | } 399 | 400 | } else { 401 | if ((*value >= '0' && *value <= '5') && 402 | (*(value + 1) >= '0' && *(value + 1) <= '9')) { 403 | *ptr++ = *value++; 404 | *ptr++ = *value++; 405 | 406 | } else { 407 | goto not_numeric; 408 | } 409 | } 410 | } 411 | 412 | if (*value == '.') { 413 | type = Y_SCALAR_IS_FLOAT | Y_SCALAR_IS_SEXAGECIMAL; 414 | goto check_float; 415 | 416 | } else if (value == end) { 417 | type = Y_SCALAR_IS_INT | Y_SCALAR_IS_SEXAGECIMAL; 418 | 419 | } else { 420 | goto not_numeric; 421 | } 422 | 423 | } else if (*value == '.') { 424 | /* float */ 425 | *ptr++ = '0'; 426 | 427 | check_float: 428 | *ptr++ = *value++; 429 | 430 | if (type == (Y_SCALAR_IS_FLOAT | Y_SCALAR_IS_SEXAGECIMAL)) { 431 | /* sexagecimal float */ 432 | while (value < end && (*(end - 1) == '_' || *(end - 1) == '0')) { 433 | end--; 434 | } 435 | 436 | if (value == end) { 437 | *ptr++ = '0'; 438 | } 439 | 440 | while (value < end) { 441 | if (*value == '_') { 442 | value++; 443 | 444 | } else if (*value >= '0' && *value <= '9') { 445 | *ptr++ = *value++; 446 | 447 | } else { 448 | goto not_numeric; 449 | } 450 | } 451 | 452 | } else { 453 | /* decimal float */ 454 | int is_exp = 0; 455 | while (value < end) { 456 | if (*value == '_') { 457 | value++; 458 | 459 | } else if (*value >= '0' && *value <= '9') { 460 | *ptr++ = *value++; 461 | 462 | } else if (*value == 'E' || *value == 'e') { 463 | /* exponential */ 464 | is_exp = 1; 465 | 466 | *ptr++ = *value++; 467 | if (value == end || (*value != '+' && *value != '-')) { 468 | goto not_numeric; 469 | } 470 | 471 | *ptr++ = *value++; 472 | if (value == end || *value < '0' || *value > '9' || 473 | (*value == '0' && value + 1 == end)) { 474 | goto not_numeric; 475 | } 476 | 477 | *ptr++ = *value++; 478 | while (value < end) { 479 | if (*value >= '0' && *value <= '9') { 480 | *ptr++ = *value++; 481 | 482 | } else { 483 | goto not_numeric; 484 | } 485 | } 486 | 487 | } else { 488 | goto not_numeric; 489 | } 490 | } 491 | 492 | /* trim */ 493 | if (!is_exp) { 494 | while (*(ptr - 1) == '0') { 495 | ptr--; 496 | } 497 | 498 | if (*(ptr - 1) == '.') { 499 | *ptr++ = '0'; 500 | } 501 | } 502 | 503 | type = Y_SCALAR_IS_FLOAT | Y_SCALAR_IS_DECIMAL; 504 | } 505 | 506 | } else { 507 | goto not_numeric; 508 | } 509 | 510 | /* terminate */ 511 | *ptr = '\0'; 512 | 513 | finish: 514 | /* convert & assign */ 515 | if ((type & Y_SCALAR_IS_INT) && lval != NULL) { 516 | switch (type & Y_SCALAR_FORMAT_MASK) { 517 | case Y_SCALAR_IS_BINARY: 518 | ptr = buf + 2; 519 | if (*ptr == 'b') { 520 | ptr++; 521 | } 522 | 523 | *lval = ZEND_STRTOL(ptr, (char **) NULL, 2); 524 | if (*buf == '-') { 525 | *lval *= -1L; 526 | } 527 | break; 528 | 529 | case Y_SCALAR_IS_OCTAL: 530 | *lval = ZEND_STRTOL(buf, (char **) NULL, 8); 531 | break; 532 | 533 | case Y_SCALAR_IS_HEXADECIMAL: 534 | *lval = ZEND_STRTOL(buf, (char **) NULL, 16); 535 | break; 536 | 537 | case Y_SCALAR_IS_SEXAGECIMAL: 538 | *lval = eval_sexagesimal_l(0, buf, ptr); 539 | if (*buf == '-') { 540 | *lval *= -1L; 541 | } 542 | break; 543 | 544 | default: 545 | #if PHP_VERSION_ID < 80100 546 | ZEND_ATOL(*lval, buf); 547 | #else 548 | *lval = ZEND_ATOL(buf); 549 | #endif 550 | break; 551 | } 552 | 553 | } else if ((type & Y_SCALAR_IS_FLOAT) && dval != NULL) { 554 | switch (type & Y_SCALAR_FORMAT_MASK) { 555 | case Y_SCALAR_IS_SEXAGECIMAL: 556 | *dval = eval_sexagesimal_d(0.0, buf, ptr); 557 | if (*buf == '-') { 558 | *dval *= -1.0; 559 | } 560 | break; 561 | 562 | case Y_SCALAR_IS_INFINITY_P: 563 | *dval = php_get_inf(); 564 | break; 565 | 566 | case Y_SCALAR_IS_INFINITY_N: 567 | *dval = -php_get_inf(); 568 | break; 569 | 570 | case Y_SCALAR_IS_NAN: 571 | *dval = php_get_nan(); 572 | break; 573 | 574 | default: 575 | *dval = zend_strtod(buf, (const char **) NULL); 576 | break; 577 | } 578 | } 579 | 580 | if (buf != NULL) { 581 | if (str != NULL) { 582 | *str = buf; 583 | 584 | } else { 585 | efree(buf); 586 | } 587 | } 588 | 589 | /* return */ 590 | return type; 591 | 592 | 593 | return_zero: 594 | if (lval != NULL) { 595 | *lval = 0; 596 | } 597 | 598 | if (dval != NULL) { 599 | *dval = 0.0; 600 | } 601 | 602 | if (buf != NULL) { 603 | efree(buf); 604 | } 605 | 606 | return (Y_SCALAR_IS_INT | Y_SCALAR_IS_ZERO); 607 | 608 | 609 | not_numeric: 610 | if (buf != NULL) { 611 | efree(buf); 612 | } 613 | 614 | return Y_SCALAR_IS_NOT_NUMERIC; 615 | } 616 | /* }}} */ 617 | 618 | 619 | /* {{{ scalar_is_timestamp(const char *,size_t) 620 | * Does this scalar encode a TIMESTAMP value? 621 | * 622 | * specification is found at http://yaml.org/type/timestamp.html. 623 | */ 624 | int scalar_is_timestamp(const char *value, size_t length) 625 | { 626 | const char *ptr = value; 627 | const char *end = value + length; 628 | const char *pos1, *pos2; 629 | 630 | if (ptr == NULL || ptr == end) { 631 | return 0; 632 | } 633 | 634 | /* skip leading space */ 635 | ts_skip_space(); 636 | 637 | /* check 4 digit year and separator */ 638 | pos1 = pos2 = ptr; 639 | ts_skip_number(); 640 | if (ptr == pos1 || ptr == end || ptr - pos1 != 4 || *ptr != '-') { 641 | return 0; 642 | } 643 | 644 | /* check 1 or 2 month and separator */ 645 | pos2 = ++ptr; 646 | ts_skip_number(); 647 | if (ptr == pos2 || ptr == end || ptr - pos2 > 2 || *ptr != '-') { 648 | return 0; 649 | } 650 | 651 | /* check 1 or 2 digit day */ 652 | pos2 = ++ptr; 653 | ts_skip_number(); 654 | if (ptr == pos2 || ptr - pos2 > 2) { 655 | return 0; 656 | } 657 | 658 | /* check separator */ 659 | pos2 = ptr; 660 | if (ptr == end) { 661 | /* date only format requires YYYY-MM-DD */ 662 | return (pos2 - pos1 == 10) ? 1 : 0; 663 | } 664 | 665 | /* time separator is T or whitespace */ 666 | if (*ptr == 'T' || *ptr == 't') { 667 | ptr++; 668 | 669 | } else if (*ptr == ' ' || *ptr == '\t') { 670 | ts_skip_space(); 671 | 672 | } else { 673 | return 0; 674 | } 675 | 676 | /* check 1 or 2 digit hour and separator */ 677 | pos1 = ptr; 678 | ts_skip_number(); 679 | if (ptr == pos1 || ptr == end || ptr - pos1 > 2 || *ptr != ':') { 680 | return 0; 681 | } 682 | 683 | /* check 2 digit minute and separator */ 684 | pos1 = ++ptr; 685 | ts_skip_number(); 686 | if (ptr == end || ptr - pos1 != 2 || *ptr != ':') { 687 | return 0; 688 | } 689 | 690 | /* check 2 digit second */ 691 | pos1 = ++ptr; 692 | ts_skip_number(); 693 | if (ptr == end) { 694 | return (ptr - pos1 == 2) ? 1 : 0; 695 | } 696 | 697 | /* check optional fraction */ 698 | if (*ptr == '.') { 699 | ptr++; 700 | ts_skip_number(); 701 | } 702 | 703 | /* skip optional separator space */ 704 | ts_skip_space(); 705 | if (ptr == end) { 706 | return 1; 707 | } 708 | 709 | /* check time zone */ 710 | if (*ptr == 'Z') { 711 | ptr++; 712 | ts_skip_space(); 713 | return (ptr == end) ? 1 : 0; 714 | } 715 | 716 | /* check time zone offset sign */ 717 | if (*ptr != '+' && *ptr != '-') { 718 | return 0; 719 | } 720 | 721 | /* check 1 or 2 digit time zone hour */ 722 | pos1 = ++ptr; 723 | ts_skip_number(); 724 | if (ptr == pos1 || ptr - pos1 == 3 || ptr - pos1 > 4) { 725 | return 0; 726 | } 727 | 728 | if (ptr == end) { 729 | return 1; 730 | } 731 | 732 | /* optional time zone minute */ 733 | if (*ptr != ':') { 734 | return 0; 735 | } 736 | 737 | pos1 = ++ptr; 738 | ts_skip_number(); 739 | 740 | if (ptr - pos1 != 2) { 741 | return 0; 742 | } 743 | 744 | /* skip following space */ 745 | ts_skip_space(); 746 | return (ptr == end) ? 1 : 0; 747 | } 748 | /* }}} */ 749 | 750 | 751 | /* {{{ eval_sexagesimal_l() 752 | * Convert a base 60 number to a long 753 | */ 754 | static zend_long eval_sexagesimal_l(zend_long lval, const char *sg, const char *eos) 755 | { 756 | const char *ep; 757 | 758 | while (sg < eos && (*sg < '0' || *sg > '9')) { 759 | sg++; 760 | } 761 | 762 | ep = sg; 763 | while (ep < eos && *ep >= '0' && *ep <= '9') { 764 | ep++; 765 | } 766 | 767 | if (sg == eos) { 768 | return lval; 769 | } 770 | 771 | return eval_sexagesimal_l( 772 | lval * 60 + ZEND_STRTOL(sg, (char **) NULL, 10), ep, eos); 773 | } 774 | /* }}} */ 775 | 776 | 777 | /* {{{ eval_sexagesimal_d() 778 | * Convert a base 60 number to a double 779 | */ 780 | static double eval_sexagesimal_d(double dval, const char *sg, const char *eos) 781 | { 782 | const char *ep; 783 | 784 | while (sg < eos && *sg != '.' && (*sg < '0' || *sg > '9')) { 785 | sg++; 786 | } 787 | 788 | ep = sg; 789 | while (ep < eos && *ep >= '0' && *ep <= '9') { 790 | ep++; 791 | } 792 | 793 | if (sg == eos || *sg == '.') { 794 | return dval; 795 | } 796 | 797 | return eval_sexagesimal_d( 798 | dval * 60.0 + zend_strtod(sg, (const char **) NULL), ep, eos); 799 | } 800 | /* }}} */ 801 | 802 | 803 | 804 | /* 805 | * Local variables: 806 | * tab-width: 4 807 | * c-basic-offset: 4 808 | * End: 809 | * vim600: noet sw=4 ts=4 fdm=marker 810 | * vim<600: noet sw=4 ts=4 811 | */ 812 | -------------------------------------------------------------------------------- /yaml.c: -------------------------------------------------------------------------------- 1 | /** 2 | * YAML parser and emitter PHP extension 3 | * 4 | * Copyright (c) 2007 Ryusuke SEKIYAMA. All rights reserved. 5 | * Copyright (c) 2009 Keynetics Inc. All rights reserved. 6 | * Copyright (c) 2015 Bryan Davis and contributors. All rights reserved. 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a 9 | * copy of this software and associated documentation files (the "Software"), 10 | * to deal in the Software without restriction, including without limitation 11 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | * and/or sell copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included 16 | * in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | * DEALINGS IN THE SOFTWARE. 25 | * 26 | * @package php_yaml 27 | * @author Ryusuke SEKIYAMA 28 | * @author Bryan Davis 29 | * @copyright 2007 Ryusuke SEKIYAMA 30 | * @copyright 2009 Keynetics Inc 31 | * @copyright 2015 Bryan Davis and contributors 32 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 33 | */ 34 | 35 | #include "php_yaml.h" 36 | #include "php_yaml_int.h" 37 | 38 | /* {{{ local prototypes 39 | */ 40 | static int php_yaml_check_callbacks(HashTable *callbacks); 41 | 42 | static PHP_MINIT_FUNCTION(yaml); 43 | static PHP_MSHUTDOWN_FUNCTION(yaml); 44 | static PHP_MINFO_FUNCTION(yaml); 45 | 46 | static PHP_GINIT_FUNCTION(yaml); 47 | 48 | static PHP_FUNCTION(yaml_parse); 49 | static PHP_FUNCTION(yaml_parse_file); 50 | static PHP_FUNCTION(yaml_parse_url); 51 | static PHP_FUNCTION(yaml_emit); 52 | static PHP_FUNCTION(yaml_emit_file); 53 | 54 | /* }}} */ 55 | 56 | /* {{{ globals */ 57 | 58 | ZEND_DECLARE_MODULE_GLOBALS(yaml); 59 | 60 | /* }}} */ 61 | 62 | /* {{{ ini entries */ 63 | 64 | PHP_INI_BEGIN() 65 | STD_PHP_INI_ENTRY("yaml.decode_binary", "0", PHP_INI_ALL, OnUpdateBool, 66 | decode_binary, zend_yaml_globals, yaml_globals) 67 | STD_PHP_INI_ENTRY("yaml.decode_timestamp", "0", PHP_INI_ALL, OnUpdateLong, 68 | decode_timestamp, zend_yaml_globals, yaml_globals) 69 | STD_PHP_INI_ENTRY("yaml.decode_php", "0", PHP_INI_ALL, OnUpdateBool, 70 | decode_php, zend_yaml_globals, yaml_globals) 71 | STD_PHP_INI_ENTRY("yaml.output_canonical", "0", PHP_INI_ALL, OnUpdateBool, 72 | output_canonical, zend_yaml_globals, yaml_globals) 73 | STD_PHP_INI_ENTRY("yaml.output_indent", "2", PHP_INI_ALL, OnUpdateLong, 74 | output_indent, zend_yaml_globals, yaml_globals) 75 | STD_PHP_INI_ENTRY("yaml.output_width", "80", PHP_INI_ALL, OnUpdateLong, 76 | output_width, zend_yaml_globals, yaml_globals) 77 | PHP_INI_END() 78 | 79 | /* }}} */ 80 | 81 | 82 | /* {{{ argument informations */ 83 | #ifdef ZEND_BEGIN_ARG_INFO 84 | ZEND_BEGIN_ARG_INFO_EX(arginfo_yaml_parse, ZEND_SEND_BY_VAL, 85 | ZEND_RETURN_VALUE, 1) 86 | ZEND_ARG_INFO(0, input) 87 | ZEND_ARG_INFO(0, pos) 88 | ZEND_ARG_INFO(1, ndocs) 89 | ZEND_ARG_ARRAY_INFO(0, callbacks, 0) 90 | ZEND_END_ARG_INFO() 91 | 92 | ZEND_BEGIN_ARG_INFO_EX(arginfo_yaml_parse_file, ZEND_SEND_BY_VAL, 93 | ZEND_RETURN_VALUE, 1) 94 | ZEND_ARG_INFO(0, filename) 95 | ZEND_ARG_INFO(0, pos) 96 | ZEND_ARG_INFO(1, ndocs) 97 | ZEND_ARG_ARRAY_INFO(0, callbacks, 0) 98 | ZEND_END_ARG_INFO() 99 | 100 | ZEND_BEGIN_ARG_INFO_EX(arginfo_yaml_parse_url, ZEND_SEND_BY_VAL, 101 | ZEND_RETURN_VALUE, 1) 102 | ZEND_ARG_INFO(0, url) 103 | ZEND_ARG_INFO(0, pos) 104 | ZEND_ARG_INFO(1, ndocs) 105 | ZEND_ARG_ARRAY_INFO(0, callbacks, 0) 106 | ZEND_END_ARG_INFO() 107 | 108 | ZEND_BEGIN_ARG_INFO_EX(arginfo_yaml_emit, ZEND_SEND_BY_VAL, 109 | ZEND_RETURN_VALUE, 1) 110 | ZEND_ARG_INFO(0, data) 111 | ZEND_ARG_INFO(0, encoding) 112 | ZEND_ARG_INFO(0, linebreak) 113 | ZEND_ARG_ARRAY_INFO(0, callbacks, 0) 114 | ZEND_END_ARG_INFO() 115 | 116 | ZEND_BEGIN_ARG_INFO_EX(arginfo_yaml_emit_file, ZEND_SEND_BY_VAL, 117 | ZEND_RETURN_VALUE, 2) 118 | ZEND_ARG_INFO(0, filename) 119 | ZEND_ARG_INFO(0, data) 120 | ZEND_ARG_INFO(0, encoding) 121 | ZEND_ARG_INFO(0, linebreak) 122 | ZEND_ARG_ARRAY_INFO(0, callbacks, 0) 123 | ZEND_END_ARG_INFO() 124 | #else 125 | #define arginfo_yaml_parse third_arg_force_ref 126 | #define arginfo_yaml_parse_file third_arg_force_ref 127 | #define arginfo_yaml_parse_url third_arg_force_ref 128 | #endif 129 | 130 | static zend_function_entry yaml_functions[] = { 131 | PHP_FE(yaml_parse, arginfo_yaml_parse) 132 | PHP_FE(yaml_parse_file, arginfo_yaml_parse_file) 133 | PHP_FE(yaml_parse_url, arginfo_yaml_parse_url) 134 | PHP_FE(yaml_emit, arginfo_yaml_emit) 135 | PHP_FE(yaml_emit_file, arginfo_yaml_emit_file) 136 | PHP_FE_END 137 | }; 138 | /* }}} */ 139 | 140 | 141 | /* {{{ cross-extension dependencies */ 142 | static zend_module_dep yaml_deps[] = { 143 | ZEND_MOD_OPTIONAL("date") {NULL, NULL, NULL, 0} 144 | }; 145 | /* }}} */ 146 | 147 | 148 | zend_module_entry yaml_module_entry = { /* {{{ */ 149 | STANDARD_MODULE_HEADER_EX, 150 | NULL, 151 | yaml_deps, 152 | "yaml", 153 | yaml_functions, 154 | PHP_MINIT(yaml), 155 | PHP_MSHUTDOWN(yaml), 156 | NULL, /* RINIT */ 157 | NULL, /* RSHUTDOWN */ 158 | PHP_MINFO(yaml), 159 | PHP_YAML_VERSION, 160 | PHP_MODULE_GLOBALS(yaml), 161 | PHP_GINIT(yaml), 162 | NULL, 163 | NULL, 164 | STANDARD_MODULE_PROPERTIES_EX 165 | }; 166 | /* }}} */ 167 | 168 | 169 | #ifdef COMPILE_DL_YAML 170 | ZEND_GET_MODULE(yaml) 171 | #endif 172 | 173 | 174 | /* {{{ PHP_MINIT_FUNCTION */ 175 | static PHP_MINIT_FUNCTION(yaml) 176 | { 177 | REGISTER_INI_ENTRIES(); 178 | 179 | /* node style constants */ 180 | REGISTER_LONG_CONSTANT("YAML_ANY_SCALAR_STYLE", 181 | YAML_ANY_SCALAR_STYLE, CONST_PERSISTENT | CONST_CS); 182 | REGISTER_LONG_CONSTANT("YAML_PLAIN_SCALAR_STYLE", 183 | YAML_PLAIN_SCALAR_STYLE, CONST_PERSISTENT | CONST_CS); 184 | REGISTER_LONG_CONSTANT("YAML_SINGLE_QUOTED_SCALAR_STYLE", 185 | YAML_SINGLE_QUOTED_SCALAR_STYLE, CONST_PERSISTENT | CONST_CS); 186 | REGISTER_LONG_CONSTANT("YAML_DOUBLE_QUOTED_SCALAR_STYLE", 187 | YAML_DOUBLE_QUOTED_SCALAR_STYLE, CONST_PERSISTENT | CONST_CS); 188 | REGISTER_LONG_CONSTANT("YAML_LITERAL_SCALAR_STYLE", 189 | YAML_LITERAL_SCALAR_STYLE, CONST_PERSISTENT | CONST_CS); 190 | REGISTER_LONG_CONSTANT("YAML_FOLDED_SCALAR_STYLE", 191 | YAML_FOLDED_SCALAR_STYLE, CONST_PERSISTENT | CONST_CS); 192 | 193 | /* tag constants */ 194 | REGISTER_STRING_CONSTANT("YAML_NULL_TAG", YAML_NULL_TAG, 195 | CONST_PERSISTENT | CONST_CS); 196 | REGISTER_STRING_CONSTANT("YAML_BOOL_TAG", YAML_BOOL_TAG, 197 | CONST_PERSISTENT | CONST_CS); 198 | REGISTER_STRING_CONSTANT("YAML_STR_TAG", YAML_STR_TAG, 199 | CONST_PERSISTENT | CONST_CS); 200 | REGISTER_STRING_CONSTANT("YAML_INT_TAG", YAML_INT_TAG, 201 | CONST_PERSISTENT | CONST_CS); 202 | REGISTER_STRING_CONSTANT("YAML_FLOAT_TAG", YAML_FLOAT_TAG, 203 | CONST_PERSISTENT | CONST_CS); 204 | REGISTER_STRING_CONSTANT("YAML_TIMESTAMP_TAG", YAML_TIMESTAMP_TAG, 205 | CONST_PERSISTENT | CONST_CS); 206 | REGISTER_STRING_CONSTANT("YAML_SEQ_TAG", YAML_SEQ_TAG, 207 | CONST_PERSISTENT | CONST_CS); 208 | REGISTER_STRING_CONSTANT("YAML_MAP_TAG", YAML_MAP_TAG, 209 | CONST_PERSISTENT | CONST_CS); 210 | REGISTER_STRING_CONSTANT("YAML_PHP_TAG", YAML_PHP_TAG, 211 | CONST_PERSISTENT | CONST_CS); 212 | REGISTER_STRING_CONSTANT("YAML_MERGE_TAG", YAML_MERGE_TAG, 213 | CONST_PERSISTENT | CONST_CS); 214 | REGISTER_STRING_CONSTANT("YAML_BINARY_TAG", YAML_BINARY_TAG, 215 | CONST_PERSISTENT | CONST_CS); 216 | 217 | /* encoding constants */ 218 | REGISTER_LONG_CONSTANT("YAML_ANY_ENCODING", YAML_ANY_ENCODING, 219 | CONST_PERSISTENT | CONST_CS); 220 | REGISTER_LONG_CONSTANT("YAML_UTF8_ENCODING", YAML_UTF8_ENCODING, 221 | CONST_PERSISTENT | CONST_CS); 222 | REGISTER_LONG_CONSTANT("YAML_UTF16LE_ENCODING", YAML_UTF16LE_ENCODING, 223 | CONST_PERSISTENT | CONST_CS); 224 | REGISTER_LONG_CONSTANT("YAML_UTF16BE_ENCODING", YAML_UTF16BE_ENCODING, 225 | CONST_PERSISTENT | CONST_CS); 226 | 227 | /* linebreak constants */ 228 | REGISTER_LONG_CONSTANT("YAML_ANY_BREAK", YAML_ANY_BREAK, 229 | CONST_PERSISTENT | CONST_CS); 230 | REGISTER_LONG_CONSTANT("YAML_CR_BREAK", YAML_CR_BREAK, 231 | CONST_PERSISTENT | CONST_CS); 232 | REGISTER_LONG_CONSTANT("YAML_LN_BREAK", YAML_LN_BREAK, 233 | CONST_PERSISTENT | CONST_CS); 234 | REGISTER_LONG_CONSTANT("YAML_CRLN_BREAK", YAML_CRLN_BREAK, 235 | CONST_PERSISTENT | CONST_CS); 236 | 237 | return SUCCESS; 238 | } 239 | /* }}} */ 240 | 241 | 242 | /* {{{ PHP_MSHUTDOWN_FUNCTION */ 243 | static PHP_MSHUTDOWN_FUNCTION(yaml) 244 | { 245 | UNREGISTER_INI_ENTRIES(); 246 | return SUCCESS; 247 | } 248 | /* }}} */ 249 | 250 | 251 | /* {{{ PHP_MINFO_FUNCTION */ 252 | PHP_MINFO_FUNCTION(yaml) 253 | { 254 | php_info_print_table_start(); 255 | php_info_print_table_row(2, "LibYAML Support", "enabled"); 256 | php_info_print_table_row(2, "Module Version", PHP_YAML_VERSION); 257 | php_info_print_table_row(2, "LibYAML Version", yaml_get_version_string()); 258 | php_info_print_table_end(); 259 | 260 | DISPLAY_INI_ENTRIES(); 261 | } 262 | /* }}} */ 263 | 264 | 265 | /* {{{ PHP_GINIT_FUNCTION() */ 266 | static PHP_GINIT_FUNCTION(yaml) 267 | { 268 | yaml_globals->decode_binary = 0; 269 | yaml_globals->decode_timestamp = 0; 270 | yaml_globals->decode_php = 0; 271 | yaml_globals->timestamp_decoder = NULL; 272 | yaml_globals->output_canonical = 0; 273 | yaml_globals->output_indent = 2; 274 | yaml_globals->output_width = 80; 275 | } 276 | /* }}} */ 277 | 278 | 279 | /* {{{ php_yaml_check_callbacks() 280 | * Validate user supplied callback array contents 281 | */ 282 | static int php_yaml_check_callbacks(HashTable *callbacks) 283 | { 284 | zval *entry; 285 | zend_string *key; 286 | 287 | ZEND_HASH_FOREACH_STR_KEY_VAL(callbacks, key, entry) { 288 | if (key) { 289 | zend_string *name; 290 | 291 | if (!zend_is_callable(entry, 0, &name)) { 292 | if (name != NULL) { 293 | php_error_docref(NULL, E_WARNING, 294 | "Callback for tag '%s', '%s' is not valid", 295 | key->val, name->val); 296 | zend_string_release(name); 297 | 298 | } else { 299 | php_error_docref(NULL, E_WARNING, 300 | "Callback for tag '%s' is not valid", key->val); 301 | } 302 | return FAILURE; 303 | } else { 304 | zend_string_release(name); 305 | } 306 | 307 | if (zend_string_equals_literal(key, YAML_TIMESTAMP_TAG)) { 308 | YAML_G(timestamp_decoder) = entry; 309 | } 310 | 311 | } else { 312 | php_error_docref(NULL, E_NOTICE, 313 | "Callback key should be a string"); 314 | } 315 | } ZEND_HASH_FOREACH_END(); 316 | 317 | return SUCCESS; 318 | } 319 | /* }}} */ 320 | 321 | 322 | /* {{{ proto mixed yaml_parse(string input[, int pos[, int &ndocs[, array callbacks]]]) 323 | Takes a YAML encoded string and converts it to a PHP variable. */ 324 | PHP_FUNCTION(yaml_parse) 325 | { 326 | zend_string *input; 327 | zend_long pos = 0; 328 | zval *zndocs = { 0 }; 329 | zval *zcallbacks = { 0 }; 330 | 331 | parser_state_t state; 332 | zval yaml; 333 | zend_long ndocs = 0; 334 | 335 | memset(&state, 0, sizeof(state)); 336 | state.have_event = 0; 337 | state.callbacks = NULL; 338 | 339 | YAML_G(timestamp_decoder) = NULL; 340 | 341 | if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), 342 | "S|lz/a/", &input, &pos, &zndocs, 343 | &zcallbacks)) { 344 | return; 345 | } 346 | 347 | if (zcallbacks != NULL) { 348 | state.callbacks = Z_ARRVAL_P(zcallbacks); 349 | if (FAILURE == php_yaml_check_callbacks(state.callbacks)) { 350 | RETURN_FALSE; 351 | } 352 | 353 | state.eval_func = eval_scalar_with_callbacks; 354 | 355 | } else { 356 | state.eval_func = eval_scalar; 357 | } 358 | 359 | yaml_parser_initialize(&state.parser); 360 | yaml_parser_set_input_string(&state.parser, (unsigned char *)input->val, input->len); 361 | 362 | 363 | if (pos < 0) { 364 | php_yaml_read_all(&state, &ndocs, &yaml); 365 | } else { 366 | php_yaml_read_partial(&state, pos, &ndocs, &yaml); 367 | } 368 | 369 | yaml_parser_delete(&state.parser); 370 | 371 | if (zndocs != NULL) { 372 | /* copy document count to var user sent in */ 373 | zval_ptr_dtor(zndocs); 374 | ZVAL_LONG(zndocs, ndocs); 375 | } 376 | 377 | if (Z_TYPE_P(&yaml) == IS_UNDEF) { 378 | RETURN_FALSE; 379 | } 380 | 381 | RETURN_ZVAL(&yaml, 1, 1); 382 | } 383 | /* }}} yaml_parse */ 384 | 385 | 386 | /* {{{ proto mixed yaml_parse_file(string filename[, int pos[, int &ndocs[, array callbacks]]]) 387 | */ 388 | PHP_FUNCTION(yaml_parse_file) 389 | { 390 | char *filename = { 0 }; 391 | size_t filename_len = 0; 392 | zend_long pos = 0; 393 | zval *zndocs = { 0 }; 394 | zval *zcallbacks = { 0 }; 395 | 396 | php_stream *stream = { 0 }; 397 | FILE *fp = { 0 }; 398 | 399 | parser_state_t state; 400 | zval yaml; 401 | zend_long ndocs = 0; 402 | 403 | memset(&state, 0, sizeof(state)); 404 | state.have_event = 0; 405 | state.callbacks = NULL; 406 | 407 | YAML_G(timestamp_decoder) = NULL; 408 | 409 | if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), 410 | "s|lz/a/", &filename, &filename_len, &pos, &zndocs, 411 | &zcallbacks)) { 412 | return; 413 | } 414 | 415 | if (zcallbacks != NULL) { 416 | state.callbacks = Z_ARRVAL_P(zcallbacks); 417 | if (FAILURE == php_yaml_check_callbacks(state.callbacks)) { 418 | RETURN_FALSE; 419 | } 420 | 421 | state.eval_func = eval_scalar_with_callbacks; 422 | 423 | } else { 424 | state.eval_func = eval_scalar; 425 | } 426 | 427 | if (NULL == (stream = php_stream_open_wrapper(filename, "rb", 428 | IGNORE_URL | REPORT_ERRORS | STREAM_WILL_CAST, 429 | NULL))) { 430 | RETURN_FALSE; 431 | } 432 | 433 | if (FAILURE == php_stream_cast( 434 | stream, PHP_STREAM_AS_STDIO, (void **) &fp, 1)) { 435 | php_stream_close(stream); 436 | RETURN_FALSE; 437 | } 438 | 439 | yaml_parser_initialize(&state.parser); 440 | yaml_parser_set_input_file(&state.parser, fp); 441 | 442 | if (pos < 0) { 443 | php_yaml_read_all(&state, &ndocs, &yaml); 444 | 445 | } else { 446 | php_yaml_read_partial(&state, pos, &ndocs, &yaml); 447 | } 448 | 449 | yaml_parser_delete(&state.parser); 450 | php_stream_close(stream); 451 | 452 | if (zndocs != NULL) { 453 | /* copy document count to var user sent in */ 454 | zval_ptr_dtor(zndocs); 455 | ZVAL_LONG(zndocs, ndocs); 456 | } 457 | 458 | if (Z_TYPE_P(&yaml) == IS_UNDEF) { 459 | RETURN_FALSE; 460 | } 461 | 462 | RETURN_ZVAL(&yaml, 1, 1); 463 | } 464 | /* }}} yaml_parse_file */ 465 | 466 | 467 | /* {{{ proto mixed yaml_parse_url(string url[, int pos[, int &ndocs[, array callbacks]]]) 468 | */ 469 | PHP_FUNCTION(yaml_parse_url) 470 | { 471 | char *url = { 0 }; 472 | size_t url_len = 0; 473 | zend_long pos = 0; 474 | zval *zndocs = { 0 }; 475 | zval *zcallbacks = { 0 }; 476 | 477 | php_stream *stream = { 0 }; 478 | zend_string *input; 479 | 480 | parser_state_t state; 481 | zval yaml; 482 | zend_long ndocs = 0; 483 | 484 | memset(&state, 0, sizeof(state)); 485 | state.have_event = 0; 486 | state.callbacks = NULL; 487 | 488 | YAML_G(timestamp_decoder) = NULL; 489 | 490 | if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), 491 | "s|lza/", &url, &url_len, &pos, &zndocs, &zcallbacks)) { 492 | return; 493 | } 494 | 495 | if (zcallbacks != NULL) { 496 | state.callbacks = Z_ARRVAL_P(zcallbacks); 497 | if (FAILURE == php_yaml_check_callbacks(state.callbacks)) { 498 | RETURN_FALSE; 499 | } 500 | 501 | state.eval_func = eval_scalar_with_callbacks; 502 | 503 | } else { 504 | state.eval_func = eval_scalar; 505 | } 506 | 507 | if (NULL == (stream = php_stream_open_wrapper(url, "rb", REPORT_ERRORS, NULL))) { 508 | RETURN_FALSE; 509 | } 510 | 511 | input = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, 0); 512 | php_stream_close(stream); 513 | if (input == NULL) { 514 | RETURN_FALSE; 515 | } 516 | 517 | yaml_parser_initialize(&state.parser); 518 | yaml_parser_set_input_string(&state.parser, (unsigned char *)ZSTR_VAL(input), ZSTR_LEN(input)); 519 | 520 | if (pos < 0) { 521 | php_yaml_read_all(&state, &ndocs, &yaml); 522 | } else { 523 | php_yaml_read_partial(&state, pos, &ndocs, &yaml); 524 | } 525 | 526 | yaml_parser_delete(&state.parser); 527 | zend_string_release(input); 528 | 529 | if (zndocs != NULL) { 530 | /* copy document count to var user sent in */ 531 | zval_dtor(zndocs); 532 | ZVAL_LONG(zndocs, ndocs); 533 | } 534 | 535 | if (Z_TYPE_P(&yaml) == IS_UNDEF) { 536 | RETURN_FALSE; 537 | } 538 | 539 | RETURN_ZVAL(&yaml, 1, 1); 540 | } 541 | /* }}} yaml_parse_url */ 542 | 543 | 544 | /* {{{ proto string yaml_emit(mixed data[, int encoding[, int linebreak[, array callbacks]]]) 545 | */ 546 | PHP_FUNCTION(yaml_emit) 547 | { 548 | zval *data = { 0 }; 549 | zend_long encoding = YAML_ANY_ENCODING; 550 | zend_long linebreak = YAML_ANY_BREAK; 551 | zval *zcallbacks = { 0 }; 552 | HashTable *callbacks = { 0 }; 553 | 554 | yaml_emitter_t emitter = { 0 }; 555 | smart_string str = { 0 }; 556 | 557 | if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "z/|lla/", 558 | &data, &encoding, &linebreak, &zcallbacks)) { 559 | return; 560 | } 561 | 562 | if (zcallbacks != NULL) { 563 | callbacks = Z_ARRVAL_P(zcallbacks); 564 | if (FAILURE == php_yaml_check_callbacks(callbacks)) { 565 | RETURN_FALSE; 566 | } 567 | } 568 | 569 | yaml_emitter_initialize(&emitter); 570 | yaml_emitter_set_output( 571 | &emitter, &php_yaml_write_to_buffer, (void *) &str); 572 | yaml_emitter_set_encoding(&emitter, (yaml_encoding_t) encoding); 573 | yaml_emitter_set_break(&emitter, (yaml_break_t) linebreak); 574 | yaml_emitter_set_canonical(&emitter, YAML_G(output_canonical)); 575 | yaml_emitter_set_indent(&emitter, YAML_G(output_indent)); 576 | yaml_emitter_set_width(&emitter, YAML_G(output_width)); 577 | yaml_emitter_set_unicode(&emitter, YAML_ANY_ENCODING != encoding); 578 | 579 | if (SUCCESS == php_yaml_write_impl( 580 | &emitter, data, (yaml_encoding_t) encoding, 581 | callbacks)) { 582 | RETVAL_STRINGL(str.c, str.len); 583 | 584 | } else { 585 | RETVAL_FALSE; 586 | } 587 | 588 | yaml_emitter_delete(&emitter); 589 | smart_string_free(&str); 590 | } 591 | /* }}} yaml_emit */ 592 | 593 | 594 | /* {{{ proto bool yaml_emit_file(string filename, mixed data[, int encoding[, int linebreak[, array callbacks]]]) 595 | */ 596 | PHP_FUNCTION(yaml_emit_file) 597 | { 598 | zend_string *filename = { 0 }; 599 | php_stream *stream = { 0 }; 600 | FILE *fp = { 0 }; 601 | zval *data = { 0 }; 602 | zend_long encoding = YAML_ANY_ENCODING; 603 | zend_long linebreak = YAML_ANY_BREAK; 604 | zval *zcallbacks = { 0 }; 605 | HashTable *callbacks = { 0 }; 606 | 607 | yaml_emitter_t emitter = { 0 }; 608 | 609 | if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "Sz/|lla/", 610 | &filename, &data, &encoding, &linebreak, &zcallbacks)) { 611 | return; 612 | } 613 | 614 | if (zcallbacks != NULL) { 615 | callbacks = Z_ARRVAL_P(zcallbacks); 616 | if (FAILURE == php_yaml_check_callbacks(callbacks)) { 617 | RETURN_FALSE; 618 | } 619 | } 620 | 621 | if (NULL == (stream = php_stream_open_wrapper(filename->val, "wb", 622 | IGNORE_URL | REPORT_ERRORS | STREAM_WILL_CAST, 623 | NULL))) { 624 | RETURN_FALSE; 625 | } 626 | 627 | if (FAILURE == php_stream_cast( 628 | stream, PHP_STREAM_AS_STDIO, (void **) &fp, 1)) { 629 | php_stream_close(stream); 630 | RETURN_FALSE; 631 | } 632 | 633 | yaml_emitter_initialize(&emitter); 634 | yaml_emitter_set_output_file(&emitter, fp); 635 | yaml_emitter_set_encoding(&emitter, (yaml_encoding_t) encoding); 636 | yaml_emitter_set_break(&emitter, (yaml_break_t) linebreak); 637 | yaml_emitter_set_canonical(&emitter, YAML_G(output_canonical)); 638 | yaml_emitter_set_indent(&emitter, YAML_G(output_indent)); 639 | yaml_emitter_set_width(&emitter, YAML_G(output_width)); 640 | yaml_emitter_set_unicode(&emitter, YAML_ANY_ENCODING != encoding); 641 | 642 | RETVAL_BOOL((SUCCESS == php_yaml_write_impl( 643 | &emitter, data, YAML_ANY_ENCODING, callbacks))); 644 | 645 | yaml_emitter_delete(&emitter); 646 | php_stream_close(stream); 647 | } 648 | /* }}} yaml_emit_file */ 649 | 650 | 651 | /* 652 | * Local variables: 653 | * tab-width: 4 654 | * c-basic-offset: 4 655 | * End: 656 | * vim600: noet sw=4 ts=4 fdm=marker 657 | * vim<600: noet sw=4 ts=4 658 | */ 659 | --------------------------------------------------------------------------------