rpm  5.4.15
lsyck.c
Go to the documentation of this file.
1 /*
2  * lsyck.c
3  *
4  * $Author: jbj $
5  * $Date: 2013/07/01 21:27:37 $
6  *
7  * Copyright (C) 2005 Zachary P. Landau <kapheine@divineinvasion.net>
8  */
9 
10 #include "system.h"
11 
12 #if defined(WITH_SYCK) && defined(WITH_LUA)
13 
14 #include <syck.h>
15 #include <string.h>
16 #include <stdlib.h>
17 
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21 
22 #include "lauxlib.h"
23 #include "lualib.h"
24 
25 LUALIB_API int luaopen_syck(lua_State *L)
26  /*@modifies L @*/;
27 
28 #ifdef __cplusplus
29 }
30 #endif
31 
32 struct emitter_xtra {
33  lua_State *L;
34  luaL_Buffer output;
35  int id;
36 };
37 
38 struct parser_xtra {
39  lua_State *L;
40 };
41 
42 /* XXX lua-5.2.0 retrofit destruction area. */
43 #if LUA_VERSION_NUM >= 502
44 static int luaL_typerror(lua_State *L, int narg, const char *tname)
45 {
46  const char *msg = lua_pushfstring(L, "%s expected, got %s",
47  tname, luaL_typename(L, narg));
48  return luaL_argerror(L, narg, msg);
49 }
50 #endif
51 
52 SYMID
53 lua_syck_parser_handler(SyckParser *p, SyckNode *n);
54 SYMID
55 lua_syck_parser_handler(SyckParser *p, SyckNode *n)
56 {
57  struct parser_xtra *bonus = (struct parser_xtra *)p->bonus;
58  int o = -1;
59  int o2 = -1;
60  int o3 = -1;
61  SYMID oid;
62  int i;
63 
64  switch (n->kind) {
65  case syck_str_kind:
66  if (n->type_id == NULL || strcmp(n->type_id, "str") == 0) {
67  lua_pushlstring(bonus->L, n->data.str->ptr, n->data.str->len);
68  o = lua_gettop(bonus->L);
69  }
70  else if (strcmp(n->type_id, "null") == 0)
71  {
72  lua_pushnil(bonus->L);
73  o = lua_gettop(bonus->L);
74  }
75  else if (strcmp(n->type_id, "bool#yes") == 0)
76  {
77  lua_pushboolean(bonus->L, 1);
78  o = lua_gettop(bonus->L);
79  }
80  else if (strcmp(n->type_id, "bool#no") == 0)
81  {
82  lua_pushboolean(bonus->L, 0);
83  o = lua_gettop(bonus->L);
84  }
85  else if (strcmp(n->type_id, "int#hex") == 0)
86  {
87  long intVal = strtol(n->data.str->ptr, NULL, 16);
88  lua_pushnumber(bonus->L, intVal);
89  o = lua_gettop(bonus->L);
90  }
91  else if (strcmp(n->type_id, "int") == 0)
92  {
93  long intVal = strtol(n->data.str->ptr, NULL, 10);
94  lua_pushnumber(bonus->L, intVal);
95  o = lua_gettop(bonus->L);
96  }
97  else
98  {
99  lua_pushlstring(bonus->L, n->data.str->ptr, n->data.str->len);
100  o = lua_gettop(bonus->L);
101  }
102  break;
103 
104  case syck_seq_kind:
105  lua_newtable(bonus->L);
106  o = lua_gettop(bonus->L);
107  for ( i=0; i < n->data.list->idx; i++ )
108  {
109  oid = syck_seq_read(n, i);
110  syck_lookup_sym(p, oid, (char **)&o2);
111  lua_pushvalue(bonus->L, o2);
112  lua_rawseti(bonus->L, o, i+1);
113  }
114  break;
115 
116  case syck_map_kind:
117  lua_newtable(bonus->L);
118  o = lua_gettop(bonus->L);
119  for ( i=0; i < n->data.pairs->idx; i++ )
120  {
121  oid = syck_map_read(n, map_key, i);
122  syck_lookup_sym(p, oid, (char **)&o2);
123  oid = syck_map_read(n, map_value, i);
124  syck_lookup_sym(p, oid, (char **)&o3);
125 
126  lua_pushvalue(bonus->L, o2);
127  lua_pushvalue(bonus->L, o3);
128  lua_settable(bonus->L, o);
129  }
130  break;
131  }
132  oid = syck_add_sym(p, (char *)((long)o));
133  return oid;
134 }
135 
136 void lua_syck_emitter_handler(SyckEmitter *e, st_data_t data);
137 void lua_syck_emitter_handler(SyckEmitter *e, st_data_t data)
138 {
139  struct emitter_xtra *bonus = (struct emitter_xtra *)e->bonus;
140  int type = lua_type(bonus->L, -1);
141  char buf[30]; /* find a better way, if possible */
142 
143  switch (type)
144  {
145  case LUA_TBOOLEAN:
146  if (lua_toboolean(bonus->L, -1))
147  strcpy(buf, "true");
148  else
149  strcpy(buf, "false");
150  syck_emit_scalar(e, (char *) "boolean", scalar_none, 0, 0, 0, (char *)buf, strlen(buf));
151  break;
152  case LUA_TSTRING:
153  syck_emit_scalar(e, (char *) "string", scalar_none, 0, 0, 0, (char *)lua_tostring(bonus->L, -1), lua_rawlen(bonus->L, -1));
154  break;
155  case LUA_TNUMBER:
156  /* should handle floats as well */
157  snprintf(buf, sizeof(buf), "%i", (int)lua_tonumber(bonus->L, -1));
158  syck_emit_scalar(e, (char *) "number", scalar_none, 0, 0, 0, buf, strlen(buf));
159  break;
160  case LUA_TTABLE:
161  if (lua_rawlen(bonus->L, -1) > 0) { /* treat it as an array */
162  syck_emit_seq(e, (char *) "table", seq_none);
163  lua_pushnil(bonus->L); /* first key */
164  while (lua_next(bonus->L, -2) != 0) {
165  /* `key' is at index -2 and `value' at index -1 */
166  syck_emit_item(e, (st_data_t)((long)bonus->id++));
167  lua_pop(bonus->L, 1); /* removes `value'; keeps `key' for next iteration */
168 
169  }
170  syck_emit_end(e);
171  } else { /* treat it as a map */
172  syck_emit_map(e, (char *) "table", map_none);
173  lua_pushnil(bonus->L);
174  while (lua_next(bonus->L, -2) != 0) {
175  lua_pushvalue(bonus->L, -2);
176  syck_emit_item(e, (st_data_t)((long)bonus->id++));
177  lua_pop(bonus->L, 1);
178  syck_emit_item(e, (st_data_t)((long)bonus->id++));
179  lua_pop(bonus->L, 1);
180  }
181  syck_emit_end(e);
182  }
183  break;
184  }
185 
186  bonus->id++;
187 }
188 
189 static void lua_syck_mark_emitter(SyckEmitter *e, int idx)
190 {
191  struct emitter_xtra *bonus = (struct emitter_xtra *)e->bonus;
192  int type = lua_type(bonus->L, idx);
193 
194  switch (type) {
195  case LUA_TTABLE:
196  lua_pushnil(bonus->L); /* first key */
197  while (lua_next(bonus->L, -2) != 0) {
198  /* `key' is at index -2 and `value' at index -1 */
199  //syck_emitter_mark_node(e, bonus->id++);
200  syck_emitter_mark_node(e, (st_data_t)((long)bonus->id++));
201  lua_syck_mark_emitter(e, -1);
202  lua_pop(bonus->L, 1);
203  }
204  break;
205  default:
206  syck_emitter_mark_node(e, (st_data_t)((long)bonus->id++));
207  break;
208  }
209 }
210 
211 
212 void lua_syck_output_handler(SyckEmitter *e, char *str, long len);
213 void lua_syck_output_handler(SyckEmitter *e, char *str, long len)
214 {
215  struct emitter_xtra *bonus = (struct emitter_xtra *)e->bonus;
216  luaL_addlstring(&bonus->output, str, len);
217 }
218 
219 static int syck_load(lua_State *L)
220 {
221  struct parser_xtra *bonus;
222  SyckParser *parser;
223  SYMID v;
224  void * obj;
225 
226  if (!luaL_checkstring(L, 1))
227  luaL_typerror(L, 1, "string");
228 
229  parser = syck_new_parser();
230  parser->bonus = S_ALLOC_N(struct emitter_xtra, 1);
231 
232  bonus = (struct parser_xtra *)parser->bonus;
233  bonus->L = lua_newthread(L);
234 
235  syck_parser_str(parser, (char *)lua_tostring(L, 1), lua_rawlen(L, 1), NULL);
236  syck_parser_handler(parser, lua_syck_parser_handler);
237  v = syck_parse(parser);
238  syck_lookup_sym(parser, v, (char **)&obj);
239 
240  syck_free_parser(parser);
241 
242  lua_xmove(bonus->L, L, 1);
243 
244  return 1;
245 }
246 
247 static int syck_dump(lua_State *L)
248 {
249  SyckEmitter *emitter;
250  struct emitter_xtra *bonus;
251 
252  emitter = syck_new_emitter();
253  emitter->bonus = S_ALLOC_N(struct emitter_xtra, 1);
254 
255  bonus = (struct emitter_xtra *)emitter->bonus;
256  bonus->L = lua_newthread(L);
257  luaL_buffinit(L, &bonus->output);
258 
259  syck_emitter_handler(emitter, lua_syck_emitter_handler);
260  syck_output_handler(emitter, lua_syck_output_handler);
261 
262  lua_pushvalue(L, -2);
263  lua_xmove(L, bonus->L, 1);
264 
265  bonus->id = 1;
266  lua_syck_mark_emitter(emitter, bonus->id);
267 
268  bonus->id = 1;
269  syck_emit(emitter, (st_data_t)((long)bonus->id));
270  syck_emitter_flush(emitter, 0);
271 
272  luaL_pushresult(&bonus->output);
273  syck_free_emitter(emitter);
274 
275  return 1;
276 }
277 
278 static const luaL_Reg sycklib[] = {
279  {"load", syck_load },
280  {"dump", syck_dump },
281  {NULL, NULL}
282 };
283 
284 LUALIB_API int luaopen_syck(lua_State *L)
285 {
286  luaL_newlib(L, sycklib);
287  return 1;
288 }
289 
290 #endif /* defined(WITH_SYCK) && defined(WITH_LUA) */
const char const char size_t len
Definition: bson.h:823
const bson * obj
Definition: bson.h:269
const char * str
Definition: bson.h:593
const char const bson_bool_t v
Definition: bson.h:919
const char const bson_oid_t * oid
Definition: bson.h:757
const char const bson * data
Definition: mongo.h:463
static void output(int indent, int *offset, const char *fmt,...)
Definition: rpmmtree.c:2497
#define L(CS)
Definition: fnmatch.c:161
const char const int i
Definition: bson.h:778
static int snprintf(char *buf, int nb, const char *fmt,...)
Definition: rpmps.c:220
const char char type
Definition: bson.h:908