esrf

Beamline Instrument Software Support
SPEC Macro documentation: [ Macro Index | BCU Home ]

# Macros package to generalize macro hooks
# hookit macro user_macro device flag parameters 
#   user_macro will be called from macro with parameters
# hookitv variablename 
#   is an alternative form of the above
# hookdef
#   does the macro definitions defined with hookit
#   attention this macro can only be called from user level 1
# hookclr 
#   deletes all hooks
# hookdel macro usermacro device
#   deletes usermacro of device from macro , * allowed and means all
#
# Flags:
# 0x01 : Device is a motor and motor must be configured
# 0x02 : Device is a scaler and scaler must be configured
# 0x04 : Want to have this macro first in chain
# 0x08 : Want to have this macro last in chain
#
# --- hooksdel added
# --- remembers defined macros now and can clean empty macros is hookdef

def hook_realdef ''

def hook_usage '

if ("$1"=="hookdel") {
   if ($#<2) {
	print "usage: $1 macroname membername devicename "
   	exit
	}
   }
else if ($#<3) {
   print "usage: $1 macroname membername devicename param_list"
   exit
   }
'

def hookit '
{
global HOOK
local _hp1 _hp2 _hp3 _hp4 _hp5 _hp str start
  _hp1="$1" ; _hp2="$2" ; _hp3="$3" ; _hp4="$4" ; 
  _hp5=substr("$*",length("$1 $2 $3 $4 "))          
  hook_usage $0 $*
_hookit
}
'
def hookitv '
{
global HOOK HOOKDEL
local _hp1 _hp2 _hp3 _hp4 _hp5 _hp str start
  str = $1 
  split(str,_hp)
  _hp1=_hp[0] ; _hp2=_hp[1] ; _hp3=_hp[2] ; _hp4=_hp[3] ; 
  start=length(_hp1)+length(_hp2)+length(_hp3)+length(_hp4)+5
  _hp5=substr($1,start)
_hookit
}
'

def _hookit '
{
local NO2
hook_check1 
if (HOOK_already1) {
	hook_check2 
	}
if (!HOOK_already1) {	
  hook_register1
  }

if (!HOOK_already2) {
  NO2=++HOOK[sprintf("%s@NO2",_hp1)]
  }
else {
  NO2=HOOK_already2
  }

hook_register2 NO2
}
'

def hook_check1 '
{  
local i 
global HOOK_already1 HOOK_already2
HOOK_already1=0 ; HOOK_already2=0

for (i=1 ; i<=HOOK["NO1"] && (!HOOK_already1) ; i++) {
    if (HOOK[i]==_hp1) {     
       HOOK_already1=i
       }
    }
}
'

def hook_check2 '
{  
local i 
for(i=1;i<=HOOK[sprintf("%s@NO2",_hp1)]&&(!HOOK_already2);i++) {
  hook_getstruct _hp1 i
  if ((MN==_hp2) && (DN==_hp3)) 	{
    HOOK_already2=i
    }
  }
}
'

def hook_getstruct '
  MN= HOOK[sprintf("%s@MN@%d",$1,$2)]
  DN= HOOK[sprintf("%s@DN@%d",$1,$2)]
  FL= HOOK[sprintf("%s@FL@%d",$1,$2)]
  P = HOOK[sprintf("%s@P@%d",$1,$2)]
'

def hook_putstruct '
  HOOK[sprintf("%s@MN@%d",$1,$2)]=$3
  HOOK[sprintf("%s@DN@%d",$1,$2)]=$4
  HOOK[sprintf("%s@FL@%d",$1,$2)]=$5
  HOOK[sprintf("%s@P@%d",$1,$2)]=$6
'

def hook_register1 '
HOOK[++HOOK["NO1"]]=_hp1
HOOK["NO@$1"]=HOOK["NO1"]
'

def hook_register2 '
{
hook_putstruct _hp1 $1 _hp2 _hp3 _hp4 _hp5
}
'

def hookclr '
{
local yn
yn=0
printf("Attention - This can not be undone !  ")
if (!yesno("continue",0)) {
  exit
  }
}
unglobal HOOK
global HOOK
'

def hookdef '
{
local  i j FL P MN DN pstr1 pstr2 pstr3 pstr 
local fulldef

fulldef=""
for (i=1;i<=HOOK["NO1"];i++) {
  pstr = "" ; pstr1 = "" ; pstr2 = "" ; pstr3 = ""
  for(j=1;j<=HOOK[sprintf("%s@NO2",HOOK[i])];j++) {
    hook_getstruct HOOK[i] j
    defit = 1
    withdev = 0
    if ( FL & 0x01 ) {
      # test if device is a conf. motor
      for (i0=0,defit=0;i0<MOTORS;i0++) { 
  	if (motor_mne(i0) == DN) {
    	  defit=1
          withdev = 1
    	  }
        }
      }
    else if (FL & 0x02) {
      # test if device is a scaler
      for (i0=0,defit=0;i0<COUNTERS;i0++) { 
  	if (cnt_mne(i0) == DN) {
    	  defit=1
          withdev = 1
    	  }
        }
      }
    if (MN == "" || MN == "none" || MN == "NONE") defit = 0
    if (defit) {
      pstr = sprintf ("%s %s %s",MN,(withdev)?DN:"",P)
      if (FL & 0x04) {
        pstr1 = sprintf("%s ; %s",pstr,pstr1)
        }
      else { 
 	if (FL & 0x08) {
           pstr3 = sprintf("%s %s ;",pstr3,pstr)
           }
        else {
           pstr2 = sprintf("%s %s ;",pstr2,pstr)
           }
        }
      }
    }
    pstr = sprintf ("%s %s %s",pstr1,pstr2,pstr3)
    fulldef = sprintf ("%srdef %s \"%s\"\n",fulldef,HOOK[i],pstr)
  }

#Delete the macros with nothing in them
fulldef = sprintf("%s; %s",HOOKDEL,fulldef)
HOOKDEL=""

rdef hook_realdef fulldef
} 
hook_realdef
'


def hookshow '
{
local  i j p

if (HOOK["NO1"]) {
  printf("number of hooked macros : %d\n",HOOK["NO1"])
  printf( "%3s %15s %3s %15s %15s %4s %18s\n","MNo","Macro","UNo",\
		"User Macro","Device","Flag","Parameters") 
  for (i=1;i<=HOOK["NO1"];i++) {
    for(j=1;j<=HOOK[sprintf("%s@NO2",HOOK[i])];j++) {
      hook_getstruct HOOK[i] j
      printf("%3d %15s %3d %15s %15s %4x %18s\n"\
	,i,HOOK[i],j,MN,DN,FL,P)
      }
    }
  }
else {
  print "No hooks defined"
  }
}'

def hookdel '
{
_dp1="$1" ; _dp2="$2" ; _dp3="$3"
_hookdel
}'

def hooksdel '
{
local _pp
split ($1,_pp)
_dp1=_pp[0]; _dp2=_pp[1] ; _dp3=_pp[2]
_hookdel
}'

def _hookdel '
{
global HOOKDEL
delit =0
for (i=1;i<=HOOK["NO1"];i++) {
  for(j=1;j<=HOOK[sprintf("%s@NO2",HOOK[i])];j++) {
    hook_getstruct HOOK[i] j
    delit = 1
    if ((_dp1 != "*") && (_dp1 != HOOK[i])) delit = 0 
    if ((_dp2 != "*") && (_dp2 != MN)) delit = 0 
    if ((_dp3 != "*") && (_dp3 != DN)) delit = 0    
    if (delit) {
      hook_delone i j
      i = 1 ; j = 0
      }
    }
  }
}
'      

def hook_delone '
{
local dno2 em
em=""
dno2=HOOK[sprintf("%s@NO2",HOOK[$1])]
hook_getstruct HOOK[$1] dno2
hook_putstruct HOOK[$1] $2 MN DN FL P
hook_putstruct HOOK[$1] dno2 em em em em
if (--HOOK[sprintf("%s@NO2",HOOK[$1])] == 0) {
  dno1 = HOOK["NO1"]
  HOOKDEL=sprintf("rdef %s \'\'; %s",HOOK[$1],HOOKDEL);
  HOOK[$1]=HOOK[dno1]
  HOOK[dno1]=""
  HOOK["NO1"]--
  }
}
'