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"
52 #include "attribute.h"
54 #define ZONE_CLASS MRP_LUA_CLASS_SIMPLE(zone)
55 #define APPCLASS_CLASS MRP_LUA_CLASS_SIMPLE(application_class)
56 #define ZONE_ATTR_CLASS MRP_LUA_CLASS(zone, attributes)
57 #define RESCLASS_CLASS MRP_LUA_CLASS(resource, class)
58 #define RESMETHOD_CLASS MRP_LUA_CLASS_SIMPLE(resource)
60 #define ATTRIBUTE_CLASSID MRP_LUA_CLASSID_ROOT "attribute"
61 #define RESOURCE_CLASSID MRP_LUA_CLASSID_ROOT "resource.instance"
63 typedef enum field_e field_t;
64 typedef enum attr_owner_e attr_owner_t;
65 typedef struct appclass_s appclass_t;
66 typedef struct zone_s zone_t;
67 typedef struct resclass_s resclass_t;
68 typedef struct resource_s resource_t;
69 typedef struct attr_def_s attr_def_t;
70 typedef struct attr_s attr_t;
72 typedef bool (*attribute_access_t)(attr_t *, int, mrp_attr_t *);
110 mrp_attr_def_t *attrs;
122 mrp_attr_def_t *attrs;
131 attribute_access_t fetch;
132 attribute_access_t update;
136 static void attributes_class_create(lua_State *);
137 static void appclass_class_create(lua_State *);
138 static void zone_class_create(lua_State *);
139 static void resclass_class_create(lua_State *);
140 static void resource_class_create(lua_State *);
141 static void resource_methods_create(lua_State *);
144 static int attributes_create(lua_State *, attr_owner_t, void *,
145 attr_def_t *, attribute_access_t,
147 static int attributes_getvalue(lua_State *);
148 static int attributes_setvalue(lua_State *);
149 static int attributes_getlength(lua_State *);
150 static attr_t *check_attributes(lua_State *, int);
151 static int push_attributes(lua_State *, int);
153 static int appclass_create(lua_State *);
154 static int appclass_getfield(lua_State *);
155 static int appclass_setfield(lua_State *);
156 static void appclass_destroy(void *);
157 /* static appclass_t *check_appclass(lua_State *, int); */
158 static appclass_t *to_appclass(lua_State *, int);
160 static int zone_create(lua_State *);
161 static int zone_getfield(lua_State *);
162 static int zone_setfield(lua_State *);
163 static void zone_destroy(void *);
164 /* static zone_t *check_zone(lua_State *, int); */
165 static zone_t *to_zone(lua_State *, int);
167 static int zone_attr_create(lua_State *);
168 static int zone_attr_getfield(lua_State *);
169 static int zone_attr_setfield(lua_State *);
170 static void zone_attr_destroy(void *);
171 /* static attr_def_t *check_zone_attr(lua_State *, int); */
172 /* static attr_def_t *to_zone_attr(lua_State *, int); */
173 static bool fetch_zone_attribute(attr_t *, int, mrp_attr_t *);
174 static bool update_zone_attribute(attr_t *, int, mrp_attr_t *);
176 static int resclass_create_from_lua(lua_State *);
177 static int resclass_getfield(lua_State *);
178 static int resclass_setfield(lua_State *);
179 static void resclass_destroy(void *);
180 /* static resclass_t *check_resclass(lua_State *, int); */
181 static resclass_t *to_resclass(lua_State *, int);
183 static int resource_getfield(lua_State *);
184 static int resource_setfield(lua_State *);
185 static resource_t *check_resource(lua_State *, int);
186 static bool fetch_resource_attribute(attr_t *, int, mrp_attr_t *);
187 static bool update_resource_attribute(attr_t *, int, mrp_attr_t *);
189 static mrp_lua_resmethod_t *resmethod_create_from_c(lua_State *);
190 static int resmethod_create_from_lua(lua_State *);
191 static int resmethod_getfield(lua_State *);
192 static int resmethod_setfield(lua_State *);
193 static void resmethod_destroy(void *);
194 static mrp_lua_resmethod_t *to_resmethod(lua_State *, int);
196 static mrp_attr_def_t *check_attrdefs(lua_State *, int, int *);
197 static void free_attrdefs(mrp_attr_def_t *);
198 static mrp_attr_t *check_attrs(lua_State *, int, attr_def_t *);
199 static void free_attrs(mrp_attr_t *);
200 static int check_attrindex(lua_State *, int, attr_def_t *);
201 static int check_boolean(lua_State *, int);
202 static mrp_resource_order_t check_order(lua_State *, int);
203 static int push_order(lua_State *, mrp_resource_order_t);
204 static field_t field_check(lua_State *, int, const char **);
205 static field_t field_name_to_type(const char *, size_t);
208 MRP_LUA_METHOD_LIST_TABLE (
209 zone_attr_methods, /* methodlist name */
210 MRP_LUA_METHOD_CONSTRUCTOR (zone_attr_create)
213 MRP_LUA_METHOD_LIST_TABLE (
214 resclass_methods, /* methodlist name */
215 MRP_LUA_METHOD_CONSTRUCTOR (resclass_create_from_lua)
219 MRP_LUA_METHOD_LIST_TABLE (
220 attributes_overrides, /* methodlist name */
221 MRP_LUA_OVERRIDE_GETFIELD (attributes_getvalue)
222 MRP_LUA_OVERRIDE_SETFIELD (attributes_setvalue)
223 MRP_LUA_OVERRIDE_GETLENGTH (attributes_getlength)
226 MRP_LUA_METHOD_LIST_TABLE (
227 zone_attr_overrides, /* methodlist name */
228 MRP_LUA_OVERRIDE_CALL (zone_attr_create)
229 MRP_LUA_OVERRIDE_GETFIELD (zone_attr_getfield)
230 MRP_LUA_OVERRIDE_SETFIELD (zone_attr_setfield)
233 MRP_LUA_METHOD_LIST_TABLE (
234 resclass_overrides, /* methodlist name */
235 MRP_LUA_OVERRIDE_CALL (resclass_create_from_lua)
236 MRP_LUA_OVERRIDE_GETFIELD (resclass_getfield)
237 MRP_LUA_OVERRIDE_SETFIELD (resclass_setfield)
240 MRP_LUA_METHOD_LIST_TABLE (
241 resource_overrides, /* methodlist name */
242 MRP_LUA_OVERRIDE_GETFIELD (resource_getfield)
243 MRP_LUA_OVERRIDE_SETFIELD (resource_setfield)
246 MRP_LUA_CLASS_DEF_SIMPLE (
247 application_class, /* main class & constructor name */
248 appclass_t, /* userdata type */
249 appclass_destroy, /* userdata destructor */
250 MRP_LUA_METHOD_LIST ( /* main class methods */
251 MRP_LUA_METHOD_CONSTRUCTOR (appclass_create)
253 MRP_LUA_METHOD_LIST ( /* main class overrides */
254 MRP_LUA_OVERRIDE_CALL (appclass_create)
255 MRP_LUA_OVERRIDE_GETFIELD (appclass_getfield)
256 MRP_LUA_OVERRIDE_SETFIELD (appclass_setfield)
260 MRP_LUA_CLASS_DEF_SIMPLE (
261 zone, /* main class & constructor name */
262 zone_t, /* userdata type */
263 zone_destroy, /* userdata destructor */
264 MRP_LUA_METHOD_LIST ( /* main class methods */
265 MRP_LUA_METHOD_CONSTRUCTOR (zone_create)
267 MRP_LUA_METHOD_LIST ( /* main class overrides */
268 MRP_LUA_OVERRIDE_CALL (zone_create)
269 MRP_LUA_OVERRIDE_GETFIELD (zone_getfield)
270 MRP_LUA_OVERRIDE_SETFIELD (zone_setfield)
275 zone, /* main class name */
276 attributes, /* constructor name */
277 attr_def_t, /* userdata type */
278 zone_attr_destroy, /* userdata destructor */
279 zone_attr_methods, /* class methods */
280 zone_attr_overrides /* class overrides */
284 resource, /* main class name */
285 class, /* constructor name */
286 resclass_t, /* userdata type */
287 resclass_destroy, /* userdata destructor */
288 resclass_methods, /* class methods */
289 resclass_overrides /* class overrides */
293 MRP_LUA_CLASS_DEF_SIMPLE (
294 resource, /* main class name */
295 mrp_lua_resmethod_t, /* userdata type */
296 resmethod_destroy, /* userdata destructor */
297 MRP_LUA_METHOD_LIST (
298 MRP_LUA_METHOD_CONSTRUCTOR (resmethod_create_from_lua)
300 MRP_LUA_METHOD_LIST (
301 MRP_LUA_OVERRIDE_CALL (resmethod_create_from_lua)
302 MRP_LUA_OVERRIDE_GETFIELD (resmethod_getfield)
303 MRP_LUA_OVERRIDE_SETFIELD (resmethod_setfield)
307 attr_def_t *zone_attr_defs;
308 attr_def_t *resource_attr_defs[MRP_RESOURCE_MAX];
309 mrp_lua_resmethod_t *resource_methods;
312 void mrp_resource_configuration_init(void)
314 static bool initialised = false;
318 if (!initialised && (L = mrp_lua_get_lua_state())) {
320 appclass_class_create(L);
321 zone_class_create(L);
322 resclass_class_create(L);
323 resource_class_create(L);
325 mrp_resource_lua_init(L);
327 resource_methods_create(L);
329 mrp_debug("lua classes are ready for resource "
330 "configuration and management");
337 mrp_lua_resmethod_t *mrp_lua_get_resource_methods(void)
339 return resource_methods;
342 uint32_t mrp_lua_to_resource_id(lua_State *L, int t)
344 resclass_t *rc = to_resclass(L, t);
346 return rc ? rc->id : MRP_RESOURCE_ID_INVALID;
349 void mrp_lua_resclass_create_from_c(uint32_t id)
352 mrp_resource_def_t *rdef;
353 resclass_t *resclass;
355 mrp_attr_def_t *attrs;
358 if ((L = mrp_lua_get_lua_state())) {
360 if (!(rdef = mrp_resource_definition_find_by_id(id)))
361 luaL_error(L, "invalid resource definition ID %d", id);
363 resclass = (resclass_t *)mrp_lua_create_object(L, RESCLASS_CLASS,
365 adef = mrp_allocz(sizeof(attr_def_t));
367 attrs = mrp_allocz(sizeof(mrp_attr_def_t) * (nattr + 1));
370 mrp_attribute_copy_definitions(rdef->attrdefs, attrs);
373 luaL_error(L, "invalid or duplicate name '%s'", rdef->name);
375 luaL_error(L,"can't to allocate memory for attribute definitions");
378 resclass->name = mrp_strdup(rdef->name);
379 resclass->attrs = attrs;
384 resource_attr_defs[id] = adef;
388 mrp_log_info("resource class '%s' created", rdef->name);
392 int mrp_lua_resource_create(lua_State *L, mrp_resource_t *res)
394 mrp_resource_def_t *rdef;
400 MRP_ASSERT(res, "invalid argument");
402 if (!(rdef = res->def))
405 adef = resource_attr_defs[rdef->id];
407 MRP_ASSERT(resource_attr_defs[rdef->id], "can't find attribute defs");
409 r = lua_newuserdata(L, sizeof(resource_t));
411 r->rsetid = res->rsetid;
413 r->name = rdef->name;
414 r->attr_tbl = attributes_create(L, RESOURCE,r, adef,
415 fetch_resource_attribute,
416 update_resource_attribute);
418 luaL_getmetatable(L, RESOURCE_CLASSID);
419 lua_setmetatable(L, -2);
426 static void attributes_class_create(lua_State *L)
428 /* create a metatable for attributes */
429 luaL_newmetatable(L, ATTRIBUTE_CLASSID);
430 lua_pushliteral(L, "__index");
431 lua_pushvalue(L, -2);
432 lua_settable(L, -3); /* metatable.__index = metatable */
433 luaL_openlib(L, NULL, attributes_overrides, 0);
436 static void appclass_class_create(lua_State *L)
438 mrp_lua_create_object_class(L, APPCLASS_CLASS);
441 static void zone_class_create(lua_State *L)
443 mrp_lua_create_object_class(L, ZONE_CLASS);
444 mrp_lua_create_object_class(L, ZONE_ATTR_CLASS);
446 attributes_class_create(L);
448 zone_attr_defs = mrp_lua_create_object(L, ZONE_ATTR_CLASS, NULL,0);
449 mrp_lua_set_object_name(L, ZONE_ATTR_CLASS, "attributes");
453 static void resclass_class_create(lua_State *L)
455 mrp_lua_create_object_class(L, RESCLASS_CLASS);
458 static void resource_class_create(lua_State *L)
460 /* create a metatable for resource instances */
461 luaL_newmetatable(L, RESOURCE_CLASSID);
462 lua_pushliteral(L, "__index");
463 lua_pushvalue(L, -2);
464 lua_settable(L, -3); /* metatable.__index = metatable */
465 luaL_openlib(L, NULL, resource_overrides, 0);
468 static void resource_methods_create(lua_State *L)
470 mrp_lua_create_object_class(L, RESMETHOD_CLASS);
471 resource_methods = resmethod_create_from_c(L);
475 static int attributes_create(lua_State *L,
476 attr_owner_t type, void *data,
478 attribute_access_t fetch,
479 attribute_access_t update)
486 attr = lua_newuserdata(L, sizeof(attr_t));
488 attr->owner.type = type;
489 attr->owner.data = data;
492 attr->update = update;
494 luaL_getmetatable(L, ATTRIBUTE_CLASSID);
495 lua_setmetatable(L, -2);
497 tblref = luaL_ref(L, LUA_REGISTRYINDEX);
499 MRP_LUA_LEAVE(tblref);
502 static int attributes_getvalue(lua_State *L)
504 attr_t *attr = check_attributes(L, 1);
505 int idx = check_attrindex(L, 2, attr->def);
506 mrp_attr_def_t *def = attr->def->attrs + idx;
516 if (!(def->access & MRP_RESOURCE_READ)) {
517 luaL_error(L, "attempt to read a non-readable attribute %s",
522 if (!attr->fetch(attr, idx, &av)) {
530 lua_pushstring(L, av.value.string);
536 lua_pushinteger(L, av.value.integer);
539 lua_pushnumber(L, av.value.floating);
549 static int attributes_setvalue(lua_State *L)
551 attr_t *attr = check_attributes(L, 1);
552 int idx = check_attrindex(L, 2, attr->def);
553 mrp_attr_def_t *def = attr->def->attrs + idx;
559 luaL_error(L, "attribute %s dows not exist", def->name);
561 if (!(def->access & MRP_RESOURCE_WRITE))
562 luaL_error(L, "attempt to read a readonly attribute %s", def->name);
566 av.value.string = luaL_checkstring(L, 3);
569 av.value.integer = luaL_checkinteger(L, 3);
572 if ((av.value.integer = luaL_checkinteger(L, 3)) < 0) {
573 luaL_error(L, "attempt to update an unsigned attribute "
574 "with negative value");
578 av.value.floating = luaL_checknumber(L, 3);
581 luaL_error(L, "internal error: invalid attribute type");
585 if (!attr->update(attr, idx, &av))
586 luaL_error(L, "attribute update failed");
591 static int attributes_getlength(lua_State *L)
593 attr_t *attr = check_attributes(L, 1);
594 attr_def_t *def = attr->def;
598 lua_pushinteger(L, def ? def->nattr : 0);
603 static attr_t *check_attributes(lua_State *L, int idx)
605 return (attr_t *)luaL_checkudata(L, idx, ATTRIBUTE_CLASSID);
608 static int push_attributes(lua_State *L, int attr_tbl)
610 lua_rawgeti(L, LUA_REGISTRYINDEX, attr_tbl);
615 static int appclass_create(lua_State *L)
617 appclass_t *appclass;
623 mrp_resource_order_t order = 0;
624 const char *name = NULL;
628 MRP_LUA_FOREACH_FIELD(L, 2, fldnam, fldnamlen) {
630 switch (field_name_to_type(fldnam, fldnamlen)) {
633 name = mrp_strdup(luaL_checkstring(L, -1));
637 priority = luaL_checkint(L, -1);
641 modal = check_boolean(L, -1);
645 share = check_boolean(L, -1);
649 order = check_order(L, -1);
653 luaL_error(L, "unexpected field '%s'", fldnam);
659 luaL_error(L, "missing or wrong name field");
661 luaL_error(L, "missing or wrong modal field");
663 luaL_error(L, "modal class can't share");
665 luaL_error(L, "missing or wrong share field");
667 luaL_error(L, "missing or wrong order field");
669 luaL_error(L, "negative priority");
670 if (!mrp_application_class_create(name, priority, modal, share, order))
671 luaL_error(L, "failed to create application class '%s'", name);
673 appclass = (appclass_t *)mrp_lua_create_object(L, APPCLASS_CLASS, name,0);
676 luaL_error(L, "invalid or duplicate name '%s'", name);
678 appclass->name = name;
679 mrp_log_info("application class '%s' created", name);
684 static int appclass_getfield(lua_State *L)
686 appclass_t *appclass = to_appclass(L, 1);
687 field_t fld = field_check(L, 2, NULL);
688 mrp_application_class_t *ac;
694 if (!appclass || !(ac = mrp_application_class_find(appclass->name)))
698 case NAME: lua_pushstring(L, ac->name); break;
699 case PRIORITY: lua_pushinteger(L, ac->priority); break;
700 case MODAL: lua_pushboolean(L, ac->modal); break;
701 case SHARE: lua_pushboolean(L, ac->share); break;
702 case ORDER: push_order(L, ac->order); break;
703 default: lua_pushnil(L); break;
710 static int appclass_setfield(lua_State *L)
714 luaL_error(L, "can't modify application classes after definition");
719 static void appclass_destroy(void *data)
721 appclass_t *appclass = (appclass_t *)data;
725 mrp_free((void *)appclass->name);
731 static appclass_t *check_appclass(lua_State *L, int idx)
733 return (appclass_t *)mrp_lua_check_object(L, APPCLASS_CLASS, idx);
737 static appclass_t *to_appclass(lua_State *L, int idx)
739 return (appclass_t *)mrp_lua_to_object(L, APPCLASS_CLASS, idx);
743 static int zone_create(lua_State *L)
749 const char *name = NULL;
750 mrp_attr_t *attrs = NULL;
754 MRP_ASSERT(zone_attr_defs, "invocation prior to initialization");
756 if (!zone_attr_defs->attrs)
757 luaL_error(L, "attempt to create zone before defining attributes");
759 MRP_LUA_FOREACH_FIELD(L, 2, fldnam, fldnamlen) {
761 switch (field_name_to_type(fldnam, fldnamlen)) {
764 name = mrp_strdup(luaL_checkstring(L, -1));
768 attrs = check_attrs(L, -1, zone_attr_defs);
772 luaL_error(L, "unexpected field '%s'", fldnam);
778 luaL_error(L, "missing or wrong name field");
779 if ((id = mrp_zone_create(name,attrs)) == MRP_ZONE_ID_INVALID)
780 luaL_error(L, "failed to create zone");
784 zone = (zone_t *)mrp_lua_create_object(L, ZONE_CLASS, name,0);
787 luaL_error(L, "invalid or duplicate name '%s'", name);
791 zone->attr_tbl = attributes_create(L, ZONE,zone, zone_attr_defs,
792 fetch_zone_attribute,
793 update_zone_attribute);
795 mrp_log_info("zone '%s' created", name);
801 static int zone_getfield(lua_State *L)
803 zone_t *zone = to_zone(L, 1);
804 field_t fld = field_check(L, 2, NULL);
811 /* attempt to access a zone definition field */
813 case ATTRIBUTES: mrp_lua_push_object(L, zone_attr_defs); break;
814 default: lua_pushnil(L); break;
818 /* attempt to access a zone instance field */
820 case ATTRIBUTES: push_attributes(L, zone->attr_tbl); break;
821 case ID: lua_pushinteger(L, zone->id + 1); break;
822 case NAME: lua_pushstring(L, zone->name); break;
823 default: lua_pushnil(L); break;
830 static int zone_setfield(lua_State *L)
832 zone_t *zone = to_zone(L, 1);
833 field_t fld = field_check(L, 2, NULL);
837 if (zone || fld != ATTRIBUTES)
838 luaL_error(L, "zones can't be exetended after definition");
843 static void zone_destroy(void *data)
845 /* zone_t *zone = (zone_t *)data; */
855 static zone_t *check_zone(lua_State *L, int idx)
857 return (zone_t *)mrp_lua_check_object(L, ZONE_CLASS, idx);
861 static zone_t *to_zone(lua_State *L, int idx)
863 return (zone_t *)mrp_lua_to_object(L, ZONE_CLASS, idx);
866 static int zone_attr_create(lua_State *L)
868 mrp_attr_def_t *attrs;
873 MRP_ASSERT(zone_attr_defs, "invocation prior to initialization");
875 if (zone_attr_defs->attrs)
876 luaL_error(L, "zone attributes already defined");
878 attrs = check_attrdefs(L, 2, &nattr);
880 mrp_zone_definition_create(attrs);
882 zone_attr_defs->nattr = nattr;
883 zone_attr_defs->attrs = attrs;
886 mrp_lua_push_object(L, zone_attr_defs);
888 mrp_log_info("zone attributes defined");
893 static int zone_attr_getfield(lua_State *L)
900 MRP_ASSERT(zone_attr_defs, "invocation prior to initialization");
902 if (!(zone = to_zone(L, 1))) {
903 mrp_debug("zone attribute definition => attribute index");
904 if ((idx = check_attrindex(L, 2, zone_attr_defs)) < 0)
907 lua_pushinteger(L, idx);
910 mrp_debug("zone attribute => nil");
917 static int zone_attr_setfield(lua_State *L)
927 static void zone_attr_destroy(void *data)
929 /* attr_def_t *attr = (attr_def_t *)data; */
939 static attr_def_t *check_zone_attr(lua_State *L, int idx)
941 return (attr_def_t *)mrp_lua_check_object(L, ZONE_ATTR_CLASS, idx);
946 static attr_def_t *to_zone_attr(lua_State *L, int idx)
948 return (attr_def_t *)mrp_lua_to_object(L, ZONE_ATTR_CLASS, idx);
952 static bool fetch_zone_attribute(attr_t *attr, int idx, mrp_attr_t *retval)
957 if (attr->owner.type == ZONE && (zone = (zone_t *)attr->owner.data)) {
958 if ((z = mrp_zone_find_by_id(zone->id))) {
959 if (mrp_zone_read_attribute(z, idx, retval))
967 static bool update_zone_attribute(attr_t *attr, int idx, mrp_attr_t *value)
975 if (attr->owner.type == ZONE && (zone = (zone_t *)attr->owner.data)) {
976 if ((z = mrp_zone_find_by_id(zone->id))) {
978 if (mrp_zone_write_attribute(z, idx, value))
987 static int resclass_create_from_lua(lua_State *L)
989 resclass_t *resclass;
994 const char *name = NULL;
995 mrp_attr_def_t *attrs = NULL;
996 bool shareable = false;
997 mrp_resource_mgr_ftbl_t *ftbl = NULL;
998 void *mgrdata = NULL;
1003 MRP_LUA_FOREACH_FIELD(L, 2, fldnam, fldnamlen) {
1005 switch (field_name_to_type(fldnam, fldnamlen)) {
1008 name = mrp_strdup(luaL_checkstring(L, -1));
1012 luaL_argcheck(L, lua_isboolean(L,-1), 2, "attempt to assign "
1013 "non-boolean value to 'shareable' field");
1014 shareable = lua_toboolean(L, -1);
1018 attrs = check_attrdefs(L, -1, &nattr);
1022 luaL_error(L, "unexpected field '%s'", fldnam);
1028 luaL_error(L, "missing or wrong name field");
1030 id = mrp_resource_definition_create(name, shareable, attrs,ftbl,mgrdata);
1032 MRP_ASSERT(id < MRP_RESOURCE_MAX, "resource id is out of range");
1034 if (id == MRP_RESOURCE_ID_INVALID)
1035 luaL_error(L, "failed to register resource class '%s'", name);
1037 resclass = (resclass_t *)mrp_lua_create_object(L, RESCLASS_CLASS, name,0);
1038 adef = mrp_allocz(sizeof(attr_def_t));
1041 luaL_error(L, "invalid or duplicate name '%s'", name);
1043 luaL_error(L, "failed to allocate memory for attribute definitions");
1046 resclass->name = name;
1047 resclass->attrs = attrs;
1049 adef->nattr = nattr;
1050 adef->attrs = attrs;
1052 resource_attr_defs[id] = adef;
1054 mrp_log_info("resource class '%s' created", name);
1059 static int resclass_getfield(lua_State *L)
1061 resclass_t *rc = to_resclass(L, 1);
1062 field_t fld = field_check(L, 2, NULL);
1063 mrp_resource_def_t *rd;
1069 if (!rc || !(rd = mrp_resource_definition_find_by_name(rc->name)))
1073 case NAME: lua_pushstring(L, rd->name); break;
1074 case ID: lua_pushinteger(L, rd->id + 1); break;
1075 case SHAREABLE: lua_pushboolean(L, rd->shareable); break;
1076 default: lua_pushnil(L); break;
1083 static int resclass_setfield(lua_State *L)
1087 luaL_error(L, "can't modify resource classes after definition");
1092 static void resclass_destroy(void *data)
1094 resclass_t *rc = (resclass_t *)data;
1098 mrp_free((void *)rc->name);
1099 free_attrdefs(rc->attrs);
1101 MRP_LUA_LEAVE_NOARG;
1105 static resclass_t *check_resclass(lua_State *L, int idx)
1107 return (resclass_t *)mrp_lua_check_object(L, RESCLASS_CLASS, idx);
1111 static resclass_t *to_resclass(lua_State *L, int idx)
1113 return (resclass_t *)mrp_lua_to_object(L, RESCLASS_CLASS, idx);
1116 static int resource_getfield(lua_State *L)
1119 resource_t *res = check_resource(L, 1);
1120 field_t fld = field_check(L, 2, &name);
1121 mrp_resource_set_t *s;
1123 mrp_resource_mask_t m;
1130 push_attributes(L, res->attr_tbl);
1135 if (!(r = mrp_resource_set_find_resource(res->rsetid, res->name)))
1138 lua_pushboolean(L, r->shared);
1142 if (!(s = mrp_resource_set_find_by_id(res->rsetid)))
1145 m = ((mrp_resource_mask_t)1) << res->resid;
1149 lua_pushboolean(L, s->resource.mask.mandatory & m ? true : false);
1152 lua_pushboolean(L, s->resource.mask.grant & m ? true : false);
1165 static int resource_setfield(lua_State *L)
1174 static resource_t *check_resource(lua_State *L, int idx)
1176 return (resource_t *)luaL_checkudata(L, idx, RESOURCE_CLASSID);
1179 static bool fetch_resource_attribute(attr_t *attr, int idx, mrp_attr_t *retval)
1181 mrp_resource_set_t *rset;
1182 resource_t *resource;
1185 if (attr->owner.type == RESOURCE) {
1186 if ((resource = (resource_t *)attr->owner.data)) {
1187 if ((rset = mrp_resource_set_find_by_id(resource->rsetid))) {
1188 a = mrp_resource_set_read_attribute(rset, resource->name,
1190 return a ? true : false;
1199 static bool update_resource_attribute(attr_t *attr, int idx, mrp_attr_t *value)
1201 mrp_resource_set_t *rset;
1202 resource_t *resource;
1203 mrp_attr_t values[2];
1208 if (attr->owner.type == RESOURCE) {
1209 if ((resource = (resource_t *)attr->owner.data)) {
1210 if ((rset = mrp_resource_set_find_by_id(resource->rsetid))) {
1211 memcpy(values + 0, value, sizeof(mrp_attr_t));
1212 memset(values + 1, 0, sizeof(mrp_attr_t));
1214 sts = mrp_resource_set_write_attributes(rset, resource->name,
1216 return (sts < 0) ? false : true;
1224 static mrp_lua_resmethod_t *resmethod_create_from_c(lua_State *L)
1226 mrp_lua_resmethod_t *method = mrp_lua_create_object(L, RESMETHOD_CLASS,
1230 luaL_error(L, "invalid or duplicate name 'method'");
1235 static int resmethod_create_from_lua(lua_State *L)
1239 luaL_error(L, "singleton object has already been created");
1246 static int resmethod_getfield(lua_State *L)
1249 mrp_lua_resmethod_t *method = to_resmethod(L, 1);
1250 field_t fld = field_check(L, 2, &name);
1257 /* attempt to access a resclass or owners */
1259 case METHOD: mrp_lua_push_object(L, resource_methods); break;
1260 case OWNERS: lua_pushstring(L,name); lua_rawget(L,1); break;
1261 default: lua_pushnil(L); break;
1265 /* attempt to access a method member */
1266 if (!resource_methods)
1271 lua_pushstring(L, name);
1284 static int resmethod_setfield(lua_State *L)
1287 mrp_lua_resmethod_t *method = to_resmethod(L, 1);
1288 field_t fld = field_check(L, 2, &name);
1295 lua_pushstring(L, name);
1296 lua_pushvalue(L, 3);
1297 method->veto = mrp_funcarray_check(L, -1);
1301 luaL_error(L, "invalid method '%s'", name);
1309 static void resmethod_destroy(void *data)
1311 mrp_lua_resmethod_t *method = (mrp_lua_resmethod_t *)data;
1315 method->veto = NULL;
1317 MRP_LUA_LEAVE_NOARG;
1320 static mrp_lua_resmethod_t *to_resmethod(lua_State *L, int idx)
1322 return (mrp_lua_resmethod_t *)mrp_lua_to_object(L, RESMETHOD_CLASS, idx);
1326 static mrp_attr_def_t *check_attrdefs(lua_State *L, int t, int *ret_len)
1328 mrp_attr_def_t attrdefs[128];
1329 mrp_attr_def_t *ad, *end, *dup;
1339 t = (t < 0) ? lua_gettop(L) + t + 1 : t;
1341 luaL_checktype(L, t, LUA_TTABLE);
1343 end = (ad = attrdefs) + (MRP_ARRAY_SIZE(attrdefs) - 1);
1345 MRP_LUA_FOREACH_FIELD(L, t, name, namlen) {
1347 luaL_error(L, "invalid attribute definition");
1349 luaL_error(L, "too many attributes");
1351 ad->name = mrp_strdup(name);
1352 ad->type = mqi_error;
1353 ad->access = MRP_RESOURCE_READ;
1357 luaL_checktype(L, -1, LUA_TTABLE);
1360 for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
1361 if (lua_type(L, -2) != LUA_TNUMBER)
1364 i = lua_tointeger(L, -2);
1368 ad->type = lua_tointeger(L, -1);
1373 if ((string = lua_tostring(L, -1))) {
1374 ad->value.string = mrp_strdup(string);
1379 ad->value.integer = lua_tointeger(L, -1);
1383 ad->value.integer = lua_tointeger(L, -1);
1387 ad->value.floating = lua_tonumber(L, -1);
1395 if (!(access = lua_tostring(L, -1)))
1396 ad->type = mqi_error;
1398 if (!strcasecmp(access, "read"))
1399 ad->access = MRP_RESOURCE_READ;
1400 else if (!strcasecmp(access, "write"))
1401 ad->access = MRP_RESOURCE_WRITE;
1402 else if (!strcasecmp(access, "rw"))
1403 ad->access = MRP_RESOURCE_RW;
1405 ad->type = mqi_error;
1409 ad->type = mqi_error;
1415 (ad->type != mqi_string &&
1416 ad->type != mqi_integer &&
1417 ad->type != mqi_unsignd &&
1418 ad->type != mqi_floating ))
1424 memset(ad, 0, sizeof(mrp_attr_def_t));
1426 len = ad - attrdefs;
1427 size = sizeof(mrp_attr_def_t) * (len+1);
1428 dup = mrp_alloc(size);
1431 luaL_error(L, "failed to allocate %u byte memory", size);
1433 memcpy(dup, attrdefs, size);
1441 luaL_argerror(L, t, "malformed attribute definition");
1446 static void free_attrdefs(mrp_attr_def_t *attrdefs)
1451 for (ad = attrdefs; ad->name; ad++) {
1452 mrp_free((void *)ad->name);
1453 if (ad->type == mqi_string)
1454 mrp_free((void *)ad->value.string);
1460 static int attr_name_to_index(const char *name, attr_def_t *def)
1462 mrp_attr_def_t *attrs = def->attrs;
1465 for (idx = 0; idx < def->nattr; idx++) {
1466 if (!strcmp(name, attrs[idx].name))
1473 static mrp_attr_t *check_attrs(lua_State *L, int t, attr_def_t *defs)
1475 mrp_attr_t attr[128];
1476 mrp_attr_t *at, *end, *dup;
1483 t = (t < 0) ? lua_gettop(L) + t + 1 : t;
1485 luaL_checktype(L, t, LUA_TTABLE);
1487 end = (at = attr) + (MRP_ARRAY_SIZE(attr) - 1);
1489 MRP_LUA_FOREACH_FIELD(L, t, name, namlen) {
1491 luaL_error(L, "invalid attribute definition");
1493 luaL_error(L, "too many attributes");
1494 if ((i = attr_name_to_index(name, defs)) < 0)
1495 luaL_error(L, "attribute %s do not exist", name);
1497 at->name = mrp_strdup(name);
1499 switch ((at->type = defs->attrs[i].type)) {
1501 at->value.string = mrp_strdup(luaL_checkstring(L,-1));
1504 at->value.integer = luaL_checkinteger(L,-1);
1507 if ((at->value.integer = luaL_checkinteger(L,-1)) < 0)
1508 luaL_error(L, "attempt to give negative value to an "
1509 "unsigned integer");
1512 luaL_error(L, "Internal error: invalid type for attribute");
1519 memset(at, 0, sizeof(mrp_attr_t));
1522 size = sizeof(mrp_attr_t) * (len + 1);
1524 dup = mrp_alloc(size);
1525 memcpy(dup, attr, size);
1531 static void free_attrs(mrp_attr_t *attrs)
1536 for (at = attrs; at->name; at++) {
1537 mrp_free((void *)at->name);
1538 if (at->type == mqi_string)
1539 mrp_free((void *)at->value.string);
1546 static int check_attrindex(lua_State *L, int arg, attr_def_t *def)
1551 if (!def || !def->attrs)
1554 switch (lua_type(L, arg)) {
1556 idx = lua_tointeger(L, arg);
1557 return (idx >= 0 && idx < def->nattr) ? idx : -1;
1559 name = lua_tostring(L, arg);
1560 return attr_name_to_index(name, def);
1567 static int check_boolean(lua_State *L, int idx)
1569 if (!lua_isboolean(L, idx))
1570 luaL_argerror(L, idx, "expected boolean");
1571 return lua_toboolean(L, idx) ? 1 : 0;
1574 static mrp_resource_order_t check_order(lua_State *L, int idx)
1576 const char *str = luaL_checkstring(L, idx);
1578 if (!strcasecmp(str, "fifo"))
1579 return MRP_RESOURCE_ORDER_FIFO;
1581 if (!strcasecmp(str, "lifo"))
1582 return MRP_RESOURCE_ORDER_LIFO;
1584 luaL_error(L, "invalid value for order ('fifo' or 'lifo' accepted only)");
1586 return MRP_RESOURCE_ORDER_UNKNOWN;
1589 static int push_order(lua_State *L, mrp_resource_order_t order)
1594 case MRP_RESOURCE_ORDER_FIFO: str = "fifo"; break;
1595 case MRP_RESOURCE_ORDER_LIFO: str = "lifo"; break;
1596 default: str = "<unknown>"; break;
1599 lua_pushstring(L, str);
1605 static field_t field_check(lua_State *L, int idx, const char **ret_fldnam)
1611 if (!(fldnam = lua_tolstring(L, idx, &fldnamlen)))
1614 fldtyp = field_name_to_type(fldnam, fldnamlen);
1617 *ret_fldnam = fldnam;
1623 static field_t field_name_to_type(const char *name, size_t len)
1628 if (!strcmp(name, "id"))
1633 if (!strcmp(name, "name"))
1635 if (!strcmp(name, "veto"))
1640 if (!strcmp(name, "class"))
1642 if (!strcmp(name, "modal"))
1644 if (!strcmp(name, "share"))
1646 if (!strcmp(name, "grant"))
1648 if (!strcmp(name, "order"))
1653 if (!strcmp(name, "method"))
1655 if (!strcmp(name, "owners"))
1657 if (!strcmp(name, "shared"))
1662 if (!strcmp(name, "priority"))
1667 if (!strcmp(name, "mandatory"))
1669 if (!strcmp(name, "shareable"))
1674 if (!strcmp(name, "attributes"))
1688 * indent-tabs-mode: nil