#%TITLE% XML_obj.mac
#%NAME%
# Some macros to handle spechardware objects manipulations
#%DESCRIPTION%
# To do
#
#%UU% (id)
#%MDESC%Creates a spechw object: Creates an associative array to store
#data, identified by <id>.
#If object was existing, overwrites it.
#%BR%returns 0 .
def c_newObj(id)'{
local myobj mywhat
myobj = sprintf("_OBJ_%s",id)
unglobal @myobj
global @myobj[]
return(0)
}'
#%UU% (id)
#%MDESC%Creates a spechw object if was not already existing.
#If object was existing, uses it.
#%BR%returns 0 .
def c_getObj(id)'{
local myobj mywhat
if (c_isObj(id) == 0) {
myobj = sprintf("_OBJ_%s",id)
unglobal @myobj
global @myobj[]
}
return(0)
}'
#%UU% (id)
#%MDESC%Kill spec hw object 'id'.
#%BR%returns 0 if OK
#%BR%returns -1 if NOT OK
def c_delObj(id)'{
local myobj
if (c_isObj(id) == 1) {
myobj = sprintf("_OBJ_%s",id)
xml_debug "removing " \'"myobj"\'
unglobal @myobj
return(0)
}
else {
return(-1)
}
}'
#%UU% (id)
#%MDESC%Check if 'id' is a valid spechw object
#%BR%returns 1 if is a spechw object
#%BR%returns 0 if not
def c_isObj(id)'{
local myobj mywhat
myobj = sprintf("_OBJ_%s",id)
mywhat = whatis(myobj)
if ( (mywhat & 0x5000004) == 0x5000004) {
return(1)
}
else {
# p id " is not a spechw object"
return(0)
}
}'
#%UU% (id)
#%MDESC%returns a string being the name of the associative array
#for the spechw object 'id'.
#%BR%returns this string name if OK
#%BR%returns "__error__" if NOT OK
def c_getObjName(id)' {
local myobj
if (c_isObj(id) ==1) {
myobj = sprintf("_OBJ_%s",id)
return(myobj)
}
else {
return("__error__")
}
}'
#%UU%(id,key,value)
#%MDESC% Sets the key,value of a spechw object 'id'
#%BR%returns 0 if OK
#%BR%returns -1 if OK
def c_setObjProp(id,key,value)'{
local myobj
if(c_isObj(id) == 1) {
myobj = sprintf("_OBJ_%s",id)
@myobj["local"][key] = value
return(0)
}
else {
return(-1)
}
}'
#%UU%(id,key)
#%MDESC% returns the key value of a spechw object
#%BR%returns "__error__" if not OK
def c_getObjProp(id,key)'{
local myobj myvalue
if (c_isObj(id) == 1) {
myobj = sprintf("_OBJ_%s",id)
if ( (key in @myobj["local"]) == 1 ) {
myvalue = @myobj["local"][key]
return(myvalue)
}
else {
return("__error__")
}
}
else {
return("__error__")
}
}'
#%UU%(id,key)
#%MDESC% delete a key of a spechw object
#%BR%returns 0 if OK
#%BR%returns "__error__" if not OK
def c_delObjProp(id,key)'{
local myobj myvalue
if (c_isObj(id) == 1) {
myobj = sprintf("_OBJ_%s",id)
delete @myobj["local"][key]
return(myvalue)
}
else {
return("__error__")
}
}'
#%UU%(id)
#%MDESC% Dumps the spechw object (only local keys)
#%BR%returns 0 if OK
#%BR%returns -1 if NOT OK
def c_showObj(id)'{
local myobj ii
if (c_isObj(id) == 1) {
myobj = sprintf("_OBJ_%s",id)
for (ii in @myobj["local"]) {
p ii " : " @myobj["local"][ii]
}
return(0)
}
else {
return(-1)
}
}'
#%UU%(id)
#%MDESC% Dumps the complete spechw object
#%BR%returns 0 if OK
#%BR%returns -1 if NOT OK
def c_dumpObj(id)'{
local myobj myvalue
if (c_isObj(id) == 1) {
myobj = sprintf("_OBJ_%s",id)
p @myobj
return(0)
}
else {
return(-1)
}
}'
#%UU%(id,key)
#%MDESC% Checks if this is a key for that spechw object.
#%BR%returns 1 if found
#%BR%returns 0 if not found
def c_hasObjProp(id,key)'{
local myobj ii found
if (c_isObj(id) == 1) {
myobj = sprintf("_OBJ_%s",id)
if ( (key in @myobj["local"]) == 1) {
return(1)
}
else {
return(0)
}
}
else {
return(0)
}
}'
#%UU%(id,value)
#%MDESC% In spechw object 'id', finds the 'first' key
#which value is 'value'.
#%BR%returns this key if found
#%BR%returns __error__ if not found
def c_getObjKey(id,value)'{
local myobj ii
if (c_isObj(id) == 1) {
myobj = sprintf("_OBJ_%s",id)
for (ii in @myobj["local"]) {
if (@myobj["local"][ii] == value) {
return(ii)
}
}
return("__error__")
}
else {
return("__error__")
}
}'
#%UU% (id)
#%MDESC% For a spechw object, returns the number of xxx["local][]
#elements.
#%BR%returns -1 in case of error
def c_countObjProp(id)'{
local ii ind myarray
if (c_isObj(id) == 1) {
myarray = c_getObjName(id)
ind = 0
for (ii in @myarray["local"] ){
ind++
}
return(ind)
}
else {
return(-1)
}
}'
#%UU%(id,hwr_obj)
#%MDESC% For a spechw object 'id', it will realize
#%BR% - extraction of all the 'hwrid' values associated to the 'role'
#properties.
#%BR% - each 'hwrid' value is assumed to be a xml path to the description
#of a hardware motor.
#%BR% - extracts from each 'hwrid' value, the associated motor name by
#reading the 'specname' property.
#%BR% - for each, register as ' real' (which checks motor present in the spec
#configuration.
#%BR% - for each, finally, if motor present, creates a property 'role' with
#value being this motor name.
#%BR%returns 0 if OK
#%BR%returns -1 if NOT OK
def c_loadMotorsByRole(id,hwr_obj)'{
local myobj mybloc myval ret mymotname _tmp_role ii anerror arr nb
myobj = sprintf("_OBJ_%s",id)
mybloc = sprintf("_XML_tmp_blocrole_%s",id)
anerror = 0
if (c_isObj(id) == 1) {
# extract to cache
myval = c_blocExtractByRole(id,hwr_obj)
if (myval == -1) {
p "c_loadMotorsByRole : equipment: " id " : error extracting roles "
return (-1)
}
# get list of keys
_tmp_role = asso_keys(@mybloc)
for (ii in _tmp_role) {
myval = @mybloc[ii]["hwrid"]
# we guess motor mne in /motors/toto string
# nb = split(myval,arr,"/")
# mymotname = arr[nb-1]
# now get the motor name itself
mymotname = c_extractByProp(id,myval,"specname",0)
if (mymotname != "__error__") {
# Check this is a valid motor name
if (motor_num(mymotname) <0) {
p "c_loadMotorsByRole: " id " motor " mymotname " is not in the config"
anerror++
}
c_setObjProp(id,ii,mymotname)
}
}
# delete for the moment, the tmp array
# p "Deleting " mybloc
unglobal @mybloc
if (anerror == 0) {
return(0)
}
else {
return(-1)
}
}
else {
return(-1)
}
}'
#%IU%(id,hwr_obj)
#%MDESC% For a spechw object 'id', extract the information by role, from
#a hardware object (hwr_obj). It creates an associative array with all
#this information, for futher use by c_extractByRole macro.
#%BR%ACCESS TO XML file
#%BR%returns 0 if OK
#%BR%returns -1 if NOT OK
def c_blocExtractByRole(id,hwr_obj)'{
local myobj myhrw_obj ii mybloc ret
# p "c_BlocExtractByRole: " id " " hwr_obj
myobj = sprintf("_OBJ_%s",id)
mybloc = sprintf("_XML_tmp_blocrole_%s",id)
unglobal @mybloc
global @mybloc
ret = xml_readRoles(hwr_obj)
if (ret == 0) {
for (ii in XML_tmp) @mybloc[ii] = XML_tmp[ii]
@myobj["_xmlrole"]["obj"]= hwr_obj
@myobj["_xmlrolearray"]["obj"]= mybloc
return(0)
}
else {
return(-1)
}
}'
#%IU%(id,hwr_obj,role,att,flagw)
#%MDESC% For an spechw object 'id', extracts from a hardware object (hwr_obj),
#the 'att' value associated to role 'role'.
#%BR%This macro executes a c_blocExtractByRole if not already done.
#%BR% - if flagw is set to 1, it means that we should be able to write
#back to the xml file. for that: sets to the spechw object the useful
#info (xml path ..) and in particular,creates a local key 'role'
#with the value being the value of hardware attribute 'att'.
#%BR%returns the 'att' value if OK
#%BR%returns the string __error__ if NOT OK
def c_extractByRole(id,hwr_obj,role,att,flagw)'{
local myobj myhrw_obj mybloc mystr myval
# p "c_extractByRole: " id " " role " " att
myobj = sprintf("_OBJ_%s",id)
mybloc = sprintf("_XML_tmp_blocrole_%s",id)
if (c_isObj(id) == 1) {
# Check if a c_blocExtractByRole has been called
if (@myobj["_xmlrole"]["obj"] != hwr_obj) {
# c_blocExtractByRole has not been called yet
ret = c_blocExtractByRole(id,hwr_obj)
if (ret != 0) {
return("__error__")
}
}
# Check that the key exists for associated array
if ( att in @mybloc[role]) {
myval = @mybloc[role][att]
if (flagw == 1) {
mystr = sprintf("%s:%s/@%s",@myobj["_xmlrole"]["obj"],\
@mybloc[role]["__path__"], att)
@myobj["_xmlpath"][role] = mystr
@myobj["local"][role] = myval
}
return(myval)
}
else {
p "c_extractByRole: " mybloc " array has no key[" role "][" att "]"
return("__error__")
}
}
else {
return("__error__")
}
}'
#%UU%(id,hwr_obj)
#%MDESC% For a spechw object 'id', it will extract from the hardware object
#(hwr_obj)all the property/values that it will store in the object,
#plus the information to be able to write them back to the xml file
#%BR%returns 0 if OK
#%BR%returns -1 if NOT OK
def c_loadByProp(id,hwr_obj)'{
local myobj mybloc myval ret mymotname _tmp_role ii mystr
myobj = sprintf("_OBJ_%s",id)
mybloc = sprintf("_XML_tmp_blocprop_%s",id)
if (c_isObj(id) == 1) {
# extract to cache
myval = c_blocExtractByProp(id,hwr_obj)
if (myval == -1) {
p "c_loadByProp: equipment: " id " : error extracting properties "
return (-1)
}
# get list of keys
_tmp_role = asso_keys(@mybloc)
for (ii in _tmp_role) {
myval = @mybloc[ii]["__value__"]
c_setObjProp(id,ii,myval)
mystr = sprintf("%s:%s", hwr_obj,\
@mybloc[ii]["__path__"])
@myobj["_xmlpath"][ii] = mystr
}
# delete for the moment, the tmp array
# p "Deleting " mybloc
unglobal @mybloc
return(0)
}
else {
return(-1)
}
}'
#%IU%(id,hwr_obj)
#%MDESC% For a spechw object 'id', extract the information by property,
#from a hardware object (hwr_obj), at first level.
#It creates an associative array with all
#this information, for futher use by c_ExtractByProp macro.
#%BR%ACCESS TO XML file
#%BR%returns 0 if OK
#%BR%returns -1 if NOT OK
def c_blocExtractByProp(id,hwr_obj)'{
local myobj myhrw_obj ii mybloc ret
# p "c_blocExtractByProp: " id " " hwr_obj
myobj = sprintf("_OBJ_%s",id)
mybloc = sprintf("_XML_tmp_blocprop_%s",id)
unglobal @mybloc
global @mybloc
ret = xml_readProperties(hwr_obj)
if (ret == 0) {
# @mybloc = XML_tmp does not work
for (ii in XML_tmp) @mybloc[ii] = XML_tmp[ii]
@myobj["_xmlprop"]["obj"]= hwr_obj
@myobj["_xmlproparray"]["obj"]= mybloc
return(0)
}
else {
return(-1)
}
}'
#%IU%(id,hwr_obj,prop,flagw)
#%MDESC% For an spechw object 'id', extracts from a hardware object (hwr_obj),
#the value of property 'prop.
#%BR%This macro executes a c_blocExtractByProp if not already done.
#%BR% - if flagw is set to 1, it means that we should be able to write
#back to the xml file. for that: sets to the spechw object the useful
#info (xml path ..) and in particular,creates a local key 'prop'
#with this value.
#%BR%returns the 'prop' value if OK
#%BR%returns the string __error__ if NOT OK
def c_extractByProp(id,hwr_obj,prop,flagw)'{
local myobj myhrw_obj mybloc mystr myval
# p "c_ExtractByProp: " id " " prop
myobj = sprintf("_OBJ_%s",id)
mybloc = sprintf("_XML_tmp_blocprop_%s",id)
if (c_isObj(id) == 1) {
# Check that a c_blocExtractByprop has been called
if (@myobj["_xmlprop"]["obj"] != hwr_obj) {
# c_blocExtractByProp has not been called yet
ret = c_blocExtractByProp(id,hwr_obj)
if (ret != 0) {
return("__error__")
}
}
# Check that the key exists for associated array
if ( "__value__" in @mybloc[prop]) {
myval = @mybloc[prop]["__value__"]
if (flagw == 1) {
mystr = sprintf("%s:%s/%s", @myobj["_xmlprop"]["obj"],\
@mybloc[prop]["__path__"],prop)
@myobj["_xmlpath"][prop] = mystr
@myobj["local"][prop] = myval
}
return(myval)
}
else {
p "c_extractByProp: " mybloc " array has no key[" prop "][__value__]"
return("__error__")
}
}
else {
return("__error__")
}
}'
#%UU%(id,motorname,type,name)
#%MDESC% registers this motor in spechw object 'id' property list
#'allrealmotor' (if type 'real')
#or 'allmacromotor' (if type 'macro'). If type 'macro', checks that
#the motor in the config is a macromotor of type 'name'
#%BR%If the motor is not in the config, does not include it in the
#corresponding list, and returns -1
#%BR% - returns 0 if OK
#%BR% - returns -1 if NOT in the config
#%BR% - returns -2 if NOT macromotor of type 'name'
#%BR% - returns -3 if 'id' is not an object or 'type' undefined
def c_registerMotor(id,motname,type,name)'{
local mystr cont contname
# Refuse, if motor is not in the config
if (motor_num(motname) <0) {
return(-1)
}
myobj = c_getObjName(id)
if (myobj != "__error__") {
if (type == "real") {
if (c_hasObjProp(id,"allrealmotor") == 1) {
mystr = concatstring(motname, @myobj["local"]["allrealmotor"])
}
else {
mystr = motname
}
@myobj["local"]["allrealmotor"] = mystr
return(0)
}
else if (type == "macro") {
if (c_hasObjProp(id,"allmacromotor") == 1) {
mystr = concatstring(motname, @myobj["local"]["allmacromotor"])
}
else {
mystr = motname
}
@myobj["local"]["allmacromotor"] = mystr
cont = motor_par(motor_num(motname),"controller")
contname = motor_par(motor_num(motname),"device_id")
if (cont != "PSE_MAC_MOT" || contname != name) {
return(-2)
}
return(0)
}
else {
# list unknown
return(-3)
}
}
else {
}
}'
#%UU%(id,motorname,type)
#%MDESC% checks if the motor was registered as 'type'
#%BR% - returns 1 if YES
#%BR% - returns 0 if NO
def c_hasMotor(id,motorname,type)'{
local mystr
myobj = c_getObjName(id)
if (myobj != "__error__") {
if (type == "real") {
if (c_hasObjProp(id,"allrealmotor") == 1) {
if ( isonstring(motorname,c_getObjProp(id,"allrealmotor")) == 1) {
return(1)
}
}
}
else if (type == "macro") {
if (c_hasObjProp(id,"allmacromotor") == 1) {
if ( isonstring(motorname,c_getObjProp(id,"allmacromotor")) == 1) {
return(1)
}
}
}
}
return(0)
}'
#%UU% (id,prop)
#%MDESC% writes a property of a spechw object to the
#corresponding xml file
def c_writeObj(id,prop)'{
local mystring myobj mypath arr hw_obj ipath nb
myobj = sprintf("_OBJ_%s",id)
mypath = @myobj["_xmlpath"][prop]
myval = c_getObjProp(id,prop)
p myval
nb = split(mypath,arr,":")
hw_obj = arr[0]
ipath = arr[1]
mystring = sprintf("xml_write(\"%s/%s\",\"%s\",\"%s\")",_XML_lp,hw_obj,ipath,myval)
p mystring
remote_eval(HWR_dev,mystring)
return(0)
}'
#%UU% (id,hw_obj)
#%MDESC% This reads a hardware object being of a particular type:
#containing the list of controllers of that type for a spec session.
#This is typically for a macromotor modules definition in the spec
#configuration.
#%BR%It stores this information in the spechw object 'id' with
#key,value being 'numerical index',controller name
#%BR%returns 0 if OK
#%BR%returns -1 if NOT OK
def c_createEquipList(id,hw_obj)'{
local ii mytmp mystr ret
c_newObj(id)
mystr = ""
ret = xml_read(hw_obj,"/unit/equipment/@hwrid","__value__")
if ("__error__" in XML_tmp) {
return(-1)
}
for (ii in XML_tmp) {
mystr = sprintf("%s %s",XML_tmp[ii],mystr)
}
c_setObjProp(id,"modules",mystr)
}'
#%IU%
#%MDESC% writes as print does, if DEBUG has bit 0x80 selected
def dbgp'{
if ((DEBUG & 0x80) != 0) {
print "$*"
}
}'
#%IU%(str1,str2)
#%MDESC%returns left pushing string str1 to str2 (setting
#a blank between them
def concatstring(str1,str2)'{
local mys
if (str1 == "") {
mys = str2
}
else if (str2 == "") {
mys = str1
}
else {
mys = sprintf("%s %s",str1,str2)
}
return(mys)
}'
#%IU%(str1,str2)
#%MDESC% str2 being a string of names separated by blanks,
#this macro checks if str1 is one of them. This macro differs
#from index as index looks at an occurence of str1 (possibly
#itself inside a string)
def isonstring(str1,str2)'{
local myarr nb ii
# p str1 " isonstrig ? " str2
nb = split(str2,arr)
for (ii=0; ii<nb; ii++) {
if ( arr[ii] == str1) {
return(1)
}
}
return(0)
}'
#%IU% (arr)
#%MDESC%Check if arr is an existing global associative array
#%BR%returns 1 if OK
#%BR%returns 0 if not
def is_ass(arr)'{
local myobj mywhat
mywhat = whatis(arr)
if ( (mywhat & 0x5000004) == 0x5000004) {
return(1)
}
else {
# p arr " is not an existing global associative array")
return(0)
}
}'
#%MACROS%
#%IMACROS%
#%DEPENDENCIES% XML_utils.mac
#
#%AUTHOR%
#%TOC%
|