#%TITLE% XML_utils.mac
#%NAME%
# Some macros to handle XML manipulations
#%DESCRIPTION%
# To do
#
global XML_tmp[]
global _XML_lp
#%UU% [host hwr]
#%MDESC% defines the host (host) and hardware repository server name (hwr)
#managing the hardware repository xml files
def setHwrHost'{
global XML_debug
global HWR_host HWR_server HWR_dev
global XML_tmp[]
global _XML_lp
if($# == 2) {
HWR_host = "$1"
HWR_server = "$2"
}
else {
HWR_host = getval("Hardware Repository host ?",HWR_host)
HWR_server = getval("Hardware Repository server ?",HWR_server)
}
HWR_dev = sprintf("%s:%s",HWR_host,HWR_server)
# relative path from HWR location to find the files
# _XML_lp = ""
_XML_lp = sprintf("/%s",SPEC)
}'
#%UU% (hw_obj)
#%MDESC% dumps an XML object situated from the Hardware Repository Location
#%BR% xml object can be on the form: xxx xxx/xx ...
#with possibly the path from the Hardware Repository Location
#%BR%ex: xml_view("pslit")
#%BR%ACCESS TO XML file
def xml_view(hw_obj)' {
local mystring
mystring = sprintf("xml_view(\"%s/%s\")",_XML_lp,hw_obj)
xml_debug "xml_view: doing: " \'"mystring"\'
p remote_eval(HWR_dev,mystring)
}'
#%UU%(hw_obj,level,[key])
#%MDESC% reading a hardware object, with a level access,(and possibly
#a key), sets the global associative array XML_tmp.
#%BR% If no key is provided: reurns a 2 dim assocoative array
#%BR%ex: xml_read("pslit","/*/*/blades/device")
#%BR%XML_tmp["0"]["role"] = "vo"
#%BR%XML_tmp["1"]["role"] = "vg"
#%BR%XML_tmp["2"]["role"] = "ho"
#%BR%XML_tmp["3"]["role"] = "hg"
#%BR%XML_tmp["0"]["hwrid"] = "/motors/psvo"
#%BR%XML_tmp["1"]["hwrid"] = "/motors/psvg"
#%BR%XML_tmp["2"]["hwrid"] = "/motors/psho"
#%BR%XML_tmp["3"]["hwrid"] = "/motors/pshg"
#%BR%XML_tmp["0"]["__path__"] = "/equipment[1]/motors[1]/blades[1]/device[1]"
#%BR%XML_tmp["1"]["__path__"] = "/equipment[1]/motors[1]/blades[1]/device[2]"
#%BR%XML_tmp["2"]["__path__"] = "/equipment[1]/motors[1]/blades[1]/device[3]"
#%BR%XML_tmp["3"]["__path__"] = "/equipment[1]/motors[1]/blades[1]/device[4]"
#%BR%XML_tmp["0"]["__value__"] = ""
#%BR%XML_tmp["1"]["__value__"] = ""
#%BR%XML_tmp["2"]["__value__"] = ""
#%BR%XML_tmp["3"]["__value__"] = ""
#%BR%XML_tmp["0"]["__children__"] = ""
#%BR%XML_tmp["1"]["__children__"] = ""
#%BR%XML_tmp["2"]["__children__"] = ""
#%BR%XML_tmp["3"]["__children__"] = ""
#%BR% if a key is provided: provides a one key associative array
#%BR%ex: xml_read("pslit","/*/*/blades/device","role")
#%BR%XML_tmp["0"] = "vo"
#%BR%XML_tmp["1"] = "vg"
#%BR%XML_tmp["2"] = "ho"
#%BR%XML_tmp["3"] = "hg"
#%BR%....
#%BR%returns 0 if OK
#%BR%returns -1 if NOT OK, in that case XML_tmp["__error__"] contains error message.
#%BR%ACCESS TO XML file
def xml_read(hw_obj,tree,key)'{
local ii mystring tmp mydim myout mytmp tmperr
unglobal XML_tmp
global XML_tmp
mystring = sprintf("xml_read(\"%s/%s\",\"%s\")",_XML_lp,hw_obj,tree)
xml_debug "xml_read: doing: " \'"mystring"\'
mytmp = remote_eval(HWR_dev,mystring)
tmperr = mytmp["__error__"]
if ( "__error__" in mytmp) {
xml_debug "xml_read: error: " \'"tmperr"\'
XML_tmp["__error__"] = mytmp["__error__"]
return(-1)
}
else {
if (key == "") {
for (ii in mytmp) {
XML_tmp[ii] = mytmp[ii]
}
}
else {
mydim = asso_len(mytmp)
for (ii=0; ii<mydim; ii++) {
XML_tmp[ii]= mytmp[ii][key]
}
}
return(0)
}
}'
#%UU% (hw_obj)
#%MDESC% From an hardware object, set the global XML_tmp associative
#array, first indexed by the roles
#This is a quick way to get an information without giving the path to it.
#%BR%ex: xml_readroles("pslit")
#%BR%returns 0 if OK, and:
#%BR%XML_tmp will have:
#%BR%XML_tmp["down"]["__children__"] = ""
#%BR%XML_tmp["down"]["__path__"] = "/equipment[1]/motors[1]/slits[1]/device[2]"
#%BR%XML_tmp["down"]["__value__"] = ""
#%BR%XML_tmp["down"]["hwrid"] = "/demo/psd"
#%BR%XML_tmp["down"]["role"] = "down"
#%BR%XML_tmp["hg"]["__children__"] = ""
#%BR%XML_tmp["hg"]["__path__"] = "/equipment[1]/motors[1]/blades[1]/device[4]"
#%BR%XML_tmp["hg"]["__value__"] = ""
#%BR%XML_tmp["hg"]["hwrid"] = "/demo/pshg"
#%BR%XML_tmp["hg"]["role"] = "hg"
#%BR%....
#%BR%returns -1 if NOT OK and:
#%BR%XML_tmp["__error__"] = "an error string"
#%BR%ACCESS TO XML file
def xml_readRoles(hw_obj)'{
local mystring tmperr
mystring = sprintf("xml_readNodesWithRoles(\"%s/%s\")",_XML_lp,hw_obj)
xml_debug "xml_readRoles: doing " \'"mystring"\'
XML_tmp = remote_eval(HWR_dev,mystring)
if ("__error__" in XML_tmp) {
tmperr = XML_tmp["__error__"]
xml_debug "xml_readRoles : error: " \'"tmperr"\'
return(-1)
}
else {
return(0)
}
}'
def xml_readMotorsByRoles(ho) '{
local xmlres[] tmp[] tmp2 motor_ho mot_mne
if (xml_readRoles(ho) > -1) {
ass_copy(XML_tmp, tmp)
tmp2 = asso_keys(XML_tmp)
for (role in tmp2) {
motor_ho = tmp[role]["hwrid"]
if (xml_read(motor_ho, "/device/specname") > -1) {
mot_mne = XML_tmp[0]["__value__"]
if (motor_num(mot_mne) > -1) {
xmlres[role] = mot_mne
}
}
}
}
return xmlres
}'
#%UU% (hw_obj)
#%MDESC% From an hardware object, set the global XML_tmp associative
#array, first indexed by the properties
#This is a quick way to get an information without giving the path to it.
#%BR%ex: xml_readProperties("motors/mydac0")
#%BR%returns 0 if OK, and:
#%BR%XML_tmp["dev"]["__path__"] = "/device[1]/dev[1]"
#%BR%XML_tmp["dev"]["__value__"] = "id/icvdac/0"
#%BR%XML_tmp["maxstep"]["__path__"] = "/device[1]/maxstep[1]"
#%BR%XML_tmp["maxstep"]["__value__"] = 3
#%BR%XML_tmp["reading"]["__path__"] = "/device[1]/reading[1]"
#%BR%XML_tmp["reading"]["__value__"] = 1
#%BR%XML_tmp["stepsize"]["__path__"] = "/device[1]/stepsize[1]"
#%BR%XML_tmp["stepsize"]["__value__"] = 0.2
#%BR%....
#%BR%returns -1 if NOT OK, and:
#%BR%XML_tmp["__error__"] = "an error string"
#%BR%ACCESS TO XML file
def xml_readProperties(hw_obj, path)'{
local mystring tmperr
if (path == 0) {
mystring = sprintf("xml_readProperties(\"%s/%s\")",_XML_lp,hw_obj)
} else {
mystring = sprintf("xml_readProperties(\"%s/%s\",\"%s\")",_XML_lp,hw_obj,path)
}
#mystring = sprintf("xml_readProperties(\"%s/%s\")",_XML_lp,hw_obj)
xml_debug "xml_readProperties: doing " \'"mystring"\'
XML_tmp = remote_eval(HWR_dev,mystring)
if ("__error__" in XML_tmp) {
tmperr = XML_tmp["__error__"]
xml_debug "xml_readProperties : error: " \'"tmperr"\'
return(-1)
}
else {
return(0)
}
}'
def xml_cache_write(hw_obj, path, value) '{
global _XML_WRITE_CACHE[]
local n
n=asso_len(_XML_WRITE_CACHE)
_XML_WRITE_CACHE[n+1]["ho"]=hw_obj
_XML_WRITE_CACHE[n+1]["path"]=path
_XML_WRITE_CACHE[n+1]=value
}'
def xml_do_write() '{
local tmp[] ho path value update
local UPDATES[] query res[] result
result=0
tmp = asso_keys(_XML_WRITE_CACHE)
for (i in tmp) {
ho = _XML_WRITE_CACHE[i]["ho"]
path = _XML_WRITE_CACHE[i]["path"]
value = _XML_WRITE_CACHE[i]
update = sprintf("(\"%s\", \"%s\")", path, value)
if (UPDATES[ho] == 0) {
UPDATES[ho] = sprintf("(%s", update)
} else {
UPDATES[ho] = sprintf("%s,%s", UPDATES[ho], update)
}
}
for (ho in UPDATES) {
UPDATES[ho]=sprintf("%s,)", UPDATES[ho])
query = sprintf("xml_multiwrite(\"%s\", \'%s\')", ho, UPDATES[ho])
res = remote_eval(HWR_dev, query)
if ("__error__" in res) {
print res["__error__"]
result = -1
}
}
if (result == 0) {
unglobal _XML_WRITE_CACHE
}
return result
}'
#%UU%(db)
#%MDESC% set debug on (0) or off (1)
def xml_setDebug(db)'{
XML_debug = db
}'
#%IU% <list>
#%MDESC% if debug is set, writes <list>
def xml_debug'{
if (XML_debug > 0) {
print "$*"
}
}'
#%IU% <arr>
#%MDESC% arr being a 2 dimension associative array with numerical first
#key, this function return its length.
def asso_len(arr)'{
local len keys_tmp k keys
keys["__"] = ""
for (ii in arr) {
split(ii,mysp,"\034")
if ((mysp[0] in keys) == 0) {
keys[mysp[0]]=""
}
}
delete keys["__"]
len = 0
for (k in keys) {
len += 1
}
return len
}'
#%IU% <arr>
#%MDESC% arr being a 2 dimension associative array.
def asso_keys(arr) '{
local ii keys mysp nb
keys["__"] = ""
for (ii in arr) {
nb = split(ii,mysp,"\034")
# we want only 2 dimension keys
if ( ((mysp[0] in keys) == 0) && (nb > 1) ) {
keys[mysp[0]]=""
}
}
delete keys["__"]
return(keys)
}'
#%UU% (aa,bb)
#%MDESC% makes a copy of array aa to bb
def ass_copy(aa,bb)'{
local ii
for (ii in aa) {
bb[ii] = aa[ii]
}
}'
#%MACROS%
#%IMACROS%
#%DEPENDENCIES%
#
#%AUTHOR%
#%TOC%
|