2 * Copyright (c) 2012, Intel Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of Intel Corporation nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 #include <murphy/common.h>
39 #include <murphy/common/debug.h>
40 #include <murphy/core/lua-bindings/murphy.h>
41 #include <murphy/core/lua-utils/object.h>
43 #include "config-lua.h"
44 #include "resource-lua.h"
45 #include "config-api.h"
46 #include "client-api.h"
47 #include "manager-api.h"
49 #include "application-class.h"
51 #include "resource-set.h"
53 #define ZONE_CLASS MRP_LUA_CLASS_SIMPLE(zone)
54 #define APPCLASS_CLASS MRP_LUA_CLASS_SIMPLE(application_class)
55 #define ZONE_ATTR_CLASS MRP_LUA_CLASS(zone, attributes)
56 #define RESCLASS_CLASS MRP_LUA_CLASS(resource, class)
57 #define RESMETHOD_CLASS MRP_LUA_CLASS_SIMPLE(resource)
59 #define ATTRIBUTE_CLASSID MRP_LUA_CLASSID_ROOT "attribute"
60 #define RESOURCE_CLASSID MRP_LUA_CLASSID_ROOT "resource.instance"
62 typedef enum field_e field_t;
63 typedef enum attr_owner_e attr_owner_t;
64 typedef struct appclass_s appclass_t;
65 typedef struct zone_s zone_t;
66 typedef struct resclass_s resclass_t;
67 typedef struct resource_s resource_t;
68 typedef struct attr_def_s attr_def_t;
69 typedef struct attr_s attr_t;
71 typedef bool (*attribute_access_t)(attr_t *, int, mrp_attr_t *);
109 mrp_attr_def_t *attrs;
121 mrp_attr_def_t *attrs;
130 attribute_access_t fetch;
131 attribute_access_t update;
135 static void attributes_class_create(lua_State *);
136 static void appclass_class_create(lua_State *);
137 static void zone_class_create(lua_State *);
138 static void resclass_class_create(lua_State *);
139 static void resource_class_create(lua_State *);
140 static void resource_methods_create(lua_State *);
143 static int attributes_create(lua_State *, attr_owner_t, void *,
144 attr_def_t *, attribute_access_t,
146 static int attributes_getvalue(lua_State *);
147 static int attributes_setvalue(lua_State *);
148 static int attributes_getlength(lua_State *);
149 static attr_t *check_attributes(lua_State *, int);
150 static int push_attributes(lua_State *, int);
152 static int appclass_create(lua_State *);
153 static int appclass_getfield(lua_State *);
154 static int appclass_setfield(lua_State *);
155 static void appclass_destroy(void *);
156 /* static appclass_t *check_appclass(lua_State *, int); */
157 static appclass_t *to_appclass(lua_State *, int);
159 static int zone_create(lua_State *);
160 static int zone_getfield(lua_State *);
161 static int zone_setfield(lua_State *);
162 static void zone_destroy(void *);
163 /* static zone_t *check_zone(lua_State *, int); */
164 static zone_t *to_zone(lua_State *, int);
166 static int zone_attr_create(lua_State *);
167 static int zone_attr_getfield(lua_State *);
168 static int zone_attr_setfield(lua_State *);
169 static void zone_attr_destroy(void *);
170 /* static attr_def_t *check_zone_attr(lua_State *, int); */
171 /* static attr_def_t *to_zone_attr(lua_State *, int); */
172 static bool fetch_zone_attribute(attr_t *, int, mrp_attr_t *);
173 static bool update_zone_attribute(attr_t *, int, mrp_attr_t *);
175 static int resclass_create_from_lua(lua_State *);
176 static int resclass_getfield(lua_State *);
177 static int resclass_setfield(lua_State *);
178 static void resclass_destroy(void *);
179 /* static resclass_t *check_resclass(lua_State *, int); */
180 static resclass_t *to_resclass(lua_State *, int);
182 static int resource_getfield(lua_State *);
183 static int resource_setfield(lua_State *);
184 static resource_t *check_resource(lua_State *, int);
185 static bool fetch_resource_attribute(attr_t *, int, mrp_attr_t *);
186 static bool update_resource_attribute(attr_t *, int, mrp_attr_t *);
188 static mrp_lua_resmethod_t *resmethod_create_from_c(lua_State *);
189 static int resmethod_create_from_lua(lua_State *);
190 static int resmethod_getfield(lua_State *);
191 static int resmethod_setfield(lua_State *);
192 static void resmethod_destroy(void *);
193 static mrp_lua_resmethod_t *to_resmethod(lua_State *, int);
195 static mrp_attr_def_t *check_attrdefs(lua_State *, int, int *);
196 static void free_attrdefs(mrp_attr_def_t *);
197 static mrp_attr_t *check_attrs(lua_State *, int, attr_def_t *);
198 static void free_attrs(mrp_attr_t *);
199 static int check_attrindex(lua_State *, int, attr_def_t *);
200 static int check_boolean(lua_State *, int);
201 static mrp_resource_order_t check_order(lua_State *, int);
202 static int push_order(lua_State *, mrp_resource_order_t);
203 static field_t field_check(lua_State *, int, const char **);
204 static field_t field_name_to_type(const char *, size_t);
207 MRP_LUA_METHOD_LIST_TABLE (
208 zone_attr_methods, /* methodlist name */
209 MRP_LUA_METHOD_CONSTRUCTOR (zone_attr_create)
212 MRP_LUA_METHOD_LIST_TABLE (
213 resclass_methods, /* methodlist name */
214 MRP_LUA_METHOD_CONSTRUCTOR (resclass_create_from_lua)
218 MRP_LUA_METHOD_LIST_TABLE (
219 attributes_overrides, /* methodlist name */
220 MRP_LUA_OVERRIDE_GETFIELD (attributes_getvalue)
221 MRP_LUA_OVERRIDE_SETFIELD (attributes_setvalue)
222 MRP_LUA_OVERRIDE_GETLENGTH (attributes_getlength)
225 MRP_LUA_METHOD_LIST_TABLE (
226 zone_attr_overrides, /* methodlist name */
227 MRP_LUA_OVERRIDE_CALL (zone_attr_create)
228 MRP_LUA_OVERRIDE_GETFIELD (zone_attr_getfield)
229 MRP_LUA_OVERRIDE_SETFIELD (zone_attr_setfield)
232 MRP_LUA_METHOD_LIST_TABLE (
233 resclass_overrides, /* methodlist name */
234 MRP_LUA_OVERRIDE_CALL (resclass_create_from_lua)
235 MRP_LUA_OVERRIDE_GETFIELD (resclass_getfield)
236 MRP_LUA_OVERRIDE_SETFIELD (resclass_setfield)
239 MRP_LUA_METHOD_LIST_TABLE (
240 resource_overrides, /* methodlist name */
241 MRP_LUA_OVERRIDE_GETFIELD (resource_getfield)
242 MRP_LUA_OVERRIDE_SETFIELD (resource_setfield)
245 MRP_LUA_CLASS_DEF_SIMPLE (
246 application_class, /* main class & constructor name */
247 appclass_t, /* userdata type */
248 appclass_destroy, /* userdata destructor */
249 MRP_LUA_METHOD_LIST ( /* main class methods */
250 MRP_LUA_METHOD_CONSTRUCTOR (appclass_create)
252 MRP_LUA_METHOD_LIST ( /* main class overrides */
253 MRP_LUA_OVERRIDE_CALL (appclass_create)
254 MRP_LUA_OVERRIDE_GETFIELD (appclass_getfield)
255 MRP_LUA_OVERRIDE_SETFIELD (appclass_setfield)
259 MRP_LUA_CLASS_DEF_SIMPLE (
260 zone, /* main class & constructor name */
261 zone_t, /* userdata type */
262 zone_destroy, /* userdata destructor */
263 MRP_LUA_METHOD_LIST ( /* main class methods */
264 MRP_LUA_METHOD_CONSTRUCTOR (zone_create)
266 MRP_LUA_METHOD_LIST ( /* main class overrides */
267 MRP_LUA_OVERRIDE_CALL (zone_create)
268 MRP_LUA_OVERRIDE_GETFIELD (zone_getfield)
269 MRP_LUA_OVERRIDE_SETFIELD (zone_setfield)
274 zone, /* main class name */
275 attributes, /* constructor name */
276 attr_def_t, /* userdata type */
277 zone_attr_destroy, /* userdata destructor */
278 zone_attr_methods, /* class methods */
279 zone_attr_overrides /* class overrides */
283 resource, /* main class name */
284 class, /* constructor name */
285 resclass_t, /* userdata type */
286 resclass_destroy, /* userdata destructor */
287 resclass_methods, /* class methods */
288 resclass_overrides /* class overrides */
292 MRP_LUA_CLASS_DEF_SIMPLE (
293 resource, /* main class name */
294 mrp_lua_resmethod_t, /* userdata type */
295 resmethod_destroy, /* userdata destructor */
296 MRP_LUA_METHOD_LIST (
297 MRP_LUA_METHOD_CONSTRUCTOR (resmethod_create_from_lua)
299 MRP_LUA_METHOD_LIST (
300 MRP_LUA_OVERRIDE_CALL (resmethod_create_from_lua)
301 MRP_LUA_OVERRIDE_GETFIELD (resmethod_getfield)
302 MRP_LUA_OVERRIDE_SETFIELD (resmethod_setfield)
306 attr_def_t *zone_attr_defs;
307 attr_def_t *resource_attr_defs[MRP_RESOURCE_MAX];
308 mrp_lua_resmethod_t *resource_methods;
311 void mrp_resource_configuration_init(void)
313 static bool initialised = false;
317 if (!initialised && (L = mrp_lua_get_lua_state())) {
319 appclass_class_create(L);
320 zone_class_create(L);
321 resclass_class_create(L);
322 resource_class_create(L);
324 mrp_resource_lua_init(L);
326 resource_methods_create(L);
328 mrp_debug("lua classes are ready for resource "
329 "configuration and management");
336 mrp_lua_resmethod_t *mrp_lua_get_resource_methods(void)
338 return resource_methods;
341 uint32_t mrp_lua_to_resource_id(lua_State *L, int t)
343 resclass_t *rc = to_resclass(L, t);
345 return rc ? rc->id : MRP_RESOURCE_ID_INVALID;
348 int mrp_lua_resource_create(lua_State *L, mrp_resource_t *res)
350 mrp_resource_def_t *rdef;
356 MRP_ASSERT(res, "invalid argument");
358 if (!(rdef = res->def))
361 adef = resource_attr_defs[rdef->id];
363 MRP_ASSERT(resource_attr_defs[rdef->id], "can't find attribute defs");
365 r = lua_newuserdata(L, sizeof(resource_t));
367 r->rsetid = res->rsetid;
369 r->name = rdef->name;
370 r->attr_tbl = attributes_create(L, RESOURCE,r, adef,
371 fetch_resource_attribute,
372 update_resource_attribute);
374 luaL_getmetatable(L, RESOURCE_CLASSID);
375 lua_setmetatable(L, -2);
382 static void attributes_class_create(lua_State *L)
384 /* create a metatable for attributes */
385 luaL_newmetatable(L, ATTRIBUTE_CLASSID);
386 lua_pushliteral(L, "__index");
387 lua_pushvalue(L, -2);
388 lua_settable(L, -3); /* metatable.__index = metatable */
389 luaL_openlib(L, NULL, attributes_overrides, 0);
392 static void appclass_class_create(lua_State *L)
394 mrp_lua_create_object_class(L, APPCLASS_CLASS);
397 static void zone_class_create(lua_State *L)
399 mrp_lua_create_object_class(L, ZONE_CLASS);
400 mrp_lua_create_object_class(L, ZONE_ATTR_CLASS);
402 attributes_class_create(L);
404 zone_attr_defs = mrp_lua_create_object(L, ZONE_ATTR_CLASS, NULL,0);
405 mrp_lua_set_object_name(L, ZONE_ATTR_CLASS, "attributes");
409 static void resclass_class_create(lua_State *L)
411 mrp_lua_create_object_class(L, RESCLASS_CLASS);
414 static void resource_class_create(lua_State *L)
416 /* create a metatable for resource instances */
417 luaL_newmetatable(L, RESOURCE_CLASSID);
418 lua_pushliteral(L, "__index");
419 lua_pushvalue(L, -2);
420 lua_settable(L, -3); /* metatable.__index = metatable */
421 luaL_openlib(L, NULL, resource_overrides, 0);
424 static void resource_methods_create(lua_State *L)
426 mrp_lua_create_object_class(L, RESMETHOD_CLASS);
427 resource_methods = resmethod_create_from_c(L);
431 static int attributes_create(lua_State *L,
432 attr_owner_t type, void *data,
434 attribute_access_t fetch,
435 attribute_access_t update)
442 attr = lua_newuserdata(L, sizeof(attr_t));
444 attr->owner.type = type;
445 attr->owner.data = data;
448 attr->update = update;
450 luaL_getmetatable(L, ATTRIBUTE_CLASSID);
451 lua_setmetatable(L, -2);
453 tblref = luaL_ref(L, LUA_REGISTRYINDEX);
455 MRP_LUA_LEAVE(tblref);
458 static int attributes_getvalue(lua_State *L)
460 attr_t *attr = check_attributes(L, 1);
461 int idx = check_attrindex(L, 2, attr->def);
462 mrp_attr_def_t *def = attr->def->attrs + idx;
472 if (!(def->access & MRP_RESOURCE_READ)) {
473 luaL_error(L, "attempt to read a non-readable attribute %s",
478 if (!attr->fetch(attr, idx, &av)) {
486 lua_pushstring(L, av.value.string);
492 lua_pushinteger(L, av.value.integer);
495 lua_pushnumber(L, av.value.floating);
505 static int attributes_setvalue(lua_State *L)
507 attr_t *attr = check_attributes(L, 1);
508 int idx = check_attrindex(L, 2, attr->def);
509 mrp_attr_def_t *def = attr->def->attrs + idx;
515 luaL_error(L, "attribute %s dows not exist", def->name);
517 if (!(def->access & MRP_RESOURCE_WRITE))
518 luaL_error(L, "attempt to read a readonly attribute %s", def->name);
522 av.value.string = luaL_checkstring(L, 3);
525 av.value.integer = luaL_checkinteger(L, 3);
528 if ((av.value.integer = luaL_checkinteger(L, 3)) < 0) {
529 luaL_error(L, "attempt to update an unsigned attribute "
530 "with negative value");
534 av.value.floating = luaL_checknumber(L, 3);
537 luaL_error(L, "internal error: invalid attribute type");
541 if (!attr->update(attr, idx, &av))
542 luaL_error(L, "attribute update failed");
547 static int attributes_getlength(lua_State *L)
549 attr_t *attr = check_attributes(L, 1);
550 attr_def_t *def = attr->def;
554 lua_pushinteger(L, def ? def->nattr : 0);
559 static attr_t *check_attributes(lua_State *L, int idx)
561 return (attr_t *)luaL_checkudata(L, idx, ATTRIBUTE_CLASSID);
564 static int push_attributes(lua_State *L, int attr_tbl)
566 lua_rawgeti(L, LUA_REGISTRYINDEX, attr_tbl);
571 static int appclass_create(lua_State *L)
573 appclass_t *appclass;
579 mrp_resource_order_t order = 0;
580 const char *name = NULL;
584 MRP_LUA_FOREACH_FIELD(L, 2, fldnam, fldnamlen) {
586 switch (field_name_to_type(fldnam, fldnamlen)) {
589 name = mrp_strdup(luaL_checkstring(L, -1));
593 priority = luaL_checkint(L, -1);
597 modal = check_boolean(L, -1);
601 share = check_boolean(L, -1);
605 order = check_order(L, -1);
609 luaL_error(L, "unexpected field '%s'", fldnam);
615 luaL_error(L, "missing or wrong name field");
617 luaL_error(L, "missing or wrong modal field");
619 luaL_error(L, "modal class can't share");
621 luaL_error(L, "missing or wrong share field");
623 luaL_error(L, "missing or wrong order field");
625 luaL_error(L, "negative priority");
626 if (!mrp_application_class_create(name, priority, modal, share, order))
627 luaL_error(L, "failed to create application class '%s'", name);
629 appclass = (appclass_t *)mrp_lua_create_object(L, APPCLASS_CLASS, name,0);
632 luaL_error(L, "invalid or duplicate name '%s'", name);
634 appclass->name = name;
635 mrp_log_info("application class '%s' created", name);
640 static int appclass_getfield(lua_State *L)
642 appclass_t *appclass = to_appclass(L, 1);
643 field_t fld = field_check(L, 2, NULL);
644 mrp_application_class_t *ac;
650 if (!appclass || !(ac = mrp_application_class_find(appclass->name)))
654 case NAME: lua_pushstring(L, ac->name); break;
655 case PRIORITY: lua_pushinteger(L, ac->priority); break;
656 case MODAL: lua_pushboolean(L, ac->modal); break;
657 case SHARE: lua_pushboolean(L, ac->share); break;
658 case ORDER: push_order(L, ac->order); break;
659 default: lua_pushnil(L); break;
666 static int appclass_setfield(lua_State *L)
670 luaL_error(L, "can't modify application classes after definition");
675 static void appclass_destroy(void *data)
677 appclass_t *appclass = (appclass_t *)data;
681 mrp_free((void *)appclass->name);
687 static appclass_t *check_appclass(lua_State *L, int idx)
689 return (appclass_t *)mrp_lua_check_object(L, APPCLASS_CLASS, idx);
693 static appclass_t *to_appclass(lua_State *L, int idx)
695 return (appclass_t *)mrp_lua_to_object(L, APPCLASS_CLASS, idx);
699 static int zone_create(lua_State *L)
705 const char *name = NULL;
706 mrp_attr_t *attrs = NULL;
710 MRP_ASSERT(zone_attr_defs, "invocation prior to initialization");
712 if (!zone_attr_defs->attrs)
713 luaL_error(L, "attempt to create zone before defining attributes");
715 MRP_LUA_FOREACH_FIELD(L, 2, fldnam, fldnamlen) {
717 switch (field_name_to_type(fldnam, fldnamlen)) {
720 name = mrp_strdup(luaL_checkstring(L, -1));
724 attrs = check_attrs(L, -1, zone_attr_defs);
728 luaL_error(L, "unexpected field '%s'", fldnam);
734 luaL_error(L, "missing or wrong name field");
735 if ((id = mrp_zone_create(name,attrs)) == MRP_ZONE_ID_INVALID)
736 luaL_error(L, "failed to create zone");
740 zone = (zone_t *)mrp_lua_create_object(L, ZONE_CLASS, name,0);
743 luaL_error(L, "invalid or duplicate name '%s'", name);
747 zone->attr_tbl = attributes_create(L, ZONE,zone, zone_attr_defs,
748 fetch_zone_attribute,
749 update_zone_attribute);
751 mrp_log_info("zone '%s' created", name);
757 static int zone_getfield(lua_State *L)
759 zone_t *zone = to_zone(L, 1);
760 field_t fld = field_check(L, 2, NULL);
767 /* attempt to access a zone definition field */
769 case ATTRIBUTES: mrp_lua_push_object(L, zone_attr_defs); break;
770 default: lua_pushnil(L); break;
774 /* attempt to access a zone instance field */
776 case ATTRIBUTES: push_attributes(L, zone->attr_tbl); break;
777 case ID: lua_pushinteger(L, zone->id + 1); break;
778 case NAME: lua_pushstring(L, zone->name); break;
779 default: lua_pushnil(L); break;
786 static int zone_setfield(lua_State *L)
788 zone_t *zone = to_zone(L, 1);
789 field_t fld = field_check(L, 2, NULL);
793 if (zone || fld != ATTRIBUTES)
794 luaL_error(L, "zones can't be exetended after definition");
799 static void zone_destroy(void *data)
801 /* zone_t *zone = (zone_t *)data; */
811 static zone_t *check_zone(lua_State *L, int idx)
813 return (zone_t *)mrp_lua_check_object(L, ZONE_CLASS, idx);
817 static zone_t *to_zone(lua_State *L, int idx)
819 return (zone_t *)mrp_lua_to_object(L, ZONE_CLASS, idx);
822 static int zone_attr_create(lua_State *L)
824 mrp_attr_def_t *attrs;
829 MRP_ASSERT(zone_attr_defs, "invocation prior to initialization");
831 if (zone_attr_defs->attrs)
832 luaL_error(L, "zone attributes already defined");
834 attrs = check_attrdefs(L, 2, &nattr);
836 mrp_zone_definition_create(attrs);
838 zone_attr_defs->nattr = nattr;
839 zone_attr_defs->attrs = attrs;
842 mrp_lua_push_object(L, zone_attr_defs);
844 mrp_log_info("zone attributes defined");
849 static int zone_attr_getfield(lua_State *L)
856 MRP_ASSERT(zone_attr_defs, "invocation prior to initialization");
858 if (!(zone = to_zone(L, 1))) {
859 mrp_debug("zone attribute definition => attribute index");
860 if ((idx = check_attrindex(L, 2, zone_attr_defs)) < 0)
863 lua_pushinteger(L, idx);
866 mrp_debug("zone attribute => nil");
873 static int zone_attr_setfield(lua_State *L)
883 static void zone_attr_destroy(void *data)
885 /* attr_def_t *attr = (attr_def_t *)data; */
895 static attr_def_t *check_zone_attr(lua_State *L, int idx)
897 return (attr_def_t *)mrp_lua_check_object(L, ZONE_ATTR_CLASS, idx);
902 static attr_def_t *to_zone_attr(lua_State *L, int idx)
904 return (attr_def_t *)mrp_lua_to_object(L, ZONE_ATTR_CLASS, idx);
908 static bool fetch_zone_attribute(attr_t *attr, int idx, mrp_attr_t *retval)
913 if (attr->owner.type == ZONE && (zone = (zone_t *)attr->owner.data)) {
914 if ((z = mrp_zone_find_by_id(zone->id))) {
915 if (mrp_zone_read_attribute(z, idx, retval))
923 static bool update_zone_attribute(attr_t *attr, int idx, mrp_attr_t *value)
931 if (attr->owner.type == ZONE && (zone = (zone_t *)attr->owner.data)) {
932 if ((z = mrp_zone_find_by_id(zone->id))) {
934 if (mrp_zone_write_attribute(z, idx, value))
943 static int resclass_create_from_lua(lua_State *L)
945 resclass_t *resclass;
950 const char *name = NULL;
951 mrp_attr_def_t *attrs = NULL;
952 bool shareable = false;
953 mrp_resource_mgr_ftbl_t *ftbl = NULL;
954 void *mgrdata = NULL;
959 MRP_LUA_FOREACH_FIELD(L, 2, fldnam, fldnamlen) {
961 switch (field_name_to_type(fldnam, fldnamlen)) {
964 name = mrp_strdup(luaL_checkstring(L, -1));
968 luaL_argcheck(L, lua_isboolean(L,-1), 2, "attempt to assign "
969 "non-boolean value to 'shareable' field");
970 shareable = lua_toboolean(L, -1);
974 attrs = check_attrdefs(L, -1, &nattr);
978 luaL_error(L, "unexpected field '%s'", fldnam);
984 luaL_error(L, "missing or wrong name field");
986 id = mrp_resource_definition_create(name, shareable, attrs,ftbl,mgrdata);
988 MRP_ASSERT(id < MRP_RESOURCE_MAX, "resource id is out of range");
990 if (id == MRP_RESOURCE_ID_INVALID)
991 luaL_error(L, "failed to register resource class '%s'", name);
993 resclass = (resclass_t *)mrp_lua_create_object(L, RESCLASS_CLASS, name,0);
994 adef = mrp_allocz(sizeof(attr_def_t));
997 luaL_error(L, "invalid or duplicate name '%s'", name);
999 luaL_error(L, "failed to allocate memory for attribute definitions");
1002 resclass->name = name;
1003 resclass->attrs = attrs;
1005 adef->nattr = nattr;
1006 adef->attrs = attrs;
1008 resource_attr_defs[id] = adef;
1010 mrp_log_info("resource class '%s' created", name);
1015 static int resclass_getfield(lua_State *L)
1017 resclass_t *rc = to_resclass(L, 1);
1018 field_t fld = field_check(L, 2, NULL);
1019 mrp_resource_def_t *rd;
1025 if (!rc || !(rd = mrp_resource_definition_find_by_name(rc->name)))
1029 case NAME: lua_pushstring(L, rd->name); break;
1030 case ID: lua_pushinteger(L, rd->id + 1); break;
1031 case SHAREABLE: lua_pushboolean(L, rd->shareable); break;
1032 default: lua_pushnil(L); break;
1039 static int resclass_setfield(lua_State *L)
1043 luaL_error(L, "can't modify resource classes after definition");
1048 static void resclass_destroy(void *data)
1050 resclass_t *rc = (resclass_t *)data;
1054 mrp_free((void *)rc->name);
1055 free_attrdefs(rc->attrs);
1057 MRP_LUA_LEAVE_NOARG;
1061 static resclass_t *check_resclass(lua_State *L, int idx)
1063 return (resclass_t *)mrp_lua_check_object(L, RESCLASS_CLASS, idx);
1067 static resclass_t *to_resclass(lua_State *L, int idx)
1069 return (resclass_t *)mrp_lua_to_object(L, RESCLASS_CLASS, idx);
1072 static int resource_getfield(lua_State *L)
1075 resource_t *res = check_resource(L, 1);
1076 field_t fld = field_check(L, 2, &name);
1077 mrp_resource_set_t *s;
1079 mrp_resource_mask_t m;
1086 push_attributes(L, res->attr_tbl);
1091 if (!(r = mrp_resource_set_find_resource(res->rsetid, res->name)))
1094 lua_pushboolean(L, r->shared);
1098 if (!(s = mrp_resource_set_find_by_id(res->rsetid)))
1101 m = ((mrp_resource_mask_t)1) << res->resid;
1105 lua_pushboolean(L, s->resource.mask.mandatory & m ? true : false);
1108 lua_pushboolean(L, s->resource.mask.grant & m ? true : false);
1121 static int resource_setfield(lua_State *L)
1130 static resource_t *check_resource(lua_State *L, int idx)
1132 return (resource_t *)luaL_checkudata(L, idx, RESOURCE_CLASSID);
1135 static bool fetch_resource_attribute(attr_t *attr, int idx, mrp_attr_t *retval)
1137 mrp_resource_set_t *rset;
1138 resource_t *resource;
1141 if (attr->owner.type == RESOURCE) {
1142 if ((resource = (resource_t *)attr->owner.data)) {
1143 if ((rset = mrp_resource_set_find_by_id(resource->rsetid))) {
1144 a = mrp_resource_set_read_attribute(rset, resource->name,
1146 return a ? true : false;
1155 static bool update_resource_attribute(attr_t *attr, int idx, mrp_attr_t *value)
1157 mrp_resource_set_t *rset;
1158 resource_t *resource;
1159 mrp_attr_t values[2];
1164 if (attr->owner.type == RESOURCE) {
1165 if ((resource = (resource_t *)attr->owner.data)) {
1166 if ((rset = mrp_resource_set_find_by_id(resource->rsetid))) {
1167 memcpy(values + 0, value, sizeof(mrp_attr_t));
1168 memset(values + 1, 0, sizeof(mrp_attr_t));
1170 sts = mrp_resource_set_write_attributes(rset, resource->name,
1172 return (sts < 0) ? false : true;
1180 static mrp_lua_resmethod_t *resmethod_create_from_c(lua_State *L)
1182 mrp_lua_resmethod_t *method = mrp_lua_create_object(L, RESMETHOD_CLASS,
1186 luaL_error(L, "invalid or duplicate name 'method'");
1191 static int resmethod_create_from_lua(lua_State *L)
1195 luaL_error(L, "singleton object has already been created");
1202 static int resmethod_getfield(lua_State *L)
1205 mrp_lua_resmethod_t *method = to_resmethod(L, 1);
1206 field_t fld = field_check(L, 2, &name);
1213 /* attempt to access a resclass or owners */
1215 case METHOD: mrp_lua_push_object(L, resource_methods); break;
1216 case OWNERS: lua_pushstring(L,name); lua_rawget(L,1); break;
1217 default: lua_pushnil(L); break;
1221 /* attempt to access a method member */
1222 if (!resource_methods)
1227 lua_pushstring(L, name);
1240 static int resmethod_setfield(lua_State *L)
1243 mrp_lua_resmethod_t *method = to_resmethod(L, 1);
1244 field_t fld = field_check(L, 2, &name);
1251 lua_pushstring(L, name);
1252 lua_pushvalue(L, 3);
1253 method->veto = mrp_funcarray_check(L, -1);
1257 luaL_error(L, "invalid method '%s'", name);
1265 static void resmethod_destroy(void *data)
1267 mrp_lua_resmethod_t *method = (mrp_lua_resmethod_t *)data;
1271 method->veto = NULL;
1273 MRP_LUA_LEAVE_NOARG;
1276 static mrp_lua_resmethod_t *to_resmethod(lua_State *L, int idx)
1278 return (mrp_lua_resmethod_t *)mrp_lua_to_object(L, RESMETHOD_CLASS, idx);
1282 static mrp_attr_def_t *check_attrdefs(lua_State *L, int t, int *ret_len)
1284 mrp_attr_def_t attrdefs[128];
1285 mrp_attr_def_t *ad, *end, *dup;
1295 t = (t < 0) ? lua_gettop(L) + t + 1 : t;
1297 luaL_checktype(L, t, LUA_TTABLE);
1299 end = (ad = attrdefs) + (MRP_ARRAY_SIZE(attrdefs) - 1);
1301 MRP_LUA_FOREACH_FIELD(L, t, name, namlen) {
1303 luaL_error(L, "invalid attribute definition");
1305 luaL_error(L, "too many attributes");
1307 ad->name = mrp_strdup(name);
1308 ad->type = mqi_error;
1309 ad->access = MRP_RESOURCE_READ;
1313 luaL_checktype(L, -1, LUA_TTABLE);
1316 for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
1317 if (lua_type(L, -2) != LUA_TNUMBER)
1320 i = lua_tointeger(L, -2);
1324 ad->type = lua_tointeger(L, -1);
1329 if ((string = lua_tostring(L, -1))) {
1330 ad->value.string = mrp_strdup(string);
1335 ad->value.integer = lua_tointeger(L, -1);
1339 ad->value.integer = lua_tointeger(L, -1);
1343 ad->value.floating = lua_tonumber(L, -1);
1351 if (!(access = lua_tostring(L, -1)))
1352 ad->type = mqi_error;
1354 if (!strcasecmp(access, "read"))
1355 ad->access = MRP_RESOURCE_READ;
1356 else if (!strcasecmp(access, "write"))
1357 ad->access = MRP_RESOURCE_WRITE;
1358 else if (!strcasecmp(access, "rw"))
1359 ad->access = MRP_RESOURCE_RW;
1361 ad->type = mqi_error;
1365 ad->type = mqi_error;
1371 (ad->type != mqi_string &&
1372 ad->type != mqi_integer &&
1373 ad->type != mqi_unsignd &&
1374 ad->type != mqi_floating ))
1380 memset(ad, 0, sizeof(mrp_attr_def_t));
1382 len = ad - attrdefs;
1383 size = sizeof(mrp_attr_def_t) * (len+1);
1384 dup = mrp_alloc(size);
1387 luaL_error(L, "failed to allocate %u byte memory", size);
1389 memcpy(dup, attrdefs, size);
1397 luaL_argerror(L, t, "malformed attribute definition");
1402 static void free_attrdefs(mrp_attr_def_t *attrdefs)
1407 for (ad = attrdefs; ad->name; ad++) {
1408 mrp_free((void *)ad->name);
1409 if (ad->type == mqi_string)
1410 mrp_free((void *)ad->value.string);
1416 static int attr_name_to_index(const char *name, attr_def_t *def)
1418 mrp_attr_def_t *attrs = def->attrs;
1421 for (idx = 0; idx < def->nattr; idx++) {
1422 if (!strcmp(name, attrs[idx].name))
1429 static mrp_attr_t *check_attrs(lua_State *L, int t, attr_def_t *defs)
1431 mrp_attr_t attr[128];
1432 mrp_attr_t *at, *end, *dup;
1439 t = (t < 0) ? lua_gettop(L) + t + 1 : t;
1441 luaL_checktype(L, t, LUA_TTABLE);
1443 end = (at = attr) + (MRP_ARRAY_SIZE(attr) - 1);
1445 MRP_LUA_FOREACH_FIELD(L, t, name, namlen) {
1447 luaL_error(L, "invalid attribute definition");
1449 luaL_error(L, "too many attributes");
1450 if ((i = attr_name_to_index(name, defs)) < 0)
1451 luaL_error(L, "attribute %s do not exist", name);
1453 at->name = mrp_strdup(name);
1455 switch ((at->type = defs->attrs[i].type)) {
1457 at->value.string = mrp_strdup(luaL_checkstring(L,-1));
1460 at->value.integer = luaL_checkinteger(L,-1);
1463 if ((at->value.integer = luaL_checkinteger(L,-1)) < 0)
1464 luaL_error(L, "attempt to give negative value to an "
1465 "unsigned integer");
1468 luaL_error(L, "Internal error: invalid type for attribute");
1475 memset(at, 0, sizeof(mrp_attr_t));
1478 size = sizeof(mrp_attr_t) * (len + 1);
1480 dup = mrp_alloc(size);
1481 memcpy(dup, attr, size);
1487 static void free_attrs(mrp_attr_t *attrs)
1492 for (at = attrs; at->name; at++) {
1493 mrp_free((void *)at->name);
1494 if (at->type == mqi_string)
1495 mrp_free((void *)at->value.string);
1502 static int check_attrindex(lua_State *L, int arg, attr_def_t *def)
1507 if (!def || !def->attrs)
1510 switch (lua_type(L, arg)) {
1512 idx = lua_tointeger(L, arg);
1513 return (idx >= 0 && idx < def->nattr) ? idx : -1;
1515 name = lua_tostring(L, arg);
1516 return attr_name_to_index(name, def);
1523 static int check_boolean(lua_State *L, int idx)
1525 if (!lua_isboolean(L, idx))
1526 luaL_argerror(L, idx, "expected boolean");
1527 return lua_toboolean(L, idx) ? 1 : 0;
1530 static mrp_resource_order_t check_order(lua_State *L, int idx)
1532 const char *str = luaL_checkstring(L, idx);
1534 if (!strcasecmp(str, "fifo"))
1535 return MRP_RESOURCE_ORDER_FIFO;
1537 if (!strcasecmp(str, "lifo"))
1538 return MRP_RESOURCE_ORDER_LIFO;
1540 luaL_error(L, "invalid value for order ('fifo' or 'lifo' accepted only)");
1542 return MRP_RESOURCE_ORDER_UNKNOWN;
1545 static int push_order(lua_State *L, mrp_resource_order_t order)
1550 case MRP_RESOURCE_ORDER_FIFO: str = "fifo"; break;
1551 case MRP_RESOURCE_ORDER_LIFO: str = "lifo"; break;
1552 default: str = "<unknown>"; break;
1555 lua_pushstring(L, str);
1561 static field_t field_check(lua_State *L, int idx, const char **ret_fldnam)
1567 if (!(fldnam = lua_tolstring(L, idx, &fldnamlen)))
1570 fldtyp = field_name_to_type(fldnam, fldnamlen);
1573 *ret_fldnam = fldnam;
1579 static field_t field_name_to_type(const char *name, size_t len)
1584 if (!strcmp(name, "id"))
1589 if (!strcmp(name, "name"))
1591 if (!strcmp(name, "veto"))
1596 if (!strcmp(name, "class"))
1598 if (!strcmp(name, "modal"))
1600 if (!strcmp(name, "share"))
1602 if (!strcmp(name, "grant"))
1604 if (!strcmp(name, "order"))
1609 if (!strcmp(name, "method"))
1611 if (!strcmp(name, "owners"))
1613 if (!strcmp(name, "shared"))
1618 if (!strcmp(name, "priority"))
1623 if (!strcmp(name, "mandatory"))
1625 if (!strcmp(name, "shareable"))
1630 if (!strcmp(name, "attributes"))
1644 * indent-tabs-mode: nil