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 "resource-owner.h"
53 #include "attribute.h"
55 #define ZONE_CLASS MRP_LUA_CLASS_SIMPLE(zone)
56 #define APPCLASS_CLASS MRP_LUA_CLASS_SIMPLE(application_class)
57 #define ZONE_ATTR_CLASS MRP_LUA_CLASS(zone, attributes)
58 #define RESCLASS_CLASS MRP_LUA_CLASS(resource, class)
59 #define RESMETHOD_CLASS MRP_LUA_CLASS_SIMPLE(resource)
61 #define ATTRIBUTE_CLASSID MRP_LUA_CLASSID_ROOT "attribute"
62 #define RESOURCE_CLASSID MRP_LUA_CLASSID_ROOT "resource.instance"
64 typedef enum field_e field_t;
65 typedef enum attr_owner_e attr_owner_t;
66 typedef struct appclass_s appclass_t;
67 typedef struct zone_s zone_t;
68 typedef struct resclass_s resclass_t;
69 typedef struct resource_s resource_t;
70 typedef struct attr_def_s attr_def_t;
71 typedef struct attr_s attr_t;
73 typedef bool (*attribute_access_t)(attr_t *, int, mrp_attr_t *);
112 mrp_attr_def_t *attrs;
124 mrp_attr_def_t *attrs;
133 attribute_access_t fetch;
134 attribute_access_t update;
138 static void attributes_class_create(lua_State *);
139 static void appclass_class_create(lua_State *);
140 static void zone_class_create(lua_State *);
141 static void resclass_class_create(lua_State *);
142 static void resource_class_create(lua_State *);
143 static void resource_methods_create(lua_State *);
146 static int attributes_create(lua_State *, attr_owner_t, void *,
147 attr_def_t *, attribute_access_t,
149 static int attributes_getvalue(lua_State *);
150 static int attributes_setvalue(lua_State *);
151 static int attributes_getlength(lua_State *);
152 static attr_t *check_attributes(lua_State *, int);
153 static int push_attributes(lua_State *, int);
155 static int appclass_create(lua_State *);
156 static int appclass_getfield(lua_State *);
157 static int appclass_setfield(lua_State *);
158 static void appclass_destroy(void *);
159 /* static appclass_t *check_appclass(lua_State *, int); */
160 static appclass_t *to_appclass(lua_State *, int);
162 static int zone_create(lua_State *);
163 static int zone_getfield(lua_State *);
164 static int zone_setfield(lua_State *);
165 static void zone_destroy(void *);
166 /* static zone_t *check_zone(lua_State *, int); */
167 static zone_t *to_zone(lua_State *, int);
169 static int zone_attr_create(lua_State *);
170 static int zone_attr_getfield(lua_State *);
171 static int zone_attr_setfield(lua_State *);
172 static void zone_attr_destroy(void *);
173 /* static attr_def_t *check_zone_attr(lua_State *, int); */
174 /* static attr_def_t *to_zone_attr(lua_State *, int); */
175 static bool fetch_zone_attribute(attr_t *, int, mrp_attr_t *);
176 static bool update_zone_attribute(attr_t *, int, mrp_attr_t *);
178 static int resclass_create_from_lua(lua_State *);
179 static int resclass_getfield(lua_State *);
180 static int resclass_setfield(lua_State *);
181 static void resclass_destroy(void *);
182 /* static resclass_t *check_resclass(lua_State *, int); */
183 static resclass_t *to_resclass(lua_State *, int);
185 static int resource_getfield(lua_State *);
186 static int resource_setfield(lua_State *);
187 static resource_t *check_resource(lua_State *, int);
188 static bool fetch_resource_attribute(attr_t *, int, mrp_attr_t *);
189 static bool update_resource_attribute(attr_t *, int, mrp_attr_t *);
191 static mrp_lua_resmethod_t *resmethod_create_from_c(lua_State *);
192 static int resmethod_create_from_lua(lua_State *);
193 static int resmethod_getfield(lua_State *);
194 static int resmethod_setfield(lua_State *);
195 static void resmethod_destroy(void *);
196 static mrp_lua_resmethod_t *to_resmethod(lua_State *, int);
198 static mrp_attr_def_t *check_attrdefs(lua_State *, int, int *);
199 static void free_attrdefs(mrp_attr_def_t *);
200 static mrp_attr_t *check_attrs(lua_State *, int, attr_def_t *);
201 static void free_attrs(mrp_attr_t *);
202 static int check_attrindex(lua_State *, int, attr_def_t *);
203 static int check_boolean(lua_State *, int);
204 static mrp_resource_order_t check_order(lua_State *, int);
205 static int push_order(lua_State *, mrp_resource_order_t);
206 static field_t field_check(lua_State *, int, const char **);
207 static field_t field_name_to_type(const char *, size_t);
209 static int method_recalc(lua_State *);
212 MRP_LUA_METHOD_LIST_TABLE (
213 zone_attr_methods, /* methodlist name */
214 MRP_LUA_METHOD_CONSTRUCTOR (zone_attr_create)
217 MRP_LUA_METHOD_LIST_TABLE (
218 resclass_methods, /* methodlist name */
219 MRP_LUA_METHOD_CONSTRUCTOR (resclass_create_from_lua)
223 MRP_LUA_METHOD_LIST_TABLE (
224 attributes_overrides, /* methodlist name */
225 MRP_LUA_OVERRIDE_GETFIELD (attributes_getvalue)
226 MRP_LUA_OVERRIDE_SETFIELD (attributes_setvalue)
227 MRP_LUA_OVERRIDE_GETLENGTH (attributes_getlength)
230 MRP_LUA_METHOD_LIST_TABLE (
231 zone_attr_overrides, /* methodlist name */
232 MRP_LUA_OVERRIDE_CALL (zone_attr_create)
233 MRP_LUA_OVERRIDE_GETFIELD (zone_attr_getfield)
234 MRP_LUA_OVERRIDE_SETFIELD (zone_attr_setfield)
237 MRP_LUA_METHOD_LIST_TABLE (
238 resclass_overrides, /* methodlist name */
239 MRP_LUA_OVERRIDE_CALL (resclass_create_from_lua)
240 MRP_LUA_OVERRIDE_GETFIELD (resclass_getfield)
241 MRP_LUA_OVERRIDE_SETFIELD (resclass_setfield)
244 MRP_LUA_METHOD_LIST_TABLE (
245 resource_overrides, /* methodlist name */
246 MRP_LUA_OVERRIDE_GETFIELD (resource_getfield)
247 MRP_LUA_OVERRIDE_SETFIELD (resource_setfield)
250 MRP_LUA_CLASS_DEF_SIMPLE (
251 application_class, /* main class & constructor name */
252 appclass_t, /* userdata type */
253 appclass_destroy, /* userdata destructor */
254 MRP_LUA_METHOD_LIST ( /* main class methods */
255 MRP_LUA_METHOD_CONSTRUCTOR (appclass_create)
257 MRP_LUA_METHOD_LIST ( /* main class overrides */
258 MRP_LUA_OVERRIDE_CALL (appclass_create)
259 MRP_LUA_OVERRIDE_GETFIELD (appclass_getfield)
260 MRP_LUA_OVERRIDE_SETFIELD (appclass_setfield)
264 MRP_LUA_CLASS_DEF_SIMPLE (
265 zone, /* main class & constructor name */
266 zone_t, /* userdata type */
267 zone_destroy, /* userdata destructor */
268 MRP_LUA_METHOD_LIST ( /* main class methods */
269 MRP_LUA_METHOD_CONSTRUCTOR (zone_create)
271 MRP_LUA_METHOD_LIST ( /* main class overrides */
272 MRP_LUA_OVERRIDE_CALL (zone_create)
273 MRP_LUA_OVERRIDE_GETFIELD (zone_getfield)
274 MRP_LUA_OVERRIDE_SETFIELD (zone_setfield)
279 zone, /* main class name */
280 attributes, /* constructor name */
281 attr_def_t, /* userdata type */
282 zone_attr_destroy, /* userdata destructor */
283 zone_attr_methods, /* class methods */
284 zone_attr_overrides /* class overrides */
288 resource, /* main class name */
289 class, /* constructor name */
290 resclass_t, /* userdata type */
291 resclass_destroy, /* userdata destructor */
292 resclass_methods, /* class methods */
293 resclass_overrides /* class overrides */
297 MRP_LUA_CLASS_DEF_SIMPLE (
298 resource, /* main class name */
299 mrp_lua_resmethod_t, /* userdata type */
300 resmethod_destroy, /* userdata destructor */
301 MRP_LUA_METHOD_LIST (
302 MRP_LUA_METHOD_CONSTRUCTOR (resmethod_create_from_lua)
304 MRP_LUA_METHOD_LIST (
305 MRP_LUA_OVERRIDE_CALL (resmethod_create_from_lua)
306 MRP_LUA_OVERRIDE_GETFIELD (resmethod_getfield)
307 MRP_LUA_OVERRIDE_SETFIELD (resmethod_setfield)
311 attr_def_t *zone_attr_defs;
312 attr_def_t *resource_attr_defs[MRP_RESOURCE_MAX];
313 mrp_lua_resmethod_t *resource_methods;
316 void mrp_resource_configuration_init(void)
318 static bool initialised = false;
322 if (!initialised && (L = mrp_lua_get_lua_state())) {
324 appclass_class_create(L);
325 zone_class_create(L);
326 resclass_class_create(L);
327 resource_class_create(L);
329 mrp_resource_lua_init(L);
331 resource_methods_create(L);
333 mrp_debug("lua classes are ready for resource "
334 "configuration and management");
341 mrp_lua_resmethod_t *mrp_lua_get_resource_methods(void)
343 return resource_methods;
346 uint32_t mrp_lua_to_resource_id(lua_State *L, int t)
348 resclass_t *rc = to_resclass(L, t);
350 return rc ? rc->id : MRP_RESOURCE_ID_INVALID;
353 void mrp_lua_resclass_create_from_c(uint32_t id)
356 mrp_resource_def_t *rdef;
357 resclass_t *resclass;
359 mrp_attr_def_t *attrs;
362 if ((L = mrp_lua_get_lua_state())) {
364 if (!(rdef = mrp_resource_definition_find_by_id(id)))
365 luaL_error(L, "invalid resource definition ID %d", id);
367 resclass = (resclass_t *)mrp_lua_create_object(L, RESCLASS_CLASS,
369 adef = mrp_allocz(sizeof(attr_def_t));
371 attrs = mrp_allocz(sizeof(mrp_attr_def_t) * (nattr + 1));
374 mrp_attribute_copy_definitions(rdef->attrdefs, attrs);
377 luaL_error(L, "invalid or duplicate name '%s'", rdef->name);
379 luaL_error(L,"can't to allocate memory for attribute definitions");
382 resclass->name = mrp_strdup(rdef->name);
383 resclass->attrs = attrs;
388 resource_attr_defs[id] = adef;
392 mrp_log_info("resource class '%s' created", rdef->name);
396 int mrp_lua_resource_create(lua_State *L, mrp_resource_t *res)
398 mrp_resource_def_t *rdef;
404 MRP_ASSERT(res, "invalid argument");
406 if (!(rdef = res->def))
409 adef = resource_attr_defs[rdef->id];
411 MRP_ASSERT(resource_attr_defs[rdef->id], "can't find attribute defs");
413 r = lua_newuserdata(L, sizeof(resource_t));
415 r->rsetid = res->rsetid;
417 r->name = rdef->name;
418 r->attr_tbl = attributes_create(L, RESOURCE,r, adef,
419 fetch_resource_attribute,
420 update_resource_attribute);
422 luaL_getmetatable(L, RESOURCE_CLASSID);
423 lua_setmetatable(L, -2);
430 static void attributes_class_create(lua_State *L)
432 /* create a metatable for attributes */
433 luaL_newmetatable(L, ATTRIBUTE_CLASSID);
434 lua_pushliteral(L, "__index");
435 lua_pushvalue(L, -2);
436 lua_settable(L, -3); /* metatable.__index = metatable */
437 luaL_openlib(L, NULL, attributes_overrides, 0);
440 static void appclass_class_create(lua_State *L)
442 mrp_lua_create_object_class(L, APPCLASS_CLASS);
445 static void zone_class_create(lua_State *L)
447 mrp_lua_create_object_class(L, ZONE_CLASS);
448 mrp_lua_create_object_class(L, ZONE_ATTR_CLASS);
450 attributes_class_create(L);
452 zone_attr_defs = mrp_lua_create_object(L, ZONE_ATTR_CLASS, NULL,0);
453 mrp_lua_set_object_name(L, ZONE_ATTR_CLASS, "attributes");
457 static void resclass_class_create(lua_State *L)
459 mrp_lua_create_object_class(L, RESCLASS_CLASS);
462 static void resource_class_create(lua_State *L)
464 /* create a metatable for resource instances */
465 luaL_newmetatable(L, RESOURCE_CLASSID);
466 lua_pushliteral(L, "__index");
467 lua_pushvalue(L, -2);
468 lua_settable(L, -3); /* metatable.__index = metatable */
469 luaL_openlib(L, NULL, resource_overrides, 0);
472 static void resource_methods_create(lua_State *L)
479 static method_def_t method_defs[] = {
480 { "recalc", method_recalc },
486 mrp_lua_create_object_class(L, RESMETHOD_CLASS);
487 resource_methods = resmethod_create_from_c(L);
489 for (md = method_defs; md->name; md++) {
490 lua_pushstring(L, md->name);
491 lua_pushcfunction(L, md->func);
497 static int attributes_create(lua_State *L,
498 attr_owner_t type, void *data,
500 attribute_access_t fetch,
501 attribute_access_t update)
508 attr = lua_newuserdata(L, sizeof(attr_t));
510 attr->owner.type = type;
511 attr->owner.data = data;
514 attr->update = update;
516 luaL_getmetatable(L, ATTRIBUTE_CLASSID);
517 lua_setmetatable(L, -2);
519 tblref = luaL_ref(L, LUA_REGISTRYINDEX);
521 MRP_LUA_LEAVE(tblref);
524 static int attributes_getvalue(lua_State *L)
526 attr_t *attr = check_attributes(L, 1);
527 int idx = check_attrindex(L, 2, attr->def);
528 mrp_attr_def_t *def = attr->def->attrs + idx;
538 if (!(def->access & MRP_RESOURCE_READ)) {
539 luaL_error(L, "attempt to read a non-readable attribute %s",
544 if (!attr->fetch(attr, idx, &av)) {
552 lua_pushstring(L, av.value.string);
558 lua_pushinteger(L, av.value.integer);
561 lua_pushnumber(L, av.value.floating);
571 static int attributes_setvalue(lua_State *L)
573 attr_t *attr = check_attributes(L, 1);
574 int idx = check_attrindex(L, 2, attr->def);
575 mrp_attr_def_t *def = attr->def->attrs + idx;
581 luaL_error(L, "attribute %s dows not exist", def->name);
583 if (!(def->access & MRP_RESOURCE_WRITE))
584 luaL_error(L, "attempt to read a readonly attribute %s", def->name);
588 av.value.string = luaL_checkstring(L, 3);
591 av.value.integer = luaL_checkinteger(L, 3);
594 if ((av.value.integer = luaL_checkinteger(L, 3)) < 0) {
595 luaL_error(L, "attempt to update an unsigned attribute "
596 "with negative value");
600 av.value.floating = luaL_checknumber(L, 3);
603 luaL_error(L, "internal error: invalid attribute type");
607 if (!attr->update(attr, idx, &av))
608 luaL_error(L, "attribute update failed");
613 static int attributes_getlength(lua_State *L)
615 attr_t *attr = check_attributes(L, 1);
616 attr_def_t *def = attr->def;
620 lua_pushinteger(L, def ? def->nattr : 0);
625 static attr_t *check_attributes(lua_State *L, int idx)
627 return (attr_t *)luaL_checkudata(L, idx, ATTRIBUTE_CLASSID);
630 static int push_attributes(lua_State *L, int attr_tbl)
632 lua_rawgeti(L, LUA_REGISTRYINDEX, attr_tbl);
637 static int appclass_create(lua_State *L)
639 appclass_t *appclass;
645 mrp_resource_order_t order = 0;
646 const char *name = NULL;
650 MRP_LUA_FOREACH_FIELD(L, 2, fldnam, fldnamlen) {
652 switch (field_name_to_type(fldnam, fldnamlen)) {
655 name = mrp_strdup(luaL_checkstring(L, -1));
659 priority = luaL_checkint(L, -1);
663 modal = check_boolean(L, -1);
667 share = check_boolean(L, -1);
671 order = check_order(L, -1);
675 luaL_error(L, "unexpected field '%s'", fldnam);
681 luaL_error(L, "missing or wrong name field");
683 luaL_error(L, "missing or wrong modal field");
685 luaL_error(L, "modal class can't share");
687 luaL_error(L, "missing or wrong share field");
689 luaL_error(L, "missing or wrong order field");
691 luaL_error(L, "negative priority");
692 if (!mrp_application_class_create(name, priority, modal, share, order))
693 luaL_error(L, "failed to create application class '%s'", name);
695 appclass = (appclass_t *)mrp_lua_create_object(L, APPCLASS_CLASS, name,0);
698 luaL_error(L, "invalid or duplicate name '%s'", name);
700 appclass->name = name;
701 mrp_log_info("application class '%s' created", name);
706 static int appclass_getfield(lua_State *L)
708 appclass_t *appclass = to_appclass(L, 1);
709 field_t fld = field_check(L, 2, NULL);
710 mrp_application_class_t *ac;
716 if (!appclass || !(ac = mrp_application_class_find(appclass->name)))
720 case NAME: lua_pushstring(L, ac->name); break;
721 case PRIORITY: lua_pushinteger(L, ac->priority); break;
722 case MODAL: lua_pushboolean(L, ac->modal); break;
723 case SHARE: lua_pushboolean(L, ac->share); break;
724 case ORDER: push_order(L, ac->order); break;
725 default: lua_pushnil(L); break;
732 static int appclass_setfield(lua_State *L)
736 luaL_error(L, "can't modify application classes after definition");
741 static void appclass_destroy(void *data)
743 appclass_t *appclass = (appclass_t *)data;
747 mrp_free((void *)appclass->name);
753 static appclass_t *check_appclass(lua_State *L, int idx)
755 return (appclass_t *)mrp_lua_check_object(L, APPCLASS_CLASS, idx);
759 static appclass_t *to_appclass(lua_State *L, int idx)
761 return (appclass_t *)mrp_lua_to_object(L, APPCLASS_CLASS, idx);
765 static int zone_create(lua_State *L)
771 const char *name = NULL;
772 mrp_attr_t *attrs = NULL;
776 MRP_ASSERT(zone_attr_defs, "invocation prior to initialization");
778 if (!zone_attr_defs->attrs)
779 luaL_error(L, "attempt to create zone before defining attributes");
781 MRP_LUA_FOREACH_FIELD(L, 2, fldnam, fldnamlen) {
783 switch (field_name_to_type(fldnam, fldnamlen)) {
786 name = mrp_strdup(luaL_checkstring(L, -1));
790 attrs = check_attrs(L, -1, zone_attr_defs);
794 luaL_error(L, "unexpected field '%s'", fldnam);
800 luaL_error(L, "missing or wrong name field");
801 if ((id = mrp_zone_create(name,attrs)) == MRP_ZONE_ID_INVALID)
802 luaL_error(L, "failed to create zone");
806 zone = (zone_t *)mrp_lua_create_object(L, ZONE_CLASS, name,0);
809 luaL_error(L, "invalid or duplicate name '%s'", name);
813 zone->attr_tbl = attributes_create(L, ZONE,zone, zone_attr_defs,
814 fetch_zone_attribute,
815 update_zone_attribute);
817 mrp_log_info("zone '%s' created", name);
823 static int zone_getfield(lua_State *L)
825 zone_t *zone = to_zone(L, 1);
826 field_t fld = field_check(L, 2, NULL);
833 /* attempt to access a zone definition field */
835 case ATTRIBUTES: mrp_lua_push_object(L, zone_attr_defs); break;
836 default: lua_pushnil(L); break;
840 /* attempt to access a zone instance field */
842 case ATTRIBUTES: push_attributes(L, zone->attr_tbl); break;
843 case ID: lua_pushinteger(L, zone->id + 1); break;
844 case NAME: lua_pushstring(L, zone->name); break;
845 default: lua_pushnil(L); break;
852 static int zone_setfield(lua_State *L)
854 zone_t *zone = to_zone(L, 1);
855 field_t fld = field_check(L, 2, NULL);
859 if (zone || fld != ATTRIBUTES)
860 luaL_error(L, "zones can't be exetended after definition");
865 static void zone_destroy(void *data)
867 /* zone_t *zone = (zone_t *)data; */
877 static zone_t *check_zone(lua_State *L, int idx)
879 return (zone_t *)mrp_lua_check_object(L, ZONE_CLASS, idx);
883 static zone_t *to_zone(lua_State *L, int idx)
885 return (zone_t *)mrp_lua_to_object(L, ZONE_CLASS, idx);
888 static int zone_attr_create(lua_State *L)
890 mrp_attr_def_t *attrs;
895 MRP_ASSERT(zone_attr_defs, "invocation prior to initialization");
897 if (zone_attr_defs->attrs)
898 luaL_error(L, "zone attributes already defined");
900 attrs = check_attrdefs(L, 2, &nattr);
902 mrp_zone_definition_create(attrs);
904 zone_attr_defs->nattr = nattr;
905 zone_attr_defs->attrs = attrs;
908 mrp_lua_push_object(L, zone_attr_defs);
910 mrp_log_info("zone attributes defined");
915 static int zone_attr_getfield(lua_State *L)
922 MRP_ASSERT(zone_attr_defs, "invocation prior to initialization");
924 if (!(zone = to_zone(L, 1))) {
925 mrp_debug("zone attribute definition => attribute index");
926 if ((idx = check_attrindex(L, 2, zone_attr_defs)) < 0)
929 lua_pushinteger(L, idx);
932 mrp_debug("zone attribute => nil");
939 static int zone_attr_setfield(lua_State *L)
949 static void zone_attr_destroy(void *data)
951 /* attr_def_t *attr = (attr_def_t *)data; */
961 static attr_def_t *check_zone_attr(lua_State *L, int idx)
963 return (attr_def_t *)mrp_lua_check_object(L, ZONE_ATTR_CLASS, idx);
968 static attr_def_t *to_zone_attr(lua_State *L, int idx)
970 return (attr_def_t *)mrp_lua_to_object(L, ZONE_ATTR_CLASS, idx);
974 static bool fetch_zone_attribute(attr_t *attr, int idx, mrp_attr_t *retval)
979 if (attr->owner.type == ZONE && (zone = (zone_t *)attr->owner.data)) {
980 if ((z = mrp_zone_find_by_id(zone->id))) {
981 if (mrp_zone_read_attribute(z, idx, retval))
989 static bool update_zone_attribute(attr_t *attr, int idx, mrp_attr_t *value)
997 if (attr->owner.type == ZONE && (zone = (zone_t *)attr->owner.data)) {
998 if ((z = mrp_zone_find_by_id(zone->id))) {
1000 if (mrp_zone_write_attribute(z, idx, value))
1009 static int resclass_create_from_lua(lua_State *L)
1011 resclass_t *resclass;
1016 const char *name = NULL;
1017 mrp_attr_def_t *attrs = NULL;
1018 bool shareable = false;
1019 mrp_resource_mgr_ftbl_t *ftbl = NULL;
1020 void *mgrdata = NULL;
1025 MRP_LUA_FOREACH_FIELD(L, 2, fldnam, fldnamlen) {
1027 switch (field_name_to_type(fldnam, fldnamlen)) {
1030 name = mrp_strdup(luaL_checkstring(L, -1));
1034 luaL_argcheck(L, lua_isboolean(L,-1), 2, "attempt to assign "
1035 "non-boolean value to 'shareable' field");
1036 shareable = lua_toboolean(L, -1);
1040 attrs = check_attrdefs(L, -1, &nattr);
1044 luaL_error(L, "unexpected field '%s'", fldnam);
1050 luaL_error(L, "missing or wrong name field");
1052 id = mrp_resource_definition_create(name, shareable, attrs,ftbl,mgrdata);
1054 MRP_ASSERT(id < MRP_RESOURCE_MAX, "resource id is out of range");
1056 if (id == MRP_RESOURCE_ID_INVALID)
1057 luaL_error(L, "failed to register resource class '%s'", name);
1059 resclass = (resclass_t *)mrp_lua_create_object(L, RESCLASS_CLASS, name,0);
1060 adef = mrp_allocz(sizeof(attr_def_t));
1063 luaL_error(L, "invalid or duplicate name '%s'", name);
1065 luaL_error(L, "failed to allocate memory for attribute definitions");
1068 resclass->name = name;
1069 resclass->attrs = attrs;
1071 adef->nattr = nattr;
1072 adef->attrs = attrs;
1074 resource_attr_defs[id] = adef;
1076 mrp_log_info("resource class '%s' created", name);
1081 static int resclass_getfield(lua_State *L)
1083 resclass_t *rc = to_resclass(L, 1);
1084 field_t fld = field_check(L, 2, NULL);
1085 mrp_resource_def_t *rd;
1091 if (!rc || !(rd = mrp_resource_definition_find_by_name(rc->name)))
1095 case NAME: lua_pushstring(L, rd->name); break;
1096 case ID: lua_pushinteger(L, rd->id + 1); break;
1097 case SHAREABLE: lua_pushboolean(L, rd->shareable); break;
1098 default: lua_pushnil(L); break;
1105 static int resclass_setfield(lua_State *L)
1109 luaL_error(L, "can't modify resource classes after definition");
1114 static void resclass_destroy(void *data)
1116 resclass_t *rc = (resclass_t *)data;
1120 mrp_free((void *)rc->name);
1121 free_attrdefs(rc->attrs);
1123 MRP_LUA_LEAVE_NOARG;
1127 static resclass_t *check_resclass(lua_State *L, int idx)
1129 return (resclass_t *)mrp_lua_check_object(L, RESCLASS_CLASS, idx);
1133 static resclass_t *to_resclass(lua_State *L, int idx)
1135 return (resclass_t *)mrp_lua_to_object(L, RESCLASS_CLASS, idx);
1138 static int resource_getfield(lua_State *L)
1141 resource_t *res = check_resource(L, 1);
1142 field_t fld = field_check(L, 2, &name);
1143 mrp_resource_set_t *s;
1145 mrp_resource_mask_t m;
1152 push_attributes(L, res->attr_tbl);
1157 if (!(r = mrp_resource_set_find_resource(res->rsetid, res->name)))
1160 lua_pushboolean(L, r->shared);
1164 if (!(s = mrp_resource_set_find_by_id(res->rsetid)))
1167 m = ((mrp_resource_mask_t)1) << res->resid;
1171 lua_pushboolean(L, s->resource.mask.mandatory & m ? true : false);
1174 lua_pushboolean(L, s->resource.mask.grant & m ? true : false);
1187 static int resource_setfield(lua_State *L)
1196 static resource_t *check_resource(lua_State *L, int idx)
1198 return (resource_t *)luaL_checkudata(L, idx, RESOURCE_CLASSID);
1201 static bool fetch_resource_attribute(attr_t *attr, int idx, mrp_attr_t *retval)
1203 mrp_resource_set_t *rset;
1204 resource_t *resource;
1207 if (attr->owner.type == RESOURCE) {
1208 if ((resource = (resource_t *)attr->owner.data)) {
1209 if ((rset = mrp_resource_set_find_by_id(resource->rsetid))) {
1210 a = mrp_resource_set_read_attribute(rset, resource->name,
1212 return a ? true : false;
1221 static bool update_resource_attribute(attr_t *attr, int idx, mrp_attr_t *value)
1223 mrp_resource_set_t *rset;
1224 resource_t *resource;
1225 mrp_attr_t values[2];
1230 if (attr->owner.type == RESOURCE) {
1231 if ((resource = (resource_t *)attr->owner.data)) {
1232 if ((rset = mrp_resource_set_find_by_id(resource->rsetid))) {
1233 memcpy(values + 0, value, sizeof(mrp_attr_t));
1234 memset(values + 1, 0, sizeof(mrp_attr_t));
1236 sts = mrp_resource_set_write_attributes(rset, resource->name,
1238 return (sts < 0) ? false : true;
1246 static mrp_lua_resmethod_t *resmethod_create_from_c(lua_State *L)
1248 mrp_lua_resmethod_t *method = mrp_lua_create_object(L, RESMETHOD_CLASS,
1252 luaL_error(L, "invalid or duplicate name 'method'");
1257 static int resmethod_create_from_lua(lua_State *L)
1261 luaL_error(L, "singleton object has already been created");
1268 static int resmethod_getfield(lua_State *L)
1271 mrp_lua_resmethod_t *method = to_resmethod(L, 1);
1272 field_t fld = field_check(L, 2, &name);
1279 /* attempt to access a resclass or owners */
1281 case METHOD: mrp_lua_push_object(L, resource_methods); break;
1282 case OWNERS: lua_pushstring(L,name); lua_rawget(L,1); break;
1283 default: lua_pushnil(L); break;
1287 /* attempt to access a method member */
1288 if (!resource_methods)
1294 lua_pushstring(L, name);
1307 static int resmethod_setfield(lua_State *L)
1310 mrp_lua_resmethod_t *method = to_resmethod(L, 1);
1311 field_t fld = field_check(L, 2, &name);
1318 lua_pushstring(L, name);
1319 lua_pushvalue(L, 3);
1320 method->veto = mrp_funcarray_check(L, -1);
1324 luaL_error(L, "invalid method '%s'", name);
1332 static void resmethod_destroy(void *data)
1334 mrp_lua_resmethod_t *method = (mrp_lua_resmethod_t *)data;
1338 method->veto = NULL;
1340 MRP_LUA_LEAVE_NOARG;
1343 static mrp_lua_resmethod_t *to_resmethod(lua_State *L, int idx)
1345 return (mrp_lua_resmethod_t *)mrp_lua_to_object(L, RESMETHOD_CLASS, idx);
1349 static mrp_attr_def_t *check_attrdefs(lua_State *L, int t, int *ret_len)
1351 mrp_attr_def_t attrdefs[128];
1352 mrp_attr_def_t *ad, *end, *dup;
1362 t = (t < 0) ? lua_gettop(L) + t + 1 : t;
1364 luaL_checktype(L, t, LUA_TTABLE);
1366 end = (ad = attrdefs) + (MRP_ARRAY_SIZE(attrdefs) - 1);
1368 MRP_LUA_FOREACH_FIELD(L, t, name, namlen) {
1370 luaL_error(L, "invalid attribute definition");
1372 luaL_error(L, "too many attributes");
1374 ad->name = mrp_strdup(name);
1375 ad->type = mqi_error;
1376 ad->access = MRP_RESOURCE_READ;
1380 luaL_checktype(L, -1, LUA_TTABLE);
1383 for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
1384 if (lua_type(L, -2) != LUA_TNUMBER)
1387 i = lua_tointeger(L, -2);
1391 ad->type = lua_tointeger(L, -1);
1396 if ((string = lua_tostring(L, -1))) {
1397 ad->value.string = mrp_strdup(string);
1402 ad->value.integer = lua_tointeger(L, -1);
1406 ad->value.integer = lua_tointeger(L, -1);
1410 ad->value.floating = lua_tonumber(L, -1);
1418 if (!(access = lua_tostring(L, -1)))
1419 ad->type = mqi_error;
1421 if (!strcasecmp(access, "read"))
1422 ad->access = MRP_RESOURCE_READ;
1423 else if (!strcasecmp(access, "write"))
1424 ad->access = MRP_RESOURCE_WRITE;
1425 else if (!strcasecmp(access, "rw"))
1426 ad->access = MRP_RESOURCE_RW;
1428 ad->type = mqi_error;
1432 ad->type = mqi_error;
1438 (ad->type != mqi_string &&
1439 ad->type != mqi_integer &&
1440 ad->type != mqi_unsignd &&
1441 ad->type != mqi_floating ))
1447 memset(ad, 0, sizeof(mrp_attr_def_t));
1449 len = ad - attrdefs;
1450 size = sizeof(mrp_attr_def_t) * (len+1);
1451 dup = mrp_alloc(size);
1454 luaL_error(L, "failed to allocate %u byte memory", size);
1456 memcpy(dup, attrdefs, size);
1464 luaL_argerror(L, t, "malformed attribute definition");
1469 static void free_attrdefs(mrp_attr_def_t *attrdefs)
1474 for (ad = attrdefs; ad->name; ad++) {
1475 mrp_free((void *)ad->name);
1476 if (ad->type == mqi_string)
1477 mrp_free((void *)ad->value.string);
1483 static int attr_name_to_index(const char *name, attr_def_t *def)
1485 mrp_attr_def_t *attrs = def->attrs;
1488 for (idx = 0; idx < def->nattr; idx++) {
1489 if (!strcmp(name, attrs[idx].name))
1496 static mrp_attr_t *check_attrs(lua_State *L, int t, attr_def_t *defs)
1498 mrp_attr_t attr[128];
1499 mrp_attr_t *at, *end, *dup;
1506 t = (t < 0) ? lua_gettop(L) + t + 1 : t;
1508 luaL_checktype(L, t, LUA_TTABLE);
1510 end = (at = attr) + (MRP_ARRAY_SIZE(attr) - 1);
1512 MRP_LUA_FOREACH_FIELD(L, t, name, namlen) {
1514 luaL_error(L, "invalid attribute definition");
1516 luaL_error(L, "too many attributes");
1517 if ((i = attr_name_to_index(name, defs)) < 0)
1518 luaL_error(L, "attribute %s do not exist", name);
1520 at->name = mrp_strdup(name);
1522 switch ((at->type = defs->attrs[i].type)) {
1524 at->value.string = mrp_strdup(luaL_checkstring(L,-1));
1527 at->value.integer = luaL_checkinteger(L,-1);
1530 if ((at->value.integer = luaL_checkinteger(L,-1)) < 0)
1531 luaL_error(L, "attempt to give negative value to an "
1532 "unsigned integer");
1535 luaL_error(L, "Internal error: invalid type for attribute");
1542 memset(at, 0, sizeof(mrp_attr_t));
1545 size = sizeof(mrp_attr_t) * (len + 1);
1547 dup = mrp_alloc(size);
1548 memcpy(dup, attr, size);
1554 static void free_attrs(mrp_attr_t *attrs)
1559 for (at = attrs; at->name; at++) {
1560 mrp_free((void *)at->name);
1561 if (at->type == mqi_string)
1562 mrp_free((void *)at->value.string);
1569 static int check_attrindex(lua_State *L, int arg, attr_def_t *def)
1574 if (!def || !def->attrs)
1577 switch (lua_type(L, arg)) {
1579 idx = lua_tointeger(L, arg);
1580 return (idx >= 0 && idx < def->nattr) ? idx : -1;
1582 name = lua_tostring(L, arg);
1583 return attr_name_to_index(name, def);
1590 static int check_boolean(lua_State *L, int idx)
1592 if (!lua_isboolean(L, idx))
1593 luaL_argerror(L, idx, "expected boolean");
1594 return lua_toboolean(L, idx) ? 1 : 0;
1597 static mrp_resource_order_t check_order(lua_State *L, int idx)
1599 const char *str = luaL_checkstring(L, idx);
1601 if (!strcasecmp(str, "fifo"))
1602 return MRP_RESOURCE_ORDER_FIFO;
1604 if (!strcasecmp(str, "lifo"))
1605 return MRP_RESOURCE_ORDER_LIFO;
1607 luaL_error(L, "invalid value for order ('fifo' or 'lifo' accepted only)");
1609 return MRP_RESOURCE_ORDER_UNKNOWN;
1612 static int push_order(lua_State *L, mrp_resource_order_t order)
1617 case MRP_RESOURCE_ORDER_FIFO: str = "fifo"; break;
1618 case MRP_RESOURCE_ORDER_LIFO: str = "lifo"; break;
1619 default: str = "<unknown>"; break;
1622 lua_pushstring(L, str);
1628 static field_t field_check(lua_State *L, int idx, const char **ret_fldnam)
1634 if (!(fldnam = lua_tolstring(L, idx, &fldnamlen)))
1637 fldtyp = field_name_to_type(fldnam, fldnamlen);
1640 *ret_fldnam = fldnam;
1646 static field_t field_name_to_type(const char *name, size_t len)
1651 if (!strcmp(name, "id"))
1656 if (!strcmp(name, "name"))
1658 if (!strcmp(name, "veto"))
1663 if (!strcmp(name, "class"))
1665 if (!strcmp(name, "modal"))
1667 if (!strcmp(name, "share"))
1669 if (!strcmp(name, "grant"))
1671 if (!strcmp(name, "order"))
1676 if (!strcmp(name, "method"))
1678 if (!strcmp(name, "owners"))
1680 if (!strcmp(name, "shared"))
1682 if (!strcmp(name, "recalc"))
1687 if (!strcmp(name, "priority"))
1692 if (!strcmp(name, "mandatory"))
1694 if (!strcmp(name, "shareable"))
1699 if (!strcmp(name, "attributes"))
1710 static int method_recalc(lua_State *L)
1712 const char *zone_name;
1715 if (lua_type(L, 1) == LUA_TSTRING && (zone_name = lua_tostring(L, 1))) {
1717 if (!(zone = mrp_zone_find_by_name(zone_name))) {
1718 luaL_error(L, "can't recalculate resources in zone '%s': "
1719 "no such zone", zone_name);
1722 mrp_resource_owner_update_zone(zone->id, NULL, 0);
1731 * indent-tabs-mode: nil