lyaml.c

Fri, 16 Dec 2011 23:21:28 +0000

author
Matthew Wild <mwild1@gmail.com>
date
Fri, 16 Dec 2011 23:21:28 +0000
changeset 0
3ebc0316f54f
permissions
-rw-r--r--

Initial commit with my changes.
Originally imported from yaml-2.0.tar.gz: http://files.luaforge.net/releases/yaml/yaml/0.2/yaml-0.2.tar.gz

0
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
1 /*
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
2 * lyaml.c, LibYAML binding for Lua
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
3 *
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
4 * Copyright (c) 2009, Andrew Danforth <acd@weirdness.net>
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
5 *
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
7 * of this software and associated documentation files (the "Software"), to deal
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
8 * in the Software without restriction, including without limitation the rights
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
10 * copies of the Software, and to permit persons to whom the Software is
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
11 * furnished to do so, subject to the following conditions:
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
12 *
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
13 * The above copyright notice and this permission notice shall be included in
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
14 * all copies or substantial portions of the Software.
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
15 *
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
22 * THE SOFTWARE.
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
23 *
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
24 * Portions of this software were inspired by Perl's YAML::LibYAML module by
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
25 * Ingy döt Net <ingy@cpan.org>
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
26 *
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
27 */
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
28
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
29 #include <string.h>
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
30 #include <stdlib.h>
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
31
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
32 #include <lauxlib.h>
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
33 #include <lua.h>
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
34 #include <lualib.h>
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
35
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
36 #include "yaml.h"
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
37 #include "b64.h"
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
38
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
39 /* configurable flags */
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
40 static char Dump_Auto_Array = 1;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
41 static char Dump_Error_on_Unsupported = 0;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
42 static char Dump_Check_Metatables = 1;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
43 static char Load_Set_Metatables = 1;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
44 static char Load_Numeric_Scalars = 1;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
45 static char Load_Nulls_As_Nil = 0;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
46
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
47 #define LUAYAML_TAG_PREFIX "tag:yaml.org,2002:"
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
48
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
49 #define LUAYAML_KIND_UNKNOWN 0
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
50 #define LUAYAML_KIND_SEQUENCE 1
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
51 #define LUAYAML_KIND_MAPPING 2
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
52
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
53 #define RETURN_ERRMSG(s, msg) do { \
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
54 lua_pushstring(s->L, msg); \
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
55 s->error = 1; \
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
56 return; \
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
57 } while(0)
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
58
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
59 struct lua_yaml_loader {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
60 lua_State *L;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
61 int anchortable_index;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
62 int sequencemt_index;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
63 int mapmt_index;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
64 int document_count;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
65 yaml_parser_t parser;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
66 yaml_event_t event;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
67 char validevent;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
68 char error;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
69 };
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
70
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
71 struct lua_yaml_dumper {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
72 lua_State *L;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
73 int anchortable_index;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
74 unsigned int anchor_number;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
75 yaml_emitter_t emitter;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
76 char error;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
77
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
78 lua_State *outputL;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
79 luaL_Buffer yamlbuf;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
80 };
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
81
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
82 static int l_null(lua_State *);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
83
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
84 static void generate_error_message(struct lua_yaml_loader *loader) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
85 char buf[256];
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
86 luaL_Buffer b;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
87
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
88 luaL_buffinit(loader->L, &b);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
89
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
90 luaL_addstring(&b, loader->parser.problem ? loader->parser.problem : "A problem");
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
91 snprintf(buf, sizeof(buf), " at document: %d", loader->document_count);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
92 luaL_addstring(&b, buf);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
93
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
94 if (loader->parser.problem_mark.line || loader->parser.problem_mark.column) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
95 snprintf(buf, sizeof(buf), ", line: %d, column: %d\n",
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
96 loader->parser.problem_mark.line + 1,
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
97 loader->parser.problem_mark.column + 1);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
98 luaL_addstring(&b, buf);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
99 } else {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
100 luaL_addstring(&b, "\n");
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
101 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
102
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
103 if (loader->parser.context) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
104 snprintf(buf, sizeof(buf), "%s at line: %d, column: %d\n",
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
105 loader->parser.context,
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
106 loader->parser.context_mark.line + 1,
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
107 loader->parser.context_mark.column + 1);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
108 luaL_addstring(&b, buf);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
109 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
110
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
111 luaL_pushresult(&b);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
112 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
113
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
114 static inline void delete_event(struct lua_yaml_loader *loader) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
115 if (loader->validevent) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
116 yaml_event_delete(&loader->event);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
117 loader->validevent = 0;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
118 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
119 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
120
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
121 static inline int do_parse(struct lua_yaml_loader *loader) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
122 delete_event(loader);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
123 if (yaml_parser_parse(&loader->parser, &loader->event) != 1) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
124 generate_error_message(loader);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
125 loader->error = 1;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
126 return 0;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
127 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
128
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
129 loader->validevent = 1;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
130 return 1;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
131 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
132
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
133 static int load_node(struct lua_yaml_loader *loader);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
134
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
135 static void handle_anchor(struct lua_yaml_loader *loader) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
136 const char *anchor = (char *)loader->event.data.scalar.anchor;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
137 if (!anchor)
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
138 return;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
139
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
140 lua_pushstring(loader->L, anchor);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
141 lua_pushvalue(loader->L, -2);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
142 lua_rawset(loader->L, loader->anchortable_index);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
143 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
144
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
145 static void load_map(struct lua_yaml_loader *loader) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
146 lua_newtable(loader->L);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
147 if (loader->mapmt_index != 0) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
148 lua_pushvalue(loader->L, loader->mapmt_index);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
149 lua_setmetatable(loader->L, -2);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
150 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
151
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
152 handle_anchor(loader);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
153 while (1) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
154 int r;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
155 /* load key */
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
156 if (load_node(loader) == 0 || loader->error)
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
157 return;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
158
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
159 /* load value */
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
160 r = load_node(loader);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
161 if (loader->error)
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
162 return;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
163 if (r != 1)
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
164 RETURN_ERRMSG(loader, "unanticipated END event");
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
165 lua_rawset(loader->L, -3);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
166 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
167 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
168
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
169 static void load_sequence(struct lua_yaml_loader *loader) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
170 int index = 1;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
171
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
172 lua_newtable(loader->L);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
173 if (loader->sequencemt_index != 0) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
174 lua_pushvalue(loader->L, loader->sequencemt_index);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
175 lua_setmetatable(loader->L, -2);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
176 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
177
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
178 handle_anchor(loader);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
179 while (load_node(loader) == 1 && !loader->error)
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
180 lua_rawseti(loader->L, -2, index++);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
181 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
182
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
183 static void load_scalar(struct lua_yaml_loader *loader) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
184 const char *str = (char *)loader->event.data.scalar.value;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
185 unsigned int length = loader->event.data.scalar.length;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
186 const char *tag = (char *)loader->event.data.scalar.tag;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
187
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
188 if (tag && !strncmp(tag, LUAYAML_TAG_PREFIX, sizeof(LUAYAML_TAG_PREFIX) - 1)) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
189 tag += sizeof(LUAYAML_TAG_PREFIX) - 1;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
190
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
191 if (!strcmp(tag, "str")) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
192 lua_pushlstring(loader->L, str, length);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
193 return;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
194 } else if (!strcmp(tag, "int")) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
195 lua_pushinteger(loader->L, strtol(str, NULL, 10));
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
196 return;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
197 } else if (!strcmp(tag, "float")) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
198 lua_pushnumber(loader->L, strtod(str, NULL));
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
199 return;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
200 } else if (!strcmp(tag, "bool")) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
201 lua_pushboolean(loader->L, !strcmp(str, "true") || !strcmp(str, "yes"));
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
202 return;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
203 } else if (!strcmp(tag, "binary")) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
204 frombase64(loader->L, (const unsigned char *)str, length);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
205 return;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
206 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
207 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
208
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
209 if (loader->event.data.scalar.style == YAML_PLAIN_SCALAR_STYLE) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
210 if (!strcmp(str, "~")) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
211 if (Load_Nulls_As_Nil)
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
212 lua_pushnil(loader->L);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
213 else
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
214 l_null(loader->L);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
215 return;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
216 } else if (!strcmp(str, "true") || !strcmp(str, "yes")) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
217 lua_pushboolean(loader->L, 1);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
218 return;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
219 } else if (!strcmp(str, "false") || !strcmp(str, "no")) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
220 lua_pushboolean(loader->L, 0);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
221 return;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
222 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
223 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
224
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
225 lua_pushlstring(loader->L, str, length);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
226
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
227 /* plain scalar and Lua can convert it to a number? make it so... */
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
228 if (Load_Numeric_Scalars
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
229 && loader->event.data.scalar.style == YAML_PLAIN_SCALAR_STYLE
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
230 && lua_isnumber(loader->L, -1)) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
231 lua_Number n = lua_tonumber(loader->L, -1);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
232 lua_pop(loader->L, 1);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
233 lua_pushnumber(loader->L, n);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
234 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
235
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
236 handle_anchor(loader);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
237 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
238
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
239 static void load_alias(struct lua_yaml_loader *loader) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
240 char *anchor = (char *)loader->event.data.alias.anchor;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
241 lua_pushstring(loader->L, anchor);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
242 lua_rawget(loader->L, loader->anchortable_index);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
243 if (lua_isnil(loader->L, -1)) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
244 char buf[256];
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
245 snprintf(buf, sizeof(buf), "invalid reference: %s", anchor);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
246 RETURN_ERRMSG(loader, buf);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
247 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
248 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
249
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
250 static int load_node(struct lua_yaml_loader *loader) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
251 if (!do_parse(loader))
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
252 return -1;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
253
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
254 switch (loader->event.type) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
255 case YAML_DOCUMENT_END_EVENT:
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
256 case YAML_MAPPING_END_EVENT:
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
257 case YAML_SEQUENCE_END_EVENT:
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
258 return 0;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
259
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
260 case YAML_MAPPING_START_EVENT:
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
261 load_map(loader);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
262 return 1;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
263
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
264 case YAML_SEQUENCE_START_EVENT:
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
265 load_sequence(loader);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
266 return 1;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
267
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
268 case YAML_SCALAR_EVENT:
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
269 load_scalar(loader);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
270 return 1;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
271
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
272 case YAML_ALIAS_EVENT:
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
273 load_alias(loader);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
274 return 1;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
275
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
276 case YAML_NO_EVENT:
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
277 lua_pushliteral(loader->L, "libyaml returned YAML_NO_EVENT");
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
278 loader->error = 1;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
279 return -1;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
280
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
281 default:
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
282 lua_pushliteral(loader->L, "invalid event");
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
283 loader->error = 1;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
284 return -1;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
285 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
286 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
287
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
288 static void load(struct lua_yaml_loader *loader) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
289 if (!do_parse(loader))
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
290 return;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
291
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
292 if (loader->event.type != YAML_STREAM_START_EVENT)
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
293 RETURN_ERRMSG(loader, "expected STREAM_START_EVENT");
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
294
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
295 while (1) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
296 if (!do_parse(loader))
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
297 return;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
298
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
299 if (loader->event.type == YAML_STREAM_END_EVENT)
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
300 return;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
301
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
302 loader->document_count++;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
303 if (load_node(loader) != 1)
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
304 RETURN_ERRMSG(loader, "unexpected END event");
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
305 if (loader->error)
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
306 return;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
307
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
308 if (!do_parse(loader))
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
309 return;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
310 if (loader->event.type != YAML_DOCUMENT_END_EVENT)
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
311 RETURN_ERRMSG(loader, "expected DOCUMENT_END_EVENT");
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
312
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
313 /* reset anchor table */
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
314 lua_newtable(loader->L);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
315 lua_replace(loader->L, loader->anchortable_index);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
316 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
317 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
318
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
319 static int l_load(lua_State *L) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
320 struct lua_yaml_loader loader;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
321 int top = lua_gettop(L);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
322
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
323 luaL_argcheck(L, lua_isstring(L, 1), 1, "must provide a string argument");
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
324
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
325 loader.L = L;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
326 loader.validevent = 0;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
327 loader.error = 0;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
328 loader.document_count = 0;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
329 loader.mapmt_index = loader.sequencemt_index = 0;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
330
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
331 if (Load_Set_Metatables) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
332 /* create sequence metatable */
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
333 lua_newtable(L);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
334 lua_pushliteral(L, "_yaml");
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
335 lua_pushliteral(L, "sequence");
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
336 lua_rawset(L, -3);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
337 loader.sequencemt_index = top + 1;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
338
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
339 /* create map metatable */
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
340 lua_newtable(L);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
341 lua_pushliteral(L, "_yaml");
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
342 lua_pushliteral(L, "map");
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
343 lua_rawset(L, -3);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
344 loader.mapmt_index = top + 2;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
345 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
346
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
347 /* create table used to track anchors */
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
348 lua_newtable(L);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
349 loader.anchortable_index = lua_gettop(L);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
350
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
351 yaml_parser_initialize(&loader.parser);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
352 yaml_parser_set_input_string(&loader.parser,
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
353 (const unsigned char *)lua_tostring(L, 1), lua_strlen(L, 1));
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
354 load(&loader);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
355
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
356 delete_event(&loader);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
357 yaml_parser_delete(&loader.parser);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
358
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
359 if (loader.error)
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
360 lua_error(L);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
361
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
362 return loader.document_count;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
363 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
364
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
365 static int dump_node(struct lua_yaml_dumper *dumper);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
366
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
367 static int is_binary_string(const unsigned char *str, size_t len) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
368 // this could be optimized to examine an entire word in each loop iteration
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
369 while (len-- > 0) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
370 if (*str++ & 0x80) return 1;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
371 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
372 return 0;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
373 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
374
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
375 static int dump_scalar(struct lua_yaml_dumper *dumper) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
376 int type = lua_type(dumper->L, -1);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
377 size_t len;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
378 const char *str = NULL;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
379 yaml_char_t *tag = NULL;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
380 yaml_event_t ev;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
381 yaml_scalar_style_t style = YAML_PLAIN_SCALAR_STYLE;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
382 int is_binary = 0;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
383
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
384 if (type == LUA_TSTRING) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
385 str = lua_tolstring(dumper->L, -1, &len);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
386 if (len <= 5 && (!strcmp(str, "true")
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
387 || !strcmp(str, "false")
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
388 || !strcmp(str, "~"))) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
389 style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
390 } else if (lua_isnumber(dumper->L, -1)) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
391 /* string is convertible to number, quote it to preserve type */
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
392 style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
393 } else if ((is_binary = is_binary_string((const unsigned char *)str, len))) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
394 tobase64(dumper->L, -1);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
395 str = lua_tolstring(dumper->L, -1, &len);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
396 tag = (yaml_char_t *) LUAYAML_TAG_PREFIX "binary";
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
397 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
398 } else if (type == LUA_TNUMBER) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
399 /* have Lua convert number to a string */
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
400 str = lua_tolstring(dumper->L, -1, &len);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
401 } else if (type == LUA_TBOOLEAN) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
402 if (lua_toboolean(dumper->L, -1)) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
403 str = "true";
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
404 len = 4;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
405 } else {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
406 str = "false";
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
407 len = 5;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
408 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
409 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
410
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
411 yaml_scalar_event_initialize(
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
412 &ev, NULL, tag, (unsigned char *)str, len,
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
413 !is_binary, !is_binary, style);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
414 if (is_binary) lua_pop(dumper->L, 1);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
415 return yaml_emitter_emit(&dumper->emitter, &ev);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
416 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
417
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
418 static yaml_char_t *get_yaml_anchor(struct lua_yaml_dumper *dumper) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
419 const char *s = "";
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
420 lua_pushvalue(dumper->L, -1);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
421 lua_rawget(dumper->L, dumper->anchortable_index);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
422 if (!lua_toboolean(dumper->L, -1)) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
423 lua_pop(dumper->L, 1);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
424 return NULL;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
425 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
426
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
427 if (lua_isboolean(dumper->L, -1)) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
428 /* this element is referenced more than once but has not been named */
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
429 char buf[32];
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
430 snprintf(buf, sizeof(buf), "%u", dumper->anchor_number++);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
431 lua_pop(dumper->L, 1);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
432 lua_pushvalue(dumper->L, -1);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
433 lua_pushstring(dumper->L, buf);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
434 s = lua_tostring(dumper->L, -1);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
435 lua_rawset(dumper->L, dumper->anchortable_index);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
436 } else {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
437 /* this is an aliased element */
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
438 yaml_event_t ev;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
439 yaml_alias_event_initialize(&ev, (yaml_char_t *)lua_tostring(dumper->L, -1));
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
440 yaml_emitter_emit(&dumper->emitter, &ev);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
441 lua_pop(dumper->L, 1);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
442 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
443 return (yaml_char_t *)s;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
444 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
445
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
446 static int dump_table(struct lua_yaml_dumper *dumper) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
447 yaml_event_t ev;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
448 yaml_char_t *anchor = get_yaml_anchor(dumper);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
449
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
450 if (anchor && !*anchor) return 1;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
451
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
452 yaml_mapping_start_event_initialize(&ev, anchor, NULL, 0,
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
453 YAML_BLOCK_MAPPING_STYLE);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
454 yaml_emitter_emit(&dumper->emitter, &ev);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
455
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
456 lua_pushnil(dumper->L);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
457 while (lua_next(dumper->L, -2)) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
458 lua_pushvalue(dumper->L, -2); /* push copy of key on top of stack */
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
459 if (!dump_node(dumper) || dumper->error)
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
460 return 0;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
461 lua_pop(dumper->L, 1); /* pop copy of key */
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
462 if (!dump_node(dumper) || dumper->error)
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
463 return 0;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
464 lua_pop(dumper->L, 1);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
465 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
466
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
467 yaml_mapping_end_event_initialize(&ev);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
468 yaml_emitter_emit(&dumper->emitter, &ev);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
469 return 1;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
470 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
471
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
472 static int dump_array(struct lua_yaml_dumper *dumper) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
473 int i, n = luaL_getn(dumper->L, -1);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
474 yaml_event_t ev;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
475 yaml_char_t *anchor = get_yaml_anchor(dumper);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
476
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
477 if (anchor && !*anchor)
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
478 return 1;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
479
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
480 yaml_sequence_start_event_initialize(&ev, anchor, NULL, 0,
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
481 YAML_BLOCK_SEQUENCE_STYLE);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
482 yaml_emitter_emit(&dumper->emitter, &ev);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
483
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
484 for (i = 0; i < n; i++) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
485 lua_rawgeti(dumper->L, -1, i + 1);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
486 if (!dump_node(dumper) || dumper->error)
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
487 return 0;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
488 lua_pop(dumper->L, 1);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
489 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
490
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
491 yaml_sequence_end_event_initialize(&ev);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
492 yaml_emitter_emit(&dumper->emitter, &ev);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
493
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
494 return 1;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
495 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
496
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
497 static int figure_table_type(lua_State *L) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
498 int type = LUAYAML_KIND_UNKNOWN;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
499
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
500 if (lua_getmetatable(L, -1)) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
501 /* has metatable, look for _yaml key */
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
502 lua_pushliteral(L, "_yaml");
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
503 lua_rawget(L, -2);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
504 if (lua_isstring(L, -1)) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
505 const char *s = lua_tostring(L, -1);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
506 if (!strcmp(s, "sequence") || !strcmp(s, "seq"))
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
507 type = LUAYAML_KIND_SEQUENCE;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
508 else if (!strcmp(s, "map") || !strcmp(s, "mapping"))
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
509 type = LUAYAML_KIND_MAPPING;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
510 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
511 lua_pop(L, 2); /* pop value and metatable */
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
512 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
513
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
514 return type;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
515 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
516
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
517 static int dump_null(struct lua_yaml_dumper *dumper) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
518 yaml_event_t ev;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
519 yaml_scalar_event_initialize(&ev, NULL, NULL,
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
520 (unsigned char *)"~", 1, 1, 1, YAML_PLAIN_SCALAR_STYLE);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
521 return yaml_emitter_emit(&dumper->emitter, &ev);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
522 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
523
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
524 static int dump_node(struct lua_yaml_dumper *dumper) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
525 int type = lua_type(dumper->L, -1);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
526
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
527 if (type == LUA_TSTRING || type == LUA_TBOOLEAN || type == LUA_TNUMBER) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
528 return dump_scalar(dumper);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
529 } else if (type == LUA_TTABLE) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
530 int type = LUAYAML_KIND_UNKNOWN;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
531
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
532 if (Dump_Check_Metatables)
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
533 type = figure_table_type(dumper->L);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
534
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
535 if (type == LUAYAML_KIND_UNKNOWN && Dump_Auto_Array &&
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
536 luaL_getn(dumper->L, -1) > 0) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
537 type = LUAYAML_KIND_SEQUENCE;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
538 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
539
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
540 if (type == LUAYAML_KIND_SEQUENCE)
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
541 return dump_array(dumper);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
542 return dump_table(dumper);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
543 } else if (type == LUA_TFUNCTION && lua_tocfunction(dumper->L, -1) == l_null) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
544 return dump_null(dumper);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
545 } else { /* unsupported Lua type */
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
546 if (Dump_Error_on_Unsupported) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
547 char buf[256];
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
548 snprintf(buf, sizeof(buf),
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
549 "cannot dump object of type: %s", lua_typename(dumper->L, type));
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
550 lua_pushstring(dumper->L, buf);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
551 dumper->error = 1;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
552 } else {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
553 return dump_null(dumper);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
554 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
555 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
556 return 0;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
557 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
558
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
559 static void dump_document(struct lua_yaml_dumper *dumper) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
560 yaml_event_t ev;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
561
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
562 yaml_document_start_event_initialize(&ev, NULL, NULL, NULL, 0);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
563 yaml_emitter_emit(&dumper->emitter, &ev);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
564
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
565 if (!dump_node(dumper) || dumper->error)
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
566 return;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
567
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
568 yaml_document_end_event_initialize(&ev, 1);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
569 yaml_emitter_emit(&dumper->emitter, &ev);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
570 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
571
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
572 static int append_output(void *arg, unsigned char *buf, unsigned int len) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
573 struct lua_yaml_dumper *dumper = (struct lua_yaml_dumper *)arg;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
574 luaL_addlstring(&dumper->yamlbuf, (char *)buf, len);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
575 return 1;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
576 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
577
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
578 static void find_references(struct lua_yaml_dumper *dumper) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
579 int newval = -1, type = lua_type(dumper->L, -1);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
580 if (type != LUA_TTABLE)
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
581 return;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
582
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
583 lua_pushvalue(dumper->L, -1); /* push copy of table */
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
584 lua_rawget(dumper->L, dumper->anchortable_index);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
585 if (lua_isnil(dumper->L, -1))
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
586 newval = 0;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
587 else if (!lua_toboolean(dumper->L, -1))
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
588 newval = 1;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
589 lua_pop(dumper->L, 1);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
590 if (newval != -1) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
591 lua_pushvalue(dumper->L, -1);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
592 lua_pushboolean(dumper->L, newval);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
593 lua_rawset(dumper->L, dumper->anchortable_index);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
594 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
595 if (newval)
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
596 return;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
597
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
598 /* recursively process other table values */
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
599 lua_pushnil(dumper->L);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
600 while (lua_next(dumper->L, -2) != 0) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
601 find_references(dumper); /* find references on value */
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
602 lua_pop(dumper->L, 1);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
603 find_references(dumper); /* find references on key */
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
604 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
605 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
606
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
607 static int l_dump(lua_State *L) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
608 struct lua_yaml_dumper dumper;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
609 int i, argcount = lua_gettop(L);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
610 yaml_event_t ev;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
611
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
612 dumper.L = L;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
613 dumper.error = 0;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
614 /* create thread to use for YAML buffer */
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
615 dumper.outputL = lua_newthread(L);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
616 luaL_buffinit(dumper.outputL, &dumper.yamlbuf);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
617
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
618 yaml_emitter_initialize(&dumper.emitter);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
619 yaml_emitter_set_unicode(&dumper.emitter, 1);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
620 yaml_emitter_set_width(&dumper.emitter, 2);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
621 yaml_emitter_set_output(&dumper.emitter, &append_output, &dumper);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
622
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
623 yaml_stream_start_event_initialize(&ev, YAML_UTF8_ENCODING);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
624 yaml_emitter_emit(&dumper.emitter, &ev);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
625
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
626 for (i = 0; i < argcount; i++) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
627 lua_newtable(L);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
628 dumper.anchortable_index = lua_gettop(L);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
629 dumper.anchor_number = 0;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
630 lua_pushvalue(L, i + 1); /* push copy of arg we're processing */
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
631 find_references(&dumper);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
632 dump_document(&dumper);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
633 if (dumper.error)
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
634 break;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
635 lua_pop(L, 2); /* pop copied arg and anchor table */
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
636 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
637
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
638 yaml_stream_end_event_initialize(&ev);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
639 yaml_emitter_emit(&dumper.emitter, &ev);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
640
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
641 yaml_emitter_flush(&dumper.emitter);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
642 yaml_emitter_delete(&dumper.emitter);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
643
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
644 /* finalize and push YAML buffer */
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
645 luaL_pushresult(&dumper.yamlbuf);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
646
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
647 if (dumper.error)
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
648 lua_error(L);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
649
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
650 /* move buffer to original thread */
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
651 lua_xmove(dumper.outputL, L, 1);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
652 return 1;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
653 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
654
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
655 static int handle_config_option(lua_State *L) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
656 const char *attr;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
657 int i;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
658 static const struct {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
659 const char *attr;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
660 char *val;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
661 } args[] = {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
662 { "dump_auto_array", &Dump_Auto_Array },
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
663 { "dump_check_metatables", &Dump_Check_Metatables },
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
664 { "dump_error_on_unsupported", &Dump_Error_on_Unsupported },
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
665 { "load_set_metatables", &Load_Set_Metatables },
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
666 { "load_numeric_scalars", &Load_Numeric_Scalars },
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
667 { "load_nulls_as_nil", &Load_Nulls_As_Nil },
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
668 { NULL, NULL }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
669 };
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
670
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
671 luaL_argcheck(L, lua_isstring(L, -2), 1, "config attribute must be string");
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
672 luaL_argcheck(L, lua_isboolean(L, -1) || lua_isnil(L, -1), 1,
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
673 "value must be boolean or nil");
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
674
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
675 attr = lua_tostring(L, -2);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
676 for (i = 0; args[i].attr; i++) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
677 if (!strcmp(attr, args[i].attr)) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
678 if (!lua_isnil(L, -1))
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
679 *(args[i].val) = lua_toboolean(L, -1);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
680 lua_pushboolean(L, *(args[i].val));
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
681 return 1;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
682 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
683 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
684
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
685 luaL_error(L, "unrecognized config option: %s", attr);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
686 return 0; /* never reached */
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
687 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
688
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
689 static int l_config(lua_State *L) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
690 if (lua_istable(L, -1)) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
691 lua_pushnil(L);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
692 while (lua_next(L, -2) != 0) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
693 handle_config_option(L);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
694 lua_pop(L, 2);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
695 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
696 return 0;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
697 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
698
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
699 return handle_config_option(L);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
700 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
701
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
702 static int l_null(lua_State *L) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
703 lua_getglobal(L, "yaml");
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
704 lua_pushliteral(L, "null");
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
705 lua_rawget(L, -2);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
706 lua_replace(L, -2);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
707
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
708 return 1;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
709 }
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
710
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
711 LUALIB_API int luaopen_yaml(lua_State *L) {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
712 const luaL_reg yamllib[] = {
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
713 { "load", l_load },
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
714 { "dump", l_dump },
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
715 { "configure", l_config },
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
716 { "null", l_null },
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
717 { NULL, NULL}
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
718 };
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
719
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
720 luaL_openlib(L, "yaml", yamllib, 0);
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
721 return 1;
3ebc0316f54f Initial commit with my changes.
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
722 }

mercurial