From 10d29d597cc3efa8aef50c06498cd2d4ead5dd9c Mon Sep 17 00:00:00 2001
From: Ferdi Franceschini
Date: Thu, 23 Apr 2015 20:49:26 +1000
Subject: [PATCH] Cleaned up ANSTO code to merge with sinqdev.sics
This is our new RELEASE-4_0 branch which was taken from ansto/93d9a7c
Conflicts:
.gitignore
SICSmain.c
asynnet.c
confvirtualmot.c
counter.c
devexec.c
drive.c
event.h
exebuf.c
exeman.c
histmem.c
interface.h
motor.c
motorlist.c
motorsec.c
multicounter.c
napi.c
napi.h
napi4.c
network.c
nwatch.c
nxscript.c
nxxml.c
nxxml.h
ofac.c
reflist.c
scan.c
sicshipadaba.c
sicsobj.c
site_ansto/docs/Copyright.txt
site_ansto/instrument/lyrebird/config/tasmad/sicscommon/nxsupport.tcl
site_ansto/instrument/lyrebird/config/tasmad/taspub_sics/tasscript.tcl
statusfile.c
tasdrive.c
tasub.c
tasub.h
tasublib.c
tasublib.h
---
.gitignore | 137 +-
HistDriv.i | 6 +-
HistMem.h | 112 +-
HistMem.i | 4 +-
SCinter.c | 3 +-
SCinter.h | 4 +-
SICSmain.c | 3 +
arrayutil.c | 15 +-
ascon.c | 24 +-
ascon.h | 8 +
ascon.i | 29 +-
asynnet.c | 28 +-
asynnet.h | 13 +-
background.c | 2 +-
commandlog.c | 6 +-
commandlog.h | 2 +-
cone.c | 3 +-
confvirtualmot.c | 37 +-
conman.c | 168 +-
conman.h | 2 +
counter.c | 248 +-
counter.h | 3 +
countersec.c | 308 +-
danu.c | 16 +-
devexec.c | 884 +--
devexec.h | 21 +-
devexec.tex | 5 +-
devexec.w | 7 +-
devser.c | 22 +-
devser.h | 16 +
diffscan.c | 2 +-
doc/manager/nxscript.htm | 22 +-
drive.c | 113 +-
dynstring.c | 10 +-
dynstring.h | 5 +
epicsmotor.c | 313 +
evcontroller.c | 8 +-
event.c | 2 +
event.h | 18 +-
event.tex | 5 +
event.w | 5 +
exebuf.c | 32 +-
exeman.c | 15 +-
exeman.h | 2 +
fitcenter.c | 73 +-
fomerge.c | 13 +-
fourlib.c | 2 +-
fourmess.c | 25 +-
frame.c | 10 +-
hdbtable.c | 21 +
hipadaba.c | 83 +-
hipadaba.h | 23 +-
histmem.c | 117 +-
histmemsec.c | 304 +-
histmemsec.h | 8 +
histogram.tex | 3 +
histogram.w | 3 +
histsim.c | 1 +
hkl.c | 49 +
hmcontrol.c | 5 +-
hmdata.c | 25 +-
initializer.c | 2 +
interface.c | 233 +-
interface.h | 196 +-
interface.tex | 13 +
interface.w | 13 +
intserv.c | 42 +-
linux_def | 2 +-
macro.c | 25 +-
make_gen | 42 +-
makefile | 24 +-
makefile_ | 25 +
makefile_alpha | 3 +-
makefile_linux | 5 +-
makefile_macosx | 3 +-
makefile_slinux | 24 +-
messagepipe.c | 118 +
messagepipe.h | 82 +
moregress.c | 2 +-
motor.c | 66 +-
motor.h | 3 +-
motorlist.c | 81 +-
motorlist.h | 1 +
motorsec.c | 189 +-
multicounter.c | 302 +-
multicountersec.c | 564 ++
mumo.c | 5 +-
mumoconf.c | 22 -
napi.c | 2133 ------
napi.h | 967 ---
napi4.c | 1983 -----
napi4.h | 60 -
napi5.c | 2301 ------
napi5.h | 54 -
network.c | 12 +-
nread.c | 10 +-
nserver.c | 43 +-
nxdict.c | 2 +-
nxio.c | 747 --
nxio.h | 50 -
nxscript.c | 509 +-
nxscript.h | 1 +
nxstack.c | 145 -
nxstack.h | 52 -
nxupdate.c | 2 +-
nxxml.c | 1992 ------
nxxml.h | 78 -
obdes.h | 54 +-
ofac.c | 17 +-
ofac.h | 1 -
oscillate.c | 64 +-
oscillate.h | 2 -
outcode.c | 4 +-
protocol.c | 30 +-
reflist.c | 71 +-
reflist.h | 2 +
regresscter.c | 21 +
remob.c | 2 +-
remoteobject.c | 1008 +++
rs232controller.c | 1 -
rwpuffer.c | 55 +-
rwpuffer.h | 15 +
sansbc.c | 9 +-
scan.c | 72 +-
scan.h | 1 +
script.c | 21 +-
scriptcontext.c | 156 +-
scriptcontext.h | 7 +-
sctcomtask.c | 517 ++
sctcomtask.h | 78 +
sctdriveadapter.c | 4 +-
sctdriveobj.c | 8 +-
selector.c | 8 +-
serialwait.c | 2 +-
sicscron.c | 98 +-
sicsdata.c | 22 +-
sicsdata.h | 48 +-
sicsdata.w | 2 +-
sicsexit.c | 2 +-
sicsget.c | 603 ++
sicsget.h | 30 +
sicshdbadapter.c | 95 +-
sicshdbfactory.c | 5 +-
sicshipadaba.c | 506 +-
sicshipadaba.h | 8 +
sicslist.c | 20 +-
sicsobj.c | 206 +-
sicspoll.c | 2 +-
sicvar.c | 5 +
singelbi.h | 1 +
singlebi.c | 100 +
singlex.c | 24 +-
singlex.h | 2 +-
site_ansto/Makefile | 250 -
site_ansto/Makefile_SICS | 48 -
site_ansto/TESTS/check_zlib/Makefile | 10 -
site_ansto/TESTS/check_zlib/README | 25 -
site_ansto/TESTS/check_zlib/mkdata.c | 23 -
site_ansto/TESTS/check_zlib/rdata.c | 39 -
site_ansto/TESTS/dingo_camera/Makefile | 8 -
.../camdriver_event_io_expect.txt | 2 -
site_ansto/TESTS/dingo_camera/camera_test.c | 209 -
.../TESTS/dingo_camera/camrep2sym_expect.txt | 8 -
.../TESTS/dingo_camera/trans_fn_expect.txt | 14 -
site_ansto/action.c | 68 -
site_ansto/action.h | 4 -
site_ansto/ansto_evcontroller.h | 14 -
site_ansto/ansto_sctdriveadapter.c | 366 -
site_ansto/ansto_tclmotdriv.c | 622 --
site_ansto/ansto_tclmotdriv.h | 43 -
site_ansto/anstohm.cpp | 447 --
site_ansto/anstohm.h | 28 -
site_ansto/anstohttp.c | 1041 ---
site_ansto/anstohttp.h | 23 -
site_ansto/anstoutil.c | 219 -
site_ansto/anstoutil.h | 13 -
site_ansto/beamstopaction.c | 377 -
site_ansto/beamstopaction.h | 5 -
site_ansto/build | 3 -
site_ansto/cameradriver.h | 4 -
site_ansto/counterdriv.c | 951 ---
site_ansto/docs/Copyright.txt | 33 -
site_ansto/docs/Doxyfile | 229 -
site_ansto/docs/sics_site.Doxyfile | 229 -
site_ansto/extract_version.sh | 63 -
site_ansto/fsm.c | 123 -
site_ansto/fsm.h | 67 -
site_ansto/hardsup/Digital/Makefile | 60 -
site_ansto/hardsup/Digital/Monitor.c | 166 -
site_ansto/hardsup/Digital/Monitor.h | 11 -
site_ansto/hardsup/Digital/device.c | 258 -
site_ansto/hardsup/Digital/device.h | 70 -
site_ansto/hardsup/Digital/display.c | 638 --
site_ansto/hardsup/Digital/display.h | 15 -
site_ansto/hardsup/Digital/hware.c | 548 --
site_ansto/hardsup/Digital/hware.h | 87 -
site_ansto/hardsup/Digital/params.c | 401 --
site_ansto/hardsup/Digital/params.h | 52 -
site_ansto/hardsup/Digital/sock.c | 523 --
site_ansto/hardsup/Digital/sock.h | 18 -
site_ansto/hardsup/Digital/utility.c | 140 -
site_ansto/hardsup/Digital/utility.h | 55 -
site_ansto/hardsup/Monitor/Makefile | 72 -
site_ansto/hardsup/Monitor/Monitor.c | 166 -
site_ansto/hardsup/Monitor/Monitor.h | 11 -
site_ansto/hardsup/Monitor/Pulser.c | 206 -
site_ansto/hardsup/Monitor/device.c | 700 --
site_ansto/hardsup/Monitor/device.h | 124 -
site_ansto/hardsup/Monitor/display.c | 724 --
site_ansto/hardsup/Monitor/display.h | 15 -
site_ansto/hardsup/Monitor/hware.c | 1013 ---
site_ansto/hardsup/Monitor/hware.h | 123 -
site_ansto/hardsup/Monitor/params.c | 416 --
site_ansto/hardsup/Monitor/params.h | 54 -
site_ansto/hardsup/Monitor/sock.c | 524 --
site_ansto/hardsup/Monitor/sock.h | 18 -
site_ansto/hardsup/Monitor/utility.c | 140 -
site_ansto/hardsup/Monitor/utility.h | 55 -
site_ansto/hardsup/README | 4 -
site_ansto/hardsup/StrMatch.c | 96 -
site_ansto/hardsup/aqp_opalstatus.c | 170 -
site_ansto/hardsup/aqp_opalstatus.h | 4 -
site_ansto/hardsup/asynsrv_def.h | 51 -
site_ansto/hardsup/asynsrv_errcodes.h | 34 -
site_ansto/hardsup/asynsrv_utility.c | 2121 ------
site_ansto/hardsup/c_interfaces.c | 472 --
site_ansto/hardsup/camera.c | 240 -
site_ansto/hardsup/camera.h | 267 -
site_ansto/hardsup/cameradriver.c | 1047 ---
site_ansto/hardsup/cameradriver.h | 4 -
site_ansto/hardsup/cd_obj | 1 -
site_ansto/hardsup/chopper.c | 1042 ---
site_ansto/hardsup/dillutil.h | 108 -
site_ansto/hardsup/el734_def.h | 73 -
site_ansto/hardsup/el734_errcodes.h | 28 -
site_ansto/hardsup/el734fix.h | 29 -
site_ansto/hardsup/el737_def.h | 67 -
site_ansto/hardsup/el737_errcodes.h | 27 -
site_ansto/hardsup/el737fix.h | 33 -
site_ansto/hardsup/el755_def.h | 31 -
site_ansto/hardsup/el755_errcodes.h | 27 -
site_ansto/hardsup/err.c | 105 -
site_ansto/hardsup/failinet.c | 109 -
site_ansto/hardsup/geterrno.c | 96 -
site_ansto/hardsup/huber_asyncprotocol.c | 333 -
site_ansto/hardsup/huber_asyncprotocol.h | 5 -
site_ansto/hardsup/itc4util.c | 449 --
site_ansto/hardsup/itc4util.h | 125 -
site_ansto/hardsup/knauer_asyncprotocol.c | 345 -
site_ansto/hardsup/knauer_asyncprotocol.h | 5 -
site_ansto/hardsup/lakeshore340util.c | 535 --
site_ansto/hardsup/lakeshore340util.h | 130 -
site_ansto/hardsup/lh45util.c | 436 --
site_ansto/hardsup/lh45util.h | 130 -
site_ansto/hardsup/loader_asyncprotocol.c | 14 -
site_ansto/hardsup/loader_asyncprotocol.h | 5 -
site_ansto/hardsup/makefile | 55 -
site_ansto/hardsup/makeprint.c | 276 -
site_ansto/hardsup/modbus_asyncprotocol.c | 733 --
site_ansto/hardsup/modbus_asyncprotocol.h | 5 -
site_ansto/hardsup/modbustcp.c | 137 -
site_ansto/hardsup/modbustcp.h | 28 -
site_ansto/hardsup/nhq200util.c | 659 --
site_ansto/hardsup/nhq200util.h | 142 -
site_ansto/hardsup/omron_asyncprotocol.c | 356 -
site_ansto/hardsup/omron_asyncprotocol.h | 5 -
site_ansto/hardsup/rs232c_def.h | 186 -
site_ansto/hardsup/sct_asyncqueue.c | 363 -
site_ansto/hardsup/sct_galilprot.c | 126 -
site_ansto/hardsup/sct_lfprot.c | 262 -
site_ansto/hardsup/sct_modbusprot.c | 330 -
site_ansto/hardsup/sct_newportprot.c | 228 -
site_ansto/hardsup/sct_orhvpsprot.c | 361 -
site_ansto/hardsup/sct_oxfordprot.c | 294 -
site_ansto/hardsup/sct_protek608.c | 470 --
site_ansto/hardsup/sct_rfamp.c | 362 -
site_ansto/hardsup/sct_tcpmodbus.c | 510 --
site_ansto/hardsup/sct_usbtmcprot.c | 53 -
site_ansto/hardsup/sct_velselprot.c | 50 -
site_ansto/hardsup/serialsinq.c | 919 ---
site_ansto/hardsup/serialsinq.h | 56 -
site_ansto/hardsup/sinq_defs.h | 108 -
site_ansto/hardsup/sinq_prototypes.h | 674 --
site_ansto/hardsup/sinqhm.h | 107 -
site_ansto/hardsup/sinqhm_def.h | 483 --
site_ansto/hardsup/sinqhttpprot.c | 247 -
site_ansto/hardsup/stredit.c | 415 --
site_ansto/hardsup/strjoin.c | 142 -
site_ansto/hardsup/table.h | 35 -
site_ansto/hardsup/usbtmc.h | 131 -
site_ansto/hardsup/velsel_def.h | 58 -
site_ansto/hardsup/west4100util.c | 507 --
site_ansto/hardsup/west4100util.h | 130 -
site_ansto/hm_asim.cpp | 1038 ---
site_ansto/hm_asim.h | 21 -
site_ansto/hm_tango.h | 30 -
site_ansto/hmcontrol_ansto.c | 175 -
site_ansto/hmcontrol_ansto.h | 29 -
site_ansto/instrument/MANIFEST.TXT | 8 -
site_ansto/instrument/TEST_SICS/README.TXT | 6 -
.../fakeCameraServer/SIM_DINGO_CAMSERVER.py | 76 -
.../TEST_SICS/fakeDChopper/SIM_ASTRIUM.py | 92 -
.../fakeDChopper/SIM_chopperServer.tcl | 227 -
.../instrument/TEST_SICS/fakeDMC/README.txt | 18 -
.../instrument/TEST_SICS/fakeDMC/cont.tcl | 18 -
.../TEST_SICS/fakeDMC/dmc2280Server.tcl | 69 -
.../instrument/TEST_SICS/fakeDMC/dmcParse.tcl | 39 -
.../TEST_SICS/fakeDMC/loadConfig.tcl | 39 -
.../TEST_SICS/fakeDMC/mkSimAxes.tcl | 111 -
.../instrument/TEST_SICS/fakeDMC/simAxis.tcl | 201 -
.../TEST_SICS/fakeFermi/SIM_FERMI.py | 326 -
.../TEST_SICS/fakeGalil/SIM_GALIL.py | 120 -
.../TEST_SICS/fakeGalil/SIM_GALIL_taipan.py | 165 -
.../TEST_SICS/fakeGalil/counterclient.py | 52 -
.../TEST_SICS/fakeGalil/galilcontroller.py | 230 -
.../TEST_SICS/fakeGalil/galilfactory.py | 87 -
.../TEST_SICS/fakeGalil/galilmotor.py | 409 --
.../TEST_SICS/fakeGalil/powdersample.py | 108 -
.../TEST_SICS/fakeHiden/xcs/HidenDevice.py | 112 -
.../TEST_SICS/fakeHiden/xcs/HidenFactory.py | 47 -
.../TEST_SICS/fakeHiden/xcs/HidenProtocol.py | 89 -
.../TEST_SICS/fakeHiden/xcs/HidenXCS.py | 180 -
.../TEST_SICS/fakeHiden/xcs/SIM_HIDEN.py | 141 -
.../TEST_SICS/fakeHuber/fakeHuber.py | 219 -
.../TEST_SICS/fakeMercury/SIM_MERCURY.py | 322 -
.../instrument/TEST_SICS/fakeNHQ/fakeNHQ.py | 221 -
.../instrument/TEST_SICS/fakeNVS/SIM_NVS.py | 53 -
.../instrument/TEST_SICS/fakeOLV/FakeOLV.py | 124 -
.../fakePfeiffer/tpg261/PfeifferDevice.py | 110 -
.../fakePfeiffer/tpg261/PfeifferFactory.py | 47 -
.../fakePfeiffer/tpg261/PfeifferProtocol.py | 87 -
.../fakePfeiffer/tpg261/Pfeiffer_tpg261.py | 76 -
.../fakePfeiffer/tpg261/SIM_PFEIFFER.py | 126 -
.../TEST_SICS/fakeRFGen/SIM_RFGen.tcl | 151 -
.../fakeTempControl/lakeshore/LS336.py | 150 -
.../fakeTempControl/lakeshore/LS340.py | 150 -
.../fakeTempControl/lakeshore/LS370.py | 150 -
.../fakeTempControl/lakeshore/Lakeshore336.py | 542 --
.../fakeTempControl/lakeshore/Lakeshore340.py | 559 --
.../fakeTempControl/lakeshore/Lakeshore370.py | 494 --
.../lakeshore/LakeshoreDevice.py | 117 -
.../lakeshore/LakeshoreFactory.py | 43 -
.../lakeshore/LakeshoreProtocol.py | 88 -
.../fakeTempControl/lakeshore/SIM_LS336.tcl | 230 -
.../fakeTempControl/oxford/MercuryDevice.py | 110 -
.../fakeTempControl/oxford/MercuryFactory.py | 47 -
.../fakeTempControl/oxford/MercuryProtocol.py | 92 -
.../fakeTempControl/oxford/MercurySCPI.py | 163 -
.../fakeTempControl/oxford/SIM_MERCURY.py | 144 -
site_ansto/instrument/TEST_SICS/setup/common | 34 -
site_ansto/instrument/TEST_SICS/setup/dingo | 22 -
site_ansto/instrument/TEST_SICS/setup/echidna | 22 -
site_ansto/instrument/TEST_SICS/setup/pelican | 16 -
site_ansto/instrument/TEST_SICS/setup/taipan | 21 -
site_ansto/instrument/TEST_SICS/setup/wombat | 22 -
.../instrument/TEST_SICS/sics_test_hosts | 21 -
.../instrument/TEST_SICS/sics_test_services | 154 -
.../TEST_SICS/tests/plot-tracking.py | 69 -
.../TEST_SICS/unit_tests/sics_hdb.py | 287 -
.../TEST_SICS/unit_tests/sics_proxy.py | 193 -
.../TEST_SICS/unit_tests/sics_test.py | 841 ---
.../TEST_SICS/unit_tests/test_sics.py | 841 ---
.../TEST_SICS/unit_tests/test_suite.tcl | 133 -
.../TEST_SICS/unit_tests/test_wombat.py | 33 -
site_ansto/instrument/barebones.tcl | 46 -
site_ansto/instrument/bilby/MANIFEST.TXT | 7 -
.../instrument/bilby/bilby_configuration.tcl | 99 -
.../instrument/bilby/config/INSTCFCOMMON.TXT | 26 -
.../bilby/config/anticollider/acscript.txt | 5 -
.../config/anticollider/anticollider.tcl | 124 -
.../bilby/config/chopper/astrium_chopper.sct | 124 -
.../config/chopper/astrium_chopper_sct.tcl | 759 --
.../bilby/config/chopper/chopper.tcl | 60 -
.../bilby/config/commands/commands.tcl | 70 -
.../bilby/config/counter/counter.tcl | 32 -
.../magneticField/oxford_labview.tcl | 1 -
.../hipadaba/hipadaba_configuration.tcl | 1 -
.../instrument/bilby/config/hmm/detector.tcl | 34 -
.../bilby/config/hmm/hmm_configuration.tcl | 74 -
...motion_control_commissioning_checklist.csv | 708 --
.../instrument/bilby/config/motors/README.TXT | 6 -
.../motors/generated_motor_configuration.tcl | 1055 ---
.../config/motors/motor_configuration.tcl | 657 --
.../bilby/config/motors/shutters.sct | 178 -
.../bilby/config/motors/shutters_sct.tcl | 529 --
.../bilby/config/motors/sicsmot_attlist.csv | 223 -
.../instrument/bilby/config/motors/tank.sct | 100 -
.../bilby/config/motors/tank_sct.tcl | 471 --
.../bilby/config/motors/userdef_attlist.csv | 24 -
.../bilby/config/nexus/nxscripts.tcl | 4 -
.../instrument/bilby/config/optics/README.TXT | 1 -
.../config/optics/aperture_configuration.tcl | 94 -
.../config/optics/guide_configuration.tcl | 66 -
.../instrument/bilby/config/optics/optics.tcl | 2 -
.../bilby/config/parameters/parameters.tcl | 9 -
.../instrument/bilby/config/plc/plc.tcl | 7 -
.../instrument/bilby/config/scan/scan.tcl | 6 -
.../instrument/bilby/hostport_config.tcl | 52 -
.../instrument/bilby/hostport_config_test.tcl | 52 -
site_ansto/instrument/bilby/runsics_def.py | 3 -
.../instrument/bilby/sics_simulation.tcl | 23 -
.../instrument/bilby/util/sics_config.ini | 11 -
site_ansto/instrument/compareSICS.py | 385 -
site_ansto/instrument/config/README.TXT | 14 -
.../anticollider/anticollider_common.tcl | 232 -
.../config/beamline/aerolas_doppler.sct | 170 -
.../config/beamline/aerolas_doppler_sct.tcl | 4455 ------------
.../config/beamline/he3_polanal.sct | 204 -
.../config/beamline/he3_polanal_sct.tcl | 1050 ---
.../config/commands/commands_common.tcl | 202 -
.../instrument/config/commands/hvcommands.tcl | 452 --
.../instrument/config/commands/pulser.tcl | 71 -
.../config/counter/counter_common_1.tcl | 133 -
.../config/environment/agilent_33220A.sct | 11 -
.../config/environment/agilent_33220A_sct.tcl | 117 -
.../environment/antonparr_MCR500_sct.tcl | 114 -
.../config/environment/he3/sct_he3.tcl | 187 -
.../config/environment/hiden_xcs.sct | 364 -
.../config/environment/hiden_xcs_sct.tcl | 1413 ----
.../config/environment/huber_pilot.sct | 100 -
.../config/environment/huber_pilot_sct.tcl | 613 --
.../config/environment/isotech_ps.sct | 57 -
.../config/environment/isotech_ps_sct.tcl | 483 --
.../config/environment/keithley_m2700.sct | 12 -
.../config/environment/keithley_m2700_sct.tcl | 191 -
.../config/environment/keysight_N8740A.sct | 159 -
.../environment/keysight_N8740A_sct.tcl | 843 ---
.../config/environment/knauer_pump.sct | 385 -
.../config/environment/knauer_pump_sct.tcl | 1309 ----
.../environment/magneticField/bruker.sct | 12 -
.../environment/magneticField/bruker_sct.tcl | 131 -
.../magneticField/green_magnet_labview.sct | 19 -
.../green_magnet_labview_sct.tcl | 123 -
.../environment/magneticField/oxford10tlv.sct | 188 -
.../magneticField/oxford10tlv_sct.tcl | 860 ---
.../environment/magneticField/oxford12tlv.sct | 16 -
.../magneticField/oxford12tlv_sct.tcl | 196 -
.../magneticField/sct_bruker_BEC1.tcl | 1370 ----
.../magneticField/sct_green_magnet.tcl | 200 -
.../magneticField/sct_lakeshore_460.tcl | 475 --
.../magneticField/sct_oxford10tlv.tcl | 860 ---
.../magneticField/sct_oxford_ips.tcl | 767 --
.../magneticField/sct_oxford_labview.tcl | 496 --
.../environment/magneticField/tsi_smc.sct | 86 -
.../environment/magneticField/tsi_smc_sct.tcl | 712 --
.../config/environment/mvp_valve.sct | 12 -
.../config/environment/mvp_valve_sct.tcl | 131 -
.../instrument/config/environment/nhq_200.sct | 64 -
.../config/environment/nhq_200_sct.tcl | 993 ---
.../config/environment/omron_hldc.sct | 53 -
.../config/environment/omron_hldc_sct.tcl | 383 -
.../pressure/sct_pfeiffer_mercury.tcl | 243 -
.../pressure/sct_pfeiffer_tpg261.tcl | 135 -
.../config/environment/protekmm.sct | 12 -
.../config/environment/protekmm_sct.tcl | 191 -
.../config/environment/sct_autolab.tcl | 423 --
.../config/environment/sct_cybaman.tcl | 1140 ---
.../config/environment/sct_keithley_2700.tcl | 682 --
.../instrument/config/environment/sct_mvp.tcl | 528 --
.../config/environment/sct_protek_common.tcl | 168 -
.../config/environment/sct_rheometer.tcl | 104 -
.../instrument/config/environment/sct_syr.tcl | 629 --
.../config/environment/syringe_pump.sct | 11 -
.../config/environment/syringe_pump_sct.tcl | 180 -
.../temperature/eurotherm_3200.sct | 57 -
.../temperature/eurotherm_3200_sct.tcl | 716 --
.../temperature/eurotherm_m2000.sct | 12 -
.../temperature/eurotherm_m2000_sct.tcl | 191 -
.../environment/temperature/julabo_lh45.sct | 145 -
.../temperature/julabo_lh45_gen_sct.tcl | 848 ---
.../environment/temperature/lakeshore_218.sct | 49 -
.../temperature/lakeshore_218_sct.tcl | 571 --
.../temperature/lakeshore_m370.sct | 16 -
.../temperature/lakeshore_m370_sct.tcl | 195 -
.../config/environment/temperature/ls336.sct | 11 -
.../environment/temperature/ls336_sct.tcl | 191 -
.../config/environment/temperature/ls340.sct | 12 -
.../environment/temperature/ls340_sct.tcl | 214 -
.../environment/temperature/mercury_base.sct | 53 -
.../temperature/mercury_base_sct.tcl | 754 --
.../environment/temperature/mercury_level.sct | 17 -
.../temperature/mercury_level_sct.tcl | 350 -
.../environment/temperature/mercury_pres.sct | 31 -
.../temperature/mercury_pres_sct.tcl | 527 --
.../environment/temperature/mercury_scpi.sct | 89 -
.../temperature/mercury_scpi_sct.tcl | 1008 ---
.../environment/temperature/mercury_temp.sct | 31 -
.../temperature/mercury_temp_sct.tcl | 540 --
.../environment/temperature/mercury_valve.sct | 33 -
.../temperature/mercury_valve_sct.tcl | 473 --
.../environment/temperature/nprvasm2.sct | 11 -
.../environment/temperature/nprvasm2_sct.tcl | 191 -
.../temperature/oxford_mercury.sct | 265 -
.../temperature/oxford_mercury_sct.tcl | 2145 ------
.../environment/temperature/pfeiffer_hg.sct | 77 -
.../temperature/pfeiffer_hg_sct.tcl | 613 --
.../temperature/sct_eurotherm_2000.tcl | 371 -
.../temperature/sct_julabo_lh45.tcl | 526 --
.../temperature/sct_lakeshore_336.tcl | 1915 -----
.../temperature/sct_lakeshore_340.tcl | 2122 ------
.../temperature/sct_lakeshore_370.tcl | 932 ---
.../temperature/sct_oxford_itc.tcl | 549 --
.../environment/temperature/sct_qlink.tcl | 136 -
.../environment/temperature/sct_rvasm2.tcl | 1090 ---
.../environment/temperature/sct_watlow_pm.tcl | 542 --
.../environment/temperature/sct_watlow_rm.tcl | 572 --
.../temperature/sct_watlow_st4.tcl | 783 --
.../environment/temperature/srs_sr630.sct | 45 -
.../environment/temperature/srs_sr630_sct.tcl | 532 --
.../environment/temperature/watlow_mpm.sct | 12 -
.../temperature/watlow_mpm_sct.tcl | 191 -
.../environment/temperature/watlow_mrm.sct | 12 -
.../temperature/watlow_mrm_sct.tcl | 191 -
.../environment/temperature/watlow_mst4.sct | 12 -
.../temperature/watlow_mst4_sct.tcl | 191 -
.../environment/temperature/west400.tcl | 52 -
.../environment/temperature/west4100.sct | 12 -
.../environment/temperature/west4100_sct.tcl | 131 -
.../environment/temperature/west_6100.sct | 83 -
.../environment/temperature/west_6100_sct.tcl | 778 --
.../hipadaba/common_instrument_dictionary.tcl | 231 -
.../hipadaba_configuration_common.tcl | 979 ---
.../hipadaba/instdict_specification.tcl | 143 -
.../instrument/config/hmm/anstohm_linked.xml | 20 -
.../config/hmm/hmm_configuration_common_1.tcl | 1953 -----
...hmm_cylindrical_detector_configuration.tcl | 49 -
.../instrument/config/hmm/hmm_object.tcl | 609 --
.../config/hmm/sct_orhvps_common.tcl | 373 -
site_ansto/instrument/config/load_setup.tcl | 16 -
.../config/motors/magnet_configuration.tcl | 18 -
.../config/motors/sct_aerotech_soloist.tcl | 340 -
.../config/motors/sct_jogmotor_common.tcl | 179 -
.../config/motors/sct_positmotor_common.tcl | 142 -
.../config/nexus/nexus_in_bmon_common_1.dic | 7 -
.../config/nexus/nexus_in_common_1.dic | 49 -
.../config/nexus/nexus_in_hmm_common_1.dic | 25 -
.../config/nexus/nexus_in_scan_common_1.dic | 16 -
.../config/nexus/nxscripts_common_1.tcl | 1382 ----
.../instrument/config/plc/plc_common_1.tcl | 38 -
.../instrument/config/robots/epson_pandp.sct | 15 -
.../config/robots/epson_pandp_sct.tcl | 132 -
.../config/robots/sct_pickandplace.tcl | 494 --
.../instrument/config/scan/scan_common_1.hdd | 8 -
.../instrument/config/scan/scan_common_1.tcl | 749 --
.../config/source/reactor_status.sct | 54 -
.../config/source/reactor_status_sct.tcl | 468 --
.../instrument/config/source/source.tcl | 13 -
.../config/source/source_common.tcl | 115 -
site_ansto/instrument/deploySICS.sh | 284 -
.../instrument/dingo/DMC2280/README.txt | 1 -
.../instrument/dingo/DMC2280/controller4.txt | 80 -
.../instrument/dingo/DMC2280/controller5.txt | 67 -
site_ansto/instrument/dingo/MANIFEST.TXT | 11 -
site_ansto/instrument/dingo/Makefile | 5 -
.../dingo/camtest_configuration.tcl | 72 -
.../instrument/dingo/config/INSTCFCOMMON.TXT | 27 -
site_ansto/instrument/dingo/config/Makefile | 4 -
.../dingo/config/anticollider/acscript.txt | 4 -
.../config/anticollider/anticollider.tcl | 14 -
.../dingo/config/commands/commands.tcl | 12 -
.../dingo/config/counter/counter.tcl | 90 -
.../hipadaba/hipadaba_configuration.tcl | 1 -
.../dingo/config/hmm/hmm_configuration.tcl | 11 -
.../dingo/config/motors/extraconfig.tcl | 14 -
.../config/motors/motor_configuration.tcl | 355 -
.../motors/positmotor_configuration.tcl | 57 -
.../instrument/dingo/config/nexus/Makefile | 3 -
.../dingo/config/nexus/nxscripts.tcl | 4 -
.../instrument/dingo/config/plc/plc.tcl | 119 -
.../instrument/dingo/config/scan/dingo.hdd | 14 -
.../instrument/dingo/config/scan/scan.tcl | 48 -
site_ansto/instrument/dingo/dingo.hdd | 14 -
.../instrument/dingo/dingo_configuration.tcl | 74 -
.../instrument/dingo/hostport_config.tcl | 26 -
.../instrument/dingo/hostport_config_test.tcl | 28 -
site_ansto/instrument/dingo/runsics_def.py | 3 -
.../dingo/script_validator_ports.tcl | 4 -
site_ansto/instrument/dingo/sics_ports.tcl | 4 -
.../instrument/dingo/sics_simulation.tcl | 23 -
.../instrument/dingo/util/sics_config.ini | 238 -
site_ansto/instrument/emu/MANIFEST.TXT | 7 -
.../instrument/emu/config/INSTCFCOMMON.TXT | 18 -
.../emu/config/anticollider/anticollider.tcl | 4 -
.../emu/config/commands/commands.tcl | 10 -
.../instrument/emu/config/counter/counter.tcl | 32 -
.../hipadaba/hipadaba_configuration.tcl | 1 -
.../emu/config/hmm/hmm_configuration.tcl | 74 -
...motion_control_commissioning_checklist.csv | 70 -
.../motors/generated_motor_configuration.tcl | 140 -
.../emu/config/motors/motor_configuration.tcl | 4 -
.../emu/config/motors/sicsmot_attlist.csv | 22 -
.../instrument/emu/config/nexus/nxscripts.tcl | 4 -
site_ansto/instrument/emu/config/plc/plc.tcl | 7 -
.../instrument/emu/config/scan/scan.tcl | 6 -
.../instrument/emu/emu_configuration.tcl | 37 -
site_ansto/instrument/emu/hostport_config.tcl | 35 -
.../instrument/emu/hostport_config_test.tcl | 36 -
site_ansto/instrument/emu/runsics_def.py | 3 -
site_ansto/instrument/emu/sics_simulation.tcl | 23 -
site_ansto/instrument/genCLOSLOOP.tcl | 83 -
site_ansto/instrument/gen_home_slits.tcl | 30 -
site_ansto/instrument/gumxml.tcl | 163 -
site_ansto/instrument/hipd/DMC2280/README.txt | 1 -
.../instrument/hipd/DMC2280/controller1.txt | 384 -
.../instrument/hipd/DMC2280/controller2.txt | 421 --
.../instrument/hipd/DMC2280/controller3.txt | 404 --
.../instrument/hipd/DMC2280/controller4.txt | 385 -
site_ansto/instrument/hipd/MANIFEST.TXT | 10 -
site_ansto/instrument/hipd/Makefile | 5 -
.../instrument/hipd/config/INSTCFCOMMON.TXT | 26 -
site_ansto/instrument/hipd/config/Makefile | 4 -
.../hipd/config/anticollider/acscript.txt | 16 -
.../hipd/config/anticollider/anticollider.tcl | 4 -
.../hipd/config/commands/cfcommands.tcl | 230 -
.../hipd/config/commands/commands.tcl | 229 -
.../hipd/config/commands/eulerscan.tcl | 93 -
.../hipd/config/commands/hvsteps.tcl | 109 -
.../hipd/config/commands/vactex.tcl | 108 -
.../hipd/config/counter/counter.tcl | 32 -
.../magneticField/oxford_labview.tcl | 1 -
.../environment/temperature/lakeshore340.tcl | 51 -
.../hipadaba/hipadaba_configuration.tcl | 1 -
.../hipd/config/hipadaba/hpaths.tcl | 29 -
.../hipd/config/hmm/anstohm_full.xml | 244 -
.../config/hmm/anstohm_full_calibration.xml | 244 -
.../hipd/config/hmm/anstohm_full_normal.xml | 244 -
.../hipd/config/hmm/anstohm_full_pulser.xml | 244 -
.../hipd/config/hmm/anstohm_full_small.xml | 353 -
.../hipd/config/hmm/anstohm_full_standard.xml | 244 -
.../hipd/config/hmm/hmm_configuration.tcl | 165 -
.../instrument/hipd/config/hmm/hmm_rapid.tcl | 181 -
.../instrument/hipd/config/hmm/hmm_temp.tcl | 74 -
.../config/motors/euler_configuration.tcl | 169 -
.../config/motors/eulinf_configuration.tcl | 168 -
.../config/motors/motor_configuration.tcl | 680 --
.../motors/positmotor_configuration.tcl | 2 -
.../hipd/config/motors/small_omega_config.tcl | 91 -
.../hipd/config/motors/tilt_configuration.tcl | 92 -
.../instrument/hipd/config/nexus/Makefile | 3 -
.../hipd/config/nexus/nexus_in_motors.dic | 22 -
.../hipd/config/nexus/nxscripts.tcl | 4 -
site_ansto/instrument/hipd/config/plc/plc.tcl | 8 -
.../instrument/hipd/config/scan/scan.tcl | 6 -
site_ansto/instrument/hipd/extraconfig.tcl | 8 -
.../instrument/hipd/hostport_config.tcl | 29 -
.../instrument/hipd/hostport_config_test.tcl | 31 -
.../instrument/hipd/instrument_vars.tcl | 3 -
site_ansto/instrument/hipd/runsics_def.py | 3 -
.../hipd/script_validator/MANIFEST.TXT | 2 -
.../config/counter/counter.tcl | 4 -
.../config/hmm/hmm_configuration.tcl | 49 -
.../hipd/script_validator/sics_ports.tcl | 4 -
.../hipd/script_validator_ports.tcl | 4 -
site_ansto/instrument/hipd/sics_ports.tcl | 4 -
.../instrument/hipd/sics_simulation.tcl | 23 -
.../hipd/util/dmc2280/troubleshoot_setup.tcl | 19 -
.../instrument/hipd/util/sics_config.ini | 414 --
.../instrument/hipd/wombat_configuration.tcl | 106 -
site_ansto/instrument/hrpd/DMC2280/README.txt | 1 -
.../instrument/hrpd/DMC2280/controller1.txt | 384 -
.../instrument/hrpd/DMC2280/controller2.txt | 377 -
.../instrument/hrpd/DMC2280/controller3.txt | 404 --
.../instrument/hrpd/DMC2280/controller4.txt | 388 -
site_ansto/instrument/hrpd/MANIFEST.TXT | 10 -
site_ansto/instrument/hrpd/Makefile | 5 -
.../instrument/hrpd/Test/cyclebatch.tcl | 35 -
.../instrument/hrpd/config/INSTCFCOMMON.TXT | 28 -
site_ansto/instrument/hrpd/config/Makefile | 4 -
.../hrpd/config/anticollider/acscript.txt | 25 -
.../hrpd/config/anticollider/anticollider.tcl | 4 -
.../hrpd/config/commands/commands.tcl | 10 -
.../hrpd/config/counter/counter.tcl | 32 -
.../environment/robby_configuration.tcl | 9 -
.../environment/temperature/lakeshore340.tcl | 51 -
.../hipadaba/hipadaba_configuration.tcl | 1 -
.../hrpd/config/hipadaba/hpaths.tcl | 30 -
.../hrpd/config/hmm/anstohm_full.xml | 244 -
.../hmm/anstohm_full_MESYTEC_PULSER.xml | 243 -
.../hrpd/config/hmm/anstohm_full_folding.xml | 243 -
.../config/hmm/anstohm_full_nofolding.xml | 243 -
.../hrpd/config/hmm/hmm_configuration.tcl | 200 -
.../config/motors/euler_configuration.tcl | 74 -
.../config/motors/motor_configuration.tcl | 708 --
.../motors/positmotor_configuration.tcl | 2 -
.../hrpd/config/motors/small_omega_config.tcl | 91 -
.../hrpd/config/motors/tilt_configuration.tcl | 84 -
.../instrument/hrpd/config/nexus/Makefile | 3 -
.../hrpd/config/nexus/nexus_in_motors.dic | 22 -
.../hrpd/config/nexus/nxscripts.tcl | 4 -
site_ansto/instrument/hrpd/config/plc/plc.tcl | 8 -
.../instrument/hrpd/config/scan/scan.tcl | 6 -
.../instrument/hrpd/echidna_configuration.tcl | 89 -
site_ansto/instrument/hrpd/extraconfig.tcl | 6 -
.../instrument/hrpd/hostport_config.tcl | 29 -
.../instrument/hrpd/hostport_config_test.tcl | 31 -
.../instrument/hrpd/instrument_vars.tcl | 9 -
site_ansto/instrument/hrpd/runsics_def.py | 3 -
.../hrpd/script_validator/MANIFEST.TXT | 0
.../config/counter/counter.tcl | 4 -
.../config/hmm/hmm_configuration.tcl | 50 -
.../hrpd/script_validator/sics_ports.tcl | 4 -
.../hrpd/script_validator_ports.tcl | 4 -
site_ansto/instrument/hrpd/sics_ports.tcl | 4 -
.../instrument/hrpd/sics_simulation.tcl | 23 -
.../hrpd/util/dmc2280/troubleshoot_setup.tcl | 19 -
.../instrument/hrpd/util/sics_config.ini | 373 -
.../instrument/kookaburra/DMC2280/README.txt | 1 -
.../kookaburra/DMC2280/controller4.txt | 80 -
.../kookaburra/DMC2280/controller5.txt | 67 -
site_ansto/instrument/kookaburra/MANIFEST.TXT | 9 -
site_ansto/instrument/kookaburra/Makefile | 5 -
.../kookaburra/config/INSTCFCOMMON.TXT | 26 -
.../instrument/kookaburra/config/Makefile | 4 -
.../config/anticollider/acscript.txt | 13 -
.../config/anticollider/anticollider.tcl | 35 -
.../config/chopper/sct_fermichopper.tcl | 247 -
.../kookaburra/config/commands/commands.tcl | 12 -
.../kookaburra/config/commands/monodrive.tcl | 122 -
.../kookaburra/config/counter/counter.tcl | 32 -
.../kookaburra/config/counter/sct_bm.tcl | 386 -
.../hipadaba/hipadaba_configuration.tcl | 1 -
.../kookaburra/config/hmm/anstohm_linked.xml | 38 -
.../config/hmm/hmm_configuration.tcl | 140 -
.../kookaburra/config/motors/extraconfig.tcl | 14 -
.../config/motors/motor_configuration.tcl | 703 --
.../motors/positmotor_configuration.tcl | 61 -
.../kookaburra/config/nexus/Makefile | 3 -
.../kookaburra/config/nexus/nxscripts.tcl | 4 -
.../config/parameters/parameters.tcl | 30 -
.../instrument/kookaburra/config/plc/plc.tcl | 8 -
.../kookaburra/config/scan/scan.tcl | 60 -
.../instrument/kookaburra/hostport_config.tcl | 28 -
.../kookaburra/hostport_config_test.tcl | 32 -
.../kookaburra/kookaburra_configuration.tcl | 76 -
.../instrument/kookaburra/runsics_def.py | 3 -
.../kookaburra/script_validator_ports.tcl | 4 -
.../instrument/kookaburra/sics_ports.tcl | 4 -
.../instrument/kookaburra/sics_simulation.tcl | 23 -
.../kookaburra/util/sics_config.ini | 237 -
.../instrument/lyrebird/DMC2280/README.txt | 1 -
.../lyrebird/DMC2280/controller1.txt | 168 -
.../lyrebird/DMC2280/controller2.txt | 140 -
.../lyrebird/DMC2280/controller3.txt | 140 -
.../lyrebird/DMC2280/controller4.txt | 152 -
site_ansto/instrument/lyrebird/MANIFEST.TXT | 9 -
site_ansto/instrument/lyrebird/Makefile | 5 -
.../lyrebird/config/INSTCFCOMMON.TXT | 26 -
.../instrument/lyrebird/config/Makefile | 4 -
.../lyrebird/config/anticollider/acscript.txt | 3 -
.../config/anticollider/anticollider.tcl | 14 -
.../lyrebird/config/commands/commands.tcl | 10 -
.../lyrebird/config/counter/counter.tcl | 32 -
.../config/goniometer/sct_goniometer.tcl | 183 -
.../config/goniometer/spin_goniometer.tcl | 10 -
.../hipadaba/hipadaba_configuration.tcl | 1 -
.../lyrebird/config/hmm/hmm_configuration.tcl | 142 -
.../config/motors/motor_configuration.tcl | 781 --
.../motors/positmotor_configuration.tcl | 61 -
.../lyrebird/config/motors/sct_flightTube.tcl | 98 -
.../lyrebird/config/motors/spin_galil.tcl | 13 -
.../instrument/lyrebird/config/nexus/Makefile | 3 -
.../lyrebird/config/nexus/nxscripts.tcl | 4 -
.../lyrebird/config/optics/README.TXT | 1 -
.../lyrebird/config/optics/optics.tcl | 2 -
.../instrument/lyrebird/config/plc/plc.tcl | 4 -
.../instrument/lyrebird/config/scan/scan.tcl | 6 -
.../config/tasmad/sicscommon/ASCIIplot.tcl | 77 -
.../config/tasmad/sicscommon/andorhm.tcl | 112 -
.../config/tasmad/sicscommon/astrium.tcl | 524 --
.../config/tasmad/sicscommon/backup.tcl | 32 -
.../config/tasmad/sicscommon/batch.tcl | 29 -
.../config/tasmad/sicscommon/ccdwww.tcl | 169 -
.../lyrebird/config/tasmad/sicscommon/debsics | 1 -
.../config/tasmad/sicscommon/deltatau.tcl | 357 -
.../config/tasmad/sicscommon/el734.tcl | 488 --
.../config/tasmad/sicscommon/el737sec.tcl | 321 -
.../config/tasmad/sicscommon/el755.tcl | 97 -
.../config/tasmad/sicscommon/fourcircle.tcl | 1773 -----
.../config/tasmad/sicscommon/fsync.jar | Bin 6108 -> 0 bytes
.../config/tasmad/sicscommon/hdbutil.tcl | 944 ---
.../config/tasmad/sicscommon/kt.sinqbck | Bin 498 -> 0 bytes
.../config/tasmad/sicscommon/motorhp.tcl | 82 -
.../config/tasmad/sicscommon/nxsupport.tcl | 126 -
.../config/tasmad/sicscommon/phytron.tcl | 311 -
.../config/tasmad/sicscommon/pimotor.tcl | 177 -
.../config/tasmad/sicscommon/secsim.tcl | 66 -
.../config/tasmad/sicscommon/simhm.tcl | 91 -
.../config/tasmad/sicscommon/sinqhttp.tcl | 152 -
.../config/tasmad/sicscommon/stddrive.tcl | 100 -
.../config/tasmad/sicscommon/syncwrapper.pag | 8 -
.../config/tasmad/sicscommon/table.tcl | 317 -
.../config/tasmad/sicscommon/tecs.tcl | 23 -
.../config/tasmad/taspub_sics/nxtas.tcl | 348 -
.../config/tasmad/taspub_sics/tas.dic | 83 -
.../config/tasmad/taspub_sics/tas.hdd | 19 -
.../config/tasmad/taspub_sics/tasp.tcl | 286 -
.../config/tasmad/taspub_sics/taspubcom.tcl | 47 -
.../config/tasmad/taspub_sics/tasscript.tcl | 1517 ----
.../config/tasmad/taspub_sics/tasub.dic | 138 -
.../instrument/lyrebird/hostport_config.tcl | 30 -
.../lyrebird/hostport_config_test.tcl | 31 -
.../lyrebird/lyrebird_configuration.tcl | 48 -
site_ansto/instrument/lyrebird/runsics_def.py | 3 -
.../lyrebird/script_validator/MANIFEST.TXT | 2 -
.../config/counter/counter.tcl | 4 -
.../config/hmm/hmm_configuration.tcl | 27 -
.../lyrebird/script_validator/sics_ports.tcl | 4 -
.../lyrebird/script_validator_ports.tcl | 4 -
site_ansto/instrument/lyrebird/sics_ports.tcl | 4 -
.../util/dmc2280/troubleshoot_setup.tcl | 19 -
site_ansto/instrument/mksim_config.tcl | 33 -
site_ansto/instrument/pas/DMC2280/README.txt | 1 -
.../instrument/pas/config/INSTCFCOMMON.TXT | 24 -
.../instrument/pas/pelican_configuration.tcl | 38 -
.../instrument/pelican/DMC2280/README.txt | 1 -
.../pelican/DMC2280/controller4.txt | 80 -
.../pelican/DMC2280/controller5.txt | 67 -
site_ansto/instrument/pelican/MANIFEST.TXT | 9 -
site_ansto/instrument/pelican/Makefile | 5 -
.../pelican/config/INSTCFCOMMON.TXT | 27 -
site_ansto/instrument/pelican/config/Makefile | 4 -
.../pelican/config/anticollider/acscript.txt | 11 -
.../config/anticollider/anticollider.tcl | 14 -
.../pelican/config/beamline/sct_power.tcl | 1127 ---
.../pelican/config/chopper/fermimot.tcl | 698 --
.../config/chopper/sct_fermichopper.tcl | 267 -
.../pelican/config/commands/commands.tcl | 12 -
.../pelican/config/commands/monodrive.tcl | 122 -
.../pelican/config/counter/counter.tcl | 32 -
.../hipadaba/hipadaba_configuration.tcl | 1 -
.../pelican/config/hmm/hmm_configuration.tcl | 275 -
.../instrument/pelican/config/hmm/sct_hv.tcl | 429 --
.../pelican/config/motors/extraconfig.tcl | 14 -
.../config/motors/motor_configuration.tcl | 978 ---
.../motors/positmotor_configuration.tcl | 1 -
.../instrument/pelican/config/nexus/Makefile | 3 -
.../pelican/config/nexus/nxscripts.tcl | 4 -
.../instrument/pelican/config/plc/plc.tcl | 12 -
.../instrument/pelican/config/scan/scan.tcl | 6 -
.../instrument/pelican/hostport_config.tcl | 38 -
.../pelican/hostport_config_test.tcl | 40 -
.../pelican/pelican_configuration.tcl | 119 -
site_ansto/instrument/pelican/runsics_def.py | 3 -
.../pelican/script_validator/MANIFEST.TXT | 2 -
.../config/counter/counter.tcl | 4 -
.../config/hmm/hmm_configuration.tcl | 27 -
.../pelican/script_validator/sics_ports.tcl | 4 -
.../pelican/script_validator_ports.tcl | 4 -
site_ansto/instrument/pelican/sics_ports.tcl | 4 -
.../instrument/pelican/sics_simulation.tcl | 23 -
.../util/dmc2280/troubleshoot_setup.tcl | 19 -
.../instrument/pelican/util/sics_config.ini | 331 -
site_ansto/instrument/qld/DMC2280/README.txt | 1 -
.../instrument/qld/DMC2280/controller1.txt | 33 -
.../instrument/qld/DMC2280/controller2.txt | 108 -
site_ansto/instrument/qld/MANIFEST.TXT | 8 -
site_ansto/instrument/qld/counter.tcl | 19 -
site_ansto/instrument/qld/extraconfig.tcl | 0
.../instrument/qld/hipadaba_configuration.tcl | 0
site_ansto/instrument/qld/hpaths.tcl | 22 -
site_ansto/instrument/qld/koala.hdd | 8 -
.../instrument/qld/koala_configuration.tcl | 22 -
.../instrument/qld/motor_configuration.tcl | 246 -
.../instrument/qld/troubleshoot_setup.tcl | 19 -
.../reflectometer/DMC2280/README.txt | 1 -
.../reflectometer/DMC2280/controller1.txt | 425 --
.../reflectometer/DMC2280/controller2.txt | 365 -
.../reflectometer/DMC2280/controller3.txt | 418 --
.../reflectometer/DMC2280/controller4.txt | 411 --
.../instrument/reflectometer/MANIFEST.TXT | 9 -
site_ansto/instrument/reflectometer/Makefile | 5 -
.../reflectometer/config/INSTCFCOMMON.TXT | 25 -
.../instrument/reflectometer/config/Makefile | 4 -
.../config/anticollider/acscript.txt | 3 -
.../config/anticollider/anticollider.tcl | 14 -
.../reflectometer/config/beamline/polanal.tcl | 43 -
.../config/beamline/sct_RFGen.tcl | 435 --
.../reflectometer/config/chopper/chopper.tcl | 9 -
.../config/chopper/sct_chopper.tcl | 325 -
.../config/commands/commands.tcl | 467 --
.../reflectometer/config/counter/counter.tcl | 32 -
.../hipadaba/hipadaba_configuration.tcl | 10 -
.../reflectometer/config/hipadaba/hpaths.tcl | 33 -
.../reflectometer/config/hmm/detector.tcl | 27 -
.../config/hmm/hmm_configuration.tcl | 110 -
.../config/motors/motor_configuration.tcl | 937 ---
.../motors/positmotor_configuration.tcl | 2 -
.../config/motors/sct_batmotor.tcl | 194 -
.../reflectometer/config/nexus/Makefile | 3 -
.../config/nexus/nexus_in_motors.dic | 22 -
.../reflectometer/config/nexus/nxscripts.tcl | 4 -
.../config/parameters/parameters.tcl | 98 -
.../reflectometer/config/plc/plc.tcl | 8 -
.../reflectometer/config/scan/scan.tcl | 14 -
.../reflectometer/hostport_config.tcl | 37 -
.../reflectometer/hostport_config_test.tcl | 37 -
.../reflectometer/platypus_configuration.tcl | 68 -
.../instrument/reflectometer/runsics_def.py | 3 -
.../script_validator/MANIFEST.TXT | 2 -
.../config/counter/counter.tcl | 4 -
.../config/hmm/hmm_configuration.tcl | 27 -
.../script_validator/sics_ports.tcl | 4 -
.../reflectometer/script_validator_ports.tcl | 4 -
.../instrument/reflectometer/sics_ports.tcl | 4 -
.../reflectometer/sics_simulation.tcl | 23 -
.../util/dmc2280/troubleshoot_setup.tcl | 19 -
.../reflectometer/util/sics_config.ini | 324 -
site_ansto/instrument/rsd/DMC2280/README.txt | 1 -
.../instrument/rsd/DMC2280/controller1.txt | 384 -
.../instrument/rsd/DMC2280/controller2.txt | 174 -
.../instrument/rsd/DMC2280/controller3.txt | 100 -
.../instrument/rsd/DMC2280/controller4.txt | 233 -
site_ansto/instrument/rsd/MANIFEST.TXT | 9 -
site_ansto/instrument/rsd/Makefile | 5 -
.../instrument/rsd/config/INSTCFCOMMON.TXT | 25 -
site_ansto/instrument/rsd/config/Makefile | 4 -
.../rsd/config/anticollider/acscript.txt | 10 -
.../rsd/config/anticollider/anticollider.tcl | 4 -
.../rsd/config/commands/commands.tcl | 10 -
.../instrument/rsd/config/counter/counter.tcl | 32 -
.../hipadaba/hipadaba_configuration.tcl | 1 -
.../instrument/rsd/config/hipadaba/hpaths.tcl | 29 -
.../rsd/config/hmm/hmm_configuration.tcl | 109 -
.../rsd/config/motors/euler_configuration.tcl | 91 -
.../rsd/config/motors/motor_configuration.tcl | 748 --
.../motors/positmotor_configuration.tcl | 2 -
.../motors/secondary_slit_configuration.tcl | 45 -
.../motors/tiny_black_euler_configuration.tcl | 104 -
.../instrument/rsd/config/nexus/nxscripts.tcl | 7 -
site_ansto/instrument/rsd/config/plc/plc.tcl | 8 -
.../instrument/rsd/config/scan/scan.tcl | 6 -
.../instrument/rsd/hipadaba_configuration.tcl | 34 -
site_ansto/instrument/rsd/hostport_config.tcl | 29 -
.../instrument/rsd/hostport_config_test.tcl | 31 -
site_ansto/instrument/rsd/hpaths.tcl | 29 -
site_ansto/instrument/rsd/kowari.hdd | 8 -
.../instrument/rsd/kowari_configuration.tcl | 62 -
site_ansto/instrument/rsd/runsics_def.py | 3 -
.../rsd/script_validator/MANIFEST.TXT | 1 -
.../rsd/script_validator/sics_ports.tcl | 4 -
.../instrument/rsd/script_validator_ports.tcl | 4 -
site_ansto/instrument/rsd/sics_ports.tcl | 4 -
site_ansto/instrument/rsd/sics_simulation.tcl | 23 -
.../instrument/rsd/util/sics_config.ini | 96 -
site_ansto/instrument/runsics.py | 242 -
site_ansto/instrument/sans/DMC2280/README.txt | 1 -
.../instrument/sans/DMC2280/controller1.txt | 168 -
.../instrument/sans/DMC2280/controller2.txt | 140 -
.../instrument/sans/DMC2280/controller3.txt | 140 -
.../instrument/sans/DMC2280/controller4.txt | 152 -
site_ansto/instrument/sans/MANIFEST.TXT | 9 -
site_ansto/instrument/sans/Makefile | 5 -
.../instrument/sans/config/INSTCFCOMMON.TXT | 26 -
site_ansto/instrument/sans/config/Makefile | 4 -
.../sans/config/anticollider/acscript.txt | 5 -
.../sans/config/anticollider/anticollider.tcl | 14 -
.../sans/config/beamline/sct_flipper.tcl | 422 --
.../sans/config/beamline/spin_flipper.tcl | 18 -
.../sans/config/commands/commands.tcl | 216 -
.../sans/config/commands/growfile.tcl | 96 -
.../sans/config/counter/counter.tcl | 32 -
.../sans/config/counter/sct_rheometer.tcl | 81 -
.../sans/config/environment/environment.tcl | 164 -
.../magneticField/oxford_labview.tcl | 1 -
.../environment/temperature/lakeshore340.tcl | 51 -
.../sans/config/goniometer/sct_goniometer.tcl | 183 -
.../config/goniometer/spin_goniometer.tcl | 10 -
.../hipadaba/hipadaba_configuration.tcl | 1 -
.../sans/config/hipadaba/hpaths.tcl | 33 -
.../instrument/sans/config/hmm/detector.tcl | 1 -
.../sans/config/hmm/detector_ordela.tcl | 536 --
.../sans/config/hmm/hmm_configuration.tcl | 90 -
.../config/hmm/nhq200_detector_config.tcl | 19 -
.../config/hmm/ordela_detector_config.tcl | 40 -
.../config/motors/motor_configuration.tcl | 1044 ---
.../motors/positmotor_configuration.tcl | 87 -
.../instrument/sans/config/nexus/Makefile | 3 -
.../sans/config/nexus/nexus_in_motors.dic | 22 -
.../sans/config/nexus/nxscripts.tcl | 13 -
.../instrument/sans/config/optics/README.TXT | 1 -
.../config/optics/aperture_configuration.tcl | 94 -
.../config/optics/guide_configuration.tcl | 66 -
.../instrument/sans/config/optics/optics.tcl | 2 -
.../sans/config/parameters/parameters.tcl | 156 -
site_ansto/instrument/sans/config/plc/plc.tcl | 8 -
.../instrument/sans/config/scan/scan.tcl | 6 -
.../sans/config/velsel/sct_velsel.tcl | 667 --
.../instrument/sans/config/velsel/velsel.tcl | 57 -
.../instrument/sans/hostport_config.tcl | 48 -
.../instrument/sans/hostport_config_test.tcl | 50 -
.../instrument/sans/quokka_configuration.tcl | 94 -
site_ansto/instrument/sans/runsics_def.py | 3 -
.../sans/script_validator/MANIFEST.TXT | 2 -
.../config/counter/counter.tcl | 4 -
.../config/hmm/hmm_configuration.tcl | 27 -
.../sans/script_validator/sics_ports.tcl | 4 -
.../sans/script_validator_ports.tcl | 4 -
site_ansto/instrument/sans/sics_ports.tcl | 4 -
.../instrument/sans/sics_simulation.tcl | 23 -
.../sans/util/dmc2280/troubleshoot_setup.tcl | 19 -
site_ansto/instrument/sans/util/dsc.py | 94 -
.../instrument/sans/util/sics_config.ini | 472 --
site_ansto/instrument/server_config.tcl | 389 -
site_ansto/instrument/tas/DMC2280/README.txt | 1 -
.../instrument/tas/DMC2280/controller1.txt | 666 --
.../instrument/tas/DMC2280/controller2.txt | 368 -
.../instrument/tas/DMC2280/controller3.txt | 252 -
.../instrument/tas/DMC2280/controller4.txt | 287 -
.../instrument/tas/DMC2280/controller5.txt | 75 -
.../instrument/tas/DMC2280/controller6.txt | 443 --
site_ansto/instrument/tas/MANIFEST.TXT | 9 -
site_ansto/instrument/tas/Makefile | 5 -
.../instrument/tas/config/INSTCFCOMMON.TXT | 26 -
site_ansto/instrument/tas/config/Makefile | 4 -
.../tas/config/anticollider/acscript.txt | 4 -
.../tas/config/anticollider/anticollider.tcl | 14 -
.../tas/config/commands/commands.tcl | 16 -
.../instrument/tas/config/counter/counter.tcl | 32 -
.../tas/config/environment/environment.tcl | 55 -
.../magneticField/oxford_labview.tcl | 1 -
.../environment/temperature/lakeshore340.tcl | 51 -
.../hipadaba/hipadaba_configuration.tcl | 1 -
.../instrument/tas/config/hmm/detector.tcl | 6 -
.../tas/config/hmm/hmm_configuration.tcl | 76 -
.../tas/config/motors/euler_configuration.tcl | 76 -
.../tas/config/motors/motor_configuration.tcl | 981 ---
.../motors/positmotor_configuration.tcl | 3 -
.../tas/config/motors/tilt_configuration.tcl | 92 -
.../instrument/tas/config/nexus/Makefile | 3 -
.../instrument/tas/config/nexus/nxscripts.tcl | 4 -
.../instrument/tas/config/optics/README.TXT | 1 -
.../instrument/tas/config/optics/optics.tcl | 2 -
site_ansto/instrument/tas/config/plc/plc.tcl | 8 -
.../instrument/tas/config/scan/scan.tcl | 6 -
.../config/tasmad/sicscommon/ASCIIplot.tcl | 77 -
.../tas/config/tasmad/sicscommon/andorhm.tcl | 112 -
.../tas/config/tasmad/sicscommon/astrium.tcl | 524 --
.../tas/config/tasmad/sicscommon/backup.tcl | 32 -
.../tas/config/tasmad/sicscommon/batch.tcl | 29 -
.../tas/config/tasmad/sicscommon/ccdwww.tcl | 169 -
.../tas/config/tasmad/sicscommon/debsics | 1 -
.../tas/config/tasmad/sicscommon/deltatau.tcl | 357 -
.../tas/config/tasmad/sicscommon/el734.tcl | 488 --
.../tas/config/tasmad/sicscommon/el737sec.tcl | 321 -
.../tas/config/tasmad/sicscommon/el755.tcl | 97 -
.../config/tasmad/sicscommon/fourcircle.tcl | 1773 -----
.../tas/config/tasmad/sicscommon/fsync.jar | Bin 6108 -> 0 bytes
.../tas/config/tasmad/sicscommon/hdbutil.tcl | 944 ---
.../tas/config/tasmad/sicscommon/kt.sinqbck | Bin 498 -> 0 bytes
.../tas/config/tasmad/sicscommon/motorhp.tcl | 82 -
.../config/tasmad/sicscommon/nxsupport.tcl | 126 -
.../tas/config/tasmad/sicscommon/phytron.tcl | 311 -
.../tas/config/tasmad/sicscommon/pimotor.tcl | 177 -
.../tas/config/tasmad/sicscommon/secsim.tcl | 66 -
.../tas/config/tasmad/sicscommon/simhm.tcl | 91 -
.../tas/config/tasmad/sicscommon/sinqhttp.tcl | 152 -
.../tas/config/tasmad/sicscommon/stddrive.tcl | 100 -
.../config/tasmad/sicscommon/syncwrapper.pag | 8 -
.../tas/config/tasmad/sicscommon/table.tcl | 317 -
.../tas/config/tasmad/sicscommon/tecs.tcl | 23 -
.../tas/config/tasmad/taspub_sics/nxtas.tcl | 348 -
.../tas/config/tasmad/taspub_sics/tas.dic | 83 -
.../tas/config/tasmad/taspub_sics/tas.hdd | 19 -
.../tas/config/tasmad/taspub_sics/tasp.tcl | 286 -
.../config/tasmad/taspub_sics/taspubcom.tcl | 47 -
.../config/tasmad/taspub_sics/tasscript.tcl | 1517 ----
.../tas/config/tasmad/taspub_sics/tasub.dic | 138 -
site_ansto/instrument/tas/hostport_config.tcl | 20 -
.../instrument/tas/hostport_config_test.tcl | 22 -
site_ansto/instrument/tas/runsics_def.py | 3 -
.../tas/script_validator/MANIFEST.TXT | 2 -
.../config/counter/counter.tcl | 4 -
.../config/hmm/hmm_configuration.tcl | 27 -
.../tas/script_validator/sics_ports.tcl | 4 -
.../instrument/tas/script_validator_ports.tcl | 4 -
site_ansto/instrument/tas/sics_ports.tcl | 4 -
site_ansto/instrument/tas/sics_simulation.tcl | 23 -
.../instrument/tas/taipan_configuration.tcl | 194 -
site_ansto/instrument/tas/tas.hdd | 33 -
.../tas/util/dmc2280/troubleshoot_setup.tcl | 19 -
.../instrument/tas/util/sics_config.ini | 439 --
site_ansto/instrument/util/check/README.TXT | 33 -
.../instrument/util/check/check_hdb.tcl | 40 -
.../instrument/util/check/check_sobj.tcl | 38 -
.../instrument/util/check/query_sics.tcl | 118 -
site_ansto/instrument/util/command.tcl | 144 -
site_ansto/instrument/util/config_edit.py | 716 --
site_ansto/instrument/util/config_reader.tcl | 133 -
site_ansto/instrument/util/displayscreen.py | 150 -
site_ansto/instrument/util/dmc2280/ckmd5.sh | 13 -
.../instrument/util/dmc2280/dmc2280_util.tcl | 68 -
.../instrument/util/dmc2280/getDMCprog.tcl | 36 -
site_ansto/instrument/util/dmc2280/mkmd5.sh | 8 -
.../instrument/util/dmc2280/motorinfo.tcl | 82 -
.../instrument/util/dmc2280/putDMCprog.tcl | 83 -
.../instrument/util/dmc2280/troubleShoot.tcl | 132 -
site_ansto/instrument/util/eventutil.tcl | 142 -
site_ansto/instrument/util/extra_utility.tcl | 248 -
site_ansto/instrument/util/fopdt.py | 123 -
site_ansto/instrument/util/gen_sct.py | 2205 ------
site_ansto/instrument/util/genmotconf.tcl | 299 -
.../instrument/util/genmotconf_procs.tcl | 247 -
site_ansto/instrument/util/gitloader.py | 69 -
site_ansto/instrument/util/gitrefer.py | 160 -
site_ansto/instrument/util/mk_SICSmd5.sh | 28 -
site_ansto/instrument/util/motor_utility.tcl | 276 -
site_ansto/instrument/util/pid.py | 119 -
site_ansto/instrument/util/runsics | 117 -
site_ansto/instrument/util/runtestsics | 93 -
.../instrument/util/script_context_util.tcl | 104 -
site_ansto/instrument/util/sicsclient | 5 -
site_ansto/instrument/util/utility.tcl | 946 ---
site_ansto/instrument/util/whatsthere.py | 192 -
site_ansto/instrument/util/write_tree.tcl | 61 -
site_ansto/itc4.c | 281 -
site_ansto/itc4.h | 43 -
site_ansto/itc4.w | 74 -
site_ansto/itc4driv.c | 478 --
site_ansto/lakeshore340.c | 284 -
site_ansto/lakeshore340.h | 49 -
site_ansto/lakeshore340driv.c | 482 --
site_ansto/lh45.c | 284 -
site_ansto/lh45.h | 49 -
site_ansto/lh45driv.c | 478 --
site_ansto/ls340.c | 1297 ----
site_ansto/ls340.h | 33 -
site_ansto/lssmonitor.c | 561 --
site_ansto/lssmonitor.h | 15 -
site_ansto/make_config.sh | 22 -
site_ansto/make_gen_variables | 39 -
site_ansto/manual/Thumbs.db | Bin 7168 -> 0 bytes
site_ansto/manual/buttonBack.JPG | Bin 1526 -> 0 bytes
site_ansto/manual/buttonBegin.JPG | Bin 1500 -> 0 bytes
site_ansto/manual/buttonCross.JPG | Bin 1038 -> 0 bytes
site_ansto/manual/buttonDrive.JPG | Bin 2502 -> 0 bytes
site_ansto/manual/buttonExport.JPG | Bin 1852 -> 0 bytes
site_ansto/manual/buttonInterrupt.JPG | Bin 5479 -> 0 bytes
site_ansto/manual/buttonLoad.JPG | Bin 1729 -> 0 bytes
site_ansto/manual/buttonNext.JPG | Bin 1465 -> 0 bytes
site_ansto/manual/buttonOK.JPG | Bin 1327 -> 0 bytes
site_ansto/manual/buttonPause.JPG | Bin 3815 -> 0 bytes
site_ansto/manual/buttonPlus.JPG | Bin 1010 -> 0 bytes
site_ansto/manual/buttonResultXML.JPG | Bin 1981 -> 0 bytes
site_ansto/manual/buttonRun.JPG | Bin 1443 -> 0 bytes
site_ansto/manual/buttonTableImage.JPG | Bin 2025 -> 0 bytes
.../manual/db5SICSInstallationManual.xml | 19 -
site_ansto/manual/db5SICSUserGuideQuokka.xml | 46 -
site_ansto/manual/db5SICSUserGuideTaipan.xml | 68 -
site_ansto/manual/db5SICSUserManual3Axis.xml | 155 -
.../manual/db5SICSUserManualPelican.xml | 161 -
.../manual/db5SICSUserManualPlatypus.xml | 166 -
site_ansto/manual/db5SICSUserManualPowder.xml | 150 -
site_ansto/manual/db5SICSUserManualQuokka.xml | 194 -
.../db5SICSUserManualSampleEnvironment.xml | 56 -
site_ansto/manual/db5alignment_taipan.xml | 412 --
.../manual/db5environment_config_taipan.xml | 241 -
.../manual/db5environment_control_taipan.xml | 207 -
site_ansto/manual/db5experiment_taipan.xml | 120 -
site_ansto/manual/db5quickstart_quokka.xml | 64 -
site_ansto/manual/db5quickstart_taipan.xml | 64 -
site_ansto/manual/db5sics_login.xml | 99 -
site_ansto/manual/dbGTQuokka_ch0_contacts.xml | 38 -
.../manual/dbGTQuokka_ch1_experiment.xml | 227 -
.../manual/dbGTQuokka_ch2_reduction.xml | 85 -
.../manual/dbGTQuokka_ch3_reduction.xml | 161 -
site_ansto/manual/dbSICSch0_TEMPLATE.xml | 63 -
site_ansto/manual/dbSICSch10_tcl_commands.xml | 209 -
site_ansto/manual/dbSICSch11_julabo.xml | 279 -
site_ansto/manual/dbSICSch12_velsel.xml | 276 -
.../manual/dbSICSch13_echidna_motor_names.xml | 234 -
.../manual/dbSICSch14_troubleshooting.xml | 138 -
site_ansto/manual/dbSICSch15_beamstop.xml | 87 -
site_ansto/manual/dbSICSch16_ordela_hv.xml | 133 -
.../dbSICSch17_control_and_interrupt.xml | 896 ---
.../manual/dbSICSch18_programmer_overview.xml | 672 --
.../manual/dbSICSch19_interrupting_sics.xml | 149 -
site_ansto/manual/dbSICSch1_intro.xml | 260 -
.../manual/dbSICSch20_file_commands.xml | 281 -
.../dbSICSch21_histogram_configuration.xml | 46 -
site_ansto/manual/dbSICSch22_installation.xml | 266 -
site_ansto/manual/dbSICSch23_extraconfig.xml | 117 -
site_ansto/manual/dbSICSch24_UB_matrix.xml | 408 --
site_ansto/manual/dbSICSch25_rheometer.xml | 137 -
site_ansto/manual/dbSICSch26_magnet_11T.xml | 73 -
site_ansto/manual/dbSICSch27_autosave.xml | 353 -
site_ansto/manual/dbSICSch28_LF_amplifier.xml | 203 -
.../manual/dbSICSch29_motor_control_py.xml | 782 --
.../dbSICSch29_motor_control_py_simple.xml | 756 --
site_ansto/manual/dbSICSch2_motor_control.xml | 843 ---
site_ansto/manual/dbSICSch30_He3.xml | 163 -
.../manual/dbSICSch31_UserGuideTaipan.xml | 957 ---
.../dbSICSch32_platypus_disk_chopper.xml | 306 -
.../manual/dbSICSch33_UserGuideQuokka.xml | 69 -
.../manual/dbSICSch34_fermi_chopper.xml | 573 --
.../dbSICSch34_fermi_chopper_shortnames.xml | 572 --
.../manual/dbSICSch35_oxford_labview.xml | 164 -
.../manual/dbSICSch36_oxford_mercury.xml | 99 -
.../manual/dbSICSch3_histogram_control.xml | 303 -
site_ansto/manual/dbSICSch4_simple_scan.xml | 308 -
.../manual/dbSICSch4_simple_scan_py.xml | 313 -
.../dbSICSch4_simple_scan_taipan_only.xml | 303 -
site_ansto/manual/dbSICSch5_batch.xml | 259 -
site_ansto/manual/dbSICSch6_counters.xml | 283 -
.../manual/dbSICSch7_user_defn_scan.xml | 504 --
site_ansto/manual/dbSICSch8_batch_manager.xml | 193 -
.../manual/dbSICSch9_motor_configuration.xml | 319 -
site_ansto/manual/igorAbort.jpg | Bin 1595 -> 0 bytes
site_ansto/manual/igorBuildProtocol.jpg | Bin 23600 -> 0 bytes
site_ansto/manual/igorBuildProtocolAll.jpg | Bin 42494 -> 0 bytes
site_ansto/manual/igorOnlineFileSelect.jpg | Bin 16717 -> 0 bytes
.../manual/igorOnlineProtocolSelect.JPG | Bin 17236 -> 0 bytes
site_ansto/manual/igorOnlineReduction.jpg | Bin 22483 -> 0 bytes
site_ansto/manual/igorPatchFiles.JPG | Bin 63318 -> 0 bytes
site_ansto/manual/igorPatchSDD.JPG | Bin 18418 -> 0 bytes
site_ansto/manual/igorPickOnlineProtocol.jpg | Bin 10522 -> 0 bytes
site_ansto/manual/igorPickPath.jpg | Bin 23010 -> 0 bytes
site_ansto/manual/igorPickProtocol.jpg | Bin 10110 -> 0 bytes
site_ansto/manual/igorRawData.jpg | Bin 22276 -> 0 bytes
site_ansto/manual/igorReductionControls.jpg | Bin 18792 -> 0 bytes
site_ansto/manual/igorSaveProtocol.jpg | Bin 42408 -> 0 bytes
site_ansto/manual/igorSelectMacros.jpg | Bin 15622 -> 0 bytes
site_ansto/manual/igorStartOnlineProtocol.jpg | Bin 17558 -> 0 bytes
site_ansto/manual/igorStartScreen.JPG | Bin 106016 -> 0 bytes
site_ansto/manual/newsics.gif | Bin 7930 -> 0 bytes
site_ansto/manual/putty.JPG | Bin 2059 -> 0 bytes
site_ansto/manual/quokkaGumtree1.jpg | Bin 110022 -> 0 bytes
site_ansto/manual/quokkaGumtree10.jpg | Bin 150425 -> 0 bytes
site_ansto/manual/quokkaGumtree11.jpg | Bin 36072 -> 0 bytes
site_ansto/manual/quokkaGumtree12.jpg | Bin 36224 -> 0 bytes
site_ansto/manual/quokkaGumtree2.jpg | Bin 114054 -> 0 bytes
site_ansto/manual/quokkaGumtree3.jpg | Bin 155664 -> 0 bytes
site_ansto/manual/quokkaGumtree4.jpg | Bin 100538 -> 0 bytes
site_ansto/manual/quokkaGumtree5.jpg | Bin 69465 -> 0 bytes
site_ansto/manual/quokkaGumtree6.jpg | Bin 63098 -> 0 bytes
site_ansto/manual/quokkaGumtree7.jpg | Bin 152340 -> 0 bytes
site_ansto/manual/quokkaGumtree8.jpg | Bin 102080 -> 0 bytes
site_ansto/manual/quokkaGumtree9.jpg | Bin 34619 -> 0 bytes
site_ansto/manual/taipanGumtree.jpg | Bin 151922 -> 0 bytes
site_ansto/manual/taipanGumtree1.jpg | Bin 165620 -> 0 bytes
site_ansto/manual/taipanGumtree2.jpg | Bin 14332 -> 0 bytes
site_ansto/manual/taipanGumtree3.jpg | Bin 327355 -> 0 bytes
site_ansto/manual/troubleshoot1.jpeg | Bin 4810 -> 0 bytes
site_ansto/manual/troubleshoot2.jpeg | Bin 23787 -> 0 bytes
site_ansto/manual/troubleshoot3.jpeg | Bin 24191 -> 0 bytes
site_ansto/manual/troubleshoot4.jpeg | Bin 15475 -> 0 bytes
site_ansto/manual/troubleshoot5.jpeg | Bin 22740 -> 0 bytes
site_ansto/manual/troubleshoot6.jpeg | Bin 25483 -> 0 bytes
site_ansto/motor_asim.c | 680 --
site_ansto/motor_asim.h | 12 -
site_ansto/motor_dmc2280.c | 6357 -----------------
site_ansto/motor_dmc2280.h | 24 -
site_ansto/motor_driver.h | 24 -
site_ansto/nhq200.c | 1385 ----
site_ansto/nhq200.h | 35 -
site_ansto/nhq200driv.c | 481 --
site_ansto/orhvps.c | 1437 ----
site_ansto/orhvps.h | 32 -
site_ansto/refl2t.c | 403 --
site_ansto/refl2t.h | 49 -
site_ansto/safetyplc.c | 525 --
site_ansto/safetyplc.h | 15 -
site_ansto/sctemonadapter.c | 282 -
site_ansto/site_ansto.c | 676 --
site_ansto/site_dummy.c | 131 -
site_ansto/tclClock.c | 2 -
site_ansto/tclDate.c | 2 -
site_ansto/tclUnixTime.c | 2 -
site_ansto/test_west.tcl | 28 -
site_ansto/west4100.c | 357 -
site_ansto/west4100.h | 41 -
site_ansto/west4100driv.c | 604 --
site_ansto/xref.py | 198 -
sllinux_def | 5 +-
statemon.c | 118 +-
status.c | 185 +-
status.h | 13 +-
statusfile.c | 2 +-
stdscan.c | 7 +-
syncedprot.c | 24 +-
syncedprot.h | 3 +-
synchronize.c | 5 -
tasdrive.c | 327 +-
tasdrive.h | 2 +
task.c | 279 +-
task.h | 120 +-
taskobj.c | 226 +
taskobj.h | 13 +
tasmono.c | 241 +
tasmono.h | 19 +
tasscanub.c | 1 -
tasub.c | 153 +-
tasub.h | 7 +-
tasublib.c | 83 +-
tasublib.h | 29 +-
tcl/astrium.tcl | 527 --
tcl/bgerror.tcl | 8 -
tcl/client.tcl | 151 -
tcl/count.tcl | 54 -
tcl/deltatau.tcl | 356 -
tcl/el737sec.tcl | 314 -
tcl/el755.tcl | 97 -
tcl/fit.tcl | 52 -
tcl/ldAout.tcl | 228 -
tcl/lof.tcl | 90 -
tcl/log.tcl | 84 -
tcl/nhq202m.tcl | 145 -
tcl/nvs.tcl | 157 -
tcl/nvs20m.tcl | 163 -
tcl/parray.tcl | 29 -
tcl/pfeiffer.tcl | 138 -
tcl/phytron.tcl | 302 -
tcl/pimotor.tcl | 156 -
tcl/reflist.tcl | 79 -
tcl/scan.tcl | 74 -
tcl/scancom.tcl | 542 --
tcl/secsim.tcl | 66 -
tcl/sicstcldebug.tcl | 74 -
tcl/simhm.tcl | 91 -
tcl/sinqhttp.tcl | 152 -
tcl/slsecho.tcl | 293 -
tcl/stddrive.tcl | 100 -
tcl/stdin.tcl | 23 -
tcl/susca.tcl | 62 -
tcl/table.tcl | 317 -
tcl/tail.tcl | 12 -
tcl/topsiold.tcl | 772 --
tcl/wwwpulver.tcl | 43 -
test/sicsstat.tcl | 26 +-
test/testini.tcl | 33 +-
testprot.c | 15 +
trace.c | 196 +-
ubcalc.c | 38 +
ubfour.h | 2 +-
vector.c | 31 +
vector.h | 10 +-
velo.c | 9 +-
1336 files changed, 9430 insertions(+), 226646 deletions(-)
create mode 100644 epicsmotor.c
create mode 100644 makefile_
create mode 100644 messagepipe.c
create mode 100644 messagepipe.h
create mode 100644 multicountersec.c
delete mode 100644 napi.c
delete mode 100644 napi.h
delete mode 100644 napi4.c
delete mode 100644 napi4.h
delete mode 100644 napi5.c
delete mode 100644 napi5.h
delete mode 100644 nxio.c
delete mode 100644 nxio.h
delete mode 100644 nxstack.c
delete mode 100755 nxstack.h
delete mode 100644 nxxml.c
delete mode 100644 nxxml.h
create mode 100644 remoteobject.c
create mode 100644 sctcomtask.c
create mode 100644 sctcomtask.h
create mode 100644 sicsget.c
create mode 100644 sicsget.h
delete mode 100755 site_ansto/Makefile
delete mode 100644 site_ansto/Makefile_SICS
delete mode 100644 site_ansto/TESTS/check_zlib/Makefile
delete mode 100644 site_ansto/TESTS/check_zlib/README
delete mode 100644 site_ansto/TESTS/check_zlib/mkdata.c
delete mode 100644 site_ansto/TESTS/check_zlib/rdata.c
delete mode 100644 site_ansto/TESTS/dingo_camera/Makefile
delete mode 100644 site_ansto/TESTS/dingo_camera/camdriver_event_io_expect.txt
delete mode 100644 site_ansto/TESTS/dingo_camera/camera_test.c
delete mode 100644 site_ansto/TESTS/dingo_camera/camrep2sym_expect.txt
delete mode 100644 site_ansto/TESTS/dingo_camera/trans_fn_expect.txt
delete mode 100644 site_ansto/action.c
delete mode 100644 site_ansto/action.h
delete mode 100644 site_ansto/ansto_evcontroller.h
delete mode 100644 site_ansto/ansto_sctdriveadapter.c
delete mode 100644 site_ansto/ansto_tclmotdriv.c
delete mode 100644 site_ansto/ansto_tclmotdriv.h
delete mode 100644 site_ansto/anstohm.cpp
delete mode 100644 site_ansto/anstohm.h
delete mode 100644 site_ansto/anstohttp.c
delete mode 100644 site_ansto/anstohttp.h
delete mode 100644 site_ansto/anstoutil.c
delete mode 100644 site_ansto/anstoutil.h
delete mode 100644 site_ansto/beamstopaction.c
delete mode 100644 site_ansto/beamstopaction.h
delete mode 100755 site_ansto/build
delete mode 100644 site_ansto/cameradriver.h
delete mode 100644 site_ansto/counterdriv.c
delete mode 100644 site_ansto/docs/Copyright.txt
delete mode 100644 site_ansto/docs/Doxyfile
delete mode 100644 site_ansto/docs/sics_site.Doxyfile
delete mode 100755 site_ansto/extract_version.sh
delete mode 100644 site_ansto/fsm.c
delete mode 100644 site_ansto/fsm.h
delete mode 100644 site_ansto/hardsup/Digital/Makefile
delete mode 100644 site_ansto/hardsup/Digital/Monitor.c
delete mode 100644 site_ansto/hardsup/Digital/Monitor.h
delete mode 100644 site_ansto/hardsup/Digital/device.c
delete mode 100644 site_ansto/hardsup/Digital/device.h
delete mode 100644 site_ansto/hardsup/Digital/display.c
delete mode 100644 site_ansto/hardsup/Digital/display.h
delete mode 100644 site_ansto/hardsup/Digital/hware.c
delete mode 100644 site_ansto/hardsup/Digital/hware.h
delete mode 100644 site_ansto/hardsup/Digital/params.c
delete mode 100644 site_ansto/hardsup/Digital/params.h
delete mode 100644 site_ansto/hardsup/Digital/sock.c
delete mode 100644 site_ansto/hardsup/Digital/sock.h
delete mode 100644 site_ansto/hardsup/Digital/utility.c
delete mode 100644 site_ansto/hardsup/Digital/utility.h
delete mode 100644 site_ansto/hardsup/Monitor/Makefile
delete mode 100644 site_ansto/hardsup/Monitor/Monitor.c
delete mode 100644 site_ansto/hardsup/Monitor/Monitor.h
delete mode 100644 site_ansto/hardsup/Monitor/Pulser.c
delete mode 100644 site_ansto/hardsup/Monitor/device.c
delete mode 100644 site_ansto/hardsup/Monitor/device.h
delete mode 100644 site_ansto/hardsup/Monitor/display.c
delete mode 100644 site_ansto/hardsup/Monitor/display.h
delete mode 100644 site_ansto/hardsup/Monitor/hware.c
delete mode 100644 site_ansto/hardsup/Monitor/hware.h
delete mode 100644 site_ansto/hardsup/Monitor/params.c
delete mode 100644 site_ansto/hardsup/Monitor/params.h
delete mode 100644 site_ansto/hardsup/Monitor/sock.c
delete mode 100644 site_ansto/hardsup/Monitor/sock.h
delete mode 100644 site_ansto/hardsup/Monitor/utility.c
delete mode 100644 site_ansto/hardsup/Monitor/utility.h
delete mode 100644 site_ansto/hardsup/README
delete mode 100644 site_ansto/hardsup/StrMatch.c
delete mode 100644 site_ansto/hardsup/aqp_opalstatus.c
delete mode 100644 site_ansto/hardsup/aqp_opalstatus.h
delete mode 100644 site_ansto/hardsup/asynsrv_def.h
delete mode 100644 site_ansto/hardsup/asynsrv_errcodes.h
delete mode 100644 site_ansto/hardsup/asynsrv_utility.c
delete mode 100644 site_ansto/hardsup/c_interfaces.c
delete mode 100644 site_ansto/hardsup/camera.c
delete mode 100644 site_ansto/hardsup/camera.h
delete mode 100644 site_ansto/hardsup/cameradriver.c
delete mode 100644 site_ansto/hardsup/cameradriver.h
delete mode 100644 site_ansto/hardsup/cd_obj
delete mode 100644 site_ansto/hardsup/chopper.c
delete mode 100644 site_ansto/hardsup/dillutil.h
delete mode 100644 site_ansto/hardsup/el734_def.h
delete mode 100644 site_ansto/hardsup/el734_errcodes.h
delete mode 100644 site_ansto/hardsup/el734fix.h
delete mode 100644 site_ansto/hardsup/el737_def.h
delete mode 100644 site_ansto/hardsup/el737_errcodes.h
delete mode 100644 site_ansto/hardsup/el737fix.h
delete mode 100644 site_ansto/hardsup/el755_def.h
delete mode 100644 site_ansto/hardsup/el755_errcodes.h
delete mode 100644 site_ansto/hardsup/err.c
delete mode 100644 site_ansto/hardsup/failinet.c
delete mode 100644 site_ansto/hardsup/geterrno.c
delete mode 100644 site_ansto/hardsup/huber_asyncprotocol.c
delete mode 100644 site_ansto/hardsup/huber_asyncprotocol.h
delete mode 100644 site_ansto/hardsup/itc4util.c
delete mode 100644 site_ansto/hardsup/itc4util.h
delete mode 100644 site_ansto/hardsup/knauer_asyncprotocol.c
delete mode 100644 site_ansto/hardsup/knauer_asyncprotocol.h
delete mode 100644 site_ansto/hardsup/lakeshore340util.c
delete mode 100644 site_ansto/hardsup/lakeshore340util.h
delete mode 100644 site_ansto/hardsup/lh45util.c
delete mode 100644 site_ansto/hardsup/lh45util.h
delete mode 100644 site_ansto/hardsup/loader_asyncprotocol.c
delete mode 100644 site_ansto/hardsup/loader_asyncprotocol.h
delete mode 100644 site_ansto/hardsup/makefile
delete mode 100644 site_ansto/hardsup/makeprint.c
delete mode 100644 site_ansto/hardsup/modbus_asyncprotocol.c
delete mode 100644 site_ansto/hardsup/modbus_asyncprotocol.h
delete mode 100644 site_ansto/hardsup/modbustcp.c
delete mode 100644 site_ansto/hardsup/modbustcp.h
delete mode 100644 site_ansto/hardsup/nhq200util.c
delete mode 100644 site_ansto/hardsup/nhq200util.h
delete mode 100644 site_ansto/hardsup/omron_asyncprotocol.c
delete mode 100644 site_ansto/hardsup/omron_asyncprotocol.h
delete mode 100644 site_ansto/hardsup/rs232c_def.h
delete mode 100644 site_ansto/hardsup/sct_asyncqueue.c
delete mode 100644 site_ansto/hardsup/sct_galilprot.c
delete mode 100644 site_ansto/hardsup/sct_lfprot.c
delete mode 100644 site_ansto/hardsup/sct_modbusprot.c
delete mode 100644 site_ansto/hardsup/sct_newportprot.c
delete mode 100644 site_ansto/hardsup/sct_orhvpsprot.c
delete mode 100644 site_ansto/hardsup/sct_oxfordprot.c
delete mode 100644 site_ansto/hardsup/sct_protek608.c
delete mode 100644 site_ansto/hardsup/sct_rfamp.c
delete mode 100644 site_ansto/hardsup/sct_tcpmodbus.c
delete mode 100644 site_ansto/hardsup/sct_usbtmcprot.c
delete mode 100644 site_ansto/hardsup/sct_velselprot.c
delete mode 100644 site_ansto/hardsup/serialsinq.c
delete mode 100644 site_ansto/hardsup/serialsinq.h
delete mode 100644 site_ansto/hardsup/sinq_defs.h
delete mode 100644 site_ansto/hardsup/sinq_prototypes.h
delete mode 100644 site_ansto/hardsup/sinqhm.h
delete mode 100644 site_ansto/hardsup/sinqhm_def.h
delete mode 100644 site_ansto/hardsup/sinqhttpprot.c
delete mode 100644 site_ansto/hardsup/stredit.c
delete mode 100644 site_ansto/hardsup/strjoin.c
delete mode 100644 site_ansto/hardsup/table.h
delete mode 100644 site_ansto/hardsup/usbtmc.h
delete mode 100644 site_ansto/hardsup/velsel_def.h
delete mode 100644 site_ansto/hardsup/west4100util.c
delete mode 100644 site_ansto/hardsup/west4100util.h
delete mode 100644 site_ansto/hm_asim.cpp
delete mode 100644 site_ansto/hm_asim.h
delete mode 100644 site_ansto/hm_tango.h
delete mode 100644 site_ansto/hmcontrol_ansto.c
delete mode 100644 site_ansto/hmcontrol_ansto.h
delete mode 100644 site_ansto/instrument/MANIFEST.TXT
delete mode 100644 site_ansto/instrument/TEST_SICS/README.TXT
delete mode 100755 site_ansto/instrument/TEST_SICS/fakeCameraServer/SIM_DINGO_CAMSERVER.py
delete mode 100755 site_ansto/instrument/TEST_SICS/fakeDChopper/SIM_ASTRIUM.py
delete mode 100644 site_ansto/instrument/TEST_SICS/fakeDChopper/SIM_chopperServer.tcl
delete mode 100644 site_ansto/instrument/TEST_SICS/fakeDMC/README.txt
delete mode 100755 site_ansto/instrument/TEST_SICS/fakeDMC/cont.tcl
delete mode 100644 site_ansto/instrument/TEST_SICS/fakeDMC/dmc2280Server.tcl
delete mode 100644 site_ansto/instrument/TEST_SICS/fakeDMC/dmcParse.tcl
delete mode 100644 site_ansto/instrument/TEST_SICS/fakeDMC/loadConfig.tcl
delete mode 100755 site_ansto/instrument/TEST_SICS/fakeDMC/mkSimAxes.tcl
delete mode 100644 site_ansto/instrument/TEST_SICS/fakeDMC/simAxis.tcl
delete mode 100755 site_ansto/instrument/TEST_SICS/fakeFermi/SIM_FERMI.py
delete mode 100755 site_ansto/instrument/TEST_SICS/fakeGalil/SIM_GALIL.py
delete mode 100755 site_ansto/instrument/TEST_SICS/fakeGalil/SIM_GALIL_taipan.py
delete mode 100644 site_ansto/instrument/TEST_SICS/fakeGalil/counterclient.py
delete mode 100644 site_ansto/instrument/TEST_SICS/fakeGalil/galilcontroller.py
delete mode 100644 site_ansto/instrument/TEST_SICS/fakeGalil/galilfactory.py
delete mode 100644 site_ansto/instrument/TEST_SICS/fakeGalil/galilmotor.py
delete mode 100644 site_ansto/instrument/TEST_SICS/fakeGalil/powdersample.py
delete mode 100755 site_ansto/instrument/TEST_SICS/fakeHiden/xcs/HidenDevice.py
delete mode 100644 site_ansto/instrument/TEST_SICS/fakeHiden/xcs/HidenFactory.py
delete mode 100755 site_ansto/instrument/TEST_SICS/fakeHiden/xcs/HidenProtocol.py
delete mode 100644 site_ansto/instrument/TEST_SICS/fakeHiden/xcs/HidenXCS.py
delete mode 100755 site_ansto/instrument/TEST_SICS/fakeHiden/xcs/SIM_HIDEN.py
delete mode 100755 site_ansto/instrument/TEST_SICS/fakeHuber/fakeHuber.py
delete mode 100755 site_ansto/instrument/TEST_SICS/fakeMercury/SIM_MERCURY.py
delete mode 100755 site_ansto/instrument/TEST_SICS/fakeNHQ/fakeNHQ.py
delete mode 100755 site_ansto/instrument/TEST_SICS/fakeNVS/SIM_NVS.py
delete mode 100755 site_ansto/instrument/TEST_SICS/fakeOLV/FakeOLV.py
delete mode 100755 site_ansto/instrument/TEST_SICS/fakePfeiffer/tpg261/PfeifferDevice.py
delete mode 100644 site_ansto/instrument/TEST_SICS/fakePfeiffer/tpg261/PfeifferFactory.py
delete mode 100755 site_ansto/instrument/TEST_SICS/fakePfeiffer/tpg261/PfeifferProtocol.py
delete mode 100644 site_ansto/instrument/TEST_SICS/fakePfeiffer/tpg261/Pfeiffer_tpg261.py
delete mode 100755 site_ansto/instrument/TEST_SICS/fakePfeiffer/tpg261/SIM_PFEIFFER.py
delete mode 100755 site_ansto/instrument/TEST_SICS/fakeRFGen/SIM_RFGen.tcl
delete mode 100755 site_ansto/instrument/TEST_SICS/fakeTempControl/lakeshore/LS336.py
delete mode 100755 site_ansto/instrument/TEST_SICS/fakeTempControl/lakeshore/LS340.py
delete mode 100755 site_ansto/instrument/TEST_SICS/fakeTempControl/lakeshore/LS370.py
delete mode 100755 site_ansto/instrument/TEST_SICS/fakeTempControl/lakeshore/Lakeshore336.py
delete mode 100755 site_ansto/instrument/TEST_SICS/fakeTempControl/lakeshore/Lakeshore340.py
delete mode 100755 site_ansto/instrument/TEST_SICS/fakeTempControl/lakeshore/Lakeshore370.py
delete mode 100755 site_ansto/instrument/TEST_SICS/fakeTempControl/lakeshore/LakeshoreDevice.py
delete mode 100644 site_ansto/instrument/TEST_SICS/fakeTempControl/lakeshore/LakeshoreFactory.py
delete mode 100755 site_ansto/instrument/TEST_SICS/fakeTempControl/lakeshore/LakeshoreProtocol.py
delete mode 100644 site_ansto/instrument/TEST_SICS/fakeTempControl/lakeshore/SIM_LS336.tcl
delete mode 100755 site_ansto/instrument/TEST_SICS/fakeTempControl/oxford/MercuryDevice.py
delete mode 100644 site_ansto/instrument/TEST_SICS/fakeTempControl/oxford/MercuryFactory.py
delete mode 100755 site_ansto/instrument/TEST_SICS/fakeTempControl/oxford/MercuryProtocol.py
delete mode 100644 site_ansto/instrument/TEST_SICS/fakeTempControl/oxford/MercurySCPI.py
delete mode 100755 site_ansto/instrument/TEST_SICS/fakeTempControl/oxford/SIM_MERCURY.py
delete mode 100755 site_ansto/instrument/TEST_SICS/setup/common
delete mode 100755 site_ansto/instrument/TEST_SICS/setup/dingo
delete mode 100755 site_ansto/instrument/TEST_SICS/setup/echidna
delete mode 100755 site_ansto/instrument/TEST_SICS/setup/pelican
delete mode 100755 site_ansto/instrument/TEST_SICS/setup/taipan
delete mode 100755 site_ansto/instrument/TEST_SICS/setup/wombat
delete mode 100644 site_ansto/instrument/TEST_SICS/sics_test_hosts
delete mode 100644 site_ansto/instrument/TEST_SICS/sics_test_services
delete mode 100755 site_ansto/instrument/TEST_SICS/tests/plot-tracking.py
delete mode 100644 site_ansto/instrument/TEST_SICS/unit_tests/sics_hdb.py
delete mode 100644 site_ansto/instrument/TEST_SICS/unit_tests/sics_proxy.py
delete mode 100644 site_ansto/instrument/TEST_SICS/unit_tests/sics_test.py
delete mode 100644 site_ansto/instrument/TEST_SICS/unit_tests/test_sics.py
delete mode 100644 site_ansto/instrument/TEST_SICS/unit_tests/test_suite.tcl
delete mode 100644 site_ansto/instrument/TEST_SICS/unit_tests/test_wombat.py
delete mode 100644 site_ansto/instrument/barebones.tcl
delete mode 100644 site_ansto/instrument/bilby/MANIFEST.TXT
delete mode 100644 site_ansto/instrument/bilby/bilby_configuration.tcl
delete mode 100644 site_ansto/instrument/bilby/config/INSTCFCOMMON.TXT
delete mode 100644 site_ansto/instrument/bilby/config/anticollider/acscript.txt
delete mode 100644 site_ansto/instrument/bilby/config/anticollider/anticollider.tcl
delete mode 100644 site_ansto/instrument/bilby/config/chopper/astrium_chopper.sct
delete mode 100644 site_ansto/instrument/bilby/config/chopper/astrium_chopper_sct.tcl
delete mode 100644 site_ansto/instrument/bilby/config/chopper/chopper.tcl
delete mode 100644 site_ansto/instrument/bilby/config/commands/commands.tcl
delete mode 100644 site_ansto/instrument/bilby/config/counter/counter.tcl
delete mode 100644 site_ansto/instrument/bilby/config/environment/magneticField/oxford_labview.tcl
delete mode 100644 site_ansto/instrument/bilby/config/hipadaba/hipadaba_configuration.tcl
delete mode 100644 site_ansto/instrument/bilby/config/hmm/detector.tcl
delete mode 100644 site_ansto/instrument/bilby/config/hmm/hmm_configuration.tcl
delete mode 100755 site_ansto/instrument/bilby/config/motors/Bilby_motion_control_commissioning_checklist.csv
delete mode 100644 site_ansto/instrument/bilby/config/motors/README.TXT
delete mode 100644 site_ansto/instrument/bilby/config/motors/generated_motor_configuration.tcl
delete mode 100644 site_ansto/instrument/bilby/config/motors/motor_configuration.tcl
delete mode 100644 site_ansto/instrument/bilby/config/motors/shutters.sct
delete mode 100644 site_ansto/instrument/bilby/config/motors/shutters_sct.tcl
delete mode 100644 site_ansto/instrument/bilby/config/motors/sicsmot_attlist.csv
delete mode 100644 site_ansto/instrument/bilby/config/motors/tank.sct
delete mode 100644 site_ansto/instrument/bilby/config/motors/tank_sct.tcl
delete mode 100644 site_ansto/instrument/bilby/config/motors/userdef_attlist.csv
delete mode 100644 site_ansto/instrument/bilby/config/nexus/nxscripts.tcl
delete mode 100644 site_ansto/instrument/bilby/config/optics/README.TXT
delete mode 100644 site_ansto/instrument/bilby/config/optics/aperture_configuration.tcl
delete mode 100644 site_ansto/instrument/bilby/config/optics/guide_configuration.tcl
delete mode 100644 site_ansto/instrument/bilby/config/optics/optics.tcl
delete mode 100644 site_ansto/instrument/bilby/config/parameters/parameters.tcl
delete mode 100644 site_ansto/instrument/bilby/config/plc/plc.tcl
delete mode 100644 site_ansto/instrument/bilby/config/scan/scan.tcl
delete mode 100644 site_ansto/instrument/bilby/hostport_config.tcl
delete mode 100644 site_ansto/instrument/bilby/hostport_config_test.tcl
delete mode 100644 site_ansto/instrument/bilby/runsics_def.py
delete mode 100644 site_ansto/instrument/bilby/sics_simulation.tcl
delete mode 100644 site_ansto/instrument/bilby/util/sics_config.ini
delete mode 100755 site_ansto/instrument/compareSICS.py
delete mode 100644 site_ansto/instrument/config/README.TXT
delete mode 100644 site_ansto/instrument/config/anticollider/anticollider_common.tcl
delete mode 100644 site_ansto/instrument/config/beamline/aerolas_doppler.sct
delete mode 100644 site_ansto/instrument/config/beamline/aerolas_doppler_sct.tcl
delete mode 100644 site_ansto/instrument/config/beamline/he3_polanal.sct
delete mode 100644 site_ansto/instrument/config/beamline/he3_polanal_sct.tcl
delete mode 100644 site_ansto/instrument/config/commands/commands_common.tcl
delete mode 100644 site_ansto/instrument/config/commands/hvcommands.tcl
delete mode 100644 site_ansto/instrument/config/commands/pulser.tcl
delete mode 100644 site_ansto/instrument/config/counter/counter_common_1.tcl
delete mode 100644 site_ansto/instrument/config/environment/agilent_33220A.sct
delete mode 100644 site_ansto/instrument/config/environment/agilent_33220A_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/antonparr_MCR500_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/he3/sct_he3.tcl
delete mode 100644 site_ansto/instrument/config/environment/hiden_xcs.sct
delete mode 100644 site_ansto/instrument/config/environment/hiden_xcs_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/huber_pilot.sct
delete mode 100644 site_ansto/instrument/config/environment/huber_pilot_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/isotech_ps.sct
delete mode 100644 site_ansto/instrument/config/environment/isotech_ps_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/keithley_m2700.sct
delete mode 100644 site_ansto/instrument/config/environment/keithley_m2700_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/keysight_N8740A.sct
delete mode 100644 site_ansto/instrument/config/environment/keysight_N8740A_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/knauer_pump.sct
delete mode 100644 site_ansto/instrument/config/environment/knauer_pump_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/magneticField/bruker.sct
delete mode 100644 site_ansto/instrument/config/environment/magneticField/bruker_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/magneticField/green_magnet_labview.sct
delete mode 100644 site_ansto/instrument/config/environment/magneticField/green_magnet_labview_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/magneticField/oxford10tlv.sct
delete mode 100644 site_ansto/instrument/config/environment/magneticField/oxford10tlv_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/magneticField/oxford12tlv.sct
delete mode 100644 site_ansto/instrument/config/environment/magneticField/oxford12tlv_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/magneticField/sct_bruker_BEC1.tcl
delete mode 100644 site_ansto/instrument/config/environment/magneticField/sct_green_magnet.tcl
delete mode 100644 site_ansto/instrument/config/environment/magneticField/sct_lakeshore_460.tcl
delete mode 100644 site_ansto/instrument/config/environment/magneticField/sct_oxford10tlv.tcl
delete mode 100644 site_ansto/instrument/config/environment/magneticField/sct_oxford_ips.tcl
delete mode 100644 site_ansto/instrument/config/environment/magneticField/sct_oxford_labview.tcl
delete mode 100644 site_ansto/instrument/config/environment/magneticField/tsi_smc.sct
delete mode 100644 site_ansto/instrument/config/environment/magneticField/tsi_smc_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/mvp_valve.sct
delete mode 100644 site_ansto/instrument/config/environment/mvp_valve_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/nhq_200.sct
delete mode 100644 site_ansto/instrument/config/environment/nhq_200_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/omron_hldc.sct
delete mode 100644 site_ansto/instrument/config/environment/omron_hldc_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/pressure/sct_pfeiffer_mercury.tcl
delete mode 100644 site_ansto/instrument/config/environment/pressure/sct_pfeiffer_tpg261.tcl
delete mode 100644 site_ansto/instrument/config/environment/protekmm.sct
delete mode 100644 site_ansto/instrument/config/environment/protekmm_sct.tcl
delete mode 100755 site_ansto/instrument/config/environment/sct_autolab.tcl
delete mode 100644 site_ansto/instrument/config/environment/sct_cybaman.tcl
delete mode 100644 site_ansto/instrument/config/environment/sct_keithley_2700.tcl
delete mode 100755 site_ansto/instrument/config/environment/sct_mvp.tcl
delete mode 100644 site_ansto/instrument/config/environment/sct_protek_common.tcl
delete mode 100644 site_ansto/instrument/config/environment/sct_rheometer.tcl
delete mode 100755 site_ansto/instrument/config/environment/sct_syr.tcl
delete mode 100644 site_ansto/instrument/config/environment/syringe_pump.sct
delete mode 100644 site_ansto/instrument/config/environment/syringe_pump_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/eurotherm_3200.sct
delete mode 100644 site_ansto/instrument/config/environment/temperature/eurotherm_3200_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/eurotherm_m2000.sct
delete mode 100644 site_ansto/instrument/config/environment/temperature/eurotherm_m2000_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/julabo_lh45.sct
delete mode 100644 site_ansto/instrument/config/environment/temperature/julabo_lh45_gen_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/lakeshore_218.sct
delete mode 100644 site_ansto/instrument/config/environment/temperature/lakeshore_218_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/lakeshore_m370.sct
delete mode 100644 site_ansto/instrument/config/environment/temperature/lakeshore_m370_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/ls336.sct
delete mode 100644 site_ansto/instrument/config/environment/temperature/ls336_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/ls340.sct
delete mode 100644 site_ansto/instrument/config/environment/temperature/ls340_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/mercury_base.sct
delete mode 100644 site_ansto/instrument/config/environment/temperature/mercury_base_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/mercury_level.sct
delete mode 100644 site_ansto/instrument/config/environment/temperature/mercury_level_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/mercury_pres.sct
delete mode 100644 site_ansto/instrument/config/environment/temperature/mercury_pres_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/mercury_scpi.sct
delete mode 100644 site_ansto/instrument/config/environment/temperature/mercury_scpi_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/mercury_temp.sct
delete mode 100644 site_ansto/instrument/config/environment/temperature/mercury_temp_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/mercury_valve.sct
delete mode 100644 site_ansto/instrument/config/environment/temperature/mercury_valve_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/nprvasm2.sct
delete mode 100644 site_ansto/instrument/config/environment/temperature/nprvasm2_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/oxford_mercury.sct
delete mode 100644 site_ansto/instrument/config/environment/temperature/oxford_mercury_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/pfeiffer_hg.sct
delete mode 100644 site_ansto/instrument/config/environment/temperature/pfeiffer_hg_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/sct_eurotherm_2000.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/sct_julabo_lh45.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/sct_lakeshore_336.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/sct_lakeshore_340.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/sct_lakeshore_370.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/sct_oxford_itc.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/sct_qlink.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/sct_rvasm2.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/sct_watlow_pm.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/sct_watlow_rm.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/sct_watlow_st4.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/srs_sr630.sct
delete mode 100644 site_ansto/instrument/config/environment/temperature/srs_sr630_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/watlow_mpm.sct
delete mode 100644 site_ansto/instrument/config/environment/temperature/watlow_mpm_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/watlow_mrm.sct
delete mode 100644 site_ansto/instrument/config/environment/temperature/watlow_mrm_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/watlow_mst4.sct
delete mode 100644 site_ansto/instrument/config/environment/temperature/watlow_mst4_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/west400.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/west4100.sct
delete mode 100644 site_ansto/instrument/config/environment/temperature/west4100_sct.tcl
delete mode 100644 site_ansto/instrument/config/environment/temperature/west_6100.sct
delete mode 100644 site_ansto/instrument/config/environment/temperature/west_6100_sct.tcl
delete mode 100644 site_ansto/instrument/config/hipadaba/common_instrument_dictionary.tcl
delete mode 100644 site_ansto/instrument/config/hipadaba/hipadaba_configuration_common.tcl
delete mode 100644 site_ansto/instrument/config/hipadaba/instdict_specification.tcl
delete mode 100644 site_ansto/instrument/config/hmm/anstohm_linked.xml
delete mode 100644 site_ansto/instrument/config/hmm/hmm_configuration_common_1.tcl
delete mode 100644 site_ansto/instrument/config/hmm/hmm_cylindrical_detector_configuration.tcl
delete mode 100644 site_ansto/instrument/config/hmm/hmm_object.tcl
delete mode 100755 site_ansto/instrument/config/hmm/sct_orhvps_common.tcl
delete mode 100644 site_ansto/instrument/config/load_setup.tcl
delete mode 100644 site_ansto/instrument/config/motors/magnet_configuration.tcl
delete mode 100644 site_ansto/instrument/config/motors/sct_aerotech_soloist.tcl
delete mode 100644 site_ansto/instrument/config/motors/sct_jogmotor_common.tcl
delete mode 100644 site_ansto/instrument/config/motors/sct_positmotor_common.tcl
delete mode 100644 site_ansto/instrument/config/nexus/nexus_in_bmon_common_1.dic
delete mode 100644 site_ansto/instrument/config/nexus/nexus_in_common_1.dic
delete mode 100644 site_ansto/instrument/config/nexus/nexus_in_hmm_common_1.dic
delete mode 100644 site_ansto/instrument/config/nexus/nexus_in_scan_common_1.dic
delete mode 100644 site_ansto/instrument/config/nexus/nxscripts_common_1.tcl
delete mode 100644 site_ansto/instrument/config/plc/plc_common_1.tcl
delete mode 100644 site_ansto/instrument/config/robots/epson_pandp.sct
delete mode 100644 site_ansto/instrument/config/robots/epson_pandp_sct.tcl
delete mode 100644 site_ansto/instrument/config/robots/sct_pickandplace.tcl
delete mode 100644 site_ansto/instrument/config/scan/scan_common_1.hdd
delete mode 100644 site_ansto/instrument/config/scan/scan_common_1.tcl
delete mode 100644 site_ansto/instrument/config/source/reactor_status.sct
delete mode 100644 site_ansto/instrument/config/source/reactor_status_sct.tcl
delete mode 100644 site_ansto/instrument/config/source/source.tcl
delete mode 100644 site_ansto/instrument/config/source/source_common.tcl
delete mode 100755 site_ansto/instrument/deploySICS.sh
delete mode 100644 site_ansto/instrument/dingo/DMC2280/README.txt
delete mode 100644 site_ansto/instrument/dingo/DMC2280/controller4.txt
delete mode 100644 site_ansto/instrument/dingo/DMC2280/controller5.txt
delete mode 100644 site_ansto/instrument/dingo/MANIFEST.TXT
delete mode 100644 site_ansto/instrument/dingo/Makefile
delete mode 100644 site_ansto/instrument/dingo/camtest_configuration.tcl
delete mode 100644 site_ansto/instrument/dingo/config/INSTCFCOMMON.TXT
delete mode 100644 site_ansto/instrument/dingo/config/Makefile
delete mode 100644 site_ansto/instrument/dingo/config/anticollider/acscript.txt
delete mode 100644 site_ansto/instrument/dingo/config/anticollider/anticollider.tcl
delete mode 100644 site_ansto/instrument/dingo/config/commands/commands.tcl
delete mode 100644 site_ansto/instrument/dingo/config/counter/counter.tcl
delete mode 100644 site_ansto/instrument/dingo/config/hipadaba/hipadaba_configuration.tcl
delete mode 100644 site_ansto/instrument/dingo/config/hmm/hmm_configuration.tcl
delete mode 100644 site_ansto/instrument/dingo/config/motors/extraconfig.tcl
delete mode 100644 site_ansto/instrument/dingo/config/motors/motor_configuration.tcl
delete mode 100644 site_ansto/instrument/dingo/config/motors/positmotor_configuration.tcl
delete mode 100644 site_ansto/instrument/dingo/config/nexus/Makefile
delete mode 100644 site_ansto/instrument/dingo/config/nexus/nxscripts.tcl
delete mode 100644 site_ansto/instrument/dingo/config/plc/plc.tcl
delete mode 100644 site_ansto/instrument/dingo/config/scan/dingo.hdd
delete mode 100644 site_ansto/instrument/dingo/config/scan/scan.tcl
delete mode 100644 site_ansto/instrument/dingo/dingo.hdd
delete mode 100644 site_ansto/instrument/dingo/dingo_configuration.tcl
delete mode 100644 site_ansto/instrument/dingo/hostport_config.tcl
delete mode 100644 site_ansto/instrument/dingo/hostport_config_test.tcl
delete mode 100644 site_ansto/instrument/dingo/runsics_def.py
delete mode 100644 site_ansto/instrument/dingo/script_validator_ports.tcl
delete mode 100644 site_ansto/instrument/dingo/sics_ports.tcl
delete mode 100644 site_ansto/instrument/dingo/sics_simulation.tcl
delete mode 100644 site_ansto/instrument/dingo/util/sics_config.ini
delete mode 100644 site_ansto/instrument/emu/MANIFEST.TXT
delete mode 100644 site_ansto/instrument/emu/config/INSTCFCOMMON.TXT
delete mode 100644 site_ansto/instrument/emu/config/anticollider/anticollider.tcl
delete mode 100644 site_ansto/instrument/emu/config/commands/commands.tcl
delete mode 100644 site_ansto/instrument/emu/config/counter/counter.tcl
delete mode 100644 site_ansto/instrument/emu/config/hipadaba/hipadaba_configuration.tcl
delete mode 100644 site_ansto/instrument/emu/config/hmm/hmm_configuration.tcl
delete mode 100755 site_ansto/instrument/emu/config/motors/Emu_motion_control_commissioning_checklist.csv
delete mode 100644 site_ansto/instrument/emu/config/motors/generated_motor_configuration.tcl
delete mode 100644 site_ansto/instrument/emu/config/motors/motor_configuration.tcl
delete mode 100644 site_ansto/instrument/emu/config/motors/sicsmot_attlist.csv
delete mode 100644 site_ansto/instrument/emu/config/nexus/nxscripts.tcl
delete mode 100644 site_ansto/instrument/emu/config/plc/plc.tcl
delete mode 100644 site_ansto/instrument/emu/config/scan/scan.tcl
delete mode 100644 site_ansto/instrument/emu/emu_configuration.tcl
delete mode 100644 site_ansto/instrument/emu/hostport_config.tcl
delete mode 100644 site_ansto/instrument/emu/hostport_config_test.tcl
delete mode 100644 site_ansto/instrument/emu/runsics_def.py
delete mode 100644 site_ansto/instrument/emu/sics_simulation.tcl
delete mode 100644 site_ansto/instrument/genCLOSLOOP.tcl
delete mode 100644 site_ansto/instrument/gen_home_slits.tcl
delete mode 100644 site_ansto/instrument/gumxml.tcl
delete mode 100644 site_ansto/instrument/hipd/DMC2280/README.txt
delete mode 100644 site_ansto/instrument/hipd/DMC2280/controller1.txt
delete mode 100644 site_ansto/instrument/hipd/DMC2280/controller2.txt
delete mode 100644 site_ansto/instrument/hipd/DMC2280/controller3.txt
delete mode 100644 site_ansto/instrument/hipd/DMC2280/controller4.txt
delete mode 100644 site_ansto/instrument/hipd/MANIFEST.TXT
delete mode 100644 site_ansto/instrument/hipd/Makefile
delete mode 100644 site_ansto/instrument/hipd/config/INSTCFCOMMON.TXT
delete mode 100644 site_ansto/instrument/hipd/config/Makefile
delete mode 100644 site_ansto/instrument/hipd/config/anticollider/acscript.txt
delete mode 100644 site_ansto/instrument/hipd/config/anticollider/anticollider.tcl
delete mode 100644 site_ansto/instrument/hipd/config/commands/cfcommands.tcl
delete mode 100644 site_ansto/instrument/hipd/config/commands/commands.tcl
delete mode 100644 site_ansto/instrument/hipd/config/commands/eulerscan.tcl
delete mode 100644 site_ansto/instrument/hipd/config/commands/hvsteps.tcl
delete mode 100644 site_ansto/instrument/hipd/config/commands/vactex.tcl
delete mode 100644 site_ansto/instrument/hipd/config/counter/counter.tcl
delete mode 100644 site_ansto/instrument/hipd/config/environment/magneticField/oxford_labview.tcl
delete mode 100644 site_ansto/instrument/hipd/config/environment/temperature/lakeshore340.tcl
delete mode 100644 site_ansto/instrument/hipd/config/hipadaba/hipadaba_configuration.tcl
delete mode 100644 site_ansto/instrument/hipd/config/hipadaba/hpaths.tcl
delete mode 100644 site_ansto/instrument/hipd/config/hmm/anstohm_full.xml
delete mode 100644 site_ansto/instrument/hipd/config/hmm/anstohm_full_calibration.xml
delete mode 100644 site_ansto/instrument/hipd/config/hmm/anstohm_full_normal.xml
delete mode 100644 site_ansto/instrument/hipd/config/hmm/anstohm_full_pulser.xml
delete mode 100644 site_ansto/instrument/hipd/config/hmm/anstohm_full_small.xml
delete mode 100644 site_ansto/instrument/hipd/config/hmm/anstohm_full_standard.xml
delete mode 100644 site_ansto/instrument/hipd/config/hmm/hmm_configuration.tcl
delete mode 100644 site_ansto/instrument/hipd/config/hmm/hmm_rapid.tcl
delete mode 100644 site_ansto/instrument/hipd/config/hmm/hmm_temp.tcl
delete mode 100644 site_ansto/instrument/hipd/config/motors/euler_configuration.tcl
delete mode 100644 site_ansto/instrument/hipd/config/motors/eulinf_configuration.tcl
delete mode 100644 site_ansto/instrument/hipd/config/motors/motor_configuration.tcl
delete mode 100644 site_ansto/instrument/hipd/config/motors/positmotor_configuration.tcl
delete mode 100644 site_ansto/instrument/hipd/config/motors/small_omega_config.tcl
delete mode 100644 site_ansto/instrument/hipd/config/motors/tilt_configuration.tcl
delete mode 100644 site_ansto/instrument/hipd/config/nexus/Makefile
delete mode 100644 site_ansto/instrument/hipd/config/nexus/nexus_in_motors.dic
delete mode 100644 site_ansto/instrument/hipd/config/nexus/nxscripts.tcl
delete mode 100644 site_ansto/instrument/hipd/config/plc/plc.tcl
delete mode 100644 site_ansto/instrument/hipd/config/scan/scan.tcl
delete mode 100644 site_ansto/instrument/hipd/extraconfig.tcl
delete mode 100644 site_ansto/instrument/hipd/hostport_config.tcl
delete mode 100644 site_ansto/instrument/hipd/hostport_config_test.tcl
delete mode 100644 site_ansto/instrument/hipd/instrument_vars.tcl
delete mode 100644 site_ansto/instrument/hipd/runsics_def.py
delete mode 100644 site_ansto/instrument/hipd/script_validator/MANIFEST.TXT
delete mode 100644 site_ansto/instrument/hipd/script_validator/config/counter/counter.tcl
delete mode 100644 site_ansto/instrument/hipd/script_validator/config/hmm/hmm_configuration.tcl
delete mode 100644 site_ansto/instrument/hipd/script_validator/sics_ports.tcl
delete mode 100644 site_ansto/instrument/hipd/script_validator_ports.tcl
delete mode 100644 site_ansto/instrument/hipd/sics_ports.tcl
delete mode 100644 site_ansto/instrument/hipd/sics_simulation.tcl
delete mode 100644 site_ansto/instrument/hipd/util/dmc2280/troubleshoot_setup.tcl
delete mode 100644 site_ansto/instrument/hipd/util/sics_config.ini
delete mode 100644 site_ansto/instrument/hipd/wombat_configuration.tcl
delete mode 100644 site_ansto/instrument/hrpd/DMC2280/README.txt
delete mode 100644 site_ansto/instrument/hrpd/DMC2280/controller1.txt
delete mode 100644 site_ansto/instrument/hrpd/DMC2280/controller2.txt
delete mode 100644 site_ansto/instrument/hrpd/DMC2280/controller3.txt
delete mode 100644 site_ansto/instrument/hrpd/DMC2280/controller4.txt
delete mode 100644 site_ansto/instrument/hrpd/MANIFEST.TXT
delete mode 100644 site_ansto/instrument/hrpd/Makefile
delete mode 100644 site_ansto/instrument/hrpd/Test/cyclebatch.tcl
delete mode 100644 site_ansto/instrument/hrpd/config/INSTCFCOMMON.TXT
delete mode 100644 site_ansto/instrument/hrpd/config/Makefile
delete mode 100644 site_ansto/instrument/hrpd/config/anticollider/acscript.txt
delete mode 100644 site_ansto/instrument/hrpd/config/anticollider/anticollider.tcl
delete mode 100644 site_ansto/instrument/hrpd/config/commands/commands.tcl
delete mode 100644 site_ansto/instrument/hrpd/config/counter/counter.tcl
delete mode 100644 site_ansto/instrument/hrpd/config/environment/robby_configuration.tcl
delete mode 100644 site_ansto/instrument/hrpd/config/environment/temperature/lakeshore340.tcl
delete mode 100644 site_ansto/instrument/hrpd/config/hipadaba/hipadaba_configuration.tcl
delete mode 100644 site_ansto/instrument/hrpd/config/hipadaba/hpaths.tcl
delete mode 100644 site_ansto/instrument/hrpd/config/hmm/anstohm_full.xml
delete mode 100644 site_ansto/instrument/hrpd/config/hmm/anstohm_full_MESYTEC_PULSER.xml
delete mode 100644 site_ansto/instrument/hrpd/config/hmm/anstohm_full_folding.xml
delete mode 100644 site_ansto/instrument/hrpd/config/hmm/anstohm_full_nofolding.xml
delete mode 100644 site_ansto/instrument/hrpd/config/hmm/hmm_configuration.tcl
delete mode 100644 site_ansto/instrument/hrpd/config/motors/euler_configuration.tcl
delete mode 100644 site_ansto/instrument/hrpd/config/motors/motor_configuration.tcl
delete mode 100644 site_ansto/instrument/hrpd/config/motors/positmotor_configuration.tcl
delete mode 100644 site_ansto/instrument/hrpd/config/motors/small_omega_config.tcl
delete mode 100644 site_ansto/instrument/hrpd/config/motors/tilt_configuration.tcl
delete mode 100644 site_ansto/instrument/hrpd/config/nexus/Makefile
delete mode 100644 site_ansto/instrument/hrpd/config/nexus/nexus_in_motors.dic
delete mode 100644 site_ansto/instrument/hrpd/config/nexus/nxscripts.tcl
delete mode 100644 site_ansto/instrument/hrpd/config/plc/plc.tcl
delete mode 100644 site_ansto/instrument/hrpd/config/scan/scan.tcl
delete mode 100644 site_ansto/instrument/hrpd/echidna_configuration.tcl
delete mode 100644 site_ansto/instrument/hrpd/extraconfig.tcl
delete mode 100644 site_ansto/instrument/hrpd/hostport_config.tcl
delete mode 100644 site_ansto/instrument/hrpd/hostport_config_test.tcl
delete mode 100644 site_ansto/instrument/hrpd/instrument_vars.tcl
delete mode 100644 site_ansto/instrument/hrpd/runsics_def.py
delete mode 100644 site_ansto/instrument/hrpd/script_validator/MANIFEST.TXT
delete mode 100644 site_ansto/instrument/hrpd/script_validator/config/counter/counter.tcl
delete mode 100644 site_ansto/instrument/hrpd/script_validator/config/hmm/hmm_configuration.tcl
delete mode 100644 site_ansto/instrument/hrpd/script_validator/sics_ports.tcl
delete mode 100644 site_ansto/instrument/hrpd/script_validator_ports.tcl
delete mode 100644 site_ansto/instrument/hrpd/sics_ports.tcl
delete mode 100644 site_ansto/instrument/hrpd/sics_simulation.tcl
delete mode 100644 site_ansto/instrument/hrpd/util/dmc2280/troubleshoot_setup.tcl
delete mode 100644 site_ansto/instrument/hrpd/util/sics_config.ini
delete mode 100644 site_ansto/instrument/kookaburra/DMC2280/README.txt
delete mode 100644 site_ansto/instrument/kookaburra/DMC2280/controller4.txt
delete mode 100644 site_ansto/instrument/kookaburra/DMC2280/controller5.txt
delete mode 100644 site_ansto/instrument/kookaburra/MANIFEST.TXT
delete mode 100644 site_ansto/instrument/kookaburra/Makefile
delete mode 100644 site_ansto/instrument/kookaburra/config/INSTCFCOMMON.TXT
delete mode 100644 site_ansto/instrument/kookaburra/config/Makefile
delete mode 100644 site_ansto/instrument/kookaburra/config/anticollider/acscript.txt
delete mode 100644 site_ansto/instrument/kookaburra/config/anticollider/anticollider.tcl
delete mode 100644 site_ansto/instrument/kookaburra/config/chopper/sct_fermichopper.tcl
delete mode 100644 site_ansto/instrument/kookaburra/config/commands/commands.tcl
delete mode 100644 site_ansto/instrument/kookaburra/config/commands/monodrive.tcl
delete mode 100644 site_ansto/instrument/kookaburra/config/counter/counter.tcl
delete mode 100644 site_ansto/instrument/kookaburra/config/counter/sct_bm.tcl
delete mode 100644 site_ansto/instrument/kookaburra/config/hipadaba/hipadaba_configuration.tcl
delete mode 100644 site_ansto/instrument/kookaburra/config/hmm/anstohm_linked.xml
delete mode 100644 site_ansto/instrument/kookaburra/config/hmm/hmm_configuration.tcl
delete mode 100644 site_ansto/instrument/kookaburra/config/motors/extraconfig.tcl
delete mode 100644 site_ansto/instrument/kookaburra/config/motors/motor_configuration.tcl
delete mode 100644 site_ansto/instrument/kookaburra/config/motors/positmotor_configuration.tcl
delete mode 100644 site_ansto/instrument/kookaburra/config/nexus/Makefile
delete mode 100644 site_ansto/instrument/kookaburra/config/nexus/nxscripts.tcl
delete mode 100644 site_ansto/instrument/kookaburra/config/parameters/parameters.tcl
delete mode 100644 site_ansto/instrument/kookaburra/config/plc/plc.tcl
delete mode 100644 site_ansto/instrument/kookaburra/config/scan/scan.tcl
delete mode 100644 site_ansto/instrument/kookaburra/hostport_config.tcl
delete mode 100644 site_ansto/instrument/kookaburra/hostport_config_test.tcl
delete mode 100644 site_ansto/instrument/kookaburra/kookaburra_configuration.tcl
delete mode 100644 site_ansto/instrument/kookaburra/runsics_def.py
delete mode 100644 site_ansto/instrument/kookaburra/script_validator_ports.tcl
delete mode 100644 site_ansto/instrument/kookaburra/sics_ports.tcl
delete mode 100644 site_ansto/instrument/kookaburra/sics_simulation.tcl
delete mode 100644 site_ansto/instrument/kookaburra/util/sics_config.ini
delete mode 100644 site_ansto/instrument/lyrebird/DMC2280/README.txt
delete mode 100644 site_ansto/instrument/lyrebird/DMC2280/controller1.txt
delete mode 100644 site_ansto/instrument/lyrebird/DMC2280/controller2.txt
delete mode 100644 site_ansto/instrument/lyrebird/DMC2280/controller3.txt
delete mode 100644 site_ansto/instrument/lyrebird/DMC2280/controller4.txt
delete mode 100644 site_ansto/instrument/lyrebird/MANIFEST.TXT
delete mode 100644 site_ansto/instrument/lyrebird/Makefile
delete mode 100644 site_ansto/instrument/lyrebird/config/INSTCFCOMMON.TXT
delete mode 100644 site_ansto/instrument/lyrebird/config/Makefile
delete mode 100644 site_ansto/instrument/lyrebird/config/anticollider/acscript.txt
delete mode 100644 site_ansto/instrument/lyrebird/config/anticollider/anticollider.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/commands/commands.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/counter/counter.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/goniometer/sct_goniometer.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/goniometer/spin_goniometer.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/hipadaba/hipadaba_configuration.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/hmm/hmm_configuration.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/motors/motor_configuration.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/motors/positmotor_configuration.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/motors/sct_flightTube.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/motors/spin_galil.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/nexus/Makefile
delete mode 100644 site_ansto/instrument/lyrebird/config/nexus/nxscripts.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/optics/README.TXT
delete mode 100644 site_ansto/instrument/lyrebird/config/optics/optics.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/plc/plc.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/scan/scan.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/tasmad/sicscommon/ASCIIplot.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/tasmad/sicscommon/andorhm.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/tasmad/sicscommon/astrium.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/tasmad/sicscommon/backup.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/tasmad/sicscommon/batch.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/tasmad/sicscommon/ccdwww.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/tasmad/sicscommon/debsics
delete mode 100644 site_ansto/instrument/lyrebird/config/tasmad/sicscommon/deltatau.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/tasmad/sicscommon/el734.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/tasmad/sicscommon/el737sec.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/tasmad/sicscommon/el755.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/tasmad/sicscommon/fourcircle.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/tasmad/sicscommon/fsync.jar
delete mode 100644 site_ansto/instrument/lyrebird/config/tasmad/sicscommon/hdbutil.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/tasmad/sicscommon/kt.sinqbck
delete mode 100644 site_ansto/instrument/lyrebird/config/tasmad/sicscommon/motorhp.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/tasmad/sicscommon/nxsupport.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/tasmad/sicscommon/phytron.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/tasmad/sicscommon/pimotor.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/tasmad/sicscommon/secsim.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/tasmad/sicscommon/simhm.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/tasmad/sicscommon/sinqhttp.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/tasmad/sicscommon/stddrive.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/tasmad/sicscommon/syncwrapper.pag
delete mode 100644 site_ansto/instrument/lyrebird/config/tasmad/sicscommon/table.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/tasmad/sicscommon/tecs.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/tasmad/taspub_sics/nxtas.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/tasmad/taspub_sics/tas.dic
delete mode 100644 site_ansto/instrument/lyrebird/config/tasmad/taspub_sics/tas.hdd
delete mode 100644 site_ansto/instrument/lyrebird/config/tasmad/taspub_sics/tasp.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/tasmad/taspub_sics/taspubcom.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/tasmad/taspub_sics/tasscript.tcl
delete mode 100644 site_ansto/instrument/lyrebird/config/tasmad/taspub_sics/tasub.dic
delete mode 100644 site_ansto/instrument/lyrebird/hostport_config.tcl
delete mode 100644 site_ansto/instrument/lyrebird/hostport_config_test.tcl
delete mode 100644 site_ansto/instrument/lyrebird/lyrebird_configuration.tcl
delete mode 100644 site_ansto/instrument/lyrebird/runsics_def.py
delete mode 100644 site_ansto/instrument/lyrebird/script_validator/MANIFEST.TXT
delete mode 100644 site_ansto/instrument/lyrebird/script_validator/config/counter/counter.tcl
delete mode 100644 site_ansto/instrument/lyrebird/script_validator/config/hmm/hmm_configuration.tcl
delete mode 100644 site_ansto/instrument/lyrebird/script_validator/sics_ports.tcl
delete mode 100644 site_ansto/instrument/lyrebird/script_validator_ports.tcl
delete mode 100644 site_ansto/instrument/lyrebird/sics_ports.tcl
delete mode 100644 site_ansto/instrument/lyrebird/util/dmc2280/troubleshoot_setup.tcl
delete mode 100755 site_ansto/instrument/mksim_config.tcl
delete mode 100644 site_ansto/instrument/pas/DMC2280/README.txt
delete mode 100644 site_ansto/instrument/pas/config/INSTCFCOMMON.TXT
delete mode 100644 site_ansto/instrument/pas/pelican_configuration.tcl
delete mode 100644 site_ansto/instrument/pelican/DMC2280/README.txt
delete mode 100644 site_ansto/instrument/pelican/DMC2280/controller4.txt
delete mode 100644 site_ansto/instrument/pelican/DMC2280/controller5.txt
delete mode 100644 site_ansto/instrument/pelican/MANIFEST.TXT
delete mode 100644 site_ansto/instrument/pelican/Makefile
delete mode 100644 site_ansto/instrument/pelican/config/INSTCFCOMMON.TXT
delete mode 100644 site_ansto/instrument/pelican/config/Makefile
delete mode 100644 site_ansto/instrument/pelican/config/anticollider/acscript.txt
delete mode 100644 site_ansto/instrument/pelican/config/anticollider/anticollider.tcl
delete mode 100644 site_ansto/instrument/pelican/config/beamline/sct_power.tcl
delete mode 100644 site_ansto/instrument/pelican/config/chopper/fermimot.tcl
delete mode 100644 site_ansto/instrument/pelican/config/chopper/sct_fermichopper.tcl
delete mode 100644 site_ansto/instrument/pelican/config/commands/commands.tcl
delete mode 100644 site_ansto/instrument/pelican/config/commands/monodrive.tcl
delete mode 100644 site_ansto/instrument/pelican/config/counter/counter.tcl
delete mode 100644 site_ansto/instrument/pelican/config/hipadaba/hipadaba_configuration.tcl
delete mode 100644 site_ansto/instrument/pelican/config/hmm/hmm_configuration.tcl
delete mode 100644 site_ansto/instrument/pelican/config/hmm/sct_hv.tcl
delete mode 100644 site_ansto/instrument/pelican/config/motors/extraconfig.tcl
delete mode 100644 site_ansto/instrument/pelican/config/motors/motor_configuration.tcl
delete mode 100644 site_ansto/instrument/pelican/config/motors/positmotor_configuration.tcl
delete mode 100644 site_ansto/instrument/pelican/config/nexus/Makefile
delete mode 100644 site_ansto/instrument/pelican/config/nexus/nxscripts.tcl
delete mode 100644 site_ansto/instrument/pelican/config/plc/plc.tcl
delete mode 100644 site_ansto/instrument/pelican/config/scan/scan.tcl
delete mode 100644 site_ansto/instrument/pelican/hostport_config.tcl
delete mode 100644 site_ansto/instrument/pelican/hostport_config_test.tcl
delete mode 100644 site_ansto/instrument/pelican/pelican_configuration.tcl
delete mode 100644 site_ansto/instrument/pelican/runsics_def.py
delete mode 100644 site_ansto/instrument/pelican/script_validator/MANIFEST.TXT
delete mode 100644 site_ansto/instrument/pelican/script_validator/config/counter/counter.tcl
delete mode 100644 site_ansto/instrument/pelican/script_validator/config/hmm/hmm_configuration.tcl
delete mode 100644 site_ansto/instrument/pelican/script_validator/sics_ports.tcl
delete mode 100644 site_ansto/instrument/pelican/script_validator_ports.tcl
delete mode 100644 site_ansto/instrument/pelican/sics_ports.tcl
delete mode 100644 site_ansto/instrument/pelican/sics_simulation.tcl
delete mode 100644 site_ansto/instrument/pelican/util/dmc2280/troubleshoot_setup.tcl
delete mode 100644 site_ansto/instrument/pelican/util/sics_config.ini
delete mode 100644 site_ansto/instrument/qld/DMC2280/README.txt
delete mode 100644 site_ansto/instrument/qld/DMC2280/controller1.txt
delete mode 100644 site_ansto/instrument/qld/DMC2280/controller2.txt
delete mode 100755 site_ansto/instrument/qld/MANIFEST.TXT
delete mode 100755 site_ansto/instrument/qld/counter.tcl
delete mode 100644 site_ansto/instrument/qld/extraconfig.tcl
delete mode 100644 site_ansto/instrument/qld/hipadaba_configuration.tcl
delete mode 100644 site_ansto/instrument/qld/hpaths.tcl
delete mode 100644 site_ansto/instrument/qld/koala.hdd
delete mode 100644 site_ansto/instrument/qld/koala_configuration.tcl
delete mode 100644 site_ansto/instrument/qld/motor_configuration.tcl
delete mode 100644 site_ansto/instrument/qld/troubleshoot_setup.tcl
delete mode 100644 site_ansto/instrument/reflectometer/DMC2280/README.txt
delete mode 100644 site_ansto/instrument/reflectometer/DMC2280/controller1.txt
delete mode 100644 site_ansto/instrument/reflectometer/DMC2280/controller2.txt
delete mode 100644 site_ansto/instrument/reflectometer/DMC2280/controller3.txt
delete mode 100644 site_ansto/instrument/reflectometer/DMC2280/controller4.txt
delete mode 100755 site_ansto/instrument/reflectometer/MANIFEST.TXT
delete mode 100644 site_ansto/instrument/reflectometer/Makefile
delete mode 100644 site_ansto/instrument/reflectometer/config/INSTCFCOMMON.TXT
delete mode 100644 site_ansto/instrument/reflectometer/config/Makefile
delete mode 100644 site_ansto/instrument/reflectometer/config/anticollider/acscript.txt
delete mode 100644 site_ansto/instrument/reflectometer/config/anticollider/anticollider.tcl
delete mode 100644 site_ansto/instrument/reflectometer/config/beamline/polanal.tcl
delete mode 100644 site_ansto/instrument/reflectometer/config/beamline/sct_RFGen.tcl
delete mode 100644 site_ansto/instrument/reflectometer/config/chopper/chopper.tcl
delete mode 100644 site_ansto/instrument/reflectometer/config/chopper/sct_chopper.tcl
delete mode 100644 site_ansto/instrument/reflectometer/config/commands/commands.tcl
delete mode 100644 site_ansto/instrument/reflectometer/config/counter/counter.tcl
delete mode 100644 site_ansto/instrument/reflectometer/config/hipadaba/hipadaba_configuration.tcl
delete mode 100644 site_ansto/instrument/reflectometer/config/hipadaba/hpaths.tcl
delete mode 100644 site_ansto/instrument/reflectometer/config/hmm/detector.tcl
delete mode 100644 site_ansto/instrument/reflectometer/config/hmm/hmm_configuration.tcl
delete mode 100644 site_ansto/instrument/reflectometer/config/motors/motor_configuration.tcl
delete mode 100644 site_ansto/instrument/reflectometer/config/motors/positmotor_configuration.tcl
delete mode 100644 site_ansto/instrument/reflectometer/config/motors/sct_batmotor.tcl
delete mode 100644 site_ansto/instrument/reflectometer/config/nexus/Makefile
delete mode 100644 site_ansto/instrument/reflectometer/config/nexus/nexus_in_motors.dic
delete mode 100644 site_ansto/instrument/reflectometer/config/nexus/nxscripts.tcl
delete mode 100644 site_ansto/instrument/reflectometer/config/parameters/parameters.tcl
delete mode 100644 site_ansto/instrument/reflectometer/config/plc/plc.tcl
delete mode 100644 site_ansto/instrument/reflectometer/config/scan/scan.tcl
delete mode 100644 site_ansto/instrument/reflectometer/hostport_config.tcl
delete mode 100644 site_ansto/instrument/reflectometer/hostport_config_test.tcl
delete mode 100644 site_ansto/instrument/reflectometer/platypus_configuration.tcl
delete mode 100644 site_ansto/instrument/reflectometer/runsics_def.py
delete mode 100644 site_ansto/instrument/reflectometer/script_validator/MANIFEST.TXT
delete mode 100644 site_ansto/instrument/reflectometer/script_validator/config/counter/counter.tcl
delete mode 100644 site_ansto/instrument/reflectometer/script_validator/config/hmm/hmm_configuration.tcl
delete mode 100644 site_ansto/instrument/reflectometer/script_validator/sics_ports.tcl
delete mode 100644 site_ansto/instrument/reflectometer/script_validator_ports.tcl
delete mode 100644 site_ansto/instrument/reflectometer/sics_ports.tcl
delete mode 100644 site_ansto/instrument/reflectometer/sics_simulation.tcl
delete mode 100644 site_ansto/instrument/reflectometer/util/dmc2280/troubleshoot_setup.tcl
delete mode 100644 site_ansto/instrument/reflectometer/util/sics_config.ini
delete mode 100644 site_ansto/instrument/rsd/DMC2280/README.txt
delete mode 100644 site_ansto/instrument/rsd/DMC2280/controller1.txt
delete mode 100644 site_ansto/instrument/rsd/DMC2280/controller2.txt
delete mode 100644 site_ansto/instrument/rsd/DMC2280/controller3.txt
delete mode 100644 site_ansto/instrument/rsd/DMC2280/controller4.txt
delete mode 100755 site_ansto/instrument/rsd/MANIFEST.TXT
delete mode 100644 site_ansto/instrument/rsd/Makefile
delete mode 100644 site_ansto/instrument/rsd/config/INSTCFCOMMON.TXT
delete mode 100644 site_ansto/instrument/rsd/config/Makefile
delete mode 100644 site_ansto/instrument/rsd/config/anticollider/acscript.txt
delete mode 100644 site_ansto/instrument/rsd/config/anticollider/anticollider.tcl
delete mode 100644 site_ansto/instrument/rsd/config/commands/commands.tcl
delete mode 100644 site_ansto/instrument/rsd/config/counter/counter.tcl
delete mode 100644 site_ansto/instrument/rsd/config/hipadaba/hipadaba_configuration.tcl
delete mode 100644 site_ansto/instrument/rsd/config/hipadaba/hpaths.tcl
delete mode 100644 site_ansto/instrument/rsd/config/hmm/hmm_configuration.tcl
delete mode 100644 site_ansto/instrument/rsd/config/motors/euler_configuration.tcl
delete mode 100644 site_ansto/instrument/rsd/config/motors/motor_configuration.tcl
delete mode 100644 site_ansto/instrument/rsd/config/motors/positmotor_configuration.tcl
delete mode 100644 site_ansto/instrument/rsd/config/motors/secondary_slit_configuration.tcl
delete mode 100644 site_ansto/instrument/rsd/config/motors/tiny_black_euler_configuration.tcl
delete mode 100644 site_ansto/instrument/rsd/config/nexus/nxscripts.tcl
delete mode 100644 site_ansto/instrument/rsd/config/plc/plc.tcl
delete mode 100644 site_ansto/instrument/rsd/config/scan/scan.tcl
delete mode 100644 site_ansto/instrument/rsd/hipadaba_configuration.tcl
delete mode 100644 site_ansto/instrument/rsd/hostport_config.tcl
delete mode 100644 site_ansto/instrument/rsd/hostport_config_test.tcl
delete mode 100644 site_ansto/instrument/rsd/hpaths.tcl
delete mode 100644 site_ansto/instrument/rsd/kowari.hdd
delete mode 100644 site_ansto/instrument/rsd/kowari_configuration.tcl
delete mode 100644 site_ansto/instrument/rsd/runsics_def.py
delete mode 100644 site_ansto/instrument/rsd/script_validator/MANIFEST.TXT
delete mode 100644 site_ansto/instrument/rsd/script_validator/sics_ports.tcl
delete mode 100644 site_ansto/instrument/rsd/script_validator_ports.tcl
delete mode 100644 site_ansto/instrument/rsd/sics_ports.tcl
delete mode 100644 site_ansto/instrument/rsd/sics_simulation.tcl
delete mode 100644 site_ansto/instrument/rsd/util/sics_config.ini
delete mode 100755 site_ansto/instrument/runsics.py
delete mode 100644 site_ansto/instrument/sans/DMC2280/README.txt
delete mode 100644 site_ansto/instrument/sans/DMC2280/controller1.txt
delete mode 100644 site_ansto/instrument/sans/DMC2280/controller2.txt
delete mode 100644 site_ansto/instrument/sans/DMC2280/controller3.txt
delete mode 100644 site_ansto/instrument/sans/DMC2280/controller4.txt
delete mode 100755 site_ansto/instrument/sans/MANIFEST.TXT
delete mode 100644 site_ansto/instrument/sans/Makefile
delete mode 100644 site_ansto/instrument/sans/config/INSTCFCOMMON.TXT
delete mode 100644 site_ansto/instrument/sans/config/Makefile
delete mode 100644 site_ansto/instrument/sans/config/anticollider/acscript.txt
delete mode 100644 site_ansto/instrument/sans/config/anticollider/anticollider.tcl
delete mode 100644 site_ansto/instrument/sans/config/beamline/sct_flipper.tcl
delete mode 100644 site_ansto/instrument/sans/config/beamline/spin_flipper.tcl
delete mode 100644 site_ansto/instrument/sans/config/commands/commands.tcl
delete mode 100644 site_ansto/instrument/sans/config/commands/growfile.tcl
delete mode 100644 site_ansto/instrument/sans/config/counter/counter.tcl
delete mode 100644 site_ansto/instrument/sans/config/counter/sct_rheometer.tcl
delete mode 100644 site_ansto/instrument/sans/config/environment/environment.tcl
delete mode 100644 site_ansto/instrument/sans/config/environment/magneticField/oxford_labview.tcl
delete mode 100644 site_ansto/instrument/sans/config/environment/temperature/lakeshore340.tcl
delete mode 100644 site_ansto/instrument/sans/config/goniometer/sct_goniometer.tcl
delete mode 100644 site_ansto/instrument/sans/config/goniometer/spin_goniometer.tcl
delete mode 100644 site_ansto/instrument/sans/config/hipadaba/hipadaba_configuration.tcl
delete mode 100644 site_ansto/instrument/sans/config/hipadaba/hpaths.tcl
delete mode 100644 site_ansto/instrument/sans/config/hmm/detector.tcl
delete mode 100644 site_ansto/instrument/sans/config/hmm/detector_ordela.tcl
delete mode 100644 site_ansto/instrument/sans/config/hmm/hmm_configuration.tcl
delete mode 100644 site_ansto/instrument/sans/config/hmm/nhq200_detector_config.tcl
delete mode 100644 site_ansto/instrument/sans/config/hmm/ordela_detector_config.tcl
delete mode 100644 site_ansto/instrument/sans/config/motors/motor_configuration.tcl
delete mode 100644 site_ansto/instrument/sans/config/motors/positmotor_configuration.tcl
delete mode 100644 site_ansto/instrument/sans/config/nexus/Makefile
delete mode 100644 site_ansto/instrument/sans/config/nexus/nexus_in_motors.dic
delete mode 100644 site_ansto/instrument/sans/config/nexus/nxscripts.tcl
delete mode 100644 site_ansto/instrument/sans/config/optics/README.TXT
delete mode 100644 site_ansto/instrument/sans/config/optics/aperture_configuration.tcl
delete mode 100644 site_ansto/instrument/sans/config/optics/guide_configuration.tcl
delete mode 100644 site_ansto/instrument/sans/config/optics/optics.tcl
delete mode 100644 site_ansto/instrument/sans/config/parameters/parameters.tcl
delete mode 100644 site_ansto/instrument/sans/config/plc/plc.tcl
delete mode 100644 site_ansto/instrument/sans/config/scan/scan.tcl
delete mode 100644 site_ansto/instrument/sans/config/velsel/sct_velsel.tcl
delete mode 100644 site_ansto/instrument/sans/config/velsel/velsel.tcl
delete mode 100644 site_ansto/instrument/sans/hostport_config.tcl
delete mode 100644 site_ansto/instrument/sans/hostport_config_test.tcl
delete mode 100644 site_ansto/instrument/sans/quokka_configuration.tcl
delete mode 100644 site_ansto/instrument/sans/runsics_def.py
delete mode 100644 site_ansto/instrument/sans/script_validator/MANIFEST.TXT
delete mode 100644 site_ansto/instrument/sans/script_validator/config/counter/counter.tcl
delete mode 100644 site_ansto/instrument/sans/script_validator/config/hmm/hmm_configuration.tcl
delete mode 100644 site_ansto/instrument/sans/script_validator/sics_ports.tcl
delete mode 100644 site_ansto/instrument/sans/script_validator_ports.tcl
delete mode 100644 site_ansto/instrument/sans/sics_ports.tcl
delete mode 100644 site_ansto/instrument/sans/sics_simulation.tcl
delete mode 100644 site_ansto/instrument/sans/util/dmc2280/troubleshoot_setup.tcl
delete mode 100755 site_ansto/instrument/sans/util/dsc.py
delete mode 100644 site_ansto/instrument/sans/util/sics_config.ini
delete mode 100644 site_ansto/instrument/server_config.tcl
delete mode 100644 site_ansto/instrument/tas/DMC2280/README.txt
delete mode 100755 site_ansto/instrument/tas/DMC2280/controller1.txt
delete mode 100755 site_ansto/instrument/tas/DMC2280/controller2.txt
delete mode 100755 site_ansto/instrument/tas/DMC2280/controller3.txt
delete mode 100644 site_ansto/instrument/tas/DMC2280/controller4.txt
delete mode 100644 site_ansto/instrument/tas/DMC2280/controller5.txt
delete mode 100755 site_ansto/instrument/tas/DMC2280/controller6.txt
delete mode 100644 site_ansto/instrument/tas/MANIFEST.TXT
delete mode 100644 site_ansto/instrument/tas/Makefile
delete mode 100644 site_ansto/instrument/tas/config/INSTCFCOMMON.TXT
delete mode 100644 site_ansto/instrument/tas/config/Makefile
delete mode 100644 site_ansto/instrument/tas/config/anticollider/acscript.txt
delete mode 100644 site_ansto/instrument/tas/config/anticollider/anticollider.tcl
delete mode 100644 site_ansto/instrument/tas/config/commands/commands.tcl
delete mode 100644 site_ansto/instrument/tas/config/counter/counter.tcl
delete mode 100644 site_ansto/instrument/tas/config/environment/environment.tcl
delete mode 100644 site_ansto/instrument/tas/config/environment/magneticField/oxford_labview.tcl
delete mode 100644 site_ansto/instrument/tas/config/environment/temperature/lakeshore340.tcl
delete mode 100644 site_ansto/instrument/tas/config/hipadaba/hipadaba_configuration.tcl
delete mode 100644 site_ansto/instrument/tas/config/hmm/detector.tcl
delete mode 100644 site_ansto/instrument/tas/config/hmm/hmm_configuration.tcl
delete mode 100644 site_ansto/instrument/tas/config/motors/euler_configuration.tcl
delete mode 100644 site_ansto/instrument/tas/config/motors/motor_configuration.tcl
delete mode 100644 site_ansto/instrument/tas/config/motors/positmotor_configuration.tcl
delete mode 100644 site_ansto/instrument/tas/config/motors/tilt_configuration.tcl
delete mode 100644 site_ansto/instrument/tas/config/nexus/Makefile
delete mode 100644 site_ansto/instrument/tas/config/nexus/nxscripts.tcl
delete mode 100644 site_ansto/instrument/tas/config/optics/README.TXT
delete mode 100644 site_ansto/instrument/tas/config/optics/optics.tcl
delete mode 100644 site_ansto/instrument/tas/config/plc/plc.tcl
delete mode 100644 site_ansto/instrument/tas/config/scan/scan.tcl
delete mode 100644 site_ansto/instrument/tas/config/tasmad/sicscommon/ASCIIplot.tcl
delete mode 100644 site_ansto/instrument/tas/config/tasmad/sicscommon/andorhm.tcl
delete mode 100644 site_ansto/instrument/tas/config/tasmad/sicscommon/astrium.tcl
delete mode 100644 site_ansto/instrument/tas/config/tasmad/sicscommon/backup.tcl
delete mode 100644 site_ansto/instrument/tas/config/tasmad/sicscommon/batch.tcl
delete mode 100644 site_ansto/instrument/tas/config/tasmad/sicscommon/ccdwww.tcl
delete mode 100644 site_ansto/instrument/tas/config/tasmad/sicscommon/debsics
delete mode 100644 site_ansto/instrument/tas/config/tasmad/sicscommon/deltatau.tcl
delete mode 100644 site_ansto/instrument/tas/config/tasmad/sicscommon/el734.tcl
delete mode 100644 site_ansto/instrument/tas/config/tasmad/sicscommon/el737sec.tcl
delete mode 100644 site_ansto/instrument/tas/config/tasmad/sicscommon/el755.tcl
delete mode 100644 site_ansto/instrument/tas/config/tasmad/sicscommon/fourcircle.tcl
delete mode 100644 site_ansto/instrument/tas/config/tasmad/sicscommon/fsync.jar
delete mode 100644 site_ansto/instrument/tas/config/tasmad/sicscommon/hdbutil.tcl
delete mode 100644 site_ansto/instrument/tas/config/tasmad/sicscommon/kt.sinqbck
delete mode 100644 site_ansto/instrument/tas/config/tasmad/sicscommon/motorhp.tcl
delete mode 100644 site_ansto/instrument/tas/config/tasmad/sicscommon/nxsupport.tcl
delete mode 100644 site_ansto/instrument/tas/config/tasmad/sicscommon/phytron.tcl
delete mode 100644 site_ansto/instrument/tas/config/tasmad/sicscommon/pimotor.tcl
delete mode 100644 site_ansto/instrument/tas/config/tasmad/sicscommon/secsim.tcl
delete mode 100644 site_ansto/instrument/tas/config/tasmad/sicscommon/simhm.tcl
delete mode 100644 site_ansto/instrument/tas/config/tasmad/sicscommon/sinqhttp.tcl
delete mode 100644 site_ansto/instrument/tas/config/tasmad/sicscommon/stddrive.tcl
delete mode 100644 site_ansto/instrument/tas/config/tasmad/sicscommon/syncwrapper.pag
delete mode 100644 site_ansto/instrument/tas/config/tasmad/sicscommon/table.tcl
delete mode 100644 site_ansto/instrument/tas/config/tasmad/sicscommon/tecs.tcl
delete mode 100644 site_ansto/instrument/tas/config/tasmad/taspub_sics/nxtas.tcl
delete mode 100644 site_ansto/instrument/tas/config/tasmad/taspub_sics/tas.dic
delete mode 100644 site_ansto/instrument/tas/config/tasmad/taspub_sics/tas.hdd
delete mode 100644 site_ansto/instrument/tas/config/tasmad/taspub_sics/tasp.tcl
delete mode 100644 site_ansto/instrument/tas/config/tasmad/taspub_sics/taspubcom.tcl
delete mode 100644 site_ansto/instrument/tas/config/tasmad/taspub_sics/tasscript.tcl
delete mode 100644 site_ansto/instrument/tas/config/tasmad/taspub_sics/tasub.dic
delete mode 100644 site_ansto/instrument/tas/hostport_config.tcl
delete mode 100644 site_ansto/instrument/tas/hostport_config_test.tcl
delete mode 100644 site_ansto/instrument/tas/runsics_def.py
delete mode 100644 site_ansto/instrument/tas/script_validator/MANIFEST.TXT
delete mode 100644 site_ansto/instrument/tas/script_validator/config/counter/counter.tcl
delete mode 100644 site_ansto/instrument/tas/script_validator/config/hmm/hmm_configuration.tcl
delete mode 100644 site_ansto/instrument/tas/script_validator/sics_ports.tcl
delete mode 100644 site_ansto/instrument/tas/script_validator_ports.tcl
delete mode 100644 site_ansto/instrument/tas/sics_ports.tcl
delete mode 100644 site_ansto/instrument/tas/sics_simulation.tcl
delete mode 100644 site_ansto/instrument/tas/taipan_configuration.tcl
delete mode 100644 site_ansto/instrument/tas/tas.hdd
delete mode 100644 site_ansto/instrument/tas/util/dmc2280/troubleshoot_setup.tcl
delete mode 100644 site_ansto/instrument/tas/util/sics_config.ini
delete mode 100644 site_ansto/instrument/util/check/README.TXT
delete mode 100644 site_ansto/instrument/util/check/check_hdb.tcl
delete mode 100644 site_ansto/instrument/util/check/check_sobj.tcl
delete mode 100644 site_ansto/instrument/util/check/query_sics.tcl
delete mode 100644 site_ansto/instrument/util/command.tcl
delete mode 100755 site_ansto/instrument/util/config_edit.py
delete mode 100644 site_ansto/instrument/util/config_reader.tcl
delete mode 100644 site_ansto/instrument/util/displayscreen.py
delete mode 100755 site_ansto/instrument/util/dmc2280/ckmd5.sh
delete mode 100644 site_ansto/instrument/util/dmc2280/dmc2280_util.tcl
delete mode 100755 site_ansto/instrument/util/dmc2280/getDMCprog.tcl
delete mode 100755 site_ansto/instrument/util/dmc2280/mkmd5.sh
delete mode 100644 site_ansto/instrument/util/dmc2280/motorinfo.tcl
delete mode 100755 site_ansto/instrument/util/dmc2280/putDMCprog.tcl
delete mode 100755 site_ansto/instrument/util/dmc2280/troubleShoot.tcl
delete mode 100644 site_ansto/instrument/util/eventutil.tcl
delete mode 100644 site_ansto/instrument/util/extra_utility.tcl
delete mode 100644 site_ansto/instrument/util/fopdt.py
delete mode 100755 site_ansto/instrument/util/gen_sct.py
delete mode 100755 site_ansto/instrument/util/genmotconf.tcl
delete mode 100755 site_ansto/instrument/util/genmotconf_procs.tcl
delete mode 100755 site_ansto/instrument/util/gitloader.py
delete mode 100755 site_ansto/instrument/util/gitrefer.py
delete mode 100755 site_ansto/instrument/util/mk_SICSmd5.sh
delete mode 100644 site_ansto/instrument/util/motor_utility.tcl
delete mode 100644 site_ansto/instrument/util/pid.py
delete mode 100755 site_ansto/instrument/util/runsics
delete mode 100755 site_ansto/instrument/util/runtestsics
delete mode 100644 site_ansto/instrument/util/script_context_util.tcl
delete mode 100755 site_ansto/instrument/util/sicsclient
delete mode 100644 site_ansto/instrument/util/utility.tcl
delete mode 100755 site_ansto/instrument/util/whatsthere.py
delete mode 100644 site_ansto/instrument/util/write_tree.tcl
delete mode 100644 site_ansto/itc4.c
delete mode 100644 site_ansto/itc4.h
delete mode 100644 site_ansto/itc4.w
delete mode 100644 site_ansto/itc4driv.c
delete mode 100644 site_ansto/lakeshore340.c
delete mode 100644 site_ansto/lakeshore340.h
delete mode 100644 site_ansto/lakeshore340driv.c
delete mode 100644 site_ansto/lh45.c
delete mode 100644 site_ansto/lh45.h
delete mode 100644 site_ansto/lh45driv.c
delete mode 100644 site_ansto/ls340.c
delete mode 100644 site_ansto/ls340.h
delete mode 100644 site_ansto/lssmonitor.c
delete mode 100644 site_ansto/lssmonitor.h
delete mode 100755 site_ansto/make_config.sh
delete mode 100644 site_ansto/make_gen_variables
delete mode 100644 site_ansto/manual/Thumbs.db
delete mode 100644 site_ansto/manual/buttonBack.JPG
delete mode 100644 site_ansto/manual/buttonBegin.JPG
delete mode 100644 site_ansto/manual/buttonCross.JPG
delete mode 100644 site_ansto/manual/buttonDrive.JPG
delete mode 100644 site_ansto/manual/buttonExport.JPG
delete mode 100644 site_ansto/manual/buttonInterrupt.JPG
delete mode 100644 site_ansto/manual/buttonLoad.JPG
delete mode 100644 site_ansto/manual/buttonNext.JPG
delete mode 100644 site_ansto/manual/buttonOK.JPG
delete mode 100644 site_ansto/manual/buttonPause.JPG
delete mode 100644 site_ansto/manual/buttonPlus.JPG
delete mode 100644 site_ansto/manual/buttonResultXML.JPG
delete mode 100644 site_ansto/manual/buttonRun.JPG
delete mode 100644 site_ansto/manual/buttonTableImage.JPG
delete mode 100644 site_ansto/manual/db5SICSInstallationManual.xml
delete mode 100644 site_ansto/manual/db5SICSUserGuideQuokka.xml
delete mode 100644 site_ansto/manual/db5SICSUserGuideTaipan.xml
delete mode 100644 site_ansto/manual/db5SICSUserManual3Axis.xml
delete mode 100644 site_ansto/manual/db5SICSUserManualPelican.xml
delete mode 100644 site_ansto/manual/db5SICSUserManualPlatypus.xml
delete mode 100644 site_ansto/manual/db5SICSUserManualPowder.xml
delete mode 100644 site_ansto/manual/db5SICSUserManualQuokka.xml
delete mode 100644 site_ansto/manual/db5SICSUserManualSampleEnvironment.xml
delete mode 100644 site_ansto/manual/db5alignment_taipan.xml
delete mode 100644 site_ansto/manual/db5environment_config_taipan.xml
delete mode 100644 site_ansto/manual/db5environment_control_taipan.xml
delete mode 100644 site_ansto/manual/db5experiment_taipan.xml
delete mode 100644 site_ansto/manual/db5quickstart_quokka.xml
delete mode 100644 site_ansto/manual/db5quickstart_taipan.xml
delete mode 100644 site_ansto/manual/db5sics_login.xml
delete mode 100644 site_ansto/manual/dbGTQuokka_ch0_contacts.xml
delete mode 100644 site_ansto/manual/dbGTQuokka_ch1_experiment.xml
delete mode 100644 site_ansto/manual/dbGTQuokka_ch2_reduction.xml
delete mode 100644 site_ansto/manual/dbGTQuokka_ch3_reduction.xml
delete mode 100644 site_ansto/manual/dbSICSch0_TEMPLATE.xml
delete mode 100644 site_ansto/manual/dbSICSch10_tcl_commands.xml
delete mode 100644 site_ansto/manual/dbSICSch11_julabo.xml
delete mode 100644 site_ansto/manual/dbSICSch12_velsel.xml
delete mode 100644 site_ansto/manual/dbSICSch13_echidna_motor_names.xml
delete mode 100644 site_ansto/manual/dbSICSch14_troubleshooting.xml
delete mode 100644 site_ansto/manual/dbSICSch15_beamstop.xml
delete mode 100644 site_ansto/manual/dbSICSch16_ordela_hv.xml
delete mode 100644 site_ansto/manual/dbSICSch17_control_and_interrupt.xml
delete mode 100644 site_ansto/manual/dbSICSch18_programmer_overview.xml
delete mode 100644 site_ansto/manual/dbSICSch19_interrupting_sics.xml
delete mode 100644 site_ansto/manual/dbSICSch1_intro.xml
delete mode 100644 site_ansto/manual/dbSICSch20_file_commands.xml
delete mode 100644 site_ansto/manual/dbSICSch21_histogram_configuration.xml
delete mode 100644 site_ansto/manual/dbSICSch22_installation.xml
delete mode 100644 site_ansto/manual/dbSICSch23_extraconfig.xml
delete mode 100644 site_ansto/manual/dbSICSch24_UB_matrix.xml
delete mode 100644 site_ansto/manual/dbSICSch25_rheometer.xml
delete mode 100644 site_ansto/manual/dbSICSch26_magnet_11T.xml
delete mode 100644 site_ansto/manual/dbSICSch27_autosave.xml
delete mode 100644 site_ansto/manual/dbSICSch28_LF_amplifier.xml
delete mode 100644 site_ansto/manual/dbSICSch29_motor_control_py.xml
delete mode 100644 site_ansto/manual/dbSICSch29_motor_control_py_simple.xml
delete mode 100644 site_ansto/manual/dbSICSch2_motor_control.xml
delete mode 100644 site_ansto/manual/dbSICSch30_He3.xml
delete mode 100644 site_ansto/manual/dbSICSch31_UserGuideTaipan.xml
delete mode 100644 site_ansto/manual/dbSICSch32_platypus_disk_chopper.xml
delete mode 100644 site_ansto/manual/dbSICSch33_UserGuideQuokka.xml
delete mode 100644 site_ansto/manual/dbSICSch34_fermi_chopper.xml
delete mode 100644 site_ansto/manual/dbSICSch34_fermi_chopper_shortnames.xml
delete mode 100644 site_ansto/manual/dbSICSch35_oxford_labview.xml
delete mode 100644 site_ansto/manual/dbSICSch36_oxford_mercury.xml
delete mode 100644 site_ansto/manual/dbSICSch3_histogram_control.xml
delete mode 100644 site_ansto/manual/dbSICSch4_simple_scan.xml
delete mode 100644 site_ansto/manual/dbSICSch4_simple_scan_py.xml
delete mode 100644 site_ansto/manual/dbSICSch4_simple_scan_taipan_only.xml
delete mode 100644 site_ansto/manual/dbSICSch5_batch.xml
delete mode 100644 site_ansto/manual/dbSICSch6_counters.xml
delete mode 100644 site_ansto/manual/dbSICSch7_user_defn_scan.xml
delete mode 100644 site_ansto/manual/dbSICSch8_batch_manager.xml
delete mode 100644 site_ansto/manual/dbSICSch9_motor_configuration.xml
delete mode 100644 site_ansto/manual/igorAbort.jpg
delete mode 100644 site_ansto/manual/igorBuildProtocol.jpg
delete mode 100644 site_ansto/manual/igorBuildProtocolAll.jpg
delete mode 100644 site_ansto/manual/igorOnlineFileSelect.jpg
delete mode 100644 site_ansto/manual/igorOnlineProtocolSelect.JPG
delete mode 100644 site_ansto/manual/igorOnlineReduction.jpg
delete mode 100644 site_ansto/manual/igorPatchFiles.JPG
delete mode 100644 site_ansto/manual/igorPatchSDD.JPG
delete mode 100644 site_ansto/manual/igorPickOnlineProtocol.jpg
delete mode 100644 site_ansto/manual/igorPickPath.jpg
delete mode 100644 site_ansto/manual/igorPickProtocol.jpg
delete mode 100644 site_ansto/manual/igorRawData.jpg
delete mode 100644 site_ansto/manual/igorReductionControls.jpg
delete mode 100644 site_ansto/manual/igorSaveProtocol.jpg
delete mode 100644 site_ansto/manual/igorSelectMacros.jpg
delete mode 100644 site_ansto/manual/igorStartOnlineProtocol.jpg
delete mode 100644 site_ansto/manual/igorStartScreen.JPG
delete mode 100644 site_ansto/manual/newsics.gif
delete mode 100644 site_ansto/manual/putty.JPG
delete mode 100644 site_ansto/manual/quokkaGumtree1.jpg
delete mode 100644 site_ansto/manual/quokkaGumtree10.jpg
delete mode 100644 site_ansto/manual/quokkaGumtree11.jpg
delete mode 100644 site_ansto/manual/quokkaGumtree12.jpg
delete mode 100644 site_ansto/manual/quokkaGumtree2.jpg
delete mode 100644 site_ansto/manual/quokkaGumtree3.jpg
delete mode 100644 site_ansto/manual/quokkaGumtree4.jpg
delete mode 100644 site_ansto/manual/quokkaGumtree5.jpg
delete mode 100644 site_ansto/manual/quokkaGumtree6.jpg
delete mode 100644 site_ansto/manual/quokkaGumtree7.jpg
delete mode 100644 site_ansto/manual/quokkaGumtree8.jpg
delete mode 100644 site_ansto/manual/quokkaGumtree9.jpg
delete mode 100644 site_ansto/manual/taipanGumtree.jpg
delete mode 100644 site_ansto/manual/taipanGumtree1.jpg
delete mode 100644 site_ansto/manual/taipanGumtree2.jpg
delete mode 100644 site_ansto/manual/taipanGumtree3.jpg
delete mode 100644 site_ansto/manual/troubleshoot1.jpeg
delete mode 100644 site_ansto/manual/troubleshoot2.jpeg
delete mode 100644 site_ansto/manual/troubleshoot3.jpeg
delete mode 100644 site_ansto/manual/troubleshoot4.jpeg
delete mode 100644 site_ansto/manual/troubleshoot5.jpeg
delete mode 100644 site_ansto/manual/troubleshoot6.jpeg
delete mode 100644 site_ansto/motor_asim.c
delete mode 100644 site_ansto/motor_asim.h
delete mode 100644 site_ansto/motor_dmc2280.c
delete mode 100644 site_ansto/motor_dmc2280.h
delete mode 100644 site_ansto/motor_driver.h
delete mode 100644 site_ansto/nhq200.c
delete mode 100644 site_ansto/nhq200.h
delete mode 100644 site_ansto/nhq200driv.c
delete mode 100644 site_ansto/orhvps.c
delete mode 100644 site_ansto/orhvps.h
delete mode 100644 site_ansto/refl2t.c
delete mode 100644 site_ansto/refl2t.h
delete mode 100644 site_ansto/safetyplc.c
delete mode 100644 site_ansto/safetyplc.h
delete mode 100644 site_ansto/sctemonadapter.c
delete mode 100644 site_ansto/site_ansto.c
delete mode 100644 site_ansto/site_dummy.c
delete mode 100644 site_ansto/tclClock.c
delete mode 100644 site_ansto/tclDate.c
delete mode 100644 site_ansto/tclUnixTime.c
delete mode 100644 site_ansto/test_west.tcl
delete mode 100644 site_ansto/west4100.c
delete mode 100644 site_ansto/west4100.h
delete mode 100644 site_ansto/west4100driv.c
delete mode 100755 site_ansto/xref.py
create mode 100644 taskobj.c
create mode 100644 taskobj.h
create mode 100644 tasmono.c
create mode 100644 tasmono.h
delete mode 100644 tcl/astrium.tcl
delete mode 100755 tcl/bgerror.tcl
delete mode 100755 tcl/client.tcl
delete mode 100644 tcl/count.tcl
delete mode 100644 tcl/deltatau.tcl
delete mode 100644 tcl/el737sec.tcl
delete mode 100644 tcl/el755.tcl
delete mode 100644 tcl/fit.tcl
delete mode 100644 tcl/ldAout.tcl
delete mode 100644 tcl/lof.tcl
delete mode 100644 tcl/log.tcl
delete mode 100644 tcl/nhq202m.tcl
delete mode 100644 tcl/nvs.tcl
delete mode 100644 tcl/nvs20m.tcl
delete mode 100644 tcl/parray.tcl
delete mode 100644 tcl/pfeiffer.tcl
delete mode 100644 tcl/phytron.tcl
delete mode 100644 tcl/pimotor.tcl
delete mode 100644 tcl/reflist.tcl
delete mode 100644 tcl/scan.tcl
delete mode 100644 tcl/scancom.tcl
delete mode 100644 tcl/secsim.tcl
delete mode 100644 tcl/sicstcldebug.tcl
delete mode 100644 tcl/simhm.tcl
delete mode 100644 tcl/sinqhttp.tcl
delete mode 100644 tcl/slsecho.tcl
delete mode 100644 tcl/stddrive.tcl
delete mode 100644 tcl/stdin.tcl
delete mode 100644 tcl/susca.tcl
delete mode 100644 tcl/table.tcl
delete mode 100644 tcl/tail.tcl
delete mode 100644 tcl/topsiold.tcl
delete mode 100644 tcl/wwwpulver.tcl
diff --git a/.gitignore b/.gitignore
index 66d8d528..2eed84ba 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,22 +1,121 @@
-SICServer
-made_config.h
-PATCH.TXT
-*.aux
-*.pdf
-.*.sw?
-*.orig
-*.svn
+# Took these from the https://github.com/github/gitignore project on October 21, 2011
+
+# **** 'Personal' entries don't belong in here - put them in your .git/info/exclude file ****
+
+# Ignore text editor (e.g. emacs) autosave files
*~
-CVS
-CVSPSI
-*.pyc
-*.png
-*.hdf5
-*.a
+
+
+# Compiled Object files
+*.slo
+*.lo
*.o
+*.obj
*.d
-*.out
-*.sqlite
-parser.out
-parsetab.py
-_trial_temp
+SICServer
+
+# Compiled Dynamic libraries
+*.so
+
+# Compiled Static libraries
+*.lai
+*.la
+*.a
+
+# Compiled python files
+*.py[co]
+
+# Eclipse-generated files
+*.pydevproject
+.project
+.metadata
+bin/**
+tmp/**
+tmp/**/*
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.classpath
+.settings/
+.loadpath
+
+# External tool builders
+.externalToolBuilders/
+
+# Locally stored "Eclipse launch configurations"
+*.launch
+
+# CDT-specific
+.cproject
+
+# PDT-specific
+.buildpath
+
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+*.sln
+*.vcproj
+*.exe
+*.vcxproj
+*.filters
+
+# User-specific files
+*.suo
+*.user
+*.sln.docstates
+*.sdf
+
+#Test results
+*.log
+
+# Build results
+[Dd]ebug/
+[Rr]elease/
+*_i.c
+*_p.c
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.vspscc
+.builds
+
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opensdf
+*.sdf
+
+# Visual Studio profiler
+*.psess
+*.vsp
+
+# ReSharper is a .NET coding add-in
+_ReSharper*
+
+
+
+# Others
+*.autosave
+
+
+# Windows image file caches
+Thumbs.db
+
+
+# Mac OS X Finder
+.DS_Store
+
diff --git a/HistDriv.i b/HistDriv.i
index b9fad721..75d4229b 100644
--- a/HistDriv.i
+++ b/HistDriv.i
@@ -1,5 +1,5 @@
-#line 467 "histogram.w"
+#line 470 "histogram.w"
/*---------------------------------------------------------------------------
H I S T D R I V
@@ -72,7 +72,7 @@
void *pPriv;
} HistDriver;
-#line 479 "histogram.w"
+#line 482 "histogram.w"
#line 232 "histogram.w"
@@ -84,7 +84,7 @@
HistInt *DefaultSubSample(pHistDriver self, SConnection *pCon,
int bank, char *command);
-#line 480 "histogram.w"
+#line 483 "histogram.w"
#endif
diff --git a/HistMem.h b/HistMem.h
index 6ceb50ab..3f22f96c 100644
--- a/HistMem.h
+++ b/HistMem.h
@@ -1,5 +1,5 @@
-#line 440 "histogram.w"
+#line 443 "histogram.w"
/*--------------------------------------------------------------------------
H I S T M E M
@@ -13,89 +13,91 @@
#define SICSHISTMEM
#define MAXDIM 3
-typedef struct __HistDriver *pHistDriver;
-typedef struct __HistMem *pHistMem;
+ typedef struct __HistDriver *pHistDriver;
+ typedef struct __HistMem *pHistMem;
/*-------------------------------------------------------------------------*/
-typedef int HistInt;
+ typedef int HistInt;
/*
32 bit integer on a DigitalUnix
*/
#line 9 "histogram.w"
-typedef enum {
- eHTransparent,
- eHNormal,
- eHTOF,
- eHStrobo,
- eHRPT,
- ePSD,
- eSANSTOF
-} HistMode;
+ typedef enum {
+ eHTransparent,
+ eHNormal,
+ eHTOF,
+ eHStrobo,
+ eHRPT,
+ ePSD,
+ eSANSTOF
+ } HistMode;
#line 36 "histogram.w"
-typedef enum {
- eOIgnore,
- eOCeil,
- eOCount,
- eReflect
-} OverFlowMode;
+ typedef enum {
+ eOIgnore,
+ eOCeil,
+ eOCount,
+ eReflect
+ } OverFlowMode;
-#line 460 "histogram.w"
+#line 463 "histogram.w"
/*--------------------------------------------------------------------------*/
#line 292 "histogram.w"
-pHistMem CreateHistMemory(char *drivername);
-void DeleteHistMemory(void *self);
+ pHistMem CreateHistMemory(char *drivername);
+ void DeleteHistMemory(void *self);
#line 308 "histogram.w"
-int HistGetOption(pHistMem self, char *name, char *result, int iResultLen);
-int HistSetOption(pHistMem self, char *name, char *value);
-int HistConfigure(pHistMem self, SConnection * pCon, SicsInterp * pSics);
+ int HistGetOption(pHistMem self, char *name, char *result, int iResultLen);
+ int HistSetOption(pHistMem self, char *name, char *value);
+ int HistConfigure(pHistMem self, SConnection *pCon, SicsInterp *pSics);
#line 336 "histogram.w"
-float GetHistPreset(pHistMem self);
-int SetHistPreset(pHistMem self, float fVal);
-CounterMode GetHistCountMode(pHistMem self);
-int SetHistCountMode(pHistMem self, CounterMode eNew);
-long GetHistMonitor(pHistMem self, int i, SConnection * pCon);
-const float *GetHistTimeBin(pHistMem self, int *iLength);
-int GetHistLength(pHistMem self);
-int GetHistDim(pHistMem self, int iDim[MAXDIM], int *nDim);
-float GetHistCountTime(pHistMem self, SConnection * pCon);
-int HistDoCount(pHistMem self, SConnection * pCon);
-int HistBlockCount(pHistMem self, SConnection * pCon);
-void HistDirty(pHistMem self);
+ float GetHistPreset(pHistMem self);
+ int SetHistPreset(pHistMem self, float fVal);
+ CounterMode GetHistCountMode(pHistMem self);
+ int SetHistCountMode(pHistMem self, CounterMode eNew);
+ long GetHistMonitor(pHistMem self, int i, SConnection *pCon);
+ const float *GetHistTimeBin(pHistMem self, int *iLength);
+ int GetHistLength(pHistMem self);
+ int GetHistDim(pHistMem self, int iDim[MAXDIM], int *nDim);
+ float GetHistCountTime(pHistMem self,SConnection *pCon);
+ int HistDoCount(pHistMem self, SConnection *pCon);
+ int HistBlockCount(pHistMem self, SConnection *pCon);
+ void HistDirty(pHistMem self);
+
+ int isSecondGen(pHistMem self);
+ pHistMem FindHM(SicsInterp *pSics, char *name);
-#line 366 "histogram.w"
+#line 369 "histogram.w"
-int SetHistogram(pHistMem self, SConnection * pCon,
- int i, int iStart, int iEnd, HistInt * lData);
-int GetHistogram(pHistMem self, SConnection * pCon,
- int i, int iStart, int iEnd, HistInt * lData,
- int iDataLen);
-HistInt *GetHistogramPointer(pHistMem self, SConnection * pCon);
-int GetHistogramDirect(pHistMem self, SConnection * pCon,
- int i, int iStart, int iEnd,
- HistInt * lData, int iDataLen);
-int PresetHistogram(pHistMem self, SConnection * pCon, HistInt lVal);
+ int SetHistogram(pHistMem self, SConnection *pCon,
+ int i,int iStart, int iEnd, HistInt *lData);
+ int GetHistogram(pHistMem self, SConnection *pCon,
+ int i,int iStart, int iEnd, HistInt *lData, int iDataLen);
+ HistInt *GetHistogramPointer(pHistMem self,SConnection *pCon);
+ int GetHistogramDirect(pHistMem self, SConnection *pCon,
+ int i, int iStart, int iEnd,
+ HistInt *lData, int iDataLen);
+ int PresetHistogram(pHistMem self, SConnection *pCon, HistInt lVal);
-#line 409 "histogram.w"
+#line 412 "histogram.w"
-int MakeHistMemory(SConnection * pCon, SicsInterp * pSics, void *pData,
- int argc, char *argv[]);
+ int MakeHistMemory(SConnection *pCon, SicsInterp *pSics, void *pData,
+ int argc, char *argv[]);
-int HistAction(SConnection * pCon, SicsInterp * pSics, void *pData,
- int argc, char *argv[]);
+ int HistAction(SConnection *pCon, SicsInterp *pSics, void *pData,
+ int argc, char *argv[]);
+
-
-#line 462 "histogram.w"
+#line 465 "histogram.w"
#endif
diff --git a/HistMem.i b/HistMem.i
index 5c6b98d0..ae1aafb5 100644
--- a/HistMem.i
+++ b/HistMem.i
@@ -1,5 +1,5 @@
-#line 485 "histogram.w"
+#line 488 "histogram.w"
/*---------------------------------------------------------------------------
H I S T M E M -- Internal
@@ -23,7 +23,7 @@
pICallBack pCall;
} HistMem;
-#line 495 "histogram.w"
+#line 498 "histogram.w"
#endif
diff --git a/SCinter.c b/SCinter.c
index acd616f3..1d5cd1a4 100644
--- a/SCinter.c
+++ b/SCinter.c
@@ -273,7 +273,7 @@ static int TclExecFunc(SConnection *pCon, SicsInterp *pInter, void *data,
SCWrite(pCon,(char *)Tcl_GetStringResult(InterpGetTcl(pInter)), eValue );
return 1;
} else {
- SCWrite(pCon,(char *)Tcl_GetStringResult(InterpGetTcl(pInter)), eValue );
+ SCWrite(pCon,(char *)Tcl_GetStringResult(InterpGetTcl(pInter)), eError );
return 0;
}
@@ -543,6 +543,7 @@ void DeleteInterp(SicsInterp * self)
call KillSicsUnknown instead to clean up all memory properly. M.Z., Apr 05
*/
+ Tcl_DeleteInterp(pTcl);
KillSicsUnknown();
}
diff --git a/SCinter.h b/SCinter.h
index fd126154..255e8db6 100644
--- a/SCinter.h
+++ b/SCinter.h
@@ -145,7 +145,7 @@ char *FindAliases(SicsInterp * pSics, char *name);
/*-------------------------------------------------------------------------
FindCommandData finds a command with the name given. It tests the name in the
ObjectDescriptor to be of name class. If all this succeeds a pointer
- to the commands data structure is retuned. Else NULL.
+ to the commands data structure is returned. Else NULL.
Do not test the Object Descriptor name when comclass == NULL.
*/
void *FindCommandData(SicsInterp * pSics, char *name, char *comclass);
@@ -155,7 +155,7 @@ void *FindCommandData(SicsInterp * pSics, char *name, char *comclass);
*/
pObjectDescriptor FindCommandDescriptor(SicsInterp * pSics, char *name);
-/*------------------------------------------------------------------------
+/*---------------------------------------------------------------------
FindDrivable tries to find Drivable object by the name given. Returns a
pointer to the drivable interface in the case of success, NULL in
case of failure. In order to save me fixing header files the pointer must
diff --git a/SICSmain.c b/SICSmain.c
index 617606a4..6062f216 100644
--- a/SICSmain.c
+++ b/SICSmain.c
@@ -24,6 +24,7 @@
#include "nserver.h"
#include "servlog.h"
#include "sicsglobal.h"
+extern void KeepStartupCommands(); /* ofac.c */
/* ========================= Less dreadful file statics =================== */
@@ -60,6 +61,8 @@ int main(int argc, char *argv[])
if (argv[i][0] == '-') {
if (strcasecmp(argv[i], "-nolog") == 0) {
SICSLogEnable(0);
+ }else if(strcmp(argv[i],"-keepstartup") == 0){
+ KeepStartupCommands();
#ifdef SITE_ANSTO
} else if (strcasecmp(argv[i], "-v") == 0) {
extern void SiteReportVersion(void);
diff --git a/arrayutil.c b/arrayutil.c
index 9d9c458a..4c352212 100644
--- a/arrayutil.c
+++ b/arrayutil.c
@@ -36,11 +36,18 @@ long sumWindow(int *data, int xstart, int xend, int xlength,
}
- for(j = ystart; j < yend; j++){
- row = data + j*xlength;
- for(i = xstart; i < xend; i++){
- result += row[i];
+ /* for(j = ystart; j < yend; j++){ */
+ /* row = data + j*xlength; */
+ /* for(i = xstart; i < xend; i++){ */
+ /* result += row[i]; */
+ /* } */
+ /* } */
+ for(i = xstart; i < xend; i++){
+ row = data + i*ylength;
+ for(j = ystart; j < yend; j++){
+ result += row[j];
}
}
+
return result;
}
diff --git a/ascon.c b/ascon.c
index 39a7facb..98039cc8 100644
--- a/ascon.c
+++ b/ascon.c
@@ -47,7 +47,7 @@ static int CreateSocketAdress(struct sockaddr_in *sockaddrPtr, /* Socket addres
}
/*
* There is a rumor that this assignment may require care on
- * some 64 bit machines.
+ * some 64 bit machines, we do not believe it.
*/
sockaddrPtr->sin_addr.s_addr = addr.s_addr;
return 1;
@@ -134,7 +134,11 @@ static void AsconConnect(Ascon * a)
}
colon = strchr(a->hostport, ':');
if (colon == NULL) {
- AsconError(a, "expected 'host:port' or 'unconnected'", 0);
+ if (strcmp(a->hostport, "unconnected") == 0) {
+ AsconError(a, "offline", 0);
+ } else {
+ AsconError(a, "expected 'host:port' or 'unconnected'", 0);
+ }
return;
}
port = atoi(colon + 1);
@@ -672,7 +676,7 @@ Ascon *AsconMake(SConnection * con, int argc, char *argv[])
free(args);
return NULL;
}
- a->rdBuffer = CreateDynString(60, 63);
+ a->rdBuffer = CreateDynString(60, 65536);
a->wrBuffer = CreateDynString(60, 63);
a->errmsg = CreateDynString(60, 63);
@@ -765,6 +769,11 @@ AsconStatus AsconTask(Ascon * a)
a->responseValid = 1;
DynStringClear(a->errmsg);
return AsconReady;
+ case AsconReadDoneReconnect:
+ a->responseValid = 1;
+ DynStringClear(a->errmsg);
+ AsconReconnect(a,NULL);
+ return AsconReady;
case AsconIdle:
return AsconReady;
case AsconTimeout:
@@ -777,7 +786,7 @@ AsconStatus AsconTask(Ascon * a)
lastClose = now;
a->fd = -1;
}
- if (now > a->lastReconnect + a->reconnectInterval) {
+ if (a->reconnectInterval > 0 && now > a->lastReconnect + a->reconnectInterval) {
a->lastReconnect = now;
a->state = AsconConnectStart;
}
@@ -844,3 +853,10 @@ double AsconGetSetTimeout(Ascon *a, double timeout, int setmode) {
}
return a->timeout;
}
+
+int AsconReconnectInterval(Ascon *a, int interval) {
+ if (interval >= 0) {
+ a->reconnectInterval = interval;
+ }
+ return a->reconnectInterval;
+}
diff --git a/ascon.h b/ascon.h
index 1065e23e..c7f81933 100644
--- a/ascon.h
+++ b/ascon.h
@@ -117,4 +117,12 @@ char *AsconHostport(Ascon *a);
*/
double AsconGetSetTimeout(Ascon *a, double timeout, int setmode);
+/**
+ * \brief set reconnectInterval
+ * \param a the Ascon
+ * \param interval the interval to set (0: no reconnect, -1: read value)
+ * \return the value
+ */
+int AsconReconnectInterval(Ascon *a, int interval);
+
#endif
diff --git a/ascon.i b/ascon.i
index 2c510287..9cadeb95 100644
--- a/ascon.i
+++ b/ascon.i
@@ -25,20 +25,21 @@
* The state of the connection.
*/
typedef enum {
- AsconNotConnected, /**< unconnected, not to be connected automatically */
- AsconConnectStart, /**< after initialisation or after AsconFailed */
- AsconConnecting, /**< after AsconConnectStart or AsconConnecting */
- AsconConnectDone, /**< after AsconConnecting */
- AsconWriteStart, /**< set by the AsconWrite function */
- AsconWriting, /**< after AsconWriteStart or AsconWriting */
- AsconWriteDone, /**< after AsconWriting */
- AsconReadStart, /**< after AsconWriteDone */
- AsconReading, /**< after AsconReadStart or AsconReading */
- AsconReadDone, /**< after AsconReading */
- AsconIdle, /**< after AsconWriteDone, AsconReadDone, AsconTimeout, AsconIdle */
- AsconFailed, /**< after any state */
- AsconTimeout, /**< after AsconReading */
- AsconMaxState /**< number of states */
+ AsconNotConnected, /**< unconnected, not to be connected automatically */
+ AsconConnectStart, /**< after initialisation or after AsconFailed */
+ AsconConnecting, /**< after AsconConnectStart or AsconConnecting */
+ AsconConnectDone, /**< after AsconConnecting */
+ AsconWriteStart, /**< set by the AsconWrite function */
+ AsconWriting, /**< after AsconWriteStart or AsconWriting */
+ AsconWriteDone, /**< after AsconWriting */
+ AsconReadStart, /**< after AsconWriteDone */
+ AsconReading, /**< after AsconReadStart or AsconReading */
+ AsconReadDone, /**< after AsconReading */
+ AsconReadDoneReconnect, /**< after AsconReading, read success, but need to reconnect */
+ AsconIdle, /**< after AsconWriteDone, AsconReadDone, AsconTimeout, AsconIdle */
+ AsconFailed, /**< after any state */
+ AsconTimeout, /**< after AsconReading */
+ AsconMaxState /**< number of states */
} AsconState;
/** \brief the task handler function prototype
diff --git a/asynnet.c b/asynnet.c
index 7b69728b..46592d9b 100644
--- a/asynnet.c
+++ b/asynnet.c
@@ -46,6 +46,7 @@
#define RBUFFERSIZE 262144 /* 256kb */
#define WBUFFERSIZE 20*262144
/* #define WBUFFERSIZE 100*262144 */
+#define MAXWBUFFERSIZE 128*1000*1024
/*--------------------------------------------------------------------------*/
typedef struct {
int socket;
@@ -204,7 +205,7 @@ int ANETregisterSocket(int socket)
flags =1;
setsockopt(socket,IPPROTO_TCP,TCP_NODELAY,(char *) &flags, sizeof(int));
socke.readBuffer = MakeRWPuffer(RBUFFERSIZE);
- socke.writeBuffer = MakeRWPuffer(WBUFFERSIZE);
+ socke.writeBuffer = MakeBigRWPuffer(WBUFFERSIZE, MAXWBUFFERSIZE);
if (socke.readBuffer == NULL || socke.writeBuffer == NULL) {
return ANETMEM;
}
@@ -247,6 +248,7 @@ int ANETconnect(char *name, int iPort)
status = connect(socke, (struct sockaddr *) &addresse,
sizeof(struct sockaddr_in));
if (status < 0) {
+ close(socke);
anetLog(ANETERROR, "Failed to open socket to %s:%d", name, iPort);
return ANETOPENFAIL;
}
@@ -503,7 +505,20 @@ int ANETinfo(int handle, char *hostname, int hostnameLen)
}
return 1;
}
+/*---------------------------------------------------------------------------*/
+int ANETcanWrite(int handle, void *buffer, int count)
+{
+ pSocketDescriptor con = NULL;
+ int status;
+ con = findSocketDescriptor(handle);
+ if (con == NULL) {
+ return ANETDISCONNECTED;
+ } else {
+ ANETprocess();
+ return CanStoreRWBuffer(con->writeBuffer, buffer, count);
+ }
+}
/*---------------------------------------------------------------------------*/
int ANETwrite(int handle, void *buffer, int count)
{
@@ -632,14 +647,3 @@ int ANETreadTillTerm(int handle,
}
return ANETTIMEOUT;
}
-
-char *ANETgetWBuffer(int handle) {
- pSocketDescriptor sock;
- int len;
- char *wdata;
-
- sock = findSocketDescriptor(handle);
- wdata = (char *) GetRWBufferData(sock->writeBuffer, &len);
- wdata[len] = '\0';
- return wdata;
-}
diff --git a/asynnet.h b/asynnet.h
index c52566c8..ae2f114d 100644
--- a/asynnet.h
+++ b/asynnet.h
@@ -145,6 +145,14 @@ int ANETinfo(int handle, char *hostname, int hostNameLen);
* \return 1 on success, 0 on failure
*/
int ANETwrite(int handle, void *buffer, int count);
+/**
+ * \brief Test if the buffer can be written to the network
+ * \param handle The handle for the connection
+ * \param buffer A pointer to the data to write
+ * \param count The number of bytes to write.
+ * \return 1 when possible, 0 when buffer overrun
+ */
+int ANETcanWrite(int handle, void *buffer, int count);
/**
* \brief copy at max bufferLength bytes into buffer. The data is not deleted from
* the read buffer yet.
@@ -207,9 +215,4 @@ int ANETreadTillTerm(int handle,
* \param userData An opaque pointer with data for lcb
*/
void ANETsetLog(ANETlog lcb, void *userData);
-/**
- * \brief Return a pointer to the socket descriptor write buffer
- * \param handle Connection object socket handle
- */
-char *ANETgetWBuffer(int handle);
#endif /*ASYNNET_H_ */
diff --git a/background.c b/background.c
index 0558ce07..6adac099 100644
--- a/background.c
+++ b/background.c
@@ -58,7 +58,7 @@ int BackgroundCommand(SConnection * pCon, char *command)
return 0;
}
- TaskRegister(pServ->pTasker, BackgroundTask, NULL, KillBckTask, self, 1);
+ TaskRegisterN(pServ->pTasker, self->command, BackgroundTask, NULL, KillBckTask, self, 1);
return 1;
}
diff --git a/commandlog.c b/commandlog.c
index 50192665..64b5c896 100644
--- a/commandlog.c
+++ b/commandlog.c
@@ -68,7 +68,8 @@ void WriteToCommandLogId(char *prompt, int id, char *text)
time_t now;
char stamp1[32], stamp2[32], buffer[80];
int doStamp, doStampId;
-
+ int old;
+
/* suppress status messages */
if (strstr(text, "status =") != NULL) {
return;
@@ -196,6 +197,7 @@ void WriteToCommandLogId(char *prompt, int id, char *text)
if (pServ->pTasker != NULL) {
if (doStamp) {
TaskSignal(pServ->pTasker, COMLOG, stamp1);
+ SCOnlySockWrite(GetSendingConnection(), stamp1, eLog);
}
TaskSignal(pServ->pTasker, COMLOG, pCopy);
}
@@ -489,7 +491,7 @@ int CommandLog(SConnection * pCon, SicsInterp * pSics, void *pData,
SCWrite(pCon, "ERROR: autologging is already active", eError);
return 0;
}
- TaskRegister(pServ->pTasker, AutoTask, NULL, NULL, NULL, 1);
+ TaskRegisterN(pServ->pTasker, "autologger", AutoTask, NULL, NULL, NULL, 1);
SCSendOK(pCon);
iAutoActive = 1;
return 1;
diff --git a/commandlog.h b/commandlog.h
index d02d1da3..82293f79 100644
--- a/commandlog.h
+++ b/commandlog.h
@@ -9,7 +9,7 @@
--------------------------------------------------------------------------*/
#ifndef COMMANDLOG
#define COMMANDLOG
-void WriteToCommandLog(char *prompt, char *pText);
+void WriteToCommandLog(const char *prompt, const char *pText);
void WriteToCommandLogId(char *prompt, int id, char *text);
void WriteToCommandLogCmd(int id, char *text);
int CompactCommandLog(void);
diff --git a/cone.c b/cone.c
index b90279ca..9ac2e252 100644
--- a/cone.c
+++ b/cone.c
@@ -171,7 +171,6 @@ static long ConeSetValue(void *pData, SConnection * pCon, float fVal)
*/
SICSHdbGetPar(obj, pCon, "target", &v);
target.h = v.v.floatArray[0];
- target.k = v.v.floatArray[1];
target.l = v.v.floatArray[2];
SICSHdbGetPar(obj, pCon, "qscale", &v);
/*
@@ -198,7 +197,7 @@ static long ConeSetValue(void *pData, SConnection * pCon, float fVal)
mat_free(csToPsi);
if (status != 1) {
SCWrite(pCon, "ERROR: cannot get cone vector into scattering position",
- eError);
+ eLogError);
SCSetInterrupt(pCon, eAbortOperation);
return 0;
}
diff --git a/confvirtualmot.c b/confvirtualmot.c
index b481e052..8cd82c2f 100644
--- a/confvirtualmot.c
+++ b/confvirtualmot.c
@@ -14,14 +14,14 @@
- a checkscript to be run at the end of driving the motor
- a means to call the write script multiple times. This is useful if
you need to drive to the value in multiple steps. An example is the
- BOA double crystal monochromator where you first have to pu the baldes to
+ BOA double crystal monochromator where you first have to put the blades to
0, then drive the translation and then drive the blades to the real theta.
All this to avoid collisions. In order to support this, a state field and
and a readable target field has been added. The mode of operation is such
that the on first run the, writescript set the state to something different
then idle. This causes after the first set of motors finished running the
writescript to be called again. This can figure out by lookin at the
- state variable what to do. This can be doen in repetition until the
+ state variable what to do. This can be done in repetition until the
writescript sets state to idle again.
Mark Koennecke, April 2012
@@ -51,6 +51,7 @@ typedef struct {
pIDrivable pDriv;
float value;
int running;
+ long taskID;
} RealMotor, *pRealMotor;
/* Data passed by event generating object */
@@ -183,9 +184,9 @@ static int startMotorList(pConfigurableVirtualMotor self,
iRet = LLDnodePtr2First(self->motorList);
while (iRet != 0) {
LLDnodeDataTo(self->motorList, &tuktuk);
- status = tuktuk.pDriv->SetValue(tuktuk.data, pCon, tuktuk.value);
- if (status != 1) {
- return status;
+ tuktuk.taskID = StartDriveTask(tuktuk.data,pCon,tuktuk.name,tuktuk.value);
+ if (tuktuk.taskID < 0) {
+ return HWFault;
}
tuktuk.running = 1;
LLDnodeDataFrom(self->motorList, &tuktuk);
@@ -346,28 +347,12 @@ static int ConfCheckStatus(void *pData, SConnection * pCon)
while (iRet != 0) {
LLDnodeDataTo(self->motorList, &tuktuk);
if (tuktuk.running == 1) {
- status = tuktuk.pDriv->CheckStatus(tuktuk.data, pCon);
- switch (status) {
- case HWIdle:
- tuktuk.running = 0;
+ status = isTaskIDRunning(pServ->pTasker,tuktuk.taskID);
+ if(status == 1){
+ return HWBusy;
+ } else {
+ tuktuk.running = 0;
LLDnodeDataFrom(self->motorList, &tuktuk);
- break;
- case HWBusy:
- result = HWBusy;
- break;
- case HWFault:
- case HWPosFault:
- if(self->state != NULL){
- free(self->state);
- self->state = strdup("idle");
- }
- return status;
- break;
- default:
- /*
- this is a programming error and has to be fixed
- */
- assert(0);
}
}
iRet = LLDnodePtr2Next(self->motorList);
diff --git a/conman.c b/conman.c
index 5a7e6974..49fa8e03 100644
--- a/conman.c
+++ b/conman.c
@@ -73,7 +73,6 @@
#include "statusfile.h"
#include "sicshipadaba.h"
#include "protocol.h"
-#include "sicsvar.h"
/*
#define UUDEB 1
define UUDEB , for buffer writing for checking encoding */
@@ -106,7 +105,8 @@ typedef struct {
static int iName = 0;
static long lastIdent = 0;
/*------------- sending connection (prevent double write when listening) ----*/
-static int sendingConnection = 0;
+static SConnection *sendingConnection = NULL;
+static int sendingSockHandle = 0;
/*------------- storing connection and context for later use ----*/
struct SCStore {
SConnection *pCon;
@@ -115,24 +115,6 @@ struct SCStore {
long macroStack;
commandContext cc;
};
-
-/*
- * This will return the value of a SICS int variable called "sicsdebug"
- * If sicsdebug is not defined it will return 1
- * TODO Maybe define debugging levels.
- *
- * return 0=debug off, 1=debug on or sicsdebug not defined.
- */
-int sicsdebug() {
- pSicsVariable debug;
-
- debug = FindVariable(pServ->pSics, "sicsdebug");
- if (debug) {
- return debug->iVal;
- } else {
- return 1;
- }
-}
/*===========================================================================*/
static char *ConName(long ident)
{
@@ -165,6 +147,23 @@ void KillFreeConnections()
{
}
+/*---------------------------------------------------------------------------*/
+SConnection *GetSendingConnection(void)
+{
+ return sendingConnection;
+}
+
+/*---------------------------------------------------------------------------*/
+static void SetSendingConnection(SConnection *pCon)
+{
+ sendingConnection = pCon;
+ if (pCon) {
+ sendingSockHandle = pCon->sockHandle;
+ } else {
+ sendingSockHandle = 0;
+ }
+}
+
/*-------------------------------------------------------------------------*/
static SConnection *SCMakeConnection()
{
@@ -605,7 +604,17 @@ int TelnetWriteANET(int sockHandle, char *pBuffer)
}
return iRet;
}
-
+/*------------------------------------------------------------------------*/
+static int mustWrite(int iOut)
+{
+ switch(iOut) {
+ case eLog:
+ case eLogError:
+ return 1;
+ default:
+ return 0;
+ }
+}
/*-------------------------------------------------------------------------*/
int SCWrite(SConnection * self, char *pBuffer, int iOut)
{
@@ -618,7 +627,7 @@ int SCWrite(SConnection * self, char *pBuffer, int iOut)
if (pBuffer == NULL) {
return 0;
}
- if(!SCinMacro(self)){
+ if(!SCinMacro(self) || mustWrite(iOut) ){
traceCommand(ConID(self),"out:%s", pBuffer);
}
return self->write(self, pBuffer, iOut);
@@ -726,14 +735,14 @@ static void testAndWriteCommandLog(SConnection * pCon, char *buffer,
{
if (SCGetRights(pCon) <= usUser) {
if (SCinMacro(pCon) != 1) {
- sendingConnection = pCon->sockHandle;
+ SetSendingConnection(pCon);
WriteToCommandLogId(NULL, pCon->sockHandle, buffer);
- sendingConnection = 0;
+ SetSendingConnection(NULL);
} else {
if (iOut == eLog || iOut == eLogError) {
- sendingConnection = pCon->sockHandle;
+ SetSendingConnection(pCon);
WriteToCommandLogId(NULL, pCon->sockHandle, buffer);
- sendingConnection = 0;
+ SetSendingConnection(NULL);
}
}
}
@@ -850,9 +859,6 @@ int SCNormalWrite(SConnection * self, char *buffer, int iOut)
/* log it for any case */
#if 0
- if ( (sicsdebug() || !SCinMacro(self)) && !(iOut == eInternal
- || (buffer[0] == 'O' && buffer[1] == 'K'
- && (buffer[2] == '\0' || buffer[2] == '\r' || buffer[2] == '\n'))))
SICSLogWrite(buffer, iOut);
#else
testAndWriteSICSLog(self, buffer, iOut);
@@ -1079,7 +1085,6 @@ int SCPureSockWrite(SConnection * self, char *buffer, int iOut)
return 1;
}
-
/*--------------------------------------------------------------------------
special for ClientLog. Do not use elsewhere without check
----------------------------------------------------------------------------*/
@@ -1091,7 +1096,9 @@ int SCLogWrite(SConnection * self, char *buffer, int iOut)
if (!VerifyConnection(self)) {
return 0;
}
+ SetSendingConnection(self);
WriteToCommandLogId(NULL, self->sockHandle, buffer);
+ SetSendingConnection(NULL);
if(self->iProtocolID == 5) {
if (strlen(buffer) + 30 > 1024) {
@@ -1105,6 +1112,18 @@ int SCLogWrite(SConnection * self, char *buffer, int iOut)
if(pPtr != pBueffel){
free(pPtr);
}
+ } else if(self->iProtocolID == 2) {
+ if (strlen(buffer) + 30 > 1024) {
+ pPtr = (char *) malloc((strlen(buffer) + 30) * sizeof(char));
+ memset(pPtr, 0, strlen(buffer) + 20);
+ } else {
+ pPtr = pBueffel;
+ }
+ sprintf(pPtr,"%s@@%s",buffer,pCode[iOut]);
+ testAndWriteSocket(self, pPtr, iOut);
+ if(pPtr != pBueffel){
+ free(pPtr);
+ }
} else {
testAndWriteSocket(self, buffer, iOut);
}
@@ -1239,6 +1258,8 @@ int SCWriteZipped(SConnection * self, char *pName, void *pData,
SCWrite(self, "ERROR: no data to write in SCWriteZiped", eError);
return 0;
}
+
+
pBuf = malloc(iDataLen*sizeof(char));
memset(pBuf,0,iDataLen*sizeof(char));
@@ -1258,13 +1279,26 @@ int SCWriteZipped(SConnection * self, char *pName, void *pData,
compStream.avail_in = iDataLen;
compStream.avail_out = iDataLen;
iRet = deflate(&compStream, Z_FINISH);
- if (iRet != Z_STREAM_END) {
+ if (iRet != Z_STREAM_END && iRet != Z_OK) {
sprintf(outBuf, "ERROR: zlib error: %d", iRet);
SCWrite(self, outBuf, eError);
return 0;
}
compressedLength = compStream.total_out;
+ /*
+ If data is large, test if we can do it
+ */
+ if(compressedLength > 2*1000*1024) {
+ if(!ANETcanWrite(self->sockHandle,pData,compressedLength)){
+ SCWrite(self,"WARNING: skipping excessive data in SCWriteZipped",eLogError);
+ deflateEnd(&compStream);
+ free(pBuf);
+ return 0;
+ }
+ }
+
+
/* write header line */
memset(outBuf, 0, 65536);
@@ -1331,6 +1365,16 @@ int SCWriteBinary(SConnection * self, char *pName, void *pData,
return 0;
}
+ /*
+ If data is large, test if we can do it
+ */
+ if(iDataLen > 2*1000*1024) {
+ if(!ANETcanWrite(self->sockHandle,pData,iDataLen)){
+ SCWrite(self,"WARNING: skipping excessive data in SCWriteBinary",eLogError);
+ return 0;
+ }
+ }
+
/* write header line */
memset(outBuf, 0, 65536);
@@ -1582,8 +1626,6 @@ int SCPrompt(SConnection * pCon, char *pPrompt, char *pResult, int iLen)
SCWrite(pCon, pPrompt, eWarning);
master = SCfindMaster(pCon);
- eOld = GetStatus();
- SetStatus(eInput);
CostaUnlock(master->pStack);
while (1) {
/*
@@ -1603,14 +1645,57 @@ int SCPrompt(SConnection * pCon, char *pPrompt, char *pResult, int iLen)
/* do we have data ? */
iRet = CostaPop(master->pStack, &pPtr);
if (iRet == 1) {
- SetStatus(eOld);
CostaLock(master->pStack);
strlcpy(pResult, pPtr, iLen);
WriteToCommandLogId(" prompted>", pCon->sockHandle, pPtr);
return 1;
}
}
- SetStatus(eOld);
+ CostaLock(master->pStack);
+ return 0;
+}
+/*----------------------------------------------------------------------------*/
+int SCPromptTMO(SConnection * pCon, char *pPrompt, char *pResult, int iLen, int timeout)
+{
+
+ int iRet, i;
+ char *pPtr = NULL;
+ char pFrom[50];
+ Status eOld;
+ int oldMode;
+ SConnection *master = NULL;
+
+ if (!VerifyConnection(pCon)) {
+ return 0;
+ }
+
+ SCWrite(pCon, pPrompt, eWarning);
+ master = SCfindMaster(pCon);
+ CostaUnlock(master->pStack);
+ for(i = 0; i < timeout; i++) {
+ /*
+ wait a second. We want to wait even in a simulation, otherwise
+ we go into an endless loop. This is why there is the hack with
+ oldMode and pServ->simMode.
+ */
+ oldMode = pServ->simMode;
+ pServ->simMode = 0;
+ SicsWait(1);
+ pServ->simMode = oldMode;
+
+ /* is there an interrupt pending ? */
+ if (SCGetInterrupt(pCon) != eContinue) {
+ break;
+ }
+ /* do we have data ? */
+ iRet = CostaPop(master->pStack, &pPtr);
+ if (iRet == 1) {
+ CostaLock(master->pStack);
+ strlcpy(pResult, pPtr, iLen);
+ WriteToCommandLogId(" prompted>", pCon->sockHandle, pPtr);
+ return 1;
+ }
+ }
CostaLock(master->pStack);
return 0;
}
@@ -1705,7 +1790,7 @@ int SCInvoke(SConnection * self, SicsInterp * pInter, char *pCommand)
* case
*/
if (SCGetWriteFunc(self) != SCNotWrite) {
- sendingConnection = self->sockHandle;
+ SetSendingConnection(self);
if (self->sockHandle >= 0) {
if(strstr(pCommand,"Poch") == NULL){
WriteToCommandLogCmd(self->sockHandle, pCommand);
@@ -1713,7 +1798,7 @@ int SCInvoke(SConnection * self, SicsInterp * pInter, char *pCommand)
} else {
WriteToCommandLog("CRON>>", pCommand);
}
- sendingConnection = 0;
+ SetSendingConnection(NULL);
}
}
@@ -1736,10 +1821,8 @@ int SCInvoke(SConnection * self, SicsInterp * pInter, char *pCommand)
return 0;
}
strlcpy(pCopy->deviceID, pBueffel, SCDEVIDLEN);
- /* SCAdvanceContext(self,pBueffel); */
traceCommand(ConID(self),"in:%s", pCommand);
iRet = InterpExecute(pInter, pCopy, pCommand);
- /* SCPopContext(self); */
SCDeleteConnection(pCopy);
StatusFileTask(NULL); /* save changed parameters */
@@ -1858,7 +1941,7 @@ int ConfigCon(SConnection * pCon, SicsInterp * pSics, void *pData,
} else if (strcmp(argv[1], "rights") == 0) {
if (argc < 4) {
snprintf(pBueffel,511, "Insufficient number of args to %s", argv[0]);
- SCWrite(pCon, pBueffel, eInError);
+ SCWrite(pCon, pBueffel, eError);
return 0;
}
i = IsValidUser(argv[2], argv[3]);
@@ -2366,6 +2449,7 @@ int SCTaskFunction(void *pData)
/* response for monit check */
if (strstr(pPtr, "How are you") == pPtr) {
SCWrite(self, "I am fine", eError);
+ ANETprocess();
ANETclose(self->sockHandle);
self->iEnd = 1;
free(pPtr);
@@ -2439,11 +2523,11 @@ void SCSignalFunction(void *pData, int iSignal, void *pSigData)
} else if (iSignal == SICSBROADCAST) {
pPtr = (char *) pSigData;
if (pPtr != NULL) {
- SCWrite(self, pPtr, eWarning);
+ SCPureSockWrite(self, pPtr, eWarning);
}
} else if (iSignal == COMLOG && self->listening == 1) {
pPtr = (char *) pSigData;
- if (pPtr != NULL && self->sockHandle != sendingConnection) {
+ if (pPtr != NULL && self->sockHandle != sendingSockHandle) {
doSockWrite(self, pPtr);
}
} else if (iSignal == TOKENRELEASE) {
diff --git a/conman.h b/conman.h
index 40308a3b..9056bde7 100644
--- a/conman.h
+++ b/conman.h
@@ -88,6 +88,7 @@ int SCVerifyConnection(SConnection * self);
/*------------------------------- tasking --------------------------------*/
int SCTaskFunction(void *pCon);
void SCSignalFunction(void *pCon, int iSignal, void *pSigData);
+SConnection *GetSendingConnection(void);
/* ***************************** I/O ************************************** */
void SCSetOutputClass(SConnection * self, int iClass);
int SCWrite(SConnection * self, char *pBuffer, int iOut);
@@ -101,6 +102,7 @@ int SCPrintf(SConnection * self, int iOut, char *fmt, ...) G_GNUC_PRINTF (3, 4);
#undef G_GNUC_PRINTF
int SCRead(SConnection * self, char *pBuffer, int iBufLen);
int SCPrompt(SConnection * pCon, char *pPrompt, char *pResult, int iLen);
+int SCPromptTMO(SConnection * pCon, char *pPrompt, char *pResult, int iLen, int timeout);
int SCSendOK(SConnection * self);
int SCnoSock(SConnection * pCon);
int SCWriteUUencoded(SConnection * pCon, char *pName, void *iData,
diff --git a/counter.c b/counter.c
index b5d0cea6..d79bc2d2 100644
--- a/counter.c
+++ b/counter.c
@@ -61,7 +61,7 @@ typedef struct {
char *pName;
} MonEvent, *pMonEvent;
-/*--------------------------------------------------------------------------*/
+/*-----------------------------------------------------------------------------*/
static int Halt(void *pData)
{
pCounter self = NULL;
@@ -71,7 +71,19 @@ static int Halt(void *pData)
return self->pDriv->Halt(self->pDriv);
}
+/*-------------------------------------------------------------------------*/
+static void SetCounterError(void *pData, char *text)
+{
+ pCounter self = NULL;
+ assert(pData);
+ self = (pCounter) pData;
+
+ if(self->error != NULL){
+ free(self->error);
+ }
+ self->error = strdup(text);
+}
/*--------------------------------------------------------------------------*/
static void SetCountParameters(void *pData, float fPreset,
CounterMode eMode)
@@ -103,6 +115,7 @@ static int StartCount(void *pData, SConnection * pCon)
return 0;
}
+ SetCounterError(pData,"None");
/* try at least three times to do it */
for (i = 0; i < 3; i++) {
iRet = self->pDriv->Start(self->pDriv);
@@ -122,6 +135,7 @@ static int StartCount(void *pData, SConnection * pCon)
eError);
SCSetInterrupt(pCon, eAbortBatch);
ReleaseCountLock(self->pCountInt);
+ SetCounterError(pData,pError);
return HWFault;
}
}
@@ -205,95 +219,6 @@ static int ContinueCount(void *pData, SConnection * pCon)
SCSetInterrupt(pCon, eAbortBatch);
return HWFault;
}
-
-/*--------------------------------------------------------------------------*/
-static int CheckCountStatus(void *pData, SConnection * pCon)
-{
- pCounter self = NULL;
- int i, iRet;
- int eCt;
- char pError[80], pBueffel[132];
- int iErr;
- float fControl, rate;
- MonEvent sMon;
-
- self = (pCounter) pData;
- assert(self);
- assert(pCon);
-
- eCt = self->pDriv->GetStatus(self->pDriv, &fControl);
- if (eCt == HWFault) {
- self->badStatusCount++;
- iRet = self->pDriv->GetError(self->pDriv, &iErr, pError, 79);
- sprintf(pBueffel, "WARNING: %s ", pError);
- SCWrite(pCon, pBueffel, eLog);
- iRet = self->pDriv->TryAndFixIt(self->pDriv, iErr);
- if (iRet == COTERM || self->badStatusCount > 3) {
- SCWrite(pCon, "ERROR: Cannot fix counter problem, aborting", eError);
- SCSetInterrupt(pCon, eAbortBatch);
- InvokeCallBack(self->pCall, COUNTEND, NULL);
- ReleaseCountLock(self->pCountInt);
- return eCt;
- } else {
- return HWBusy;
- }
- }
-
- if(self->pDriv->fTime > .0){
- rate = (float)(self->pDriv->lCounts[1])/self->pDriv->fTime;
- if(rate > 10000){
- SCWrite(pCon,"WARNING: Your control monitor is running into dead time",
- eWarning);
- }
- }
- /*
- handle count parameters and notify listeners on progress
- */
- sMon.fCurrent = fControl;
- sMon.fPreset = self->pDriv->fPreset;
- sMon.pName = self->name;
- self->badStatusCount = 0; /* clear: we managed to read OK */
- if (self->iCallbackCounter > 20) {
- InvokeCallBack(self->pCall, MONITOR, &sMon);
- tracePar(self->name,"control:%f", fControl);
- self->iCallbackCounter = 0;
- } else {
- self->iCallbackCounter++;
- }
- self->pDriv->fLastCurrent = fControl;
-
- /*
- notification on finish
- */
- if (eCt == HWIdle) {
- self->isUpToDate = 0;
- InvokeCallBack(self->pCall, COUNTEND, NULL);
- ReleaseCountLock(self->pCountInt);
- }
- return eCt;
-}
-
-/*------------------------------------------------------------------------*/
-static int SaveCounterStatus(void *pData, char *name, FILE * fd)
-{
- pCounter self = NULL;
-
- assert(pData);
- assert(fd);
-
- self = (pCounter) pData;
-
- fprintf(fd, "# Counter %s\n", name);
- fprintf(fd, "%s SetPreset %f\n", name, self->pDriv->fPreset);
- if (self->pDriv->eMode == eTimer) {
- fprintf(fd, "%s SetMode Timer\n", name);
- } else {
- fprintf(fd, "%s SetMode Monitor\n", name);
- }
-
- return 1;
-}
-
/*------------------------------------------------------------------------*/
static int TransferData(void *pData, SConnection * pCon)
{
@@ -322,6 +247,7 @@ static int TransferData(void *pData, SConnection * pCon)
SCWrite(pCon, "ERROR: Cannot fix counter problem, aborting",
eError);
SCSetInterrupt(pCon, eAbortBatch);
+ SetCounterError(pData,pError);
return HWFault;
}
}
@@ -331,6 +257,98 @@ static int TransferData(void *pData, SConnection * pCon)
return HWFault;
}
+/*--------------------------------------------------------------------------*/
+static int CheckCountStatus(void *pData, SConnection * pCon)
+{
+ pCounter self = NULL;
+ int i, iRet;
+ int eCt;
+ char pError[80], pBueffel[132];
+ int iErr;
+ float fControl = .0, rate;
+ MonEvent sMon;
+
+ self = (pCounter) pData;
+ assert(self);
+ assert(pCon);
+
+ eCt = self->pDriv->GetStatus(self->pDriv, &fControl);
+ if (eCt == HWFault) {
+ self->badStatusCount++;
+ iRet = self->pDriv->GetError(self->pDriv, &iErr, pError, 79);
+ sprintf(pBueffel, "WARNING: %s ", pError);
+ SCWrite(pCon, pBueffel, eLog);
+ iRet = self->pDriv->TryAndFixIt(self->pDriv, iErr);
+ if (iRet == COTERM || self->badStatusCount > 3) {
+ SCWrite(pCon, "ERROR: Cannot fix counter problem, aborting", eError);
+ SCSetInterrupt(pCon, eAbortBatch);
+ InvokeCallBack(self->pCall, COUNTEND, NULL);
+ ReleaseCountLock(self->pCountInt);
+ SetCounterError(pData,pError);
+ return eCt;
+ } else {
+ return HWBusy;
+ }
+ }
+
+ /* if(self->pDriv->fTime > .0){ */
+ /* rate = (float)(self->pDriv->lCounts[1])/self->pDriv->fTime; */
+ /* if(rate > 10000){ */
+ /* SCWrite(pCon,"WARNING: Your control monitor is running into dead time", */
+ /* eLogError); */
+ /* } */
+ /* } */
+
+ /*
+ handle count parameters and notify listeners on progress
+ */
+ sMon.fCurrent = fControl;
+ sMon.fPreset = self->pDriv->fPreset;
+ sMon.pName = self->name;
+ self->badStatusCount = 0; /* clear: we managed to read OK */
+ if (self->iCallbackCounter > 20) {
+ InvokeCallBack(self->pCall, MONITOR, &sMon);
+ tracePar(self->name,"control:%f", fControl);
+ self->iCallbackCounter = 0;
+ } else {
+ self->iCallbackCounter++;
+ }
+ self->pDriv->fLastCurrent = fControl;
+
+ /*
+ notification on finish
+ */
+ if (eCt == HWIdle) {
+ self->isUpToDate = 0;
+ TransferData(self,pCon);
+ InvokeCallBack(self->pCall, COUNTEND, NULL);
+ ReleaseCountLock(self->pCountInt);
+ }
+ return eCt;
+}
+
+/*------------------------------------------------------------------------*/
+static int SaveCounterStatus(void *pData, char *name, FILE * fd)
+{
+ pCounter self = NULL;
+
+ assert(pData);
+ assert(fd);
+
+ self = (pCounter) pData;
+
+ fprintf(fd, "# Counter %s\n", name);
+ fprintf(fd, "%s SetPreset %f\n", name, self->pDriv->fPreset);
+ if (self->pDriv->eMode == eTimer) {
+ fprintf(fd, "%s SetMode Timer\n", name);
+ } else {
+ fprintf(fd, "%s SetMode Monitor\n", name);
+ }
+
+ return 1;
+}
+
+
/*------------------------------------------------------------------------*/
static void *CounterGetInterface(void *pData, int iID)
{
@@ -391,8 +409,6 @@ int DoCount(pCounter self, float fPreset, SConnection * pCon, int iBlock)
return 0;
}
- eOld = GetStatus();
- SetStatus(eCounting);
/* set Preset */
SetCounterPreset(self, fPreset);
@@ -405,7 +421,6 @@ int DoCount(pCounter self, float fPreset, SConnection * pCon, int iBlock)
iRet = StartDevice(GetExecutor(), self->name, self->pDes, self, pCon,
level, fPreset);
if (!iRet) {
- SetStatus(eOld);
SCWrite(pCon, "Counting aborted", eError);
return 0;
}
@@ -426,7 +441,6 @@ int DoCount(pCounter self, float fPreset, SConnection * pCon, int iBlock)
SCWrite(pCon, "Counting finished", eValue);
iRet = 1;
}
- SetStatus(eOld);
return iRet;
}
/*-------------------------------------------------------------------------*/
@@ -444,12 +458,13 @@ int MakeCounter(SConnection * pCon, SicsInterp * pSics, void *pData,
assert(pCon);
assert(pSics);
- argtolower(argc, argv);
if (argc < 3) {
SCWrite(pCon, "ERROR: insuficient number of arguments to MakeCounter",
eError);
return 0;
}
+ strtolower(argv[1]);
+ strtolower(argv[2]);
site = getSite();
if (site != NULL) {
pDriv = site->CreateCounterDriver(pCon, argc, argv);
@@ -708,13 +723,16 @@ static int isAuthorised(SConnection * pCon, int iCode)
}
/*-----------------------------------------------------------------------*/
-static int CounterInterest(int iEvent, void *pEvent, void *pUser)
+int CounterInterest(int iEvent, void *pEvent, void *pUser)
{
SConnection *pCon = NULL;
pMonEvent pMon = NULL;
char pBueffel[512];
int rights;
+ pCon = (SConnection *) pUser;
+ pMon = (pMonEvent) pEvent;
+
if (pCon == NULL || !SCisConnected(pCon)) {
return -1;
}
@@ -723,17 +741,13 @@ static int CounterInterest(int iEvent, void *pEvent, void *pUser)
return 0;
}
- pCon = (SConnection *) pUser;
- pMon = (pMonEvent) pEvent;
- assert(pCon);
- assert(pMon);
snprintf(pBueffel,511, "%s.CountStatus = %f %d", pMon->pName, pMon->fPreset,
(int) nintf(pMon->fCurrent));
/**
* prevent this to be written to log files
*/
SCSetRights(pCon, usSpy);
- SCWrite(pCon, pBueffel, eWarning);
+ SCWrite(pCon, pBueffel, eLog);
return 1;
}
/*------------------------------------------------------------------------*/
@@ -789,6 +803,7 @@ pCounter CreateCounter(char *name, pCounterDriver pDriv)
pRes->isUpToDate = 1;
pRes->iExponent = 0;
pRes->name = strdup(name);
+ pRes->error = strdup("None");
return pRes;
}
@@ -829,9 +844,13 @@ int CountAction(SConnection * pCon, SicsInterp * pSics, void *pData,
{"send", 0, {0, 0}},
{"setpar", 3, {FUPATEXT, FUPAINT, FUPAFLOAT}},
{"getpar", 2, {FUPATEXT, FUPAOPT}},
+ {"getnmon", 0, {0, 0}},
+ {"state", 0, {0, 0}},
+ {"error", 0, {0, 0}},
{"getnmon",0,{0,0}},
{"getchannel",0,{0}},
- {"setchannel",1,{FUPAINT}}
+ {"setchannel",1,{FUPAINT}},
+ {"countstatus", 0, {0, 0}}
};
char *pMode[] = {
"timer",
@@ -848,7 +867,7 @@ int CountAction(SConnection * pCon, SicsInterp * pSics, void *pData,
argtolower(argc, argv);
argx = &argv[1];
iRet =
- EvaluateFuPa((pFuncTemplate) & ActionTemplate, 25, argc - 1, argx,
+ EvaluateFuPa((pFuncTemplate) & ActionTemplate, 27 argc - 1, argx,
&PaRes);
if (iRet < 0) {
snprintf(pBueffel, 255,"%s", PaRes.pError);
@@ -957,6 +976,7 @@ int CountAction(SConnection * pCon, SicsInterp * pSics, void *pData,
SCSendOK(pCon);
return 1;
case 11: /* status */
+ case 25:
self->pCountInt->TransferData(self, pCon);
if (GetCounterMode(self) == ePreset) {
lVal = GetCounterPreset(self);
@@ -1008,9 +1028,9 @@ int CountAction(SConnection * pCon, SicsInterp * pSics, void *pData,
"ERROR: Insufficient privilege to set threshold", eError);
return 0;
}
- if (isInRunMode(pServ->pExecutor)) {
+ if (isRunning(self->pCountInt)) {
SCWrite(pCon,
- "ERROR: cannot change threshold while instrument is active",
+ "ERROR: cannot change threshold while counting",
eError);
return 0;
}
@@ -1155,14 +1175,28 @@ int CountAction(SConnection * pCon, SicsInterp * pSics, void *pData,
case 22: /* getnmon */
snprintf(pBueffel, 131, "%s.getnmon = %d", argv[0], GetNMonitor(self));
SCWrite(pCon, pBueffel, eValue);
+ break;
+ case 23: /* state */
+ if(isRunning(self->pCountInt)){
+ snprintf(pBueffel, 131, "%s.state = run", argv[0]);
+ } else {
+ snprintf(pBueffel, 131, "%s.state = idle", argv[0]);
+ }
+ SCWrite(pCon, pBueffel, eValue);
return 1;
break;
- case 23: /* getchannel */
+ case 24: /* error */
+ snprintf(pBueffel, 131, "%s.error = %s", argv[0],self->error);
+ SCWrite(pCon, pBueffel, eValue);
+ return 1;
+ return 1;
+ break;
+ case 25: /* getchannel */
snprintf(pBueffel,131,"%s.getchannel = %d", argv[0], GetControlMonitor(self));
SCWrite(pCon,pBueffel,eValue);
return 1;
break;
- case 24: /* setchannel */
+ case 26: /* setchannel */
if (SetControlMonitor(self, PaRes.Arg[0].iVal)) {
return 1;
} else {
diff --git a/counter.h b/counter.h
index 55264363..81105e98 100644
--- a/counter.h
+++ b/counter.h
@@ -30,6 +30,9 @@ typedef struct __Counter{
int iCallbackCounter;
int badStatusCount;
int haltFixFlag; /* solely here to prevent multiple calls to the halt function on overrun timers in countersec.c*/
+ int tbLength; /* These two for caching float time bins in second generation HM's */
+ float *timeBinning;
+ char *error;
int (*setMode)(struct __Counter *self, CounterMode eMode);
CounterMode (*getMode)(struct __Counter *self);
int (*getNMonitor)(struct __Counter *self);
diff --git a/countersec.c b/countersec.c
index 9fdc3520..5eb78ad5 100644
--- a/countersec.c
+++ b/countersec.c
@@ -9,10 +9,13 @@
*
* Mark Koennecke, February 2009
*/
+#include
#include
#include
#include
#include "sicshipadaba.h"
+
+
/*---------------------------------------------------------------------------
* defines for commmands
* -------------------------------------------------------------------------*/
@@ -26,6 +29,19 @@ typedef struct {
float fCurrent;
char *pName;
} MonEvent, *pMonEvent;
+/*-------------------------------------------------------------------------*/
+static void SecCounterSetError(pCounter self, char *text)
+{
+ hdbValue v;
+ pHdb node;
+
+ node = GetHipadabaNode(self->pDes->parNode, "error");
+ if(node != NULL){
+ v = MakeHdbText(strdup(text));
+ UpdateHipadabaPar(node,v,NULL);
+ ReleaseHdbValue(&v);
+ }
+}
/*---------------------------------------------------------------------------*/
int SecCtrInvokeFunction(pCounter self, SConnection *pCon, int code)
{
@@ -52,7 +68,7 @@ static int SecStartCount(void *pData, SConnection *pCon)
{
pCounter self = (pCounter)pData;
int status;
- pHdb node;
+ pHdb node, statusNode;
assert(self != NULL);
@@ -60,14 +76,14 @@ static int SecStartCount(void *pData, SConnection *pCon)
return 0;
}
+ statusNode = GetHipadabaNode(self->pDes->parNode, "status");
+ UpdateHipadabaPar(statusNode,MakeHdbText("run"), pCon);
status = SecCtrInvokeFunction(self,pCon, START);
self->haltFixFlag = 0;
if(status == 1){
self->isUpToDate = 0;
self->badStatusCount = 0;
self->tStart = time(NULL);
- node = GetHipadabaNode(self->pDes->parNode, "status");
- UpdateHipadabaPar(node,MakeHdbText("run"), pCon);
node = GetHipadabaNode(self->pDes->parNode, "control");
UpdateHipadabaPar(node,MakeHdbFloat(.0), pCon);
SetHdbProperty(node,"geterror", NULL);
@@ -79,8 +95,10 @@ static int SecStartCount(void *pData, SConnection *pCon)
node = GetHipadabaNode(self->pDes->parNode, "time");
UpdateHipadabaPar(node,MakeHdbFloat(.0), pCon);
InvokeCallBack(self->pCall,COUNTSTART, pCon);
+ SecCounterSetError(self,"None");
return 1;
} else {
+ UpdateHipadabaPar(statusNode,MakeHdbText("error"), pCon);
ReleaseCountLock(self->pCountInt);
return HWFault;
}
@@ -104,85 +122,96 @@ static int SecContinue(void *pData, SConnection *pCon)
/*----------------------------------------------------------------------------*/
static int SecCtrCheckStatus(void *pData, SConnection *pCon)
{
- pCounter self = (pCounter)pData;
- pHdb node = NULL, control = NULL;
- hdbValue v;
- int status;
- MonEvent sMon;
- float fControl, fPreset;
+ pCounter self = (pCounter)pData;
+ pHdb node = NULL, control = NULL;
+ hdbValue v;
+ int status;
+ MonEvent sMon;
+ float fControl, fPreset;
+ char error[132];
+
+ assert(self != NULL);
- assert(self != NULL);
+ node = GetHipadabaNode(self->pDes->parNode,"status");
+ assert(node != NULL);
+ status = GetHipadabaPar(node,&v,pCon);
- node = GetHipadabaNode(self->pDes->parNode,"status");
- assert(node != NULL);
- status = GetHipadabaPar(node,&v,pCon);
+ if(status != 1){
+ ReleaseCountLock(self->pCountInt);
+ return HWFault;
+ }
- if(status != 1){
- ReleaseCountLock(self->pCountInt);
- return HWFault;
- }
-
- if(v.v.text == NULL){
- return HWBusy;
- }
- if (strstr(v.v.text, "idle") != NULL) {
- InvokeCallBack(self->pCall, COUNTEND, NULL);
- ReleaseCountLock(self->pCountInt);
- status = HWIdle;
- } else if (strstr(v.v.text, "run") != NULL) {
- status = HWBusy;
- } else if (strstr(v.v.text, "nobeam") != NULL) {
- status = HWNoBeam;
- } else if (strstr(v.v.text, "pause") != NULL) {
- status = HWPause;
- } else if (strstr(v.v.text, "error") != NULL) {
- InvokeCallBack(self->pCall, COUNTEND, NULL);
- ReleaseCountLock(self->pCountInt);
- status = HWFault;
- } else {
- SCPrintf(pCon, eError, "ERROR: unknown counter status %s found",
- v.v.text);
- ReleaseCountLock(self->pCountInt);
- status = HWFault;
- }
- ReleaseHdbValue(&v);
+ if(v.v.text == NULL){
+ return HWBusy;
+ }
+ if (strstr(v.v.text, "idle") != NULL) {
+ InvokeCallBack(self->pCall, COUNTEND, NULL);
+ ReleaseCountLock(self->pCountInt);
+ status = HWIdle;
+ } else if (strstr(v.v.text, "run") != NULL) {
+ status = HWBusy;
+ } else if (strstr(v.v.text, "nobeam") != NULL) {
+ status = HWNoBeam;
+ } else if (strstr(v.v.text, "pause") != NULL) {
+ status = HWPause;
+ } else if (strstr(v.v.text, "restart") != NULL) {
+ SecStartCount(self, pCon);
+ return HWBusy;
+ } else if (strstr(v.v.text, "error") != NULL) {
+ InvokeCallBack(self->pCall, COUNTEND, NULL);
+ ReleaseCountLock(self->pCountInt);
+ if(GetHdbProperty(node,"geterror",error,sizeof(error)) == 1){
+ SCPrintf(pCon,eError,"ERROR: %s", error);
+ SecCounterSetError(self,error);
+ } else {
+ SecCounterSetError(self,"Undefined counter error: set status geterror");
+ SCPrintf(pCon,eError,"ERROR: Unknown counter status error: set status geterror property");
+ }
+ status = HWFault;
+ } else {
+ SCPrintf(pCon, eError, "ERROR: unknown counter status %s found",
+ v.v.text);
+ ReleaseCountLock(self->pCountInt);
+ status = HWFault;
+ }
+ ReleaseHdbValue(&v);
- node = GetHipadabaNode(self->pDes->parNode,"control");
- assert(node != NULL);
- GetHipadabaPar(node,&v,pCon);
- fControl = v.v.doubleValue;
- node = GetHipadabaNode(self->pDes->parNode,"preset");
- assert(node != NULL);
- GetHipadabaPar(node,&v,pCon);
- fPreset = v.v.doubleValue;
+ node = GetHipadabaNode(self->pDes->parNode,"control");
+ assert(node != NULL);
+ GetHipadabaPar(node,&v,pCon);
+ fControl = v.v.doubleValue;
+ node = GetHipadabaNode(self->pDes->parNode,"preset");
+ assert(node != NULL);
+ GetHipadabaPar(node,&v,pCon);
+ fPreset = v.v.doubleValue;
- sMon.fCurrent = fControl;
- sMon.fPreset = fPreset;
- sMon.pName = self->name;
- self->badStatusCount = 0;
+ sMon.fCurrent = fControl;
+ sMon.fPreset = fPreset;
+ sMon.pName = self->name;
+ self->badStatusCount = 0;
- /*
- * check for overrun counter boxes
- */
- if(self->getMode(self) == eTimer &&
- (sMon.fCurrent > sMon.fPreset +1)
- && self->haltFixFlag == 0){
- SecCtrHalt(self);
- self->haltFixFlag = 1;
- }
+ /*
+ * check for overrun counter boxes
+ */
+ if(self->getMode(self) == eTimer &&
+ (sMon.fCurrent > sMon.fPreset +1)
+ && self->haltFixFlag == 0){
+ SecCtrHalt(self);
+ self->haltFixFlag = 1;
+ }
- /*
- * invoke notifiactions, if necessary
- */
- if (self->iCallbackCounter > 20) {
- InvokeCallBack(self->pCall, MONITOR, &sMon);
- self->iCallbackCounter = 0;
- } else {
- self->iCallbackCounter++;
- }
+ /*
+ * invoke notifiactions, if necessary
+ */
+ if (self->iCallbackCounter > 20) {
+ InvokeCallBack(self->pCall, MONITOR, &sMon);
+ self->iCallbackCounter = 0;
+ } else {
+ self->iCallbackCounter++;
+ }
- return status;
+ return status;
}
/*---------------------------------------------------------------------------
* Here is an issue: this ought to wait until data has arrived. Callers
@@ -193,6 +222,12 @@ static int SecCtrCheckStatus(void *pData, SConnection *pCon)
* - add an update callback which deletes the property when done.
* - Check that property or the geterror property here in a loop
* until done or we timeout.
+ *
+ * Nope! Update October 2013:
+ * How it is normally done is to read the data through scripcontext when
+ * counting is finished and not to finish with counting until this has
+ * been done. The code below is only usefule for non scriptcontext
+ * drivers.
* -----------------------------------------------------------------------*/
static int SecCtrTransferData(void *pData, SConnection *pCon)
{
@@ -373,25 +408,68 @@ static int CountCmd(pSICSOBJ ccmd, SConnection * con,
Hdb * cmdNode, Hdb * par[], int nPar)
{
float preset;
+ pHdb presetNode = NULL;
if(nPar < 1){
- return 0;
+ presetNode = GetHipadabaNode(ccmd->objectNode,"preset");
+ if(presetNode != NULL){
+ preset = presetNode->value.v.doubleValue;
+ } else {
+ /*
+ This can really only happen when the counter is corrupt
+ */
+ assert(0);
+ }
+ } else {
+ preset = par[0]->value.v.doubleValue;
}
-
- preset = par[0]->value.v.doubleValue;
return DoCount((pCounter)ccmd, preset, con, 1);
}
/*--------------------------------------------------------------------------*/
+static int GetMonitorCmd(pSICSOBJ ccmd, SConnection * con,
+ Hdb * cmdNode, Hdb * par[], int nPar)
+{
+ long counts;
+ pCounter self = (pCounter)ccmd;
+ if(nPar < 1) {
+ SCWrite(con,"ERROR: missing monitor no in getmonitor",eError);
+ return 0;
+ }
+ counts = self->getMonitor(self,par[0]->value.v.intValue,con);
+ SCPrintf(con,eValue,"%s.monitor.%d = %ld", self->name,
+ par[0]->value.v.intValue,counts);
+ return 1;
+}
+/*--------------------------------------------------------------------------*/
+static int GetCountsCmd(pSICSOBJ ccmd, SConnection * con,
+ Hdb * cmdNode, Hdb * par[], int nPar)
+{
+ long counts;
+ pCounter self = (pCounter)ccmd;
+ counts = self->getCounts(self,con);
+ SCPrintf(con,eValue,"%s.counts = %ld", self->name,counts);
+ return 1;
+}
+/*--------------------------------------------------------------------------*/
static int CountNBCmd(pSICSOBJ ccmd, SConnection * con,
Hdb * cmdNode, Hdb * par[], int nPar)
{
float preset;
+ pHdb presetNode = NULL;
if(nPar < 1){
- return 0;
+ presetNode = GetHipadabaNode(ccmd->objectNode,"preset");
+ if(presetNode != NULL){
+ preset = presetNode->value.v.doubleValue;
+ } else {
+ /*
+ This can really only happen when the counter is corrupt
+ */
+ assert(0);
+ }
+ } else {
+ preset = par[0]->value.v.doubleValue;
}
-
- preset = par[0]->value.v.doubleValue;
return DoCount((pCounter)ccmd, preset, con, 0);
}
/*--------------------------------------------------------------------------*/
@@ -415,6 +493,55 @@ static int ContinueCmd(pSICSOBJ ccmd, SConnection * con,
pCounter self = (pCounter)ccmd;
return self->pCountInt->Continue(self,con);
}
+/*-------------------------------------------------------------------------*/
+extern int CounterInterest(int iEvent, void *pEvent, void *pUser);
+/*--------------------------------------------------------------------------*/
+static int InterestCmd(pSICSOBJ ccmd, SConnection * con,
+ Hdb * cmdNode, Hdb * par[], int nPar)
+{
+ long lID;
+ pCounter self = (pCounter)ccmd;
+ lID = RegisterCallback(self->pCall, MONITOR, CounterInterest,
+ SCCopyConnection(con), SCDeleteConnection);
+ SCSendOK(con);
+ return 1;
+
+}
+/*--------------------------------------------------------------------------*/
+static int CountStatusCmd(pSICSOBJ ccmd, SConnection * con,
+ Hdb * cmdNode, Hdb * par[], int nPar)
+{
+ float preset, done;
+ int exponent;
+ pHdb node, data;
+
+ node = GetHipadabaNode(ccmd->objectNode,"preset");
+ assert(node != NULL);
+ preset = node->value.v.doubleValue;
+
+ node = GetHipadabaNode(ccmd->objectNode,"mode");
+ assert(node != NULL);
+ strtolower(node->value.v.text);
+ if(strcmp(node->value.v.text,"timer") == 0) {
+ data = GetHipadabaNode(ccmd->objectNode,"time");
+ assert(data != NULL);
+ done = data->value.v.doubleValue;
+ } else {
+ data = GetHipadabaNode(ccmd->objectNode,"values");
+ assert(data != NULL);
+ done = data->value.v.intArray[0];
+ data = GetHipadabaNode(ccmd->objectNode,"exponent");
+ assert(data != NULL);
+ exponent = data->value.v.intValue;
+ if(exponent != 0){
+ done /= pow(10,exponent);
+ }
+ }
+ SCPrintf(con,eValue,"%s.CountStatus = %f %f",
+ ccmd->objectNode->name, preset, done);
+
+ return 1;
+}
/*--------------------------------------------------------------------------*/
pCounter CreateSecCounter(SConnection *pCon, char *type, char *name, int length)
{
@@ -491,6 +618,9 @@ pCounter CreateSecCounter(SConnection *pCon, char *type, char *name, int length)
return NULL;
}
SetHdbProperty(child, "__save", "true");
+ SetHdbProperty(child, "values", "timer,monitor");
+ PrependHipadabaCallback(child,MakeHipadabaCallback(SICSValueCheckCallback,
+ NULL,NULL));
AddHipadabaChild(node, child, NULL);
child = MakeSICSHdbPar("status", usInternal, MakeHdbText("idle"));
@@ -499,6 +629,12 @@ pCounter CreateSecCounter(SConnection *pCon, char *type, char *name, int length)
}
AddHipadabaChild(node, child, NULL);
+ child = MakeSICSHdbPar("error", usInternal, MakeHdbText("None"));
+ if (child == NULL) {
+ return NULL;
+ }
+ AddHipadabaChild(node, child, NULL);
+
child = MakeSICSHdbPar("control", usUser, MakeHdbFloat(.0));
if (child == NULL) {
return NULL;
@@ -512,15 +648,29 @@ pCounter CreateSecCounter(SConnection *pCon, char *type, char *name, int length)
}
AddHipadabaChild(node, child, NULL);
+ child = MakeSICSHdbPar("exponent", usUser,
+ MakeHdbInt(0));
+ if (child == NULL) {
+ return NULL;
+ }
+ SetHdbProperty(child, "__save", "true");
+ AddHipadabaChild(node, child, NULL);
+
child = AddSICSHdbPar(node,"count", usUser, MakeSICSFunc(CountCmd));
AddSICSHdbPar(child, "preset", usUser, MakeHdbFloat(2));
child = AddSICSHdbPar(node,"countnb", usUser, MakeSICSFunc(CountNBCmd));
AddSICSHdbPar(child, "preset", usUser, MakeHdbFloat(2));
+ child = AddSICSHdbPar(node,"getmonitor", usSpy, MakeSICSFunc(GetMonitorCmd));
+ AddSICSHdbPar(child, "no", usSpy, MakeHdbInt(1));
+ child = AddSICSHdbPar(node,"getcounts", usUser, MakeSICSFunc(GetCountsCmd));
+
child = AddSICSHdbPar(node,"stop", usUser, MakeSICSFunc(StopCmd));
child = AddSICSHdbPar(node,"pause", usUser, MakeSICSFunc(PauseCmd));
child = AddSICSHdbPar(node,"continue", usUser, MakeSICSFunc(ContinueCmd));
+ child = AddSICSHdbPar(node,"interest", usUser, MakeSICSFunc(InterestCmd));
+ child = AddSICSHdbPar(node,"countstatus", usUser, MakeSICSFunc(CountStatusCmd));
return pRes;
}
diff --git a/danu.c b/danu.c
index 8354ccd8..f19410e8 100644
--- a/danu.c
+++ b/danu.c
@@ -75,7 +75,7 @@ static int readDataNumber(pDataNumber self)
}
/*-----------------------------------------------------------------------*/
-static int writeDataNumber(pDataNumber self, int iNum)
+ static int writeDataNumber(pDataNumber self, int iNum)
{
FILE *fd = NULL;
@@ -126,7 +126,18 @@ static int InterestCallback(int iEvent, void *pEvent, void *pUser)
}
return 1;
}
-
+/*-------------------------------------------------------------------------*/
+static void *GetDanuInterface(void *data, int interfaceID)
+{
+ pDataNumber self = (pDataNumber)data;
+ if(self == NULL){
+ return NULL;
+ }
+ if(interfaceID == CALLBACKINTERFACE){
+ return self->pCall;
+ }
+ return NULL;
+}
/*-------------------------------------------------------------------------*/
pDataNumber CreateDataNumber(char *pFileName)
{
@@ -140,6 +151,7 @@ pDataNumber CreateDataNumber(char *pFileName)
memset(pNew, 0, sizeof(DataNumber));
pNew->pDes = CreateDescriptor("DataNumber");
+ pNew->pDes->GetInterface = GetDanuInterface;
pNew->pCall = CreateCallBackInterface();
if (!pNew->pDes || !pNew->pCall) {
free(pNew);
diff --git a/devexec.c b/devexec.c
index 1a0bfb20..0cc9268f 100644
--- a/devexec.c
+++ b/devexec.c
@@ -17,6 +17,10 @@
Modified to accommodate run levels
Mark Koennecke, April 2009
+
+ Heavily restructured to use separate tasks for each action
+
+ Mark Koennecke, February 2013
Copyright:
@@ -118,75 +122,24 @@ void DevexecLog(char *operation, char *device)
traceDevice("devexec","%s:%s",device, operation);
}
-/*======================== internal data structures =======================*/
-typedef struct _DevEntry {
- void *pData;
- pObjectDescriptor pDescriptor;
- float fVal;
- char *name;
- SConnection *pCon;
- int level;
-} DevEntry, *pDevEntry;
-/*------------------------------------------------------------------------*/
-typedef struct {
- pExeList self;
- pDevEntry pDev;
- pICountable pCountInt;
- pIDrivable pDrivInt;
-} checkContext, *pCheckContext;
-/*-------------------------------------------------------------------------*/
-static pDevEntry CreateDevEntry(pObjectDescriptor pDes, SConnection * pCon,
- void *pData, float fVal, char *name, int level)
-{
- pDevEntry pNew = NULL;
-
- assert(pDes);
-
- pNew = (pDevEntry) malloc(sizeof(DevEntry));
- if (!pNew) {
- return NULL;
- }
- pNew->pDescriptor = pDes;
- pNew->pData = pData;
- pNew->name = strdup(name);
- pNew->fVal = fVal;
- pNew->pCon = SCCopyConnection(pCon);
- pNew->pCon->runLevel = level;
- pNew->level = level;
- return pNew;
-}
-
-/*-------------------------------------------------------------------------*/
-static void DeleteDevEntry(pDevEntry self)
-{
- assert(self);
-
- if (self->name) {
- free(self->name);
- }
- if (self->pCon) {
- SCDeleteConnection(self->pCon);
- }
- free(self);
-}
/* ----------------- The Executor himself ---------------------------------*/
typedef struct __EXELIST {
pObjectDescriptor pDes;
SConnection *pOwner;
- int iList;
int iRun;
- int iStop;
int iStatus;
- int iEnd;
int drivePrint;
long lTask;
+ long waitID;
+ long runID;
pTaskMan pTask;
int iLock;
pICallBack pCall;
time_t lastRun;
int paused;
int taskRunning;
+ int instStatus;
} ExeList;
static pExeList pExecutor = NULL;
@@ -222,22 +175,20 @@ pExeList CreateExeList(pTaskMan pTask)
free(pRes);
return NULL;
}
- pRes->iList = LLDcreate(sizeof(pDevEntry));
- if (pRes->iList == -1) {
- free(pRes);
- return NULL;
- }
pRes->iRun = 0;
pRes->iStatus = DEVDONE;
pRes->pTask = pTask;
pRes->lTask = -1;
+ pRes->waitID = -1;
+ pRes->runID = -1;
pRes->iLock = 0;
- pRes->drivePrint = 0;
+ pRes->drivePrint = 0;
pRes->paused = 0;
pRes->taskRunning = 0;
pRes->pCall = CreateCallBackInterface();
pRes->lastRun = time(NULL);
pRes->pDes->GetInterface = DevexecInterface;
+ pRes->instStatus = eEager;
return pRes;
}
@@ -252,7 +203,6 @@ void DeleteExeList(void *pData)
if (self->pDes)
DeleteDescriptor(self->pDes);
ClearExecutor(self);
- LLDdelete(self->iList);
if (self->pCall)
DeleteCallBackInterface(self->pCall);
@@ -268,16 +218,13 @@ void DeleteExeList(void *pData)
devLog = NULL;
}
}
-
/*--------------------------------------------------------------------------*/
-void ExeInterest(pExeList self, pDevEntry pDev, char *text)
+void ExeInterest(pExeList self, char *name, char *text)
{
char buf[128];
- if (pDev) {
- snprintf(buf, sizeof(buf), "%s %s", pDev->name, text);
- InvokeCallBack(self->pCall, DRIVSTAT, buf);
- }
+ snprintf(buf, sizeof(buf), "%s %s", name, text);
+ InvokeCallBack(self->pCall, DRIVSTAT, buf);
}
/*------------------------------------------------------------------------*/
void InvokeNewTarget(pExeList self, char *name, float target)
@@ -295,14 +242,15 @@ void InvokeNewTarget(pExeList self, char *name, float target)
int StartDevice(pExeList self, char *name, pObjectDescriptor pDes,
void *pData, SConnection * pCon, int level, float fNew)
{
- pDevEntry pNew = NULL;
- int iRet;
+ int iRet;
char pBueffel[132], pError[80];
pIDrivable pDrivInt = NULL;
pICountable pCountInt = NULL;
static int overwriteOwner = -1;
char *overwriteOption;
float oldVal;
+ long taskID;
+ pTaskGroupData taskGroup = NULL;
assert(self);
assert(pDes);
@@ -327,73 +275,67 @@ int StartDevice(pExeList self, char *name, pObjectDescriptor pDes,
return 0;
}
}
- } else {
- self->pOwner = SCCopyConnection(pCon);
- }
+ }
if (self->iLock == 1) {
SCWrite(pCon, "ERROR: instrument is locked", eError);
return 0;
}
- /* well create a new entry */
- self->iStop = 0;
- pNew = CreateDevEntry(pDes, pCon, pData, fNew, name, level);
- if (!pNew) {
- SCWrite(pCon, "ERROR: memory exhausted in Device Executor ", eError);
- return 0;
+ SetDevexecStatus(self,DEVDONE);
+ if(self->waitID < 0 && level == RUNDRIVE){
+ self->waitID = GetTaskGroupID(pServ->pTasker);
+ self->iStatus = DEVBUSY;
+ } else if(self->runID < 0 && level == RUNRUN){
+ self->runID = GetTaskGroupID(pServ->pTasker);
+ self->iStatus = DEVBUSY;
}
- /* start it */
- pDrivInt = pDes->GetInterface(pData, DRIVEID);
- pCountInt = pDes->GetInterface(pData, COUNTID);
- if (pDrivInt) {
- iRet = pDrivInt->SetValue(pData, pCon, fNew);
- if (iRet == OKOK && self->drivePrint == 1) {
+
+
+ if((pDrivInt = pDes->GetInterface(pData,DRIVEID)) != NULL){
+ taskID = StartDriveTask(pData, pCon, name, fNew);
+ if(taskID > 0 && self->instStatus != eCounting){
+ self->instStatus = eDriving;
+ }
+ if(taskID > 0 && self->drivePrint == 1){
oldVal = pDrivInt->GetValue(pData, pCon);
snprintf(pBueffel, 131, "Driving %s from %8.3f to %8.3f",
name, oldVal, fNew);
SCWrite(pCon, pBueffel, eValue);
}
- if(iRet == OKOK){
- InvokeNewTarget(self,name,fNew);
+ } else if(pDes->GetInterface(pData,COUNTID) != NULL){
+ taskID = StartCountTask(pData,pCon,name);
+ if(taskID > 0){
+ self->instStatus = eCounting;
}
- } else if (pCountInt) {
- iRet = pCountInt->StartCount(pData, pCon);
- } else { /* this is a programmers error */
- SCWrite(pCon, "ERROR: Programmer error in StartDevice ", eError);
- iRet = 0;
+ } else {
+ SCPrintf(pCon,eLogError, "ERROR: type unkonw, cannot start %s", name);
+ return 0;
}
- /* check return status */
- if (iRet == OKOK) {
- LLDnodeAppendFrom(self->iList, &pNew);
- sprintf(pBueffel, "started");
- if (NULL != pNew->pCon->deviceID) {
- snprintf(pBueffel, 130, "started (%s)", pNew->pCon->deviceID);
+ if(taskID > 0){
+ if(self->pOwner == NULL){
+ self->pOwner = SCCopyConnection(pCon);
+ }
+ self->lastRun = time(NULL);
+ if(level == RUNRUN){
+ AddTaskToGroup(pServ->pTasker, taskID, self->runID);
+ } else {
+ AddTaskToGroup(pServ->pTasker, taskID, self->waitID);
}
- ExeInterest(self, pNew, pBueffel);
self->iRun = 1;
- self->iStatus = DEVDONE;
- /* if no task: start it */
- if (self->lTask < 0) {
- self->lTask = TaskRegister(self->pTask,
+ self->iStatus = DEVBUSY;
+ if(self->lTask < 0) {
+ self->lTask = TaskRegisterN(self->pTask,"devexec",
DevExecTask,
- DevExecSignal, NULL, self, 1);
- self->iEnd = 0;
- pCon->conStatus = HWBusy;
+ DevExecSignal,
+ NULL, self,1);
}
- DevexecLog("START", pNew->name);
+ pCon->conStatus = HWBusy;
return 1;
} else {
snprintf(pBueffel,131, "ERROR: cannot start device %s", name);
SCWrite(pCon, pBueffel, eError);
- DeleteDevEntry(pNew);
- if (LLDcheck(self->iList) >= LIST_EMPTY) {
- if (self->pOwner != NULL) {
- SCDeleteConnection(self->pOwner);
- }
- self->pOwner = NULL;
- }
return 0;
}
return 0;
@@ -406,97 +348,18 @@ int StartDevice(pExeList self, char *name, pObjectDescriptor pDes,
static int ForceStartDevice(pExeList self, char *name, pObjectDescriptor pDes,
void *pData, SConnection * pCon, float fNew)
{
- pDevEntry pNew = NULL;
- int iRet;
- char pBueffel[132], pError[80];
+ long taskID;
pIDrivable pDrivInt = NULL;
- pICountable pCountInt = NULL;
- static int overwriteOwner = -1;
- char *overwriteOption;
- float oldVal;
- assert(self);
- assert(pDes);
- assert(pCon);
-
- /* may we? */
- if (self->pOwner != NULL) {
- pCon = self->pOwner;
- }
- if (self->iLock == 1) {
- SCWrite(pCon, "ERROR: instrument is locked", eError);
- return 0;
- }
-
- /* well create a new entry */
- self->iStop = 0;
- pNew = CreateDevEntry(pDes, SCCopyConnection(pCon),
- pData, fNew, name, RUNRUN);
- if (!pNew) {
- SCWrite(pCon, "ERROR: memory exhausted in Device Executor ", eError);
- return 0;
- }
-
- /* start it */
- pDrivInt = pDes->GetInterface(pData, DRIVEID);
- pCountInt = pDes->GetInterface(pData, COUNTID);
- if (pDrivInt) {
- iRet = pDrivInt->SetValue(pData, pCon, fNew);
- if (iRet == OKOK && self->drivePrint == 1) {
- oldVal = pDrivInt->GetValue(pData, pCon);
- snprintf(pBueffel, 131, "Driving %s from %8.3f to %8.3f",
- name, oldVal, fNew);
- SCWrite(pCon, pBueffel, eValue);
- }
- if(iRet == OKOK){
- InvokeNewTarget(self,name,fNew);
- }
- } else if (pCountInt) {
- /**
- * Cannot set count parameters here: means of getting hold of the
- * count mode missing here. As this is a POLDI hack where I only need
- * to run a HV, I omit this now. But it will work if a proper
- * preset and mode is set on a counter to start it.
- */
- iRet = pCountInt->StartCount(pData, pCon);
- } else { /* this is a programmers error */
- SCWrite(pCon, "ERROR: Programmer error in StartDevice ", eError);
- iRet = 0;
- }
-
- /* check return status */
- if (iRet == OKOK) {
- LLDnodeAppendFrom(self->iList, &pNew);
- sprintf(pBueffel, "started");
- if (NULL != pNew->pCon->deviceID) {
- snprintf(pBueffel, 130, "started (%s)", pNew->pCon->deviceID);
- }
- ExeInterest(self, pNew, pBueffel);
- self->iRun = 1;
- self->iStatus = DEVDONE;
- /* if no task: start it */
- if (self->lTask < 0) {
- self->lTask = TaskRegister(self->pTask,
- DevExecTask,
- DevExecSignal, NULL, self, 1);
- self->iEnd = 0;
- pCon->conStatus = HWBusy;
- }
- DevexecLog("START", pNew->name);
- return 1;
+ if((pDrivInt = pDes->GetInterface(pData,DRIVEID)) != NULL){
+ taskID = StartDriveTask(pData, pCon, name, fNew);
+ } else if(pDes->GetInterface(pData,COUNTID) != NULL){
+ taskID = StartCountTask(pData,pCon,name);
} else {
- snprintf(pBueffel,131, "ERROR: cannot start device %s", name);
- SCWrite(pCon, pBueffel, eError);
- DeleteDevEntry(pNew);
- if (LLDcheck(self->iList) >= LIST_EMPTY) {
- if (self->pOwner != NULL) {
- SCDeleteConnection(self->pOwner);
- }
- self->pOwner = NULL;
- }
+ SCPrintf(pCon,eLogError, "ERROR: type unkonw, cannot start %s", name);
return 0;
}
- return 0;
+ return 1;
}
/*--------------------------------------------------------------------------*/
int StartMotor(pExeList self, SicsInterp * pSics, SConnection * pCon,
@@ -578,232 +441,21 @@ int StartCounter(pExeList self, SicsInterp * pSics, SConnection * pCon,
pCon, level, pCter->pDriv->fPreset);
}
-/*-------------------------------------------------------------------------*/
-static int checkInterrupt(pCheckContext pCheck, int targetStatus)
-{
- if (SCGetInterrupt(pCheck->self->pOwner) != eContinue) {
- pCheck->self->iStatus = DEVINT;
- SetStatus(eEager);
- return -1;
- } else {
- return targetStatus;
- }
-}
-
-/*--------------------------------------------------------------------------*/
-static int initializeCheck(pCheckContext pCheck, pDevEntry pDev)
-{
- int eCode = HWFault;
-
- pCheck->pDev = pDev;
- pCheck->pDrivInt = pDev->pDescriptor->GetInterface(pDev->pData, DRIVEID);
- pCheck->pCountInt =
- pDev->pDescriptor->GetInterface(pDev->pData, COUNTID);
- if (pCheck->pDrivInt != NULL) {
- eCode = pCheck->pDrivInt->CheckStatus(pDev->pData, pDev->pCon);
- } else if (pCheck->pCountInt != NULL) {
- eCode = pCheck->pCountInt->CheckCountStatus(pDev->pData, pDev->pCon);
- }
- return eCode;
-}
-
-/*--------------------------------------------------------------------------*/
-static int finishDevice(pCheckContext pCheck)
-{
- int status;
-
- if (pCheck->pCountInt != NULL) {
- pCheck->pCountInt->TransferData(pCheck->pDev->pData,
- pCheck->pDev->pCon);
- } else if (pCheck->pDrivInt != NULL) {
- pCheck->pDrivInt->iErrorCount = 0;
- }
- ExeInterest(pCheck->self, pCheck->pDev, "finished");
- DevexecLog("STOP", pCheck->pDev->name);
- DeleteDevEntry(pCheck->pDev);
- LLDnodeDelete(pCheck->self->iList);
- status = LLDnodePtr2Prev(pCheck->self->iList);
- SCWrite(pCheck->self->pOwner, "", eFinish);
- pCheck->self->iStatus = DEVDONE;
- return checkInterrupt(pCheck, status);
-}
-
-/*-------------------------------------------------------------------------*/
-static int errorDevice(pCheckContext pCheck)
-{
- int status;
-
- ExeInterest(pCheck->self, pCheck->pDev, "finished with problem");
- DevexecLog("STOP", pCheck->pDev->name);
- LLDnodeDelete(pCheck->self->iList);
- status = LLDnodePtr2Prev(pCheck->self->iList);
- SCWrite(pCheck->self->pOwner, "", eFinish);
- pCheck->self->iStatus = DEVERROR;
- if (pCheck->pDrivInt != NULL) {
- pCheck->pDrivInt->iErrorCount++;
- }
- status = checkInterrupt(pCheck, status);
- DeleteDevEntry(pCheck->pDev);
- return status;
-}
-
-/*-------------------------------------------------------------------------*/
-static int testFinish(pExeList self)
-{
- if ((self->pOwner == NULL) || (LLDcheck(self->iList) == LIST_EMPTY)) {
- if (self->pOwner != NULL) {
- SCDeleteConnection(self->pOwner);
- }
- self->pOwner = NULL;
- self->iRun = 0;
- self->iEnd = 1;
- self->iStop = 0;
- self->lTask = -1;
- return 1;
- } else {
- return 0;
- }
-}
-
-/*--------------------------------------------------------------------------*/
-int CheckExeList(pExeList self)
-{
- int iRet, status;
- checkContext check;
- pDevEntry pDev = NULL;
- pICountable pCountInt = NULL;
- pIDrivable pDrivInt = NULL;
- int eCode;
- int isCounting = 0, isDriving = 0;
- char pBueffel[512];
-
- assert(self);
-
- /* Sometimes this gets called, though nothing is running. There are
- cases where this is feasible for maintenance, but in some cases it
- is pure rubbish, because nothing runs. This will be checked here.
- */
- if (testFinish(self) == 1) {
- return 1;
- }
-
- /*
- check the status of all registered devices. Remove when finished
- */
- check.self = self;
- status = LLDnodePtr2First(self->iList);
- while (status != 0) {
- LLDnodeDataTo(self->iList, &pDev);
- if (pDev) {
- eCode = initializeCheck(&check, pDev);
- if (eCode != HWNoBeam && eCode != HWPause && self->paused == 1) {
- DevexecLog("CONTINUE", "ALL");
- self->paused = 0;
- }
- switch (eCode) {
- case HWIdle:
- case OKOK:
- status = finishDevice(&check);
- if (status < 0) {
- return status;
- }
- break;
- case HWFault: /* real HW error: burning, no net etc.. */
- status = errorDevice(&check);
- if (status < 0) {
- return status;
- }
- break;
- case HWNoBeam:
- SetStatus(eOutOfBeam);
- if (self->paused == 0) {
- self->paused = 1;
- DevexecLog("NOBEAM", "ALL");
- }
- status = checkInterrupt(&check, 1);
- if (status < 0) {
- return status;
- }
- break;
- case HWPause:
- SetStatus(ePaused);
- if (self->paused == 0) {
- self->paused = 1;
- DevexecLog("PAUSE", "ALL");
- }
- status = checkInterrupt(&check, 1);
- if (status < 0) {
- /*
- * continue in order to wait for devices to come to a stop
- */
- ContinueExecution(self);
- return status;
- }
- break;
- case HWBusy:
- if (check.pDrivInt != NULL) {
- isDriving = 1;
- } else if (check.pCountInt != NULL) {
- isCounting = 1;
- }
- self->iStatus = DEVBUSY;
- break;
- case HWPosFault: /* cannot get somewhere... */
- status = errorDevice(&check);
- if (status < 0) {
- return status;
- }
- break;
- }
- }
- status = LLDnodePtr2Next(self->iList);
- }
-
- if (isCounting) {
- if (isDriving) {
- SetStatus(eCountDrive);
- } else {
- SetStatus(eCounting);
- }
- } else if (isDriving) {
- SetStatus(eDriving);
- }
-
- iRet = LLDnodePtr2First(self->iList);
- return testFinish(self);
-}
-/*--------------------------------------------------------------------------
-Cludge to not move the current pointer for CheckExeList
-*/
-void *LLDgetCurrent(int List);
-void LLDsetCurrent(int List, void *pointer);
/*---------------------------------------------------------------------------*/
int DevExecLevelRunning(pExeList self, int level)
{
- int iRet;
- pDevEntry pDev = NULL;
- void *current;
-
- if(self->lTask < 0){
- return 0;
- }
- current = LLDgetCurrent(self->iList);
- iRet = LLDnodePtr2First(self->iList);
- while (iRet != 0) {
- LLDnodeDataTo(self->iList, &pDev);
- if (pDev) {
- if(pDev->level >= level){
- LLDsetCurrent(self->iList,current);
- return 1;
- }
+ if(level == RUNRUN){
+ if(isTaskGroupRunning(self->pTask, self->runID)){
+ return 1;
}
- iRet = LLDnodePtr2Next(self->iList);
- }
- LLDsetCurrent(self->iList,current);
+ } else if(level == RUNDRIVE){
+ if(isTaskGroupRunning(self->pTask, self->waitID)){
+ return 1;
+ }
+ }
return 0;
}
-
/*---------------------------------------------------------------------------*/
int Wait4Success(pExeList self)
{
@@ -819,7 +471,7 @@ int Wait4Success(pExeList self)
/* wait for Devexec task to finish */
/*TaskWait(self->pTask, self->lTask); */
- while(DevExecLevelRunning(self,RUNDRIVE)){
+ while(isTaskIDRunning(self->pTask,self->lTask)){
TaskYield(self->pTask);
}
#ifdef DEBUG
@@ -829,40 +481,6 @@ int Wait4Success(pExeList self)
return self->iStatus;
}
-/*--------------------------------------------------------------------------*/
-int ListPending(pExeList self, SConnection * pCon)
-{
- int iRet, i;
- char pBueffel[512];
- pDevEntry pDev = NULL;
-
- assert(self);
- assert(pCon);
-
- /* first make sure that the list is fully updated */
- iRet = CheckExeList(self);
- if (iRet == 1) { /* nothing to do! */
- SCWrite(pCon, "Machine idle", eValue);
- return 1;
- } else if (iRet == -1) {
- SCWrite(pCon, "Handling Interrupt", eError);
- return 0;
- }
-
-
- /* search the list for entries */
- iRet = LLDnodePtr2First(self->iList);
- while (iRet != 0) {
- LLDnodeDataTo(self->iList, &pDev);
- if (pDev) {
- sprintf(pBueffel, "\t%s %f", pDev->name, pDev->fVal);
- SCWrite(pCon, pBueffel, eValue);
- }
- iRet = LLDnodePtr2Next(self->iList);
- }
- return 1;
-}
-
/* -----------------------------------------------------------------------*/
long GetDevexecID(pExeList self)
{
@@ -874,113 +492,29 @@ long GetDevexecID(pExeList self)
/*--------------------------------------------------------------------------*/
int StopExe(pExeList self, char *name)
{
- int i, iRet;
- pDevEntry pDev = NULL;
- pIDrivable pDrivInt = NULL;
- pICountable pCountInt = NULL;
+ int interrupt = 3;
+
assert(self);
/* if not active, nothing to do */
- if ((self->pOwner == NULL) || (LLDcheck(self->iList) == LIST_EMPTY)) {
+ if ((self->pOwner == NULL) ) {
self->iRun = 0;
return 1;
}
-
- /* first the ALL case */
- if (strcmp(name, "all") == 0) {
- /*
- check for stop flag. This is to stop unnecessary calls to StopExe.
- There may be way to many, but each call is reasonable under certain
- circumstances.
- */
- if (self->iStop == 1) {
- return 0;
- } else {
- self->iStop = 1;
- }
-
- iRet = LLDnodePtr2First(self->iList);
- while (iRet != 0) {
- pDev = (pDevEntry) LLDnodePtr(self->iList);
- if (pDev) {
- pDrivInt = pDev->pDescriptor->GetInterface(pDev->pData, DRIVEID);
- pCountInt = pDev->pDescriptor->GetInterface(pDev->pData, COUNTID);
- if (pDrivInt) {
- pDrivInt->Halt(pDev->pData);
- } else if (pCountInt) {
- pCountInt->Halt(pDev->pData);
- }
- }
- iRet = LLDnodePtr2Next(self->iList);
- }
- SCWrite(self->pOwner, "ERROR: Full Stop called!!", eLogError);
- if (SCGetInterrupt(self->pOwner) > eContinue) {
- self->iStatus = DEVINT;
- }
+ if (strcasecmp(name, "run") == 0) {
+ TaskSignalGroup(self->pTask, SICSINT, &interrupt, self->runID);
return 1;
}
+ TaskSignalGroup(self->pTask, SICSINT, &interrupt, self->waitID);
- /* now the special case: a well defined command */
- iRet = LLDnodePtr2First(self->iList);
- while (iRet != 0) {
- pDev = (pDevEntry) LLDnodePtr(self->iList);
- if (pDev) {
- if (strcmp(pDev->name, name) == 0) {
- pDrivInt = pDev->pDescriptor->GetInterface(pDev->pData, DRIVEID);
- pCountInt = pDev->pDescriptor->GetInterface(pDev->pData, COUNTID);
- if (pDrivInt) {
- pDrivInt->Halt(pDev->pData);
- } else if (pCountInt) {
- pCountInt->Halt(pDev->pData);
- }
- return 1;
- }
- }
- iRet = LLDnodePtr2Next(self->iList);
- }
-
- return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-int StopByData(pExeList self, void *data)
-{
- int iRet;
- pDevEntry pDev = NULL;
- pIDrivable pDrivInt = NULL;
- pICountable pCountInt = NULL;
-
- iRet = LLDnodePtr2First(self->iList);
- while (iRet != 0) {
- pDev = (pDevEntry) LLDnodePtr(self->iList);
- if (pDev) {
- if (pDev->pData == data) {
- pDrivInt = pDev->pDescriptor->GetInterface(pDev->pData, DRIVEID);
- pCountInt = pDev->pDescriptor->GetInterface(pDev->pData, COUNTID);
- if (pDrivInt) {
- pDrivInt->Halt(pDev->pData);
- } else if (pCountInt) {
- pCountInt->Halt(pDev->pData);
- }
- ExeInterest(self, pDev, "finished");
- DevexecLog("FINISHED", pDev->name);
- DeleteDevEntry(pDev);
- LLDnodeDelete(self->iList);
- self->iStatus = DEVDONE;
- SCWrite(self->pOwner, "", eFinish);
- return 1;
- }
- }
- iRet = LLDnodePtr2Next(self->iList);
- }
- return 0;
+ return 1;
}
/*-------------------------------------------------------------------------*/
int StopExeWait(pExeList self)
{
StopExe(self, "all");
- while(DevExecLevelRunning(self,RUNRUN)){
+ while(isTaskIDRunning(self->pTask, self->lTask)){
TaskYield(self->pTask);
}
return 1;
@@ -988,102 +522,52 @@ int StopExeWait(pExeList self)
/*--------------------------------------------------------------------------*/
int PauseExecution(pExeList self)
{
- int i, iRet, iRes;
- pDevEntry pDev = NULL;
- pICountable pCountInt = NULL;
+ int interrupt = 0;
+
assert(self);
-
- /* step through the list */
- iRes = 1;
- iRet = LLDnodePtr2First(self->iList);
- while (iRet != 0) {
- pDev = (pDevEntry) LLDnodePtr(self->iList);
- if (pDev) {
- pCountInt = pDev->pDescriptor->GetInterface(pDev->pData, COUNTID);
- if (pCountInt) {
- iRet = pCountInt->Pause(pDev->pData, pDev->pCon);
- if (!iRet) {
- iRes = 0;
- }
- }
-
- }
- iRet = LLDnodePtr2Next(self->iList);
+
+ if(IsCounting(self)){
+ TaskSignalGroup(self->pTask, IPAUSE, &interrupt, self->waitID);
+ TaskSignalGroup(self->pTask, IPAUSE, &interrupt, self->runID);
}
- SetStatus(ePaused);
- return iRes;
+
+ return 1;
}
-/*------------------------------------------------------------------------*/
+/*------------------------------------------------------------------------
+ check, may be obsolete
+*/
int IsCounting(pExeList self)
{
- int iRet;
- pDevEntry pDev = NULL;
- pICountable pCountInt = NULL;
assert(self);
/* step through the list */
- iRet = LLDnodePtr2First(self->iList);
- while (iRet != 0) {
- pDev = (pDevEntry) LLDnodePtr(self->iList);
- if (pDev) {
- pCountInt = pDev->pDescriptor->GetInterface(pDev->pData, COUNTID);
- if (pCountInt) {
- return 1;
- }
- }
- iRet = LLDnodePtr2Next(self->iList);
- }
+ if(self->instStatus == eCounting){
+ return 1;
+ }
return 0;
}
/*--------------------------------------------------------------------------*/
int ContinueExecution(pExeList self)
{
- int i, iRet, iRes;
- pDevEntry pDev = NULL;
- pICountable pCountInt = NULL;
+ int interrupt = 0;
assert(self);
- /* step through the list */
- iRes = 1;
- iRet = LLDnodePtr2First(self->iList);
- while (iRet != 0) {
- pDev = (pDevEntry) LLDnodePtr(self->iList);
- if (pDev) {
- pCountInt = pDev->pDescriptor->GetInterface(pDev->pData, COUNTID);
- if (pCountInt) {
- iRet = pCountInt->Continue(pDev->pData, pDev->pCon);
- if (!iRet) {
- iRes = 0;
- }
- }
-
- }
- iRet = LLDnodePtr2Next(self->iList);
+ if(GetStatus() == ePaused){
+ TaskSignalGroup(self->pTask, CONTINUE, &interrupt, self->waitID);
+ TaskSignalGroup(self->pTask, CONTINUE, &interrupt, self->runID);
}
- SetStatus(eCounting);
- return iRes;
+ return 1;
}
/*------------------------------------------------------------------------*/
void ClearExecutor(pExeList self)
{
int iRet;
- pDevEntry pDev = NULL;
assert(self);
- iRet = LLDnodePtr2First(self->iList);
- while (iRet != 0) {
- pDev = (pDevEntry) LLDnodePtr(self->iList);
- if (pDev) {
- DeleteDevEntry(pDev);
- }
- LLDnodeDelete(self->iList);
- iRet = LLDnodePtr2Prev(self->iList);
- iRet = LLDnodePtr2Next(self->iList);
- }
if (self->pOwner) {
if (SCGetInterrupt(self->pOwner) > eContinue) {
self->iStatus = DEVINT;
@@ -1091,8 +575,8 @@ void ClearExecutor(pExeList self)
SCDeleteConnection(self->pOwner);
}
self->pOwner = NULL;
- self->iEnd = 1;
self->lTask = -1;
+ self->waitID = -1;
self->iRun = 0;
self->iLock = 0;
}
@@ -1117,10 +601,6 @@ int StopCommand(SConnection * pCon, SicsInterp * pSics, void *pData,
argtolower(argc, argv);
self = (pExeList) pData;
- if (argc < 2) {
- ListPending(self, pCon);
- return 1;
- }
iRet = StopExe(self, argv[1]);
if (!iRet) {
@@ -1143,7 +623,37 @@ static int DrivStatCallback(int iEvent, void *text, void *pCon)
SCWrite(pCon, text, eLog);
return 1;
}
+/*---------------------------------------------------------------------------*/
+int ListPending(pExeList self, SConnection *pCon)
+{
+ pDynString buffer;
+ pTaskHead it = NULL;
+ long id;
+ if(self->lTask < 0){
+ SCWrite(pCon,"Machine Idle",eValue);
+ return 1;
+ }
+
+ buffer = CreateDynString(128,128);
+ if(buffer == NULL){
+ SCWrite(pCon,"ERROR: out of memory in Listpending",eError);
+ return 0;
+ }
+
+ for(it = TaskIteratorStart(self->pTask); it != NULL; it = TaskIteratorNext(it)){
+ id = GetGroupID(it);
+ if(id == self->waitID || id == self->runID){
+ DynStringConcat(buffer,(char *)GetTaskName(it));
+ DynStringConcatChar(buffer,'\n');
+ }
+ }
+
+ SCWrite(pCon,GetCharArray(buffer),eValue);
+ DeleteDynString(buffer);
+ return 1;
+
+}
/*--------------------------------------------------------------------------*/
int ListExe(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[])
@@ -1198,23 +708,26 @@ int SicsIdle(SConnection * pCon, SicsInterp * pSics, void *pData,
int Success(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[])
{
- int iRet, level;
+ int iRet, level = RUNRUN;
Status eOld;
pExeList self = (pExeList)pData;
eOld = GetStatus();
- SetStatus(eRunning);
if(argc > 1){
if(strcmp(argv[1],"RUNDRIVE") == 0){
level = RUNDRIVE;
}
- } else {
- level = RUNRUN;
}
- while(DevExecLevelRunning(self, level)){
+ if(level == RUNRUN) {
+ while(isTaskIDRunning(self->pTask,self->lTask)){
TaskYield(self->pTask);
+ }
+ } else {
+ while(DevExecLevelRunning(self, level)){
+ TaskYield(self->pTask);
+ }
}
iRet = self->iStatus;
if (iRet == DEVINT) {
@@ -1226,12 +739,21 @@ int Success(SConnection * pCon, SicsInterp * pSics, void *pData,
}
} else if (iRet == DEVDONE) {
SCWrite(pCon, "All done", eValue);
+ self->iRun = 0;
iRet = 1;
} else if (iRet == DEVERROR) {
SCWrite(pCon, "Finished with Problems", eValue);
iRet = 1;
+ } else if(iRet == DEVBUSY){
+ /*
+ some other level may still be running
+ */
+ if(level == RUNRUN){
+ self->iRun = 0;
+ }
+ SCWrite(pCon, "Level done", eValue);
+ iRet = 1;
}
- SetStatus(eEager);
return iRet;
}
/*-------------------------------------------------------------------------*/
@@ -1346,70 +868,44 @@ SConnection *GetExeOwner(pExeList self)
return self->pOwner;
}
-
/*--------------------------------------------------------------------------*/
int DevExecTask(void *pData)
{
pExeList self = NULL;
- char pBueffel[132], pInterrupt[80];
- int iRet, iInterrupt;
-
self = (pExeList) pData;
- /* am I bound to end ? */
- if (self->iEnd) {
- self->lTask = -1;
- SetStatus(eEager);
- return 0;
- }
+ assert(self != NULL);
- if (self->taskRunning == 1) {
- printf("DevexecTask reentrant protection triggered\n");
+ if(isTaskGroupRunning(self->pTask,self->waitID)
+ || isTaskGroupRunning(self->pTask,self->runID)){
+ self->iStatus = DEVBUSY;
return 1;
}
+
/*
- * CheckExeList may cause waits and thus reentrant calls to
- * this. Which can cause trouble
+ We are done, clean up
+ */
+ self->waitID = -1;
+ self->lTask = -1;
+ self->iRun = 0;
+ self->instStatus = eEager;
+ /*
+ This is sort of unclean. Setting DEVERROR has to be done in the
+ device task function as it is the only one that knows about this.
+ Interrupts always have priority, thus they are dealt with here.
*/
- self->taskRunning = 1;
- iRet = CheckExeList(self);
- self->taskRunning = 0;
-
-
- self->lastRun = time(NULL);
- switch (iRet) {
- case -1: /* some problem */
- iInterrupt = SCGetInterrupt(self->pOwner);
- if (iInterrupt != eContinue) {
- if (iInterrupt > 1) {
- self->taskRunning = 1;
- StopExe(self, "all");
- self->taskRunning = 0;
- }
-#ifdef DEBUG
- printf("DevExecTask found an error\n");
-#endif
- return 1;
- } else {
- return 1;
+ if(SCGetInterrupt(self->pOwner) != eContinue){
+ self->iStatus = DEVINT;
+ } else {
+ if(self->iStatus != DEVERROR){
+ self->iStatus = DEVDONE;
}
- break;
- case 1: /* Success */
- self->lTask = -1;
- self->iEnd = 1;
- SetStatus(eEager);
-#ifdef DEBUG
- printf("DevExecTask finishes on success\n");
-#endif
- return 0;
- break;
- default: /* continue, still busy */
- return 1;
}
- /* should not get here */
- return 1;
-}
+ SCDeleteConnection(self->pOwner);
+ self->pOwner = NULL;
+ return 0;
+}
/*---------------------------------------------------------------------------*/
void DevExecSignal(void *pEL, int iSignal, void *pSigData)
{
@@ -1420,34 +916,14 @@ void DevExecSignal(void *pEL, int iSignal, void *pSigData)
self = (pExeList) pEL;
assert(self);
- if (iSignal == SICSINT) {
- iInt = (int *) pSigData;
- if (*iInt != eContinue) {
- if (self->pOwner) {
- pCon = SCCopyConnection(self->pOwner);
- if (pCon != NULL) {
- pCon->transID = 0;
- strcpy(pCon->deviceID, "system");
- SCWrite(pCon,
- "ERROR: Interrupting Current Hardware Operation",
- eError);
- SCSetInterrupt(pCon, *iInt);
- SCSetInterrupt(self->pOwner, *iInt);
- SCDeleteConnection(pCon);
- }
- }
- StopExe(self, "all");
- }
- }
+ TaskSignalGroup(self->pTask,iSignal, pSigData, self->waitID);
}
-
/*--------------------------------------------------------------------*/
void LockDeviceExecutor(pExeList self)
{
assert(self);
self->iLock = 1;
}
-
/*--------------------------------------------------------------------*/
void UnlockDeviceExecutor(pExeList self)
{
@@ -1476,3 +952,19 @@ void *GetExecutorCallback(pExeList self)
{
return self->pCall;
}
+/*----------------------------------------------------------------------*/
+void SetDevexecStatus(pExeList pExe, int code)
+{
+ if(code >= 0 || code <= DEVBUSY){
+ pExe->iStatus = code;
+ }
+}
+/*------------------------------------------------------------------------*/
+int GetDevExecInstStatus(pExeList self)
+{
+ if(self->lTask < 0){
+ return eEager;
+ } else {
+ return self->instStatus;
+ }
+}
diff --git a/devexec.h b/devexec.h
index 3a8a1668..c9290e2c 100644
--- a/devexec.h
+++ b/devexec.h
@@ -1,5 +1,5 @@
-#line 202 "devexec.w"
+#line 204 "devexec.w"
/*----------------------------------------------------------------------------
@@ -57,7 +57,7 @@
int StartCounter(pExeList self, SicsInterp *pSics, SConnection *pCon,
int level, char *name);
-#line 249 "devexec.w"
+#line 251 "devexec.w"
/*------------------------------------------------------------------------*/
@@ -77,8 +77,10 @@
int DevExecTask(void *pEL);
void DevExecSignal(void *pEL, int iSignal, void *pSigData);
+ int GetDevExecInstStatus(pExeList self);
-#line 251 "devexec.w"
+
+#line 253 "devexec.w"
/*
@@ -98,7 +100,7 @@
*/
/*-------------------------------------------------------------------------*/
-#line 142 "devexec.w"
+#line 144 "devexec.w"
int StopExe(pExeList self, char *name);
int StopExeWait(pExeList self);
@@ -122,7 +124,7 @@
int ContinueExecution(pExeList self);
-#line 269 "devexec.w"
+#line 271 "devexec.w"
/*-------------------------- Commands ------------------------------------*/
int DevexecAction(SConnection *pCon, SicsInterp *pSics, void *pData,
@@ -164,13 +166,13 @@
/*--------------------------- Locking ---------------------------------*/
-#line 190 "devexec.w"
+#line 192 "devexec.w"
void LockDeviceExecutor(pExeList self);
void UnlockDeviceExecutor(pExeList self);
-#line 309 "devexec.w"
+#line 311 "devexec.w"
/* -------------------------- Executor management -------------------------*/
@@ -184,5 +186,8 @@
*/
void *GetExecutorCallback(pExeList self);
/*----------------------- Logging -----------------------------------------*/
- void DevexecLog(char *op, char *device);
+ void DevexecLog(char *op, char *device);
+ void ExeInterest(pExeList pExe, char *name, char *action);
+ void InvokeNewTarget(pExeList pExe, char *name, float fTarget);
+ void SetDevexecStatus(pExeList pExe, int code);
#endif
diff --git a/devexec.tex b/devexec.tex
index 1539537a..fa2bd6ba 100644
--- a/devexec.tex
+++ b/devexec.tex
@@ -373,7 +373,10 @@ to the global SICS device executor.
\mbox{}\verb@ */ @\\
\mbox{}\verb@ void *GetExecutorCallback(pExeList self);@\\
\mbox{}\verb@/*----------------------- Logging -----------------------------------------*/@\\
-\mbox{}\verb@ void DevexecLog(char *op, char *device); @\\
+\mbox{}\verb@ void DevexecLog(char *op, char *device);@\\
+\mbox{}\verb@ void ExeInterest(pExeList pExe, char *name, char *action); @\\
+\mbox{}\verb@ void InvokeNewTarget(pExeList pExe, char *name, float fTarget);@\\
+\mbox{}\verb@ void SetDevexecStatus(pExeList pExe, int code);@\\
\mbox{}\verb@#endif @\\
\mbox{}\verb@@$\Diamond$
\end{list}
diff --git a/devexec.w b/devexec.w
index 0f2cca05..403e60eb 100644
--- a/devexec.w
+++ b/devexec.w
@@ -101,6 +101,8 @@ From within the SICS main loops this special function is called:
int DevExecTask(void *pEL);
void DevExecSignal(void *pEL, int iSignal, void *pSigData);
+ int GetDevExecInstStatus(pExeList self);
+
@}
CheckExeList then scan through its list of executing objects and request a
status from each of them. The next action depend on the status returned from
@@ -319,7 +321,10 @@ to the global SICS device executor.
*/
void *GetExecutorCallback(pExeList self);
/*----------------------- Logging -----------------------------------------*/
- void DevexecLog(char *op, char *device);
+ void DevexecLog(char *op, char *device);
+ void ExeInterest(pExeList pExe, char *name, char *action);
+ void InvokeNewTarget(pExeList pExe, char *name, float fTarget);
+ void SetDevexecStatus(pExeList pExe, int code);
#endif
@}
diff --git a/devser.c b/devser.c
index 506a168e..fc1f90b2 100644
--- a/devser.c
+++ b/devser.c
@@ -228,7 +228,7 @@ void DevAsconStatistics(DevSer *self, double *avg, \
*longCount = self->maxCount;
}
-static int DevQueueTask(void *ds)
+int DevQueueTask(void *ds)
{
DevSer *devser = ds;
DevAction *action;
@@ -256,17 +256,19 @@ static int DevQueueTask(void *ds)
* TODO: this may be a place to record the end time
*/
if(devser->startTime > 0){
- LogResponse(devser,1);
+ LogResponse(devser,1);
} else {
- /* This is a follow up error and should not go into statistics */
+ /* This is a follow up error and should not go into statistics */
}
} else if (devser->status == AsconReady) {
replyData = AsconRead(devser->ascon);
if(replyData != NULL){
- LogResponse(devser,0);
+ LogResponse(devser,0);
}
+ } else if (devser->status == AsconOffline) {
+ replyData = "ASCERR: offline";
} else {
- return 1;
+ return 1;
}
if (devser->steps > 0) { /* debugging mode */
devser->steps--;
@@ -308,7 +310,8 @@ DevSer *DevMake(SConnection * con, int argc, char *argv[])
devser->steps = -1; /* no debugging by default */
devser->status = AsconUnconnected;
devser->startTime = -1;
- TaskRegister(pServ->pTasker, DevQueueTask, NULL, NULL, devser, 0);
+ TaskRegisterN(pServ->pTasker, AsconHostport(ascon),
+ DevQueueTask, NULL, NULL, devser, 0);
return devser;
}
@@ -330,7 +333,8 @@ static void DevReset(DevSer * devser)
devser->current->kill(devser->current->data);
}
devser->killCurrent = 0;
- /* free(devser->current); */
+ free(devser->current);
+ devser->current = NULL;
}
}
@@ -601,3 +605,7 @@ char *DevStatus(DevSer *devser) {
double DevGetSetTimeout(DevSer *devser, double timeout, int setmode) {
return AsconGetSetTimeout(devser->ascon, timeout, setmode);
}
+
+int DevReconnectInterval(DevSer *devser, int interval) {
+ return AsconReconnectInterval(devser->ascon, interval);
+}
diff --git a/devser.h b/devser.h
index b91e8f51..897c1471 100644
--- a/devser.h
+++ b/devser.h
@@ -207,4 +207,20 @@ char *DevStatus(DevSer *devser);
*/
double DevGetSetTimeout(DevSer *devser, double timeout, int setmode);
+/**
+ * \brief set reconnectInterval
+ * \param a the Ascon
+ * \param interval the interval to set (0: no reconnect, -1: read value)
+ * \return the value
+ */
+int DevReconnectInterval(DevSer *devser, int interval);
+
+/**
+ * Drive devser processing. Normally called as a SICS task
+ * @param ds The device serialiser to run
+ * @return 1 when continuing the task, 0 when the task is to be stopped
+ */
+int DevQueueTask(void *ds);
+
+
#endif
diff --git a/diffscan.c b/diffscan.c
index 284cb8bb..87e1b616 100644
--- a/diffscan.c
+++ b/diffscan.c
@@ -475,7 +475,7 @@ int RunDiffScan(pDiffScan self, pScanData pScan,
InvokeCallBack(self->scanObject->pCall, SCANSTART, self->scanObject);
- lID = TaskRegister(pServ->pTasker, DiffScanTask, NULL, NULL, self, 10);
+ lID = TaskRegisterN(pServ->pTasker,"diffscan", DiffScanTask, NULL, NULL, self, 10);
TaskWait(pServ->pTasker, lID);
diff --git a/doc/manager/nxscript.htm b/doc/manager/nxscript.htm
index 6c27eff5..b804ceea 100644
--- a/doc/manager/nxscript.htm
+++ b/doc/manager/nxscript.htm
@@ -113,7 +113,8 @@ experiment.
property on the node or as given on the command line. The alias is expected to match the size and type of
the data. Please note that hipadaba stores all floats as double which is NX_FLOAT64 as number type. Writing
data is started with the offset specified from the start of the data. This is useful to split a histogram
- memory area into separate detectors or whatever.
+ memory area into separate detectors or whatever. The length of the amount of data to
+ copy is implied by the dimension of the SDS alias points to.
nxscript puthdbslab path start size
Put a hipdaba node as a slab. The node must have a property nxalias to determine where to write to.
Start and size are Tcl lists which give the start point where to write and the size of the data
@@ -168,6 +169,25 @@ designated by targetAlias.
The difference is that this converts the data to a6 bit int before writing.
And SICSData objects are not supported.
+nxscript puts alias sgetstring [dim,dim]
+
+ Writes any SICS data which can be fetched with sget. The input to sget is the
+ sgetstring. If sgetstring contains spaces, it must be quoted. The code tries to guess types
+ and dimensions automatically, thus alias must point to a definition string without -type,
+ -dim and -rank. The dimensions can be overriden with the optional dim argument which is a
+ komma separated list of dimensions.
+
+nxscript sappend alias sgetstring point [dim,dim]
+
+ Appends any SICS data which can be fetched with sget to alias. The input to sget is the
+ sgetstring. If sgetstring contains spaces, it must be quoted. The code tries to guess types
+ and dimensions automatically, thus alias must point to a definition string without -type,
+ -dim and -rank. It is assumed that the first dimension is NX_UNLIMITED. The dimensions can be
+ overriden with the optional dim argument which is a komma separated list of dimensions. This override
+ only allows to specify the correct dimensions of the detector, NX_UNLIMITED is prepended
+ automatically. Point is the count in the dataset where to append to. Usually this is the
+ scan point number.
+
Automatic Updating of NeXus Files
diff --git a/drive.c b/drive.c
index 16fbf6bc..f0554a96 100644
--- a/drive.c
+++ b/drive.c
@@ -169,7 +169,7 @@ int Start2Run(SConnection * pCon, SicsInterp * pInter, char *name,
/* first try to find the thing to drive */
pObject = FindCommand(pInter, name);
if (!pObject) {
- snprintf(pBueffel,511, "Cannot find %s to drive ", name);
+ snprintf(pBueffel,511, "ERROR: Cannot find %s to drive ", name);
SCWrite(pCon, pBueffel, eError);
return 0;
}
@@ -180,7 +180,7 @@ int Start2Run(SConnection * pCon, SicsInterp * pInter, char *name,
pDum = (Dummy *) pObject->pData;
pDes = pDum->pDescriptor;
if (!pDes) {
- snprintf(pBueffel,511, "%s is NOT drivable!", pDes->name);
+ snprintf(pBueffel,511, "ERROR: %s is NOT drivable!", pDes->name);
SCWrite(pCon, pBueffel, eError);
return 0;
}
@@ -190,14 +190,14 @@ int Start2Run(SConnection * pCon, SicsInterp * pInter, char *name,
*/
pInt = pDes->GetInterface(pDum, DRIVEID);
if (!pInt) {
- snprintf(pBueffel,511, "%s is NOT drivable!", pDes->name);
+ snprintf(pBueffel,511, "ERROR: %s is NOT drivable!", pDes->name);
SCWrite(pCon, pBueffel, eError);
return 0;
}
if (pInt) {
iRet = pInt->CheckLimits(pDum, fNew, pBueffel, 511);
if (!iRet) {
- SCWrite(pCon, pBueffel, eError);
+ SCPrintf(pCon, eError, "ERROR: %s", pBueffel);
SCSetInterrupt(pCon, eAbortOperation);
return 0;
}
@@ -208,7 +208,7 @@ int Start2Run(SConnection * pCon, SicsInterp * pInter, char *name,
return 1;
}
} else {
- snprintf(pBueffel,511, "%s is NOT drivable", pDes->name);
+ snprintf(pBueffel,511, "ERROR: %s is NOT drivable", pDes->name);
SCWrite(pCon, pBueffel, eError);
return 0;
}
@@ -302,18 +302,21 @@ int DriveWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
return 0;
}
+<<<<<<< HEAD
/* interpret arguments as pairs (name, value) and check */
- SetStatus(eDriving);
+=======
+ /* interprete arguments as pairs name value and try to start */
+>>>>>>> master
for (i = 1; i < argc; i += 2) {
if (argv[i + 1] == NULL) {
snprintf(pBueffel, 511, "ERROR: no value found for driving %s", argv[i]);
SCWrite(pCon, pBueffel, eError);
- SetStatus(eOld);
return 0;
}
iRet = Tcl_GetDouble(tcl_interp, argv[i + 1], &dTarget);
if (iRet == TCL_ERROR) {
SCWrite(pCon, Tcl_GetStringResult(tcl_interp), eError);
+<<<<<<< HEAD
SetStatus(eOld);
return 0;
} else if (!isfinite(dTarget)) {
@@ -321,7 +324,6 @@ int DriveWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
"ERROR: target %s value for %s is not a finite number",
argv[i + 1], argv[i]);
SCWrite(pCon, pBueffel, eError);
- SetStatus(eOld);
return 0;
}
}
@@ -330,7 +332,9 @@ int DriveWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
iRet = Tcl_GetDouble(tcl_interp, argv[i + 1], &dTarget);
if (iRet == TCL_ERROR) {
SCWrite(pCon, Tcl_GetStringResult(tcl_interp), eError);
- SetStatus(eOld);
+=======
+ StopExe(GetExecutor(), "ALL");
+>>>>>>> master
return 0;
}
iRet = Start2Run(pCon, pSics, argv[i], RUNDRIVE, dTarget);
@@ -344,7 +348,6 @@ int DriveWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
}
SCWrite(pCon, pBueffel, eError);
StopExe(GetExecutor(), "ALL");
- SetStatus(eOld);
return 0;
}
}
@@ -367,17 +370,18 @@ int DriveWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
sprintf(pBueffel, "Driving finished with problem");
SCWrite(pCon, pBueffel, eError);
ClearExecutor(GetExecutor());
- SetStatus(eOld);
return 0;
} else if (iRet == DEVINT) {
sprintf(pBueffel, "ERROR: Driving Interrupted!");
SCWrite(pCon, pBueffel, eError);
ClearExecutor(GetExecutor());
- SetStatus(eOld);
return 0;
}
+<<<<<<< HEAD
SCWrite(pCon, "Driving finished successfully", eValue);
- SetStatus(eOld);
+=======
+ SCWrite(pCon, "Driving finished sucessfully", eValue);
+>>>>>>> master
return 1;
}
@@ -414,20 +418,21 @@ int RunWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
return 0;
}
+<<<<<<< HEAD
/* interpret arguments as pairs name value and try to start */
- SetStatus(eDriving);
+=======
+ /* interprete arguments as pairs name value and try to start */
+>>>>>>> master
for (i = 1; i < argc; i += 2) {
if (argv[i + 1] == NULL) {
snprintf(pBueffel,511, "ERROR: no value found for driving %s", argv[i]);
SCWrite(pCon, pBueffel, eError);
- SetStatus(eOld);
return 0;
}
iRet = Tcl_GetDouble(tcl_interp, argv[i + 1], &dTarget);
if (iRet == TCL_ERROR) {
SCWrite(pCon, Tcl_GetStringResult(tcl_interp), eError);
StopExe(GetExecutor(), "ALL");
- SetStatus(eOld);
return 0;
}
iRet = Start2Run(pCon, pSics, argv[i], RUNRUN, dTarget);
@@ -436,13 +441,75 @@ int RunWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
argv[i + 1]);
SCWrite(pCon, pBueffel, eError);
StopExe(GetExecutor(), "ALL");
- SetStatus(eOld);
return 0;
}
}
return 1;
}
+/*---------------------------------------------------------------------------*/
+int MoveWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
+ int argc, char *argv[])
+{
+ Tcl_Interp *tcl_interp;
+ int iRet, i;
+ double dTarget;
+ float curPos;
+ char pBueffel[512];
+ Status eOld;
+ long groupID, taskID;
+ void *obj;
+ assert(pCon);
+ assert(pSics);
+ tcl_interp = InterpGetTcl(pSics);
+ /* check Status */
+ eOld = GetStatus();
+
+
+ /* check no of args */
+ if (argc < 3) {
+ snprintf(pBueffel,511, "Insufficient number of args. Usage %s name val",
+ argv[0]);
+ SCWrite(pCon, pBueffel, eError);
+ return 0;
+ }
+
+ /* check authorisation */
+ if (!SCMatchRights(pCon, usUser)) {
+ SCWrite(pCon,
+ "ERROR: You are not authorized to use the mv command",
+ eError);
+ return 0;
+ }
+ groupID = GetTaskGroupID(pServ->pTasker);
+ for (i = 1; i < argc; i += 2) {
+ if (argv[i + 1] == NULL) {
+ snprintf(pBueffel,511, "ERROR: no value found for driving %s", argv[i]);
+ SCWrite(pCon, pBueffel, eError);
+ return 0;
+ }
+ iRet = Tcl_GetDouble(tcl_interp, argv[i + 1], &dTarget);
+ if (iRet == TCL_ERROR) {
+ SCWrite(pCon, Tcl_GetStringResult(tcl_interp), eError);
+ StopExe(GetExecutor(), "ALL");
+ return 0;
+ }
+ obj = FindCommandData(pSics,argv[i],NULL);
+ if(obj == NULL || GetDrivableInterface(obj) == NULL){
+ SCPrintf(pCon,eError, "ERROR: %s not found, not started",argv[i]);
+ break;
+ }
+ GetDrivablePosition(obj,pCon,&curPos);
+ dTarget = curPos + dTarget;
+ taskID = StartDriveTask(obj, pCon, argv[i], (float)dTarget);
+ AddTaskToGroup(pServ->pTasker,taskID,groupID);
+ }
+ while(isTaskGroupRunning(pServ->pTasker,groupID)){
+ TaskYield(pServ->pTasker);
+ }
+ SCSendOK(pCon);
+ return 0;
+}
/*---------------------------------------------------------------------------*/
int MakeDrive(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[])
@@ -473,5 +540,17 @@ int MakeDrive(SConnection * pCon, SicsInterp * pSics, void *pData,
SCWrite(pCon, pBueffel, eError);
return 0;
}
+
+ if (argc > 3) {
+ iRet = AddCommand(pSics, argv[2], MoveWrapper, NULL, NULL);
+ } else {
+ iRet = AddCommand(pSics, "mv", MoveWrapper, NULL, NULL);
+ }
+ if (!iRet) {
+ sprintf(pBueffel, "ERROR: duplicate command mv not created");
+ SCWrite(pCon, pBueffel, eError);
+ return 0;
+ }
+
return 1;
}
diff --git a/dynstring.c b/dynstring.c
index 83977115..c45a6afd 100644
--- a/dynstring.c
+++ b/dynstring.c
@@ -83,7 +83,15 @@ static int Resize(pDynString self, int iRequested)
self->iBufferSize = iNewSize;
return 1;
}
-
+/*--------------------------------------------------------------------------*/
+int DynStringCapacity(pDynString self, int length)
+{
+ if(self->iBufferSize < length){
+ return Resize(self,length);
+ } else {
+ return 1;
+ }
+}
/*--------------------------------------------------------------------------*/
void DeleteDynString(pDynString self)
{
diff --git a/dynstring.h b/dynstring.h
index be9d90be..95013c3d 100644
--- a/dynstring.h
+++ b/dynstring.h
@@ -109,4 +109,9 @@ char *Dyn2Cstring(pDynString self);
/*
convert to C string and delete dynstring. The result must be freed when no longer used.
*/
+/*
+ Ensures that the DynString has the capacity length. In order to avoid unnecessary
+ concatenation when the length is already known.
+*/
+int DynStringCapacity(pDynString self, int length);
#endif
diff --git a/epicsmotor.c b/epicsmotor.c
new file mode 100644
index 00000000..f15a7764
--- /dev/null
+++ b/epicsmotor.c
@@ -0,0 +1,313 @@
+/**
+ * This is a very basic first generation SICS EPICS motor driver for testing.
+ * It should be replaced by a second generation version when SINQ gets serious
+ * about EPICS and SICS.
+ *
+ * Mark Koennecke, February 2012
+ */
+#include
+#include
+#include
+
+/* EPICS stuff */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+typedef struct __epicsMoDriv{
+ /* general motor driver interface
+ fields. REQUIRED!
+ */
+ float fUpper; /* upper limit */
+ float fLower; /* lower limit */
+ char *name;
+ int (*GetPosition)(void *self, float *fPos);
+ int (*RunTo)(void *self,float fNewVal);
+ int (*GetStatus)(void *self);
+ void (*GetError)(void *self, int *iCode, char *buffer, int iBufLen);
+ int (*TryAndFixIt)(void *self, int iError,float fNew);
+ int (*Halt)(void *self);
+ int (*GetDriverPar)(void *self, char *name,
+ float *value);
+ int (*SetDriverPar)(void *self,SConnection *pCon,
+ char *name, float newValue);
+ void (*ListDriverPar)(void *self, char *motorName,
+ SConnection *pCon);
+ void (*KillPrivate)(void *self);
+ /* your drivers private fields follow below */
+ char *motBaseName;
+ char *ezcaError;
+ int ezcaCode;
+ int connectCount;
+ } epicsMotorDriver;
+
+/*================================================================
+ GetPos returns OKOK on success, HWFault on failure
+------------------------------------------------------------------*/
+static int epicsGetPos(void *data, float *fPos){
+ epicsMotorDriver *self = NULL;
+ char fullName[132];
+ int status;
+ double position;
+
+ self = (epicsMotorDriver *)data;
+ snprintf(fullName,sizeof(fullName),"%s.DRBV",self->motBaseName);
+ status = ezcaGet(fullName,ezcaDouble,1, &position);
+ if(status == EZCA_OK){
+ *fPos =(float) position;
+ self->connectCount = 0;
+ return OKOK;
+ } else {
+ ezcaGetErrorString("ERROR: EPICS: ", &self->ezcaError);
+ self->ezcaCode = status;
+ return HWFault;
+ }
+}
+/*-------------- dummy callback for runto -------------------------*/
+static void RunToDummy(struct event_handler_args d)
+{
+}
+/*----------------------------------------------------------------
+ RunTo starts the motor running. Returns OKOK on success, HWfault
+ on Errors
+------------------------------------------------------------------*/
+static int epicsRunTo(void *data, float newValue){
+ epicsMotorDriver *self = NULL;
+ char fullName[132];
+ double position = newValue;
+ int status;
+ chid *cid;
+
+ self = (epicsMotorDriver *)data;
+ snprintf(fullName,sizeof(fullName),"%s.DVAL",self->motBaseName);
+ ezcaPvToChid(fullName,&cid);
+ status = ca_put_callback(DBR_DOUBLE,*cid,&position, RunToDummy,NULL);
+ if(status != ECA_NORMAL){
+ snprintf(fullName, sizeof(fullName),"Bad CA status %d", status);
+ self->ezcaError = strdup(fullName);
+ self->ezcaCode = status;
+ return HWFault;
+ } else {
+ ca_pend_event(.05);
+ self->connectCount = 0;
+ return OKOK;
+ }
+
+}
+/*------------------------------------------------------------------
+ CheckStatus queries the sattus of a running motor. Possible return
+ values can be:
+ HWBusy : motor still running
+ HWFault : motor error detected
+ HWPosFault : motor finished, but position not reached
+ HWIdle : motor finished OK
+ HWWarn : motor issued warning
+--------------------------------------------------------------------*/
+static int epicsCheckStatus(void *data){
+ epicsMotorDriver *self = NULL;
+ char fullName[132];
+ short smov, stat;
+ int status;
+
+ self = (epicsMotorDriver *)data;
+ snprintf(fullName,sizeof(fullName),"%s.DMOV",self->motBaseName);
+ status = ezcaGet(fullName,ezcaShort,1, &smov);
+ if(status == EZCA_OK){
+ self->connectCount = 0;
+ if(smov == 0){
+ return HWBusy;
+ } else {
+ snprintf(fullName,sizeof(fullName),"%s.STAT",self->motBaseName);
+ status = ezcaGet(fullName,ezcaShort,1, &stat);
+ if(stat != menuAlarmStatNO_ALARM){
+ snprintf(fullName,sizeof(fullName),"EPICS ALARM: %s", epicsAlarmConditionStrings[stat]);
+ self->ezcaError = strdup(fullName);
+ return HWFault;
+ } else {
+ return HWIdle;
+ }
+ }
+ } else {
+ ezcaGetErrorString("ERROR: EPICS: ", &self->ezcaError);
+ self->ezcaCode = status;
+ return HWFault;
+ }
+}
+/*------------------------------------------------------------------
+ GetError gets more information about error which occurred
+ *iCode is an integer error code to be used in TryFixIt as indicator
+ buffer is a buffer for a text description of the problem
+ iBufLen is the length of buffer
+--------------------------------------------------------------------*/
+static void epicsGetError(void *data, int *iCode, char *buffer,
+ int iBufLen){
+ epicsMotorDriver *self = NULL;
+
+ self = (epicsMotorDriver *)data;
+ if(self->ezcaError != NULL){
+ strncpy(buffer,self->ezcaError,iBufLen);
+ ezcaFree(self->ezcaError);
+ self->ezcaError = NULL;
+ }
+}
+/*------------------------------------------------------------------
+ TryAndFixIt tries everything which is possible in software to fix
+ a problem. iError is the error code from GetError, newValue is
+ the target value for the motor
+ Possible retrun values are:
+ MOTOK : everything fixed
+ MOTREDO : try again
+ MOTFAIL : cannot fix this
+--------------------------------------------------------------------*/
+static int epicsFixIt(void *data, int iError, float newValue){
+ epicsMotorDriver *self = NULL;
+
+ self = (epicsMotorDriver *)data;
+ if(self->ezcaCode == EZCA_NOTCONNECTED && self->connectCount < 2) {
+ self->connectCount++;
+ return MOTREDO;
+ }
+ return MOTFAIL;
+}
+/*-------------------------------------------------------------------
+ Halt tries to stop the motor. Halt errors are ignored.
+
+ For some as yet unknown reasons, I cannot send the stop on the
+ same CA line then the rest. But with a new thread which just sends
+ the stop, it works. This is a straightforward use of a thread:
+ do your thing and terminate. Do not interact with other parts
+ of the program.
+---------------------------------------------------------------------*/
+static void HaltThreadFunc(void *param)
+{
+ char *pvName = (char *)param;
+ short stop = 1;
+ chid cid;
+
+ ca_context_create(ca_disable_preemptive_callback);
+ ca_create_channel(pvName,NULL,NULL,10,&cid);
+ ca_pend_io(5.);
+ ca_put(DBR_SHORT,cid,&stop);
+ ca_pend_io(5.0);
+ free(pvName);
+ printf("HaltThread ends\n");
+
+}
+/*-------------------------------------------------------------------*/
+static int epicsHalt(void *data){
+ epicsMotorDriver *self = NULL;
+ char fullName[132];
+ short stop =1;
+ chid *cid;
+ int status;
+
+ self = (epicsMotorDriver *)data;
+ snprintf(fullName,sizeof(fullName),"%s.STOP",self->motBaseName);
+ /* ezcaStartGroup(); */
+ /* ezcaPut(fullName,ezcaShort,1,&stop); */
+ /* ezcaEndGroup(); */
+ /* ezcaPvToChid(fullName,&cid); */
+ /* status = ca_put_callback(DBR_SHORT,*cid,&stop, RunToDummy,NULL); */
+ /* printf("Halt status %d\n", status); */
+ /* ca_flush_io(); */
+ /* printf("Halt after poll\n"); */
+ epicsThreadCreate("Hugo",
+ epicsThreadPriorityHigh,
+ epicsThreadStackMedium,
+ HaltThreadFunc,
+ (void *)strdup(fullName));
+
+ return 1;
+}
+/*--------------------------------------------------------------------
+ GetDriverPar retrieves the value of a driver parameter.
+ Name is the name of the parameter, fValue the value when found.
+ Returns 0 on success, 0 else
+-----------------------------------------------------------------------*/
+static int epicsGetDriverPar(void *data, char *name, float *value){
+ epicsMotorDriver *self = NULL;
+
+ self = (epicsMotorDriver *)data;
+ return 0;
+}
+/*----------------------------------------------------------------------
+ SetDriverPar sets a driver parameter. Returns 0 on failure, 1 on
+ success. Name is the parameter name, pCon the connection to report
+ errors too, value the new value
+------------------------------------------------------------------------*/
+static int epicsSetDriverPar(void *data, SConnection *pCon,
+ char *name, float value){
+ epicsMotorDriver *self = NULL;
+
+ self = (epicsMotorDriver *)data;
+ return 0;
+}
+/*-----------------------------------------------------------------------
+ ListDriverPar lists the names and values of driver parameters to
+ pCon. Motorname is the name of the motor ro prefix to the listing.
+-------------------------------------------------------------------------*/
+static void epicsListDriverPar(void *data, char *motorname,
+ SConnection *pCon){
+ epicsMotorDriver *self = NULL;
+
+ self = (epicsMotorDriver *)data;
+}
+/*-----------------------------------------------------------------------
+ KillPrivate has the task to delete possibly dynamically allocated
+ memory in the private part of the driver structure
+------------------------------------------------------------------------*/
+static void epicsKillPrivate(void *data){
+ epicsMotorDriver *self = NULL;
+
+ self = (epicsMotorDriver *)data;
+ if(self->ezcaError != NULL){
+ ezcaFree(self->ezcaError);
+ }
+ if(self->motBaseName != NULL){
+ free(self->motBaseName);
+ }
+}
+/*=======================================================================*/
+MotorDriver *epicsMakeMotorDriver(char *baseName) {
+ epicsMotorDriver *pNew = NULL;
+ char fullName[132];
+ double limit;
+
+ pNew = malloc(sizeof(epicsMotorDriver));
+ if(pNew == NULL){
+ return NULL;
+ }
+ memset(pNew,0,sizeof(epicsMotorDriver));
+ pNew->motBaseName = strdup(baseName);
+ snprintf(fullName,sizeof(fullName),"%s.DRBV",pNew->motBaseName);
+ ezcaSetMonitor(fullName,ezcaDouble,1);
+ snprintf(fullName,sizeof(fullName),"%s.DMOV",pNew->motBaseName);
+ ezcaSetMonitor(fullName,ezcaShort,1);
+ snprintf(fullName,sizeof(fullName),"%s.STAT",pNew->motBaseName);
+ ezcaSetMonitor(fullName,ezcaShort,1);
+
+ snprintf(fullName,sizeof(fullName),"%s.HLM",pNew->motBaseName);
+ ezcaGet(fullName,ezcaDouble,1, &limit);
+ pNew->fUpper = limit;
+ snprintf(fullName,sizeof(fullName),"%s.LLM",pNew->motBaseName);
+ ezcaGet(fullName,ezcaDouble,1, &limit);
+ pNew->fLower = limit;
+
+ pNew->GetPosition = epicsGetPos;
+ pNew->RunTo = epicsRunTo;
+ pNew->Halt = epicsHalt;
+ pNew->GetStatus = epicsCheckStatus;
+ pNew->GetError = epicsGetError;
+ pNew->TryAndFixIt = epicsFixIt;
+ pNew->GetDriverPar = epicsGetDriverPar;
+ pNew->SetDriverPar = epicsSetDriverPar;
+ pNew->ListDriverPar = epicsListDriverPar;
+ pNew->KillPrivate = epicsKillPrivate;
+
+ /* ezcaTraceOn(); */
+ return (MotorDriver *)pNew;
+}
diff --git a/evcontroller.c b/evcontroller.c
index 3c6ecb43..f1120b5c 100644
--- a/evcontroller.c
+++ b/evcontroller.c
@@ -80,12 +80,9 @@ static long EVIDrive(void *pData, SConnection * pCon, float fVal)
assert(pCon);
if (self->runScript != NULL) {
- savedStatus = GetStatus();
- SetStatus(eBatch);
pTcl = InterpGetTcl(pServ->pSics);
snprintf(pBueffel, sizeof(pBueffel), "%s %f", self->runScript, fVal);
iRet = Tcl_Eval(pTcl, pBueffel);
- SetStatus(savedStatus);
if (iRet != TCL_OK) {
SCPrintf(pCon, eError,
"ERROR: %s while processing runscript for %s",
@@ -423,7 +420,6 @@ static int ErrPause(void *pData)
}
/* OK now, continue */
- SetStatus(eEager);
self->iWarned = 0;
ContinueExecution(pExe);
return 1;
@@ -674,7 +670,7 @@ pEVControl CreateEVController(pEVDriver pDriv, char *pName, int *iErr)
memset(pRes, 0, sizeof(EVControl));
/* new Object Descriptor */
- pRes->pDes = CreateDescriptor("Environment_Controller");
+ pRes->pDes = CreateDescriptor("Environment Controller");
if (!pRes->pDes) {
free(pRes);
return NULL;
@@ -1481,7 +1477,7 @@ int EVControlFactory(SConnection * pCon, SicsInterp * pSics, void *pData,
}
strtolower(argv[2]);
strtolower(argv[3]);
- if (FindCommandData(pSics, argv[2], "Environment_Controller")) {
+ if (FindCommandData(pSics, argv[2], "Environment Controller")) {
if (strcmp(argv[1], "replace") == 0) {
if (!RemoveEVController(pCon, argv[2])) {
return 0;
diff --git a/event.c b/event.c
index 233dd792..0d64b6e3 100644
--- a/event.c
+++ b/event.c
@@ -71,6 +71,8 @@ static char *pEvent[] = {
"STATEEND",
"NEWTARGET",
"DIMCHANGE",
+ "PAUSE",
+ "CONTINUE",
NULL
};
diff --git a/event.h b/event.h
index b39a241d..4e6556e9 100644
--- a/event.h
+++ b/event.h
@@ -1,5 +1,5 @@
-#line 103 "event.w"
+#line 108 "event.w"
/*----------------------------------------------------------------------------
E V E N T
@@ -18,7 +18,7 @@
int Text2Event(char *pText);
-#line 116 "event.w"
+#line 121 "event.w"
@@ -49,12 +49,10 @@
#define STEND 22
#define NEWTARGET 23
#define DIMCHANGE 24
-#define STPAUSE 25
-#define STCONTINUE 26
-#define STBUSY 27
-#define STIDLE 28
+#define IPAUSE 25
+#define CONTINUE 26
-#line 118 "event.w"
+#line 123 "event.w"
/*----------------- event data structure for the NEWTARGET event ---------*/
@@ -64,15 +62,15 @@ typedef struct {
} NewTarget, *pNewTarget;
/*--------------- Signals for the Signalfunction of each task ------------*/
-#line 85 "event.w"
+#line 90 "event.w"
#define SICSINT 300
#define SICSBROADCAST 301
#define TOKENGRAB 302
#define TOKENRELEASE 303
#define COMLOG 304
-#define CRONLIST 305
+#define CRONFUNC 305
-#line 126 "event.w"
+#line 131 "event.w"
#endif
diff --git a/event.tex b/event.tex
index 34aef4fb..3d3fade1 100644
--- a/event.tex
+++ b/event.tex
@@ -60,6 +60,8 @@ $\langle$VE {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@#define STEND 22@\\
\mbox{}\verb@#define NEWTARGET 23@\\
\mbox{}\verb@#define DIMCHANGE 24@\\
+\mbox{}\verb@#define IPAUSE 25@\\
+\mbox{}\verb@#define CONTINUE 26@\\
\mbox{}\verb@@$\Diamond$
\end{list}
\vspace{-1ex}
@@ -99,8 +101,11 @@ operation.
\item[HDBVAL] The Hdb is notified of a value change. The eventData will be
the object on which the data changed.
\item[NEWTARGET] is invoked when a new target has been set on a drivable.
+\item[PAUSE] Pause counting
+\item[CONTINUE] Continue counting
\end{description}
+
Furthermore event contains system wide signal codes which are interpreted in
the signal functions provided by each SICS task. These code are
evaluated by the TaskSignalFunction which may be configured for each
diff --git a/event.w b/event.w
index 6f4ed0c0..5b53b7c1 100644
--- a/event.w
+++ b/event.w
@@ -43,6 +43,8 @@ if the event code is not known, else the apropriate event code.
#define STEND 22
#define NEWTARGET 23
#define DIMCHANGE 24
+#define IPAUSE 25
+#define CONTINUE 26
@}
\begin{description}
\item[VALUECHANGE] This is a variable changing its value. As event data a pointer to the
@@ -74,8 +76,11 @@ operation.
\item[HDBVAL] The Hdb is notified of a value change. The eventData will be
the object on which the data changed.
\item[NEWTARGET] is invoked when a new target has been set on a drivable.
+\item[PAUSE] Pause counting
+\item[CONTINUE] Continue counting
\end{description}
+
Furthermore event contains system wide signal codes which are interpreted in
the signal functions provided by each SICS task. These code are
evaluated by the TaskSignalFunction which may be configured for each
diff --git a/exebuf.c b/exebuf.c
index 331f3095..aefa8b7c 100644
--- a/exebuf.c
+++ b/exebuf.c
@@ -91,13 +91,39 @@ static char *locateName(char *filename)
}
return filename;
}
+/*----------------------------------------------------------------------
+ If this is MOUNTAINBATCH file, replace ocurrences of @nl@ with \n
+------------------------------------------------------------------------*/
+static void fixMountainBatch(pExeBuf self)
+{
+ char *pPtr, *pData, *pNL;
+ pPtr = GetCharArray(self->bufferContent);
+ if(strstr(pPtr, "#MOUNTAINBATCH") != pPtr){
+ /*
+ nothing to do
+ */
+ return;
+ }
+ pData = strdup(pPtr);
+ DynStringClear(self->bufferContent);
+ pPtr = pData;
+ while((pNL = strstr(pPtr,"@nl@")) != NULL){
+ *pNL = '\n';
+ *(pNL+1) = '\0';
+ DynStringConcat(self->bufferContent, pPtr);
+ pPtr = pNL +4;
+ }
+ DynStringConcat(self->bufferContent,pPtr);
+ free(pData);
+
+}
/*-----------------------------------------------------------------------*/
int exeBufLoad(pExeBuf self, char *filename)
{
char line[256], *pPtr;
FILE *fd = NULL;
- int status, idx;
+ int status, idx, gtsebatch = 0;
assert(self);
fd = fopen(filename, "r");
@@ -128,6 +154,7 @@ int exeBufLoad(pExeBuf self, char *filename)
free(self->name);
}
self->name = strdup(locateName(filename));
+ fixMountainBatch(self);
return 1;
}
@@ -297,8 +324,6 @@ int exeBufProcess(pExeBuf self, SicsInterp * pSics,
DeleteDynString(command);
if (SCGetInterrupt(pCon) >= eAbortBatch) {
SCWrite(pCon, "ERROR: batch processing interrupted", eError);
- InvokeCallBack(pCall, BATCHEND, self->name);
- SetStatus(eEager);
if (pCall != NULL) {
InvokeCallBack(pCall, BATCHEND, self->name);
}
@@ -350,7 +375,6 @@ int exeBufProcessErrList(pExeBuf self, SicsInterp * pSics,
DeleteDynString(command);
if (SCGetInterrupt(pCon) >= eAbortBatch) {
SCWrite(pCon, "ERROR: batch processing interrupted", eError);
- SetStatus(eEager);
return 0;
} else {
SCSetInterrupt(pCon, eContinue);
diff --git a/exeman.c b/exeman.c
index d5920ac2..55ae402a 100644
--- a/exeman.c
+++ b/exeman.c
@@ -224,7 +224,16 @@ pDynString findBatchFile(SicsInterp * pSics, char *name)
}
return locateBatchBuffer(self, name);
}
-
+/*--------------------------------------------------------------------*/
+int isBatchRunning()
+{
+ pExeMan self = (pExeMan) FindCommandData(pServ->pSics, "exe", "ExeManager");
+ if(self != NULL && self->exeStackPtr > 0){
+ return 1;
+ } else {
+ return 0;
+ }
+}
/*--------------------------------------------------------------------*/
static int runBatchBuffer(pExeMan self, SConnection * pCon,
SicsInterp * pSics, char *name)
@@ -1175,7 +1184,9 @@ static int printBuffer(pExeMan self, SConnection * pCon,
}
while (fgets(pLine, 511, fd) != NULL) {
DynStringConcat(filePath, pLine);
- DynStringConcatChar(filePath,'\n');
+ if(strrchr(pLine,(int)'\n') == NULL){
+ DynStringConcatChar(filePath,'\n');
+ }
}
fclose(fd);
SCWrite(pCon, GetCharArray(filePath), eValue);
diff --git a/exeman.h b/exeman.h
index fc110a6e..0718c67f 100644
--- a/exeman.h
+++ b/exeman.h
@@ -19,4 +19,6 @@ pDynString findBatchFile(SicsInterp * pSics, char *name);
int exeHdbBuffer(SConnection * pCon, SicsInterp * pSics, char *name);
int exeHdbNode(pHdb exeNode, SConnection * pCon);
+int isBatchRunning();
+
#endif
diff --git a/fitcenter.c b/fitcenter.c
index f4d0112e..bbb1afee 100644
--- a/fitcenter.c
+++ b/fitcenter.c
@@ -20,10 +20,6 @@
#include "scan.h"
#include "fitcenter.h"
#define THRESHOLD .1
-
-float ggf1[] = { 0.006, 0.061, 0.242, 0.383, 0.242, 0.061, 0.006 }; // Gaussian Smooth Filter
-float ggf2[] = { 0.1429, 0.1429, 0.1429, 0.1429, 0.1429, 0.1429, 0.1429 }; // Mean Smooth Filter
-
/*--------------------------------------------------------------------------*/
typedef struct __FitCenter {
pObjectDescriptor pDes;
@@ -77,28 +73,6 @@ void DeleteFitCenter(void *pData)
free(self);
}
-/*--------------------------------------------------------------------------*/
-static void SmoothScanCounts(long *lData, int iDataLen)
-{
- int ind = (int) (sizeof(ggf1) / sizeof(float) - 1) / 2;
- long *pData = (long *) malloc(iDataLen * sizeof(long));
-
- for (int i = 0; i < iDataLen; i++)
- pData[i] = lData[i];
-
- for (int i = 0; i < iDataLen; i++) {
- lData[i] = pData[i] * ggf1[ind];
- for (int j = 1; j <= ind; j++) {
- if ((i - j) > 0)
- lData[i] += pData[i - j] * ggf1[ind - j];
- if ((i + j) < iDataLen)
- lData[i] += pData[i + j] * ggf1[ind + j];
- }
- }
-
- free(pData);
-}
-
/*--------------------------------------------------------------------------*/
static int Init(pFit self)
{
@@ -123,9 +97,6 @@ static int Init(pFit self)
}
GetScanCounts(self->pScan, self->lCounts, self->iNP);
-
- SmoothScanCounts(self->lCounts, self->iNP);
-
GetScanVar(self->pScan, 0, self->fAxis, self->iNP);
GetScanVarName(self->pScan, 0, self->pName, 131);
@@ -462,40 +433,11 @@ int FitWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
int iRet;
char pBueffel[256];
pDynString buf = NULL;
- pScanData pScan = NULL;
- char *cmd = NULL;
self = (pFit) pData;
assert(self);
- /*
- * allow for an optional scan object as first argument
- * and make cmd point at the command
- */
- if (argc > 1) {
- cmd = argv[1];
- CommandList *pCom = NULL;
- pCom = FindCommand(pSics, argv[1]);
- if (pCom) {
- pDummy pDum = NULL;
- pDum = (pDummy) pCom->pData;
- if (pDum) {
- if (strcmp(pDum->pDescriptor->name, "ScanObject") == 0) {
- pScan = (pScanData) pDum;
- if (argc > 2)
- cmd = argv[2];
- }
- }
- }
- }
- if (pScan) {
- pScanData pScanSave;
- pScanSave = self->pScan;
- self->pScan = pScan;
- iRet = CalculateFit(self);
- self->pScan = pScanSave;
- } else {
- iRet = CalculateFit(self);
- }
+
+ iRet = CalculateFit(self);
switch (iRet) {
case 0:
SCWrite(pCon, "ERROR: failure to fit your data!", eError);
@@ -528,14 +470,14 @@ int FitWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
This is a little feature to get the peak without rubbish for
the TAS routines
*/
- if (cmd) {
- strtolower(cmd);
- if (strcmp(cmd, "value") == 0) {
- sprintf(pBueffel, "%f", self->fCenter);
+ if (argc > 1) {
+ strtolower(argv[1]);
+ if (strcmp(argv[1], "value") == 0) {
+ snprintf(pBueffel,sizeof(pBueffel)-1, "%f", self->fCenter);
SCWrite(pCon, pBueffel, eValue);
return 1;
}
- if (strcmp(cmd, "data") == 0) {
+ if (strcmp(argv[1], "data") == 0) {
snprintf(pBueffel, 255, "%f,%f,%ld",
self->fCenter, self->FWHM, self->lPeak);
SCWrite(pCon, pBueffel, eValue);
@@ -629,5 +571,6 @@ int CenterWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
self = (pFit) pData;
assert(self);
+ CalculateFit(self);
return DriveCenter(self, pCon, pSics);
}
diff --git a/fomerge.c b/fomerge.c
index 39b88481..40af9380 100644
--- a/fomerge.c
+++ b/fomerge.c
@@ -19,6 +19,9 @@
extended to support nxscripted file writing: Mark Koennecke, May 2004
extended to support GTSE, Mark Koennecke, May 2008
+
+ modifed to support second generation HM's via the bridge,
+ Mark Koennecke, December 2012
--------------------------------------------------------------------------*/
#include
#include
@@ -428,20 +431,20 @@ static int updateHMFMData(SicsInterp * pSics, SConnection * pCon)
HistInt *data = NULL;
pHistMem pMem = NULL;
- pMem = (pHistMem) FindCommandData(pSics, "hm2", "HistMem");
+ pMem = (pHistMem) FindHM(pSics, "hm2");
if (pMem == NULL) {
return 0;
}
fTimeBin = GetHistTimeBin(pMem, &iTime);
setFMDataPointer(GetHistogramPointer(pMem, pCon), iTime, MIDDLE);
- pMem = (pHistMem) FindCommandData(pSics, "hm1", "HistMem");
+ pMem = (pHistMem) FindHM(pSics, "hm1");
if (pMem == NULL) {
return 0;
}
setFMDataPointer(GetHistogramPointer(pMem, pCon), iTime, LOWER);
- pMem = (pHistMem) FindCommandData(pSics, "hm3", "HistMem");
+ pMem = (pHistMem) FindHM(pSics, "hm3");
if (pMem == NULL) {
return 0;
}
@@ -567,7 +570,7 @@ static int TOFLambda(SicsInterp * pSics, SConnection * pCon,
float fCenter, fFWHM, fStdDev, fVal;
float fMon, fData, distMonoDet, distFermiDet, tdiff, lambda;
- pMem = (pHistMem) FindCommandData(pSics, "hm1", "HistMem");
+ pMem = (pHistMem) FindHM(pSics, "hm1");
if (pMem == NULL) {
SCWrite(pCon,
"ERROR: need lower detector bank for lambda calculation",
@@ -650,7 +653,7 @@ static float calcElastic(SicsInterp * pSics, SConnection * pCon)
pHistMem pMem = NULL;
float fCenter, fFWHM, fStdDev, fVal;
- pMem = (pHistMem) FindCommandData(pSics, "hm2", "HistMem");
+ pMem = (pHistMem) FindHM(pSics, "hm2");
if (pMem == NULL) {
SCWrite(pCon,
"ERROR: need middle detector bank for elastic peak calculation",
diff --git a/fourlib.c b/fourlib.c
index 3ce972c2..7352bc0d 100644
--- a/fourlib.c
+++ b/fourlib.c
@@ -647,7 +647,7 @@ void z1FromNormalBeam(double lambda, double omega, double gamma,
/*--------------------------------------------------------------------*/
double circlify(double val)
{
- while (val > 360.) {
+ while (val >= 359.8) {
val -= 360.;
}
while (val < 0.) {
diff --git a/fourmess.c b/fourmess.c
index b6cb77b5..c497e21e 100644
--- a/fourmess.c
+++ b/fourmess.c
@@ -753,11 +753,11 @@ static int GenInconsumerate(pSICSOBJ self, SConnection * pCon,
{
double hkl[3], qvec[3];
pFourMess priv = self->pPrivate;
- int i, j;
+ int i, j, iGen = 0, startCount;
if (nPar < 3) {
SCWrite(pCon,
- "ERROR: need q displacement vector with three compononts",
+ "ERROR: need q displacement vector with three components",
eError);
return 0;
}
@@ -765,31 +765,32 @@ static int GenInconsumerate(pSICSOBJ self, SConnection * pCon,
qvec[1] = par[1]->value.v.doubleValue;
qvec[2] = par[2]->value.v.doubleValue;
- for (i = 0; i < priv->masterCount; i++) {
+ startCount = priv->masterCount;
+ for (i = 0; i < startCount; i++) {
GetRefIndex(priv->messList, i, hkl);
- if(ABS(hkl[0])+ABS(hkl[1])+ABS(hkl[2]) < .3){
- /*
- * Stop generation for 0,0,0,
- */
- continue;
- }
for (j = 0; j < 3; j++) {
hkl[j] += qvec[j];
}
AddRefIdx(priv->messList, hkl);
+ iGen++;
GetRefIndex(priv->messList, i, hkl);
for (j = 0; j < 3; j++) {
hkl[j] -= qvec[j];
}
- AddRefIdx(priv->messList, hkl);
+ if(FindHKL(priv->messList, hkl[0], hkl[1], hkl[2]) == NULL){
+ AddRefIdx(priv->messList, hkl);
+ iGen++;
+ }
if(SCGetInterrupt(pCon) != eContinue){
SCWrite(pCon,"ERROR: generating incommensurate reflections aborted", eError);
return 0;
}
+ if( (i % 50) == 0 ){
+ SCPrintf(pCon,eLog, "%d of %d input reflections processed", i, startCount);
+ }
}
SCPrintf(pCon, eValue,
- "%d additional inconsumerate reflections generated",
- priv->masterCount*2);
+ "%d additional inconsumerate reflections generated", iGen);
return 1;
}
diff --git a/frame.c b/frame.c
index bef62cba..09e06ea1 100644
--- a/frame.c
+++ b/frame.c
@@ -19,8 +19,8 @@
#include "HistMem.h"
#include "HistMem.i"
#include "HistDriv.i"
-#include "psi/hardsup/sinqhm.h"
-#include "psi/sinqhmdriv.i"
+#include "sicspsi/hardsup/sinqhm.h"
+#include "sicspsi/sinqhmdriv.i"
#include "nxdict.h"
#include "frame.h"
@@ -66,7 +66,7 @@ static int readHMFrame(SConnection * pCon, pHistMem pHM,
if (nFrame >= noTimeBins) {
nFrame = noTimeBins - 1;
}
- if (isSINQHMDriv(pHM->pDriv) && noTimeBins > 2) {
+ if (!isSecondGen(pHM) && isSINQHMDriv(pHM->pDriv) && noTimeBins > 2) {
/*
read from HM. The 5 is PROJECT__FRAME in Sinqhm_def.h
Again: be friendly: fix out of range frames
@@ -81,7 +81,7 @@ static int readHMFrame(SConnection * pCon, pHistMem pHM,
free(buffer);
return 0;
}
- } else if(isSINQHTTP(pHM->pDriv) && noTimeBins > 2){
+ } else if(!isSecondGen(pHM) && isSINQHTTP(pHM->pDriv) && noTimeBins > 2){
if(sansflag){
snprintf(histCommand,132,"sample:0:%d:%d:%d", iDim[0]*iDim[1], nFrame, nFrame+1);
} else {
@@ -244,7 +244,7 @@ int PSDFrameAction(SConnection * pCon, SicsInterp * pSics, void *pData,
eError);
return 0;
}
- pHM = (pHistMem) FindCommandData(pSics, argv[2], "HistMem");
+ pHM = (pHistMem) FindHM(pSics, argv[2]);
if (pHM == NULL) {
SCWrite(pCon, "ERROR: Did not find histogram memory", eError);
return 0;
diff --git a/hdbtable.c b/hdbtable.c
index abdc7efc..ca241960 100644
--- a/hdbtable.c
+++ b/hdbtable.c
@@ -17,6 +17,10 @@
* copyright: see file COPYRIGHT
*
* Mark Koennecke, March 2009
+ *
+ * Added CountTblCmd
+ *
+ * Mark Koennecke, march 2013
*/
#include
#include "sicshipadaba.h"
@@ -75,6 +79,20 @@ static int ClearTblCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
return 1;
}
/*----------------------------------------------------------------------*/
+int CountTblCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
+ pHdb par[], int nPar)
+{
+ pHdb node;
+ int nRows = 0;
+
+ node = GetHipadabaNode(self->objectNode,"data");
+ if(node != NULL){
+ nRows = CountHdbChildren(node);
+ }
+ SCPrintf(pCon,eValue,"rows = %d", nRows);
+ return 1;
+}
+/*----------------------------------------------------------------------*/
static int AddTblRowCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
pHdb par[], int nPar)
{
@@ -470,6 +488,9 @@ pSICSOBJ MakeHdbTable(char *name, char *hdbclass)
SetHdbProperty(node,"priv","user");
AddHipadabaChild(cmd,node, NULL);
+ cmd = AddSICSHdbPar(result->objectNode, "count", usSpy,
+ MakeSICSFunc(CountTblCmd));
+
return result;
}
/*---------------------------------------------------------------------------*/
diff --git a/hipadaba.c b/hipadaba.c
index 0dd1c186..0a08d520 100644
--- a/hipadaba.c
+++ b/hipadaba.c
@@ -10,6 +10,7 @@
#include
#include
#include
+#include
#include "hipadaba.h"
#define ABS(x) (x < 0 ? -(x) : (x))
@@ -21,6 +22,7 @@ static char update[] = { "update" };
static char treeChange[] = { "treeChange" };
static char dataSearch[] = { "dataSearch" };
static char killNode[] = { "killNode" };
+static char propertyChange[] = { "propertyChange" };
/*------------------------------------------------------------------------*/
pHdbDataMessage GetHdbSetMessage(pHdbMessage toTest)
@@ -76,6 +78,15 @@ pHdbMessage GetHdbKillNodeMessage(pHdbMessage toTest)
return NULL;
}
+/*-------------------------------------------------------------------------*/
+pHdbPropertyChange GetPropertyChangeMessage(pHdbMessage toTest)
+{
+ if (toTest->type == propertyChange) {
+ return (pHdbPropertyChange)toTest;
+ }
+ return NULL;
+}
+
/*================== internal functions ===================================*/
void DeleteCallbackChain(pHdb node)
{
@@ -305,6 +316,10 @@ static pHdb locateChild(pHdb root, char *name)
{
pHdb current = NULL;
+ if(root == NULL){
+ return NULL;
+ }
+
current = root->child;
while (current != NULL) {
if (strcmp(current->name, name) == 0) {
@@ -486,8 +501,57 @@ static unsigned short fletcher16( char *data, size_t len)
result = result << 8 | checkB;
return result ;
}
-/*------------------------------------------------------------------------*/
#define MAXLEN 65536
+/*------------------------------------------------------------------------*/
+static unsigned short longfletcher16(char *data, size_t len)
+{
+ char buffer[MAXLEN];
+ int i, j, div, count;
+ char *pPtr;
+
+ if(len < MAXLEN){
+ return fletcher16(data,len);
+ }
+
+ /**
+ * sum together to run the more complex checksum on
+ * more juicy data
+ */
+ div = (int)trunc((float)len/(float)MAXLEN);
+ for(i = 0; i < MAXLEN; i++){
+ pPtr = data + div*i;
+ for(j = 0; j < div; j++){
+ buffer[i] += *(pPtr + j);
+ }
+ }
+ return fletcher16(buffer,MAXLEN);
+}
+#define MAXLEN 65536
+/*------------------------------------------------------------------------*/
+static unsigned short longfletcher16(char *data, size_t len)
+{
+ char buffer[MAXLEN];
+ int i, j, div, count;
+ char *pPtr;
+
+ if(len < MAXLEN){
+ return fletcher16(data,len);
+ }
+
+ /**
+ * sum together to run the more complex checksum on
+ * more juicy data
+ */
+ div = (int)trunc((float)len/(float)MAXLEN);
+ for(i = 0; i < MAXLEN; i++){
+ pPtr = data + div*i;
+ for(j = 0; j < div; j++){
+ buffer[i] += *(pPtr + j);
+ }
+ }
+ return fletcher16(buffer,MAXLEN);
+}
+/*------------------------------------------------------------------------*/
unsigned short getHdbCheckSum(hdbValue *val)
{
char *data;
@@ -740,7 +804,6 @@ void AddHipadabaChild(pHdb parent, pHdb child, void *callData)
* step to end of child chain
*/
while (current != NULL) {
- assert(strcmp(current->name, child->name) != 0);
prev = current;
current = current->next;
}
@@ -933,12 +996,22 @@ static int canCopy(hdbValue * source, hdbValue * target)
return 1;
}
}
+ if(target->dataType == HIPINTAR &&
+ (source->dataType == HIPINTAR || source->dataType == HIPINTVARAR)
+ && target->arrayLength == source->arrayLength){
+ return 1;
+ }
if (target->dataType == HIPFLOATVARAR) {
if (source->dataType == HIPFLOATAR ||
source->dataType == HIPFLOATVARAR) {
return 1;
}
}
+ if(target->dataType == HIPFLOATAR &&
+ (source->dataType == HIPFLOATAR || source->dataType == HIPFLOATVARAR)
+ && target->arrayLength == source->arrayLength){
+ return 1;
+ }
if (source->dataType != target->dataType) {
return 0;
} else {
@@ -1106,6 +1179,8 @@ static int calcDataLength(pHdb node, int testLength)
/*============================= Property Functions ==========================*/
void SetHdbProperty(pHdb node, char *key, char *value)
{
+ hdbPropertyChange propMes;
+
if (node != NULL && key != NULL && node->properties != NULL) {
if (value == NULL) {
StringDictDelete(node->properties, key);
@@ -1114,6 +1189,10 @@ void SetHdbProperty(pHdb node, char *key, char *value)
} else {
StringDictAddPair(node->properties, key, value);
}
+ propMes.type = propertyChange;
+ propMes.key = key;
+ propMes.value = value;
+ InvokeCallbackChain(node,(pHdbMessage)&propMes);
}
}
diff --git a/hipadaba.h b/hipadaba.h
index 5d3d999c..d07488c8 100644
--- a/hipadaba.h
+++ b/hipadaba.h
@@ -1,4 +1,4 @@
-/** @file
+ /** @file
* Hipadaba is a hierarchical database of parameters. Parameters can be of
* various types. What happens when a parameter is being set, updated or read
* is largely determined through callbacks which can be registered on
@@ -26,6 +26,8 @@
* Added support for properties, Mark Koennecke, January 2007
*
* Refactored callback handling, Markus Zolliker, Mark Koennecke, March 2008
+ *
+ * Added property chnage events. Mark Koennecke, February 2015
*/
#ifndef HIPADABA
#define HIPADABA
@@ -72,11 +74,12 @@ typedef struct __hipadaba {
char *name;
char *path;
hdbValue value;
- int protected;
+ int iprotected;
pStringDict properties;
} Hdb, *pHdb;
/*-------------- return values for callback functions -------------------------*/
-typedef enum { hdbContinue,
+typedef enum {
+ hdbContinue,
hdbAbort,
hdbKill
} hdbCallbackReturn;
@@ -102,6 +105,12 @@ typedef struct {
void *result;
} hdbDataSearch, *pHdbDataSearch;
/*-------------------------------------------------------------------------------*/
+typedef struct {
+ char *type;
+ char *key;
+ char *value;
+} hdbPropertyChange, *pHdbPropertyChange;
+/*-------------------------------------------------------------------------------*/
typedef hdbCallbackReturn(*hdbCallbackFunction) (pHdb currentNode,
void *userData,
pHdbMessage message);
@@ -157,6 +166,14 @@ pHdbDataSearch GetHdbDataSearchMessage(pHdbMessage toTest);
* pointer if it is.
*/
pHdbMessage GetHdbKillNodeMessage(pHdbMessage toTest);
+/**
+ * Test a message if it is a property change message
+ * @param toTest The message to test.
+ * @return NULL if the message is no property chnage message or a message
+ * pointer if it is.
+ */
+pHdbPropertyChange GetPropertyChangeMessage(pHdbMessage toTest);
+
/*======================== Function protoypes: hdbData ========================*/
/**
* make a hdbValue with the given datatype and length
diff --git a/histmem.c b/histmem.c
index f6b91730..4e92896c 100644
--- a/histmem.c
+++ b/histmem.c
@@ -18,6 +18,10 @@
Mark Koennecke, March 2009
+ Added an error field in the options stringdict
+
+ Mark Koennecke, June 2013
+
Copyright:
Labor fuer Neutronenstreuung
@@ -70,6 +74,7 @@
#include "event.h"
#include "status.h"
#include "site.h"
+#include "histmemsec.h"
#define ABS(x) (x < 0 ? -(x) : (x))
/*
@@ -84,6 +89,27 @@ extern pHistDriver CreateRegressHM(pStringDict pOpt);
*/
extern pHistDriver MakeHMSlaveHM(pStringDict pOpt);
/*------------------------------------------------------------------------*/
+int isSecondGen(pHistMem self)
+{
+ pDummy test = (pDummy)self;
+ if(strcmp(test->pDescriptor->name,"HistMemSec") == 0) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+/*-----------------------------------------------------------------------*/
+pHistMem FindHM(SicsInterp *pSics, char *name)
+{
+ pHistMem result = NULL;
+
+ result = (pHistMem)FindCommandData(pSics,name,"HistMem");
+ if(result == NULL){
+ result = (pHistMem)FindCommandData(pSics,name,"HistMemSec");
+ }
+ return result;
+}
+/*------------------------------------------------------------------------*/
static int HistHalt(void *pData)
{
pHistMem self = NULL;
@@ -182,12 +208,13 @@ static int HistStartCount(void *pData, SConnection * pCon)
}
/* try at least three times to do it */
+ StringDictUpdate(self->pDriv->pOption, "error", "None");
for (i = 0; i < 3; i++) {
iRet = self->pDriv->Start(self->pDriv, pCon);
if (iRet == OKOK) {
/* send a COUNTSTART event */
+ clearHMData(self->pDriv->data);
InvokeCallBack(self->pCall, COUNTSTART, pCon);
- updateHMData(self->pDriv->data);
return iRet;
} else {
iRet = self->pDriv->GetError(self->pDriv, &iErr, pError, 79);
@@ -199,6 +226,7 @@ static int HistStartCount(void *pData, SConnection * pCon)
eLogError);
SCSetInterrupt(pCon, eAbortBatch);
ReleaseCountLock(self->pCountInt);
+ StringDictUpdate(self->pDriv->pOption, "error", pError);
return HWFault;
}
}
@@ -322,15 +350,16 @@ static int HistCountStatus(void *pData, SConnection * pCon)
SCSetInterrupt(pCon, eAbortBatch);
InvokeCallBack(self->pCall, COUNTEND, NULL);
ReleaseCountLock(self->pCountInt);
+ StringDictUpdate(self->pDriv->pOption, "error", pError);
return eCt;
} else {
updateHMData(self->pDriv->data);
return HWBusy;
}
}
- if (eCt == HWBusy){
- updateHMData(self->pDriv->data);
- }
+ /* if (eCt == HWBusy){ */
+ /* updateHMData(self->pDriv->data); */
+ /* } */
if (eCt == HWIdle) {
/* force an update of local histogram data with next
@@ -377,6 +406,7 @@ static int HistTransfer(void *pData, SConnection * pCon)
SCWrite(pCon, "ERROR: failed to fix histogram memory problem",
eError);
SCSetInterrupt(pCon, eAbortBatch);
+ StringDictUpdate(self->pDriv->pOption, "error", pError);
iStatus = HWFault;
}
}
@@ -443,6 +473,7 @@ pHistMem CreateHistMemory(char *driver)
}
StringDictAddPair(pOption, "driver", driver);
StringDictAddPair(pOption, "update", "0");
+ StringDictAddPair(pOption, "error", "None");
/* initialise driver */
if (strcmp(driver, "sim") == 0) {
@@ -715,6 +746,12 @@ long GetHistMonitor(pHistMem self, int i, SConnection * pCon)
void HistDirty(pHistMem self)
{
assert(self);
+
+ if(isSecondGen(self)){
+ SecHistDirty(self);
+ return;
+ }
+
if(self->pDriv != NULL){
updateHMData(self->pDriv->data);
}
@@ -724,6 +761,11 @@ void HistDirty(pHistMem self)
const float *GetHistTimeBin(pHistMem self, int *iLength)
{
assert(self);
+
+ if(isSecondGen(self)){
+ return GetSecHistTimeBin(self,iLength);
+ }
+
*iLength = getNoOfTimebins(self->pDriv->data);
return getTimeBinning(self->pDriv->data);
}
@@ -733,6 +775,10 @@ int GetHistLength(pHistMem self)
{
assert(self);
+ if(isSecondGen(self)){
+ return GetSecHistLength(self);
+ }
+
return getHMDataLength(self->pDriv->data);
}
@@ -827,6 +873,11 @@ int GetHistogram(pHistMem self, SConnection * pCon,
{
assert(self);
+ if(isSecondGen(self)){
+ return GetSecHistogram(self,pCon,i,iStart,iEnd,lData,iDataLen);
+ }
+
+
if (!self->iInit) {
SCWrite(pCon, "ERROR: histogram memory not initialised", eError);
return 0;
@@ -837,7 +888,7 @@ int GetHistogram(pHistMem self, SConnection * pCon,
eWarning);
iEnd = (iDataLen / sizeof(HistInt)) - 1;
}
- return getHMDataHistogram(self, pCon, i, iStart, iEnd, lData);
+ return getHMDataHistogram(self, pCon, i, iStart, iEnd-iStart, lData);
}
/*-------------------------------------------------------------------------*/
@@ -870,6 +921,7 @@ int GetHistogramDirect(pHistMem self, SConnection * pCon,
SCWrite(pCon, pBueffel, eError);
iRet = self->pDriv->TryAndFixIt(self->pDriv, iErr);
if (iRet == COTERM) {
+ StringDictUpdate(self->pDriv->pOption, "error", pError);
return 0;
}
}
@@ -883,6 +935,11 @@ HistInt *GetHistogramPointer(pHistMem self, SConnection * pCon)
{
assert(self);
+ if(isSecondGen(self)){
+ return GetSecHistogramPointer(self,pCon);
+ }
+
+
if (!self->iInit) {
SCWrite(pCon, "ERROR: histogram memory not initialised", eError);
return NULL;
@@ -916,6 +973,7 @@ int PresetHistogram(pHistMem self, SConnection * pCon, HistInt lVal)
SCWrite(pCon, pBueffel, eError);
iRet = self->pDriv->TryAndFixIt(self->pDriv, iErr);
if (iRet == COTERM) {
+ StringDictUpdate(self->pDriv->pOption, "error", pError);
return 0;
}
}
@@ -1185,7 +1243,7 @@ int HistAction(SConnection * pCon, SicsInterp * pSics, void *pData,
/* do it */
Arg2Text(argc - 3, &argv[3], pBueffel, 511);
/* authorise */
- if (!SCMatchRights(pCon, usUser)) { /* FIXME ffr stupid hack */
+ if (!SCMatchRights(pCon, usMugger)) {
snprintf(pBueffel,sizeof(pBueffel)-1,
"ERROR: you need to be manager in order to configure %s",
argv[0]);
@@ -1271,11 +1329,7 @@ int HistAction(SConnection * pCon, SicsInterp * pSics, void *pData,
}
} else if (strcmp(argv[1], "init") == 0) {
- if (GetStatus() != eEager) {
- SCWrite(pCon, "ERROR: cannot initialize HM while running", eError);
- return 0;
- }
- if (SCMatchRights(pCon, usUser)) { /* FIXME ffr stupid hack */
+ if (SCMatchRights(pCon, usMugger)) {
iRet = HistConfigure(self, pCon, pSics);
if (iRet) {
self->iInit = 1;
@@ -1288,6 +1342,22 @@ int HistAction(SConnection * pCon, SicsInterp * pSics, void *pData,
} else {
return 0;
}
+ } else if (strcmp(argv[1], "clearhm") == 0) {
+ /*
+ clear the local copy of the HM. Assumes that the HM
+ clears itself on start. Which it does.
+ */
+ if (SCMatchRights(pCon, usUser)) {
+ if(self->pDriv->data != NULL){
+ clearHMData(self->pDriv->data);
+ SCSendOK(pCon);
+ return 1;
+ } else {
+ return 0;
+ }
+ } else {
+ return 0;
+ }
} else if (strcmp(argv[1], "list") == 0) {
HMListOption(self, pCon);
return 1;
@@ -1301,14 +1371,6 @@ int HistAction(SConnection * pCon, SicsInterp * pSics, void *pData,
SCSendOK(pCon);
return 1;
}
- else if (strcmp(argv[1], "astop") == 0) {
- if (!SCMatchRights(pCon, usUser)) {
- return 0;
- }
- self->pDriv->Halt(self->pDriv);
- SCSendOK(pCon);
- return 1;
- }
/* pause */
else if (strcmp(argv[1], "pause") == 0) {
if (!SCMatchRights(pCon, usUser)) {
@@ -1318,6 +1380,16 @@ int HistAction(SConnection * pCon, SicsInterp * pSics, void *pData,
SCSendOK(pCon);
return 1;
}
+ /* state */
+ else if (strcmp(argv[1], "status") == 0) {
+ HistCountStatus(self,pCon);
+ if(isRunning(self->pCountInt)){
+ SCPrintf(pCon,eValue,"%s.status = run",argv[0]);
+ } else {
+ SCPrintf(pCon,eValue,"%s.status = idle",argv[0]);
+ }
+ return 1;
+ }
/* normal counting */
else if (strcmp(argv[1], "count") == 0) {
if (SCMatchRights(pCon, self->iAccess)) {
@@ -1725,6 +1797,12 @@ int HistAction(SConnection * pCon, SicsInterp * pSics, void *pData,
SCSendOK(pCon);
return 1;
}
+ /* error */
+ else if (strcmp(argv[1], "error") == 0) {
+ StringDictGet(self->pDriv->pOption, "error", pBueffel, sizeof(pBueffel));
+ SCPrintf(pCon,eValue,"%s.error = %s", argv[0], pBueffel);
+ return 1;
+ }
/*-------- sum */
else if (strcmp(argv[1], "sum") == 0) {
/* read following arguments as ints and put them
@@ -1759,4 +1837,5 @@ int HistAction(SConnection * pCon, SicsInterp * pSics, void *pData,
SCWrite(pCon, pBueffel, eError);
return 0;
}
+ return 0;
}
diff --git a/histmemsec.c b/histmemsec.c
index 053d82cf..248b57c2 100644
--- a/histmemsec.c
+++ b/histmemsec.c
@@ -10,10 +10,17 @@
* copyright: see file COPYRIGHT
*
* Mark Koennecke, May 2009
+ *
+ * Added bridging routines implementing first gen HM interfaces
+ *
+ * Mark Koennecke, December 2012
*/
#include
#include
#include
+#include "HistMem.h"
+#include "HistMem.i"
+#include "arrayutil.h"
#define CONFIG 1005
@@ -37,9 +44,11 @@ static int initArray(pCounter self, int value)
assert(datalength != NULL);
length = dim->value.v.intArray[0];
- for(i = 1; i < rank->value.v.intValue; i++){
+ for(i = 1; i < dim->value.arrayLength; i++){
length *= dim->value.v.intArray[i];
}
+ /* printf("initArray called with length %d\n", length);*/
+
v = MakeHdbInt(length);
UpdateHipadabaPar(datalength, v, NULL);
@@ -82,6 +91,45 @@ static int ResetCmd(pSICSOBJ ccmd, SConnection * pCon,
return 1;
}
/*--------------------------------------------------------------------------*/
+static int NoTimeBinCmd(pSICSOBJ ccmd, SConnection * pCon,
+ Hdb * cmdNode, Hdb * par[], int nPar)
+{
+ pHdb timeNode = NULL;
+
+ timeNode = GetHipadabaNode(ccmd->objectNode,"time_binning");
+ if(timeNode == NULL){
+ SCWrite(pCon,"ERROR: HM has no time binning",eError);
+ return 0;
+ }
+ SCPrintf(pCon,eValue,"%s.totimebin = %d", ccmd->objectNode->name,
+ timeNode->value.arrayLength);
+
+ return 1;
+}
+/*--------------------------------------------------------------------------*/
+static int TimebinsCmd(pSICSOBJ ccmd, SConnection * pCon,
+ Hdb * cmdNode, Hdb * par[], int nPar)
+{
+ pHdb timeNode = NULL;
+ pDynString data= NULL;
+
+ timeNode = GetHipadabaNode(ccmd->objectNode,"time_binning");
+ if(timeNode == NULL){
+ SCWrite(pCon,"ERROR: HM has no time binning",eError);
+ return 0;
+ }
+ data = formatValue(timeNode->value,timeNode);
+ if(data != NULL){
+ SCPrintf(pCon,eValue,"%s.timebins = %s", ccmd->objectNode->name,
+ GetCharArray(data));
+ DeleteDynString(data);
+ } else {
+ SCWrite(pCon,"ERROR: out of memory formatting timebins", eError);
+ return 0;
+ }
+ return 1;
+}
+/*--------------------------------------------------------------------------*/
static int GenbinCmd(pSICSOBJ ccmd, SConnection * pCon,
Hdb * cmdNode, Hdb * par[], int nPar)
{
@@ -124,6 +172,113 @@ static int GenbinCmd(pSICSOBJ ccmd, SConnection * pCon,
return 1;
}
/*--------------------------------------------------------------------------*/
+static int ConfigureCmd(pSICSOBJ ccmd, SConnection * pCon,
+ Hdb * cmdNode, Hdb * par[], int nPar)
+{
+ pHdb dimNode = NULL;
+
+ if(nPar < 1) {
+ SCWrite(pCon,"ERROR: need a parameter to read", eError);
+ return 0;
+ }
+ dimNode = GetHipadabaNode(ccmd->objectNode,"dim");
+
+ assert(dimNode != NULL);
+
+ if(strcmp(par[0]->value.v.text,"dim0") == 0){
+ SCPrintf(pCon,eValue,"%s.dim0 = %d", ccmd->objectNode->name,
+ dimNode->value.v.intArray[0]);
+ } else if(strcmp(par[0]->value.v.text,"dim1") == 0){
+ SCPrintf(pCon,eValue,"%s.dim1 = %d", ccmd->objectNode->name,
+ dimNode->value.v.intArray[1]);
+ } else {
+ SCPrintf(pCon,eError,"ERROR: subcommand %s to configure not found",
+ par[0]->value.v.text);
+ return 0;
+ }
+
+ return 1;
+}
+/*--------------------------------------------------------------------------*/
+static int SumCmd(pSICSOBJ ccmd, SConnection * pCon,
+ Hdb * cmdNode, Hdb * par[], int nPar)
+{
+ pHdb dimNode = NULL, dataNode = NULL;
+ int xstart, xend, ystart, yend, i;
+ long lSum = 0;
+
+ dimNode = GetHipadabaNode(ccmd->objectNode,"dim");
+ dataNode = GetHipadabaNode(ccmd->objectNode,"data");
+ assert(dimNode != NULL && dataNode != NULL);
+
+ switch(dimNode->value.arrayLength){
+ case 1:
+ if(nPar < 2) {
+ SCWrite(pCon,"ERROR: need start and end for summing 1D data",eError);
+ return 0;
+ }
+ xstart = par[0]->value.v.intValue;
+ xend = par[1]->value.v.intValue;
+ if(xstart < 0){
+ xstart = 0;
+ }
+ if(xend > dataNode->value.arrayLength){
+ xend = dataNode->value.arrayLength;
+ }
+ for(i = xstart; i < xend; i++){
+ lSum += dataNode->value.v.intArray[i];
+ }
+ SCPrintf(pCon,eValue,"%s.sum = %ld", ccmd->objectNode->name, lSum);
+ break;
+ case 2:
+ if(nPar < 4) {
+ SCWrite(pCon,"ERROR: need start and end in x and y for summing 2D data",eError);
+ return 0;
+ }
+ xstart = par[0]->value.v.intValue;
+ xend = par[1]->value.v.intValue;
+ if(xstart < 0){
+ xstart = 0;
+ }
+ if(xend > dimNode->value.v.intArray[0]){
+ xend = dimNode->value.v.intArray[0];
+ }
+ ystart = par[2]->value.v.intValue;
+ yend = par[3]->value.v.intValue;
+ if(ystart < 0){
+ ystart = 0;
+ }
+ if(yend > dimNode->value.v.intArray[1]){
+ yend = dimNode->value.v.intArray[1];
+ }
+ lSum = sumWindow(dataNode->value.v.intArray, xstart,xend,dimNode->value.v.intArray[0],
+ ystart, yend, dimNode->value.v.intArray[1]);
+ SCPrintf(pCon,eValue,"%s.sum = %ld", ccmd->objectNode->name, lSum);
+ break;
+ default:
+ SCPrintf(pCon, eError, "ERROR: summing not supported for %d dimensional data",
+ dimNode->value.arrayLength);
+ return 0;
+ }
+ return 1;
+}
+/*-------------------------------------------------------------------------*/
+static int TotalCmd(pSICSOBJ ccmd, SConnection * pCon,
+ Hdb * cmdNode, Hdb * par[], int nPar)
+{
+ pHdb dataNode = NULL;
+ long lSum = 0;
+ int i;
+
+ dataNode = GetHipadabaNode(ccmd->objectNode,"data");
+ assert(dataNode != NULL);
+ for(i = 0, lSum = 0; i < dataNode->value.arrayLength; i++){
+ lSum += dataNode->value.v.intArray[i];
+ }
+ SCPrintf(pCon,eValue,"%s.total = %ld", ccmd->objectNode->name, lSum);
+ return 1;
+}
+/*--------------------------------------------------------------------------*/
static int InitCmd(pSICSOBJ ccmd, SConnection * con,
Hdb * cmdNode, Hdb * par[], int nPar)
{
@@ -189,6 +344,15 @@ int MakeSecHM(SConnection * pCon, SicsInterp * pSics, void *pData,
if(pRes == NULL){
return 0;
}
+ /*
+ remove count and rename countnb to it
+ */
+ node = GetHipadabaNode(pRes->pDes->parNode,"count");
+ DeleteHipadabaNode(node,NULL);
+ node = GetHipadabaNode(pRes->pDes->parNode,"countnb");
+ strcpy(node->name,"count");
+
+
pRes->pCountInt->TransferData = HMCtrTransferData;
node = pRes->objectNode;
@@ -197,13 +361,13 @@ int MakeSecHM(SConnection * pCon, SicsInterp * pSics, void *pData,
DeleteHipadabaNode(child,pCon);
}
- child = MakeSICSHdbPar("rank", usInternal, MakeHdbInt(rank));
+ child = MakeSICSHdbPar("rank", usMugger, MakeHdbInt(rank));
if (child == NULL) {
return 0;
}
AddHipadabaChild(node, child, NULL);
- child = MakeSICSHdbPar("dim", usMugger, makeHdbValue(HIPINTAR,rank));
+ child = MakeSICSHdbPar("dim", usMugger, makeHdbValue(HIPINTVARAR,rank));
if (child == NULL) {
return 0;
}
@@ -228,24 +392,36 @@ int MakeSecHM(SConnection * pCon, SicsInterp * pSics, void *pData,
child = AddSICSHdbPar(node,"init", usMugger, MakeSICSFunc(InitCmd));
+ child = AddSICSHdbPar(node,"sum", usSpy, MakeSICSFunc(SumCmd));
+ AddSICSHdbPar(child, "xstart", usSpy, MakeHdbInt(0));
+ AddSICSHdbPar(child, "xend", usSpy, MakeHdbInt(0));
+ AddSICSHdbPar(child, "ystart", usSpy, MakeHdbInt(0));
+ AddSICSHdbPar(child, "yend", usSpy, MakeHdbInt(0));
+
+ child = AddSICSHdbPar(node,"total", usSpy, MakeSICSFunc(TotalCmd));
+
/*
* test TOF option
*/
if(argc > 3){
- if(strcmp(argv[3],"tof") == 0){
- child = MakeSICSHdbPar("time_binning", usMugger, makeHdbValue(HIPFLOATVARAR,100));
- if (child == NULL) {
- return 0;
- }
- AddHipadabaChild(node, child, NULL);
- AppendHipadabaCallback(child,
- MakeHipadabaCallback(HMTOFCallback, NULL, NULL));
+ if(strcmp(argv[3],"tof") == 0){
+ child = MakeSICSHdbPar("time_binning", usMugger, makeHdbValue(HIPFLOATVARAR,100));
+ if (child == NULL) {
+ return 0;
+ }
+ AddHipadabaChild(node, child, NULL);
+ AppendHipadabaCallback(child,
+ MakeHipadabaCallback(HMTOFCallback, NULL, NULL));
- child = AddSICSHdbPar(node,"genbin", usMugger, MakeSICSFunc(GenbinCmd));
- AddSICSHdbPar(child, "start", usMugger, MakeHdbFloat(10.));
- AddSICSHdbPar(child, "step", usMugger, MakeHdbFloat(10.));
- AddSICSHdbPar(child, "np", usMugger, MakeHdbInt(10));
- }
+ child = AddSICSHdbPar(node,"genbin", usMugger, MakeSICSFunc(GenbinCmd));
+ AddSICSHdbPar(child, "start", usMugger, MakeHdbFloat(10.));
+ AddSICSHdbPar(child, "step", usMugger, MakeHdbFloat(10.));
+ AddSICSHdbPar(child, "np", usMugger, MakeHdbInt(10));
+
+ child = AddSICSHdbPar(node,"notimebin", usSpy, MakeSICSFunc(NoTimeBinCmd));
+ child = AddSICSHdbPar(node,"timebins", usSpy, MakeSICSFunc(TimebinsCmd));
+
+ }
}
status =
@@ -257,3 +433,99 @@ int MakeSecHM(SConnection * pCon, SicsInterp * pSics, void *pData,
}
return 1;
}
+/*===========================================================================
+ This is a set of adapter functions which make the second gen HM look like
+ a first generation one. This saves me from rewriting all the calculation codes
+ based on the first gen HM
+
+ !!!! BEWARE: In the functions below pHistMem should never be a pointer to a
+ HistMem but rather a second generation HM which is a counter object !!!!
+ ===============================================================================*/
+const float *GetSecHistTimeBin(pHistMem self, int *iLength)
+{
+ float *tb = NULL;
+ pHdb tbNode = NULL;
+ int i;
+ pCounter pCter;
+
+ assert(self->pDes->parNode != NULL);
+
+ pCter = (pCounter)self;
+ tbNode = GetHipadabaNode(self->pDes->parNode,"time_binning");
+ if(tbNode == NULL){
+ return NULL;
+ }
+ *iLength = tbNode->value.arrayLength;
+ if(*iLength != pCter->tbLength){
+ if(pCter->timeBinning){
+ free(pCter->timeBinning);
+ }
+ pCter->timeBinning = malloc(*iLength*sizeof(float));
+ }
+
+ for(i = 0; i < *iLength; i++){
+ pCter->timeBinning[i] = tbNode->value.v.floatArray[i];
+ }
+
+ return (const float*)pCter->timeBinning;
+}
+/*---------------------------------------------------------------------------*/
+HistInt *GetSecHistogramPointer(pHistMem self,SConnection *pCon)
+{
+ pHdb dataNode = NULL;
+
+ assert(self->pDes->parNode != NULL);
+
+ dataNode = GetHipadabaNode(self->pDes->parNode,"data");
+ if(dataNode == NULL){
+ return NULL;
+ }
+ return (HistInt *)dataNode->value.v.intArray;
+}
+/*--------------------------------------------------------------------------*/
+int GetSecHistogram(pHistMem self, SConnection *pCon,
+ int i,int iStart, int iEnd, HistInt *lData, int iDataLen)
+{
+ pHdb dataNode = NULL;
+
+ assert(self->pDes->parNode != NULL);
+
+ dataNode = GetHipadabaNode(self->pDes->parNode,"data");
+ if(dataNode == NULL){
+ return 0;
+ }
+ if(iEnd > dataNode->value.arrayLength){
+ iEnd = dataNode->value.arrayLength;
+ }
+ if ((iEnd - iStart) > iDataLen / sizeof(HistInt)) {
+ SCWrite(pCon, "WARNING: truncating request to fit data space",
+ eWarning);
+ iEnd = (iDataLen / sizeof(HistInt)) - 1;
+ }
+ memcpy(lData,dataNode->value.v.intArray+iStart, (iEnd-iStart)*sizeof(int));
+
+ return 1;
+}
+/*-------------------------------------------------------------------------*/
+void SecHistDirty(pHistMem self)
+{
+ /* Nothing to do */
+}
+/*-------------------------------------------------------------------------*/
+int GetSecHistLength(pHistMem self)
+{
+ pHdb dataNode = NULL;
+ int i, length = 1;
+
+ assert(self->pDes->parNode != NULL);
+
+ dataNode = GetHipadabaNode(self->pDes->parNode,"dim");
+ if(dataNode == NULL){
+ return 0;
+ }
+ for(i = 0; i < dataNode->value.arrayLength; i++){
+ length *= dataNode->value.v.intArray[i];
+ }
+
+ return length;
+}
diff --git a/histmemsec.h b/histmemsec.h
index b0b244fe..486011ac 100644
--- a/histmemsec.h
+++ b/histmemsec.h
@@ -17,4 +17,12 @@
int MakeSecHM(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[]);
+const float *GetSecHistTimeBin(pHistMem self, int *iLength);
+HistInt *GetSecHistogramPointer(pHistMem self,SConnection *pCon);
+int GetSecHistogram(pHistMem self, SConnection *pCon,
+ int i,int iStart, int iEnd, HistInt *lData, int iDataLen);
+void SecHistDirty(pHistMem self);
+int GetSecHistLength(pHistMem self);
+
+
#endif /*HISTMEMSEC_H_*/
diff --git a/histogram.tex b/histogram.tex
index 564af499..e9abcd5f 100644
--- a/histogram.tex
+++ b/histogram.tex
@@ -443,6 +443,9 @@ $\langle$Protos {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ int HistBlockCount(pHistMem self, SConnection *pCon);@\\
\mbox{}\verb@ void HistDirty(pHistMem self); @\\
\mbox{}\verb@@\\
+\mbox{}\verb@ int isSecondGen(pHistMem self);@\\
+\mbox{}\verb@ pHistMem FindHM(SicsInterp *pSics, char *name);@\\
+\mbox{}\verb@@\\
\mbox{}\verb@@$\Diamond$
\end{list}
\vspace{-1ex}
diff --git a/histogram.w b/histogram.w
index a5bed0e9..43b7123e 100644
--- a/histogram.w
+++ b/histogram.w
@@ -347,6 +347,9 @@ controlled by the following functions:
int HistBlockCount(pHistMem self, SConnection *pCon);
void HistDirty(pHistMem self);
+ int isSecondGen(pHistMem self);
+ pHistMem FindHM(SicsInterp *pSics, char *name);
+
@}
The first four functions are simple parameter enquiry and manipulation
functions. GetHistMonitor returns the count on monitor number i for the
diff --git a/histsim.c b/histsim.c
index 1813b584..3fa3e114 100644
--- a/histsim.c
+++ b/histsim.c
@@ -77,6 +77,7 @@ static int SimConfig(pHistDriver self, SConnection * pCon,
self->pPriv = NewSIMCounter("HistoSim", fFail);
}
+
/*
configured test value
*/
diff --git a/hkl.c b/hkl.c
index b4030f8b..f5c3cb41 100644
--- a/hkl.c
+++ b/hkl.c
@@ -26,6 +26,10 @@
Heavily reworked to fit into the new four circle setup
Mark Koennecke, July 2008
+
+ Added calculation of angles between reflection
+
+ Mark Koennecke, March 2013
-----------------------------------------------------------------------------*/
#include
#include
@@ -687,6 +691,47 @@ static int HKLCalculateTheta(pHKL self, float fHKL[3], double *stt)
*stt = 2. * theta;
return status;
}
+/*-------------------------------------------------------------------------*/
+static int HKLAngle(SConnection *pCon, int argc, char *argv[])
+{
+ reflection r1, r2;
+ lattice direct;
+ const double *cell;
+ MATRIX B;
+ double ang;
+
+ if(argc < 8){
+ SCWrite(pCon,"ERROR: insufficient no of arguments to hkl angle",eError);
+ return 0;
+ }
+ r1.h = atof(argv[2]);
+ r1.k = atof(argv[3]);
+ r1.l = atof(argv[4]);
+
+ r2.h = atof(argv[5]);
+ r2.k = atof(argv[6]);
+ r2.l = atof(argv[7]);
+
+ cell = SXGetCell();
+ direct.a = cell[0];
+ direct.b = cell[1];
+ direct.c = cell[2];
+ direct.alpha = cell[3];
+ direct.beta = cell[4];
+ direct.gamma = cell[5];
+
+ B = mat_creat(3,3,ZERO_MATRIX);
+ if(B == NULL){
+ SCWrite(pCon,"ERROR: out of memory in HKL angle",eError);
+ return 0;
+ }
+
+ calculateBMatrix(direct,B);
+ ang = angleBetweenReflections(B,r1,r2);
+ SCPrintf(pCon,eValue,"angle = %f", ang);
+ mat_free(B);
+ return 1;
+}
/*--------------------------------------------------------------------------*/
static int HandleBiToNB(SConnection *pCon, int argc, char *argv[])
{
@@ -993,6 +1038,10 @@ int HKLAction(SConnection * pCon, SicsInterp * pSics, void *pData,
SCPrintf(pCon, eValue, "two-theta = %lf", stt);
return 1;
}
+ /*--------------- calculate angle */
+ else if (strcmp(argv[1], "angle") == 0) {
+ return HKLAngle(pCon,argc,argv);
+ }
/*------------------ run */
else if (strcmp(argv[1], "run") == 0) {
if (!SCMatchRights(pCon, usUser)) {
diff --git a/hmcontrol.c b/hmcontrol.c
index aed00d55..dd0e22fe 100644
--- a/hmcontrol.c
+++ b/hmcontrol.c
@@ -126,6 +126,9 @@ static int HMCStatus(void *pData, SConnection * pCon)
assert(self);
if(self->checkSlaves == 0) {
+ /*
+ check master
+ */
status = self->slaves[0]->CheckCountStatus(self->slaveData[0], pCon);
/*
Warning: this assumes that slaves 1 - MAXSLAVE are histogram memories.
@@ -194,7 +197,7 @@ static int HMCBoaStatus(void *pData, SConnection * pCon)
HMCHalt(self);
ReleaseCountLock(self->pCount);
self->checkSlaves = 0;
- for(j = 0; j < 100; j++){
+ for(j = 0; j < 200; j++){
SicsWait(1);
status = self->slaves[i]->CheckCountStatus(self->slaveData[i], pCon);
if(status == HWIdle || status == HWFault) {
diff --git a/hmdata.c b/hmdata.c
index cc801e8c..5584d910 100644
--- a/hmdata.c
+++ b/hmdata.c
@@ -58,7 +58,10 @@ void clearHMData(pHMdata self)
if (self->tofMode) {
size *= getNoOfTimebins(self);
}
- memset(self->localBuffer, 0, size * sizeof(HistInt));
+ if(self->localBuffer != NULL){
+ memset(self->localBuffer, 0, size * sizeof(HistInt));
+ }
+ self->nextUpdate = time(NULL) + self->updateIntervall;
}
/*----------------------------------------------------------------------*/
@@ -145,18 +148,10 @@ int configureHMdata(pHMdata self, pStringDict pOpt, SConnection * pCon)
self->localBuffer = NULL;
}
- /*
- note: remove update request in histmem.c
- */
- if (self->updateIntervall > 0) {
- /*
- we do buffer
- */
- status = resizeBuffer(self);
- if (!status) {
- SCWrite(pCon, "ERROR: failed to resize buffer", eError);
- return 0;
- }
+ status = resizeBuffer(self);
+ if (!status) {
+ SCWrite(pCon, "ERROR: failed to resize buffer", eError);
+ return 0;
}
return 1;
}
@@ -313,7 +308,7 @@ static int updateHMbuffer(pHistMem hist, int bank, SConnection * pCon)
}
if (status == OKOK) {
return 1;
- } else {
+ } else {
return HWFault;
}
}
@@ -541,7 +536,7 @@ static pNXDS hmDataToNXDataset(pHMdata self)
if (isInTOFMode(self)) {
result->rank++;
}
- result->dim = malloc(self->rank * sizeof(int));
+ result->dim = malloc(self->rank * sizeof(int64_t));
if (result->dim == NULL) {
free(result);
return NULL;
diff --git a/initializer.c b/initializer.c
index 9d47ed99..f64e53d8 100644
--- a/initializer.c
+++ b/initializer.c
@@ -79,6 +79,7 @@ static int MakeObject(SConnection * con, SicsInterp * sics,
return 0;
}
+/* missing check for user (manager?) privilege */
cmdin = (CmdInitializer) GetInitializer("Object", argv[2]);
if (cmdin) {
return cmdin(con, argc, argv, strcasecmp(argv[0], "makeobject") == 0);
@@ -141,6 +142,7 @@ static int RemoveObject(SConnection * con, SicsInterp * sics,
return 0;
}
+/* missing check for user (manager?) privilege */
desc = FindCommandDescriptor(sics, argv[1]);
if (!desc) {
SCPrintf(con, eError, "ERROR: %s not found", argv[1]);
diff --git a/interface.c b/interface.c
index c0f8ebf2..d661b2c3 100644
--- a/interface.c
+++ b/interface.c
@@ -1,4 +1,4 @@
-/*--------------------------------------------------------------------------
+ /*--------------------------------------------------------------------------
I N T E R F A C E
@@ -12,6 +12,11 @@
Paul Scherrer Institut
CH-5423 Villigen-PSI
+ Extended over time with utility functions
+
+ Added Drivable and Countable task functions
+
+ Mark Koennecke, February 2013
The authors hereby grant permission to use, copy, modify, distribute,
and license this software and its documentation for any purpose, provided
@@ -42,6 +47,7 @@
#include "fortify.h"
#include "sics.h"
#include "motor.h"
+#include
/*=========================================================================
Empty driveable interface functions
==========================================================================*/
@@ -168,7 +174,118 @@ int GetDrivablePosition(void *pObject, SConnection * pCon, float *fPos)
*fPos = value;
return 1;
}
+/*--------------------------------------------------------------------------*/
+typedef struct {
+ int id;
+ void *obj;
+ pIDrivable pDriv;
+ SConnection *pCon;
+ char *name;
+}DriveTaskData;
+/*-------------------------------------------------------------------------*/
+static void KillDriveTaskData(void *data)
+{
+ DriveTaskData *taskData = (DriveTaskData *)data;
+ if(taskData == NULL){
+ return;
+ }
+ if(taskData->name != NULL){
+ free(taskData->name);
+ }
+ if(taskData->pCon != NULL){
+ SCDeleteConnection(taskData->pCon);
+ }
+ free(taskData);
+}
+/*-------------------------------------------------------------------------*/
+static void DriveTaskSignal(void *data, int iSignal, void *pSigData)
+{
+ DriveTaskData *taskData = (DriveTaskData *)data;
+ int *interrupt;
+
+ assert(taskData != NULL);
+
+ if(iSignal == SICSINT){
+ interrupt = (int *)pSigData;
+ if(*interrupt != eContinue){
+ SCPrintf(taskData->pCon,eLogError,"ERROR: Interrupting %s", taskData->name);
+ taskData->pDriv->Halt(taskData->obj);
+ SCSetInterrupt(taskData->pCon,*interrupt);
+ }
+ }
+}
+/*--------------------------------------------------------------------------*/
+static int DriveTaskFunc(void *data)
+{
+ DriveTaskData *taskData = (DriveTaskData *)data;
+ int status;
+
+ assert(taskData != NULL);
+
+
+ status = taskData->pDriv->CheckStatus(taskData->obj,taskData->pCon);
+ if(status == HWBusy){
+ return 1;
+ }
+ if(status == HWFault){
+ taskData->pDriv->iErrorCount++;
+ }
+ if(status == HWFault || status == HWPosFault){
+ SetDevexecStatus(pServ->pExecutor,DEVERROR);
+ }
+ DevexecLog("STOP",taskData->name);
+ if(status == HWIdle || status == OKOK){
+ ExeInterest(pServ->pExecutor,taskData->name, "finished");
+
+ } else {
+ ExeInterest(pServ->pExecutor,taskData->name, "finished with problem");
+ }
+ traceSys("drive","DriveTask %s finished with state %d", taskData->name,status);
+ return 0;
+}
+/*--------------------------------------------------------------------------*/
+long StartDriveTask(void *obj, SConnection *pCon, char *name, float fTarget)
+{
+ pIDrivable pDriv = NULL;
+ char error[132], buffer[132];
+ DriveTaskData *taskData = NULL;
+
+ pDriv = GetDrivableInterface(obj);
+ if(pDriv == NULL){
+ SCPrintf(pCon,eError,"ERROR: %s is not drivable", name);
+ return -1;
+ }
+ if(pDriv->CheckLimits(obj,fTarget,error,sizeof(error)) != OKOK){
+ SCPrintf(pCon,eError,"ERROR: %s cannot reach %f, reason %s", name,
+ fTarget, error);
+ return -1;
+ }
+ taskData = calloc(1,sizeof(DriveTaskData));
+ if(taskData == NULL){
+ SCPrintf(pCon,eError,"ERROR: out of memory starting %s", name);
+ return -1;
+ }
+ if(pDriv->SetValue(obj,pCon,fTarget) != OKOK){
+ return -1;
+ }
+ ExeInterest(pServ->pExecutor,name,"started");
+ DevexecLog("START",name);
+ InvokeNewTarget(pServ->pExecutor,name,fTarget);
+
+ taskData->id = DRIVEID;
+ taskData->obj = obj;
+ taskData->pDriv = pDriv;
+ taskData->pCon = SCCopyConnection(pCon);
+ taskData->name = strdup(name);
+
+ return TaskRegisterN(pServ->pTasker,
+ name,
+ DriveTaskFunc,
+ DriveTaskSignal,
+ KillDriveTaskData,
+ taskData,0);
+}
/*--------------------------------------------------------------------------*/
pICountable GetCountableInterface(void *pObject)
{
@@ -201,6 +318,120 @@ int isRunning(pICountable self)
{
return self->running;
}
+/*--------------------------------------------------------------------------*/
+typedef struct {
+ int id;
+ void *obj;
+ pICountable pCount;
+ SConnection *pCon;
+ char *name;
+}CountTaskData;
+/*-------------------------------------------------------------------------*/
+static void KillCountTaskData(void *data)
+{
+ CountTaskData *taskData = (CountTaskData *)data;
+
+ if(taskData == NULL){
+ return;
+ }
+ if(taskData->name != NULL){
+ free(taskData->name);
+ }
+ if(taskData->pCon != NULL){
+ SCDeleteConnection(taskData->pCon);
+ }
+ free(taskData);
+}
+/*-------------------------------------------------------------------------*/
+static void CountTaskSignal(void *data, int iSignal, void *pSigData)
+{
+ CountTaskData *taskData = (CountTaskData *)data;
+ int *interrupt;
+
+ assert(taskData != NULL);
+
+ if(iSignal == SICSINT){
+ interrupt = (int *)pSigData;
+ if(*interrupt != eContinue){
+ SCPrintf(taskData->pCon,eLogError,"ERROR: Interrupting %s", taskData->name);
+ taskData->pCount->Halt(taskData->obj);
+ SCSetInterrupt(taskData->pCon,*interrupt);
+ }
+ } else if(iSignal == IPAUSE){
+ taskData->pCount->Pause(taskData->obj,taskData->pCon);
+ } else if(iSignal == CONTINUE){
+ taskData->pCount->Continue(taskData->obj,taskData->pCon);
+ }
+}
+/*--------------------------------------------------------------------------*/
+static int CountTaskFunc(void *data)
+{
+ CountTaskData *taskData = (CountTaskData *)data;
+ int status;
+
+ assert(taskData != NULL);
+
+ status = taskData->pCount->CheckCountStatus(taskData->obj,taskData->pCon);
+ if(status == HWBusy) {
+ return 1;
+ } else if(status == HWNoBeam){
+ return 1;
+ } else if(status == HWPause){
+ return 1;
+ }
+
+ taskData->pCount->TransferData(taskData->obj, taskData->pCon);
+
+ if(status == HWFault){
+ SetDevexecStatus(pServ->pExecutor,DEVERROR);
+ }
+
+ DevexecLog("STOP",taskData->name);
+ if(status == HWIdle || status == OKOK){
+ ExeInterest(pServ->pExecutor,taskData->name, "finished");
+ } else {
+ ExeInterest(pServ->pExecutor,taskData->name, "finished with problem");
+ }
+ traceSys("count","CountTask %s finished with state %d", taskData->name,status);
+ return 0;
+}
+/*--------------------------------------------------------------------------*/
+long StartCountTask(void *obj, SConnection *pCon, char *name)
+{
+ pICountable pCount = NULL;
+ char error[132], buffer[132];
+ CountTaskData *taskData = NULL;
+
+ pCount = FindInterface(obj,COUNTID);
+ if(pCount == NULL){
+ SCPrintf(pCon,eError,"ERROR: %s is not countable", name);
+ return 1;
+ }
+ taskData = calloc(1,sizeof(CountTaskData));
+ if(taskData == NULL){
+ SCPrintf(pCon,eError,"ERROR: out of memory starting %s", name);
+ return -1;
+ }
+ if(pCount->StartCount(obj,pCon) != OKOK){
+ pCount->running = 0;
+ return -1;
+ }
+ ExeInterest(pServ->pExecutor,name,"started");
+ DevexecLog("START",name);
+
+ taskData->id = COUNTID;
+ taskData->obj = obj;
+ taskData->pCount = pCount;
+ taskData->pCon = SCCopyConnection(pCon);
+ taskData->name = strdup(name);
+
+ return TaskRegisterN(pServ->pTasker,
+ name,
+ CountTaskFunc,
+ CountTaskSignal,
+ KillCountTaskData,
+ taskData,0);
+}
/*--------------------------------------------------------------------------*/
pICallBack GetCallbackInterface(void *pObject)
diff --git a/interface.h b/interface.h
index c5375600..4f292471 100644
--- a/interface.h
+++ b/interface.h
@@ -1,5 +1,5 @@
-#line 399 "interface.w"
+#line 412 "interface.w"
/*---------------------------------------------------------------------------
I N T E R F A C E S
@@ -30,108 +30,114 @@
#line 121 "interface.w"
-typedef struct {
- int ID;
- int (*Halt) (void *self);
- int (*CheckLimits) (void *self, float fVal, char *error, int iErrLen);
- long (*SetValue) (void *self, SConnection * pCon, float fVal);
- int (*CheckStatus) (void *self, SConnection * pCon);
- float (*GetValue) (void *self, SConnection * pCon);
- int iErrorCount;
- int drivableStatus;
-} IDrivable, *pIDrivable;
+ typedef struct {
+ int ID;
+ int (*Halt)(void *self);
+ int (*CheckLimits)(void *self, float fVal,
+ char *error, int iErrLen);
+ long (*SetValue)(void *self, SConnection *pCon,
+ float fVal);
+ int (*CheckStatus)(void *self, SConnection *pCon);
+ float (*GetValue)(void *self, SConnection *pCon);
+ int iErrorCount;
+ int drivableStatus;
+ } IDrivable, *pIDrivable;
-pIDrivable GetDrivableInterface(void *pObject);
-int GetDrivablePosition(void *pObject, SConnection * pCon, float *fPos);
+ pIDrivable GetDrivableInterface(void *pObject);
+ int GetDrivablePosition(void *pObject, SConnection *pCon,
+ float *fPos);
+ long StartDriveTask(void *self, SConnection *pCon, char *name, float fTarget);
-#line 425 "interface.w"
-
-
-pIDrivable CreateDrivableInterface(void);
-
-/* ------------------------ The countable interface ---------------------*/
-
-#line 188 "interface.w"
-
-typedef struct {
- int ID;
- int running;
- int (*Halt) (void *self);
- void (*SetCountParameters) (void *self, float fPreset,
- CounterMode eMode);
- int (*StartCount) (void *self, SConnection * pCon);
- int (*CheckCountStatus) (void *self, SConnection * pCon);
- int (*Pause) (void *self, SConnection * pCon);
- int (*Continue) (void *self, SConnection * pCon);
- int (*TransferData) (void *self, SConnection * pCon);
-} ICountable, *pICountable;
-
-pICountable GetCountableInterface(void *pObject);
-int GetCountLock(pICountable self, SConnection * pCon);
-void ReleaseCountLock(pICountable self);
-int isRunning(pICountable self);
-
-#line 430 "interface.w"
-
-
-pICountable CreateCountableInterface(void);
-
-/* ------------------------- The CallBack Interface --------------------*/
-
-#line 253 "interface.w"
-
-typedef void (*KillFuncIT) (void *pData);
-typedef int (*SICSCallBack) (int iEvent, void *pEventData,
- void *pUserData);
-
-#line 435 "interface.w"
-
-
-#line 275 "interface.w"
-
-typedef struct __ICallBack *pICallBack;
-
- /* event source side */
-pICallBack CreateCallBackInterface(void);
-void DeleteCallBackInterface(pICallBack self);
-int InvokeCallBack(pICallBack pInterface, int iEvent, void *pEventData);
-
- /* callback client side */
-long RegisterCallback(pICallBack pInterface,
- int iEvent, SICSCallBack pFunc,
- void *pUserData, KillFuncIT pKill);
-int RemoveCallback(pICallBack pInterface, long iID);
-int RemoveCallback2(pICallBack pInterface, void *pUserData);
-int RemoveCallbackUsr(pICallBack self, SICSCallBack pFunc, int (*userfunc)(const void* pContext, const void* pUserData), void *pCtx);
-int RemoveCallbackCon(pICallBack pInterface, SConnection * pCon);
-
-int CallbackScript(SConnection * pCon, SicsInterp * pSics, void *pData,
- int argc, char *argv[]);
-
-pICallBack GetCallbackInterface(void *pData);
-
-#line 436 "interface.w"
-
-/*---------------------- The Environment Interface --------------------*/
-
-#line 353 "interface.w"
-
-typedef enum { EVIdle, EVDrive, EVMonitor, EVError } EVMode;
-typedef struct {
- int iID;
- EVMode(*GetMode) (void *self);
- int (*IsInTolerance) (void *self);
- int (*HandleError) (void *self);
-} EVInterface, *pEVInterface;
#line 438 "interface.w"
-#line 379 "interface.w"
+ pIDrivable CreateDrivableInterface(void);
-pEVInterface CreateEVInterface(void);
+/* ------------------------ The countable interface ---------------------*/
-#line 439 "interface.w"
+#line 195 "interface.w"
+
+ typedef struct {
+ int ID;
+ int running;
+ int (*Halt)(void *self);
+ void (*SetCountParameters)(void *self, float fPreset,
+ CounterMode eMode);\
+ int (*StartCount)(void *self, SConnection *pCon);
+ int (*CheckCountStatus)(void *self, SConnection *pCon);
+ int (*Pause)(void *self, SConnection *pCon);
+ int (*Continue)(void *self, SConnection *pCon);
+ int (*TransferData)(void *self, SConnection *pCon);
+ } ICountable, *pICountable;
+
+ pICountable GetCountableInterface(void *pObject);
+ int GetCountLock(pICountable self, SConnection *pCon);
+ void ReleaseCountLock(pICountable self);
+ int isRunning(pICountable self);
+ long StartCountTask(void *self, SConnection *pCon, char *name);
+
+#line 443 "interface.w"
+
+
+ pICountable CreateCountableInterface(void);
+
+/* ------------------------- The CallBack Interface --------------------*/
+
+#line 266 "interface.w"
+
+ typedef void (*KillFuncIT)(void *pData);
+ typedef int (*SICSCallBack)(int iEvent, void *pEventData,
+ void *pUserData);
+
+#line 448 "interface.w"
+
+
+#line 288 "interface.w"
+
+ typedef struct __ICallBack *pICallBack;
+
+ /* event source side */
+ pICallBack CreateCallBackInterface(void);
+ void DeleteCallBackInterface(pICallBack self);
+ int InvokeCallBack(pICallBack pInterface, int iEvent, void *pEventData);
+
+ /* callback client side */
+ long RegisterCallback(pICallBack pInterface,
+ int iEvent, SICSCallBack pFunc,
+ void *pUserData, KillFuncIT pKill);
+ int RemoveCallback(pICallBack pInterface, long iID);
+ int RemoveCallback2(pICallBack pInterface, void *pUserData);
+int RemoveCallbackUsr(pICallBack self, SICSCallBack pFunc, int (*userfunc)(const void* pContext, const void* pUserData), void *pCtx);
+ int RemoveCallbackCon(pICallBack pInterface, SConnection *pCon);
+
+ int CallbackScript(SConnection *pCon, SicsInterp *pSics, void *pData,
+ int argc, char *argv[]);
+
+ pICallBack GetCallbackInterface(void *pData);
+
+#line 449 "interface.w"
+
+/*---------------------- The Environment Interface --------------------*/
+
+#line 366 "interface.w"
+
+ typedef enum { EVIdle, EVDrive, EVMonitor, EVError } EVMode;
+ typedef struct {
+ int iID;
+ EVMode (*GetMode)(void *self);
+ int (*IsInTolerance)(void *self);
+ int (*HandleError)(void *self);
+ } EVInterface, *pEVInterface;
+
+#line 451 "interface.w"
+
+
+#line 392 "interface.w"
+
+ pEVInterface CreateEVInterface(void);
+
+#line 452 "interface.w"
#endif
diff --git a/interface.tex b/interface.tex
index 663fefd9..43da4e3b 100644
--- a/interface.tex
+++ b/interface.tex
@@ -154,6 +154,8 @@ $\langle$driv {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ int GetDrivablePosition(void *pObject, SConnection *pCon,@\\
\mbox{}\verb@ float *fPos);@\\
\mbox{}\verb@@\\
+\mbox{}\verb@ long StartDriveTask(void *self, SConnection *pCon, char *name, float fTarget);@\\
+\mbox{}\verb@@\\
\mbox{}\verb@@$\Diamond$
\end{list}
\vspace{-1ex}
@@ -206,6 +208,11 @@ will be returned.
object. If the device is a motor corrections for zero points and signs
will be applied. Returns 1 on success and 0 on failure}
+{\bf StartDriveTask starts a drivable in a new task. If the task can be started, its
+task ID is returned. -1 is returned on failure.
+}
+
+
\subsubsection{The Countable Interface}
This is an interface for interacting with anything which counts.
@@ -233,6 +240,7 @@ $\langle$count {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ int GetCountLock(pICountable self, SConnection *pCon);@\\
\mbox{}\verb@ void ReleaseCountLock(pICountable self);@\\
\mbox{}\verb@ int isRunning(pICountable self);@\\
+\mbox{}\verb@ long StartCountTask(void *self, SConnection *pCon, char *name);@\\
\mbox{}\verb@@$\Diamond$
\end{list}
\vspace{-1ex}
@@ -273,6 +281,11 @@ will be returned.
{\bf ReleaseCountLock} release the count lock.
{\bf isRunning} returns the running flag.
+
+{\bf StartCountTask starts a countable in a new task. If the task can be started, its
+task ID is returned. -1 is returned on failure.
+}
+
\subsubsection{The Callback Interface}
The Callback Interface is SICS suport for component behaviour for objects.
diff --git a/interface.w b/interface.w
index 9aa75d36..3b66d74b 100644
--- a/interface.w
+++ b/interface.w
@@ -137,6 +137,8 @@ environment controllers fit this bill as well.
int GetDrivablePosition(void *pObject, SConnection *pCon,
float *fPos);
+ long StartDriveTask(void *self, SConnection *pCon, char *name, float fTarget);
+
@}
The first member of this structure is an ID which can be used in order to
check if the right datastructure has been obtained.
@@ -181,6 +183,11 @@ will be returned.
object. If the device is a motor corrections for zero points and signs
will be applied. Returns 1 on success and 0 on failure}
+{\bf StartDriveTask starts a drivable in a new task. If the task can be started, its
+task ID is returned. -1 is returned on failure.
+}
+
+
\subsubsection{The Countable Interface}
This is an interface for interacting with anything which counts.
@@ -203,6 +210,7 @@ This is an interface for interacting with anything which counts.
int GetCountLock(pICountable self, SConnection *pCon);
void ReleaseCountLock(pICountable self);
int isRunning(pICountable self);
+ long StartCountTask(void *self, SConnection *pCon, char *name);
@}
{\bf running } Is a flag which says if the counter is operating or not.
@@ -236,6 +244,11 @@ will be returned.
{\bf ReleaseCountLock} release the count lock.
{\bf isRunning} returns the running flag.
+
+{\bf StartCountTask starts a countable in a new task. If the task can be started, its
+task ID is returned. -1 is returned on failure.
+}
+
\subsubsection{The Callback Interface}
The Callback Interface is SICS suport for component behaviour for objects.
diff --git a/intserv.c b/intserv.c
index ba6c9bc3..e0a92e0f 100644
--- a/intserv.c
+++ b/intserv.c
@@ -8,6 +8,10 @@
Mark Koennecke, November 1996
Revised: Mark Koennecke, September 1997
+
+ Removed unused UDP interrupt port stuff
+
+ Mark Koennecke, February 2013
Copyright: see copyright.h
@@ -22,10 +26,7 @@
#include
#include "fortify.h"
-#include "conman.h"
-#include "SCinter.h"
-#include "nserver.h"
-#include "obdes.h"
+#include "sics.h"
#include "network.h"
#include "interrupt.h"
#include "status.h"
@@ -40,8 +41,6 @@
#define MAXINTERRUPT 7
#define INTERUPTWAIT 5
-static mkChannel *IntPort = NULL;
-static pTaskMan pTask = NULL;
/*----------------------------------------------------------------------------*/
static char *pIntText[] = {
"continue",
@@ -53,35 +52,6 @@ static char *pIntText[] = {
"end",
NULL
};
-
-/*---------------------------------------------------------------------------*/
-int ServerSetupInterrupt(int iPort, pNetRead pNet, pTaskMan pTasker)
-{
- int i;
-
-
- pTask = pTasker;
- /* setup interrupt port */
- IntPort = UDPOpen(iPort);
- if (IntPort == NULL) {
- return 0;
- } else {
- NetReadRegister(pNet, IntPort, udp, NULL);
- return 1;
- }
-}
-
-/*--------------------------------------------------------------------------*/
-void ServerStopInterrupt(void)
-{
-
- /* close the port */
- if (IntPort) {
- NETClosePort(IntPort);
- free(IntPort);
- }
-}
-
/*-------------------------------------------------------------------------*/
void SetInterrupt(int iCode)
{
@@ -89,7 +59,7 @@ void SetInterrupt(int iCode)
iInt = iCode;
- TaskSignal(pTask, SICSINT, &iInt);
+ TaskSignal(pServ->pTasker, SICSINT, &iInt);
}
/*--------------------------------------------------------------------------*/
diff --git a/linux_def b/linux_def
index 45815958..e312d828 100644
--- a/linux_def
+++ b/linux_def
@@ -10,4 +10,4 @@
MFLAGS=-f makefile_linux$(DUMMY)
HDFROOT=/usr/local
-TCLINC=/usr/include/tcl8.3
\ No newline at end of file
+TCLINC=/usr/include/tcl
\ No newline at end of file
diff --git a/macro.c b/macro.c
index 86216907..2f48d5df 100644
--- a/macro.c
+++ b/macro.c
@@ -172,21 +172,6 @@ static int SicsUnknownProc(ClientData pData, Tcl_Interp * pInter,
return TCL_ERROR;
}
- /* check for endless loop */
- Arg2Text(margc, myarg, comBuffer, 131);
- if (lastCommand != NULL) {
- if (strcmp(lastCommand, comBuffer) == 0) {
- Tcl_AppendResult(pInter, "ERROR: Never ending loop in unknown\n",
- "Offending command: ", comBuffer,
- " Probably Tcl command not found", NULL);
- SCSetInterrupt(pCon, eAbortBatch);
- return TCL_ERROR;
- }
- }
- if (pSics->lastUnknown[pSics->iStack])
- free(pSics->lastUnknown[pSics->iStack]);
- pSics->lastUnknown[pSics->iStack] = strdup(comBuffer);
-
/* invoke */
pCon->sicsError = 0;
iMacro = SCinMacro(pCon);
@@ -491,8 +476,6 @@ int MacroFileEval(SConnection * pCon, SicsInterp * pInter, void *pData,
}
/* handle status first */
- eOld = GetStatus();
- SetStatus(eBatch);
SICSLogWrite("Evaluating in MacroFileEval", eValue);
SICSLogWrite(argv[1], eValue);
@@ -518,7 +501,6 @@ int MacroFileEval(SConnection * pCon, SicsInterp * pInter, void *pData,
Tcl_DStringAppend(&command, pBueffel, -1);
pCom = Tcl_DStringValue(&command);
if (Tcl_CommandComplete(pCom)) {
- SetStatus(eEager);
FirstWord(pCom, pBueffel);
if (FindCommand(pInter, pBueffel) != NULL) {
snprintf(pBueffel,sizeof(pBueffel)-1, "%s:%d>> %s", argv[1], iLine, pCom);
@@ -529,7 +511,6 @@ int MacroFileEval(SConnection * pCon, SicsInterp * pInter, void *pData,
pWhere = strdup(pBueffel);
}
iRet = Tcl_Eval(pTcl, pCom);
- SetStatus(eBatch);
if (iRet != TCL_OK) {
/* write TCL error and check for total interrupt */
if (Tcl_GetVar(pTcl, SICSERROR, TCL_GLOBAL_ONLY) == NULL) { /* Tcl error */
@@ -554,7 +535,6 @@ int MacroFileEval(SConnection * pCon, SicsInterp * pInter, void *pData,
fclose(fp);
Tcl_DStringFree(&command);
SCWrite(pCon, "ERROR: batch processing interrupted", eError);
- SetStatus(eEager);
return 0;
} else {
SCSetInterrupt(pCon, eContinue);
@@ -572,7 +552,6 @@ int MacroFileEval(SConnection * pCon, SicsInterp * pInter, void *pData,
/* clean up */
fclose(fp);
Tcl_DStringFree(&command);
- SetStatus(eOld);
SCSendOK(pCon);
return 1;
}
@@ -763,7 +742,7 @@ int ClientLog(SConnection * pCon, SicsInterp * pInter, void *pData,
memset(pMessage, 0, (iLen + 100) * sizeof(char));
Arg2Text(argc - 1, &argv[1], pMessage, (iLen + 100) * sizeof(char));
- SCLogWrite(pCon,pMessage, eError);
+ SCLogWrite(pCon,pMessage, eLog);
free(pMessage);
return 1;
}
@@ -1012,7 +991,7 @@ static int TclAction(SConnection * pCon, SicsInterp * pSics, void *pData,
Tcl_UnsetVar(pTcl, SICSERROR, TCL_GLOBAL_ONLY);
}
if (strlen(pTcl->result) > 0) {
- SCPrintf(pCon, eError, "ERROR: Tcl reported %s in %s", pTcl->result,
+ SCPrintf(pCon, eError, "ERROR: Tcl reported %s in %s", pTcl->result,
pCommand);
}
if (pCommand != pBueffel)
diff --git a/make_gen b/make_gen
index 7c710e42..e7191dac 100644
--- a/make_gen
+++ b/make_gen
@@ -5,15 +5,18 @@
# Markus Zolliker March 2003
#---------------------------------------------------------------------------
+EPICSOBJ=epicsmotor.o
+#EPICSOBJ=
+
COBJ = Sclient.o network.o ifile.o intcli.o $(FORTIFYOBJ)
SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \
servlog.o sicvar.o nserver.o SICSmain.o motorlist.o\
sicsexit.o costa.o task.o $(FORTIFYOBJ) testprot.o\
- macro.o ofac.o obpar.o obdes.o drive.o status.o intserv.o \
+ macro.o ofac.o obpar.o obdes.o drive.o status.o intserv.o \
devexec.o mumo.o mumoconf.o selector.o selvar.o fupa.o lld.o \
- lld_blob.o strrepl.o lin2ang.o fomerge.o napi5.o napi4.o\
- script.o o2t.o alias.o napi.o stringdict.o sdynar.o \
- histmem.o histdriv.o histsim.o interface.o callback.o nxio.o \
+ lld_blob.o strrepl.o lin2ang.o fomerge.o \
+ script.o o2t.o alias.o stringdict.o sdynar.o \
+ histmem.o histdriv.o histsim.o interface.o callback.o \
event.o emon.o evcontroller.o evdriver.o simev.o perfmon.o \
danu.o nxdict.o varlog.o stptok.o nread.o trigd.o cell.o\
scan.o fitcenter.o telnet.o token.o wwildcard.o hklmot.o\
@@ -23,7 +26,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \
simchop.o choco.o chadapter.o trim.o scaldate.o tasub.o\
xytable.o exebuf.o exeman.o ubfour.o ubcalc.o\
circular.o maximize.o sicscron.o scanvar.o tasublib.o\
- d_sign.o d_mod.o tcldrivable.o stdscan.o diffscan.o nxxml.o\
+ d_sign.o d_mod.o tcldrivable.o stdscan.o diffscan.o \
synchronize.o definealias.o oscillate.o tasdrive.o \
hmcontrol.o userscan.o rs232controller.o lomax.o tasscanub.o \
fourlib.o motreg.o motreglist.o anticollider.o nxdataset.o \
@@ -36,19 +39,20 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \
moregress.o multicounter.o regresscter.o histregress.o \
sicshdbadapter.o polldriv.o sicspoll.o statemon.o hmslave.o \
nwatch.o asyncqueue.o asyncprotocol.o sicsobj.o frame.o syncedprot.o\
- nxcopy.o nxinterhelper.o nxinter_wrap.o nxstack.o arrayutil.o \
+ nxcopy.o nxinterhelper.o nxinter_wrap.o arrayutil.o \
sctdriveadapter.o sctdriveobj.o reflist.o singlex.o fourmess.o \
sgclib.o sgfind.o sgio.o sgsi.o sghkl.o singlediff.o singlebi.o \
singlenb.o simindex.o simidx.o uselect.o singletas.o motorsec.o \
rwpuffer.o asynnet.o background.o countersec.o hdbtable.o velosec.o \
histmemsec.o sansbc.o sicsutil.o strlutil.o genbinprot.o trace.o\
- singlebinb.o
+ singlebinb.o taskobj.o sctcomtask.o tasmono.o multicountersec.o \
+ messagepipe.o sicsget.o remoteobject.o
MOTOROBJ = motor.o simdriv.o
COUNTEROBJ = countdriv.o simcter.o counter.o
VELOOBJ = velo.o velosim.o
-OBJ = $(SOBJ) $(MOTOROBJ) $(COUNTEROBJ) $(VELOOBJ) $(DIFIL) $(EXTRA)
+OBJ = $(SOBJ) $(MOTOROBJ) $(COUNTEROBJ) $(VELOOBJ) $(DIFIL) $(EXTRA) $(EPICSOBJ)
.SUFFIXES:
.SUFFIXES: .tcl .htm .c .o .tc
@@ -59,43 +63,37 @@ OBJ = $(SOBJ) $(MOTOROBJ) $(COUNTEROBJ) $(VELOOBJ) $(DIFIL) $(EXTRA)
#--- This .SECONDARY. target is necessary to preserve generated .c files for debugging
.SECONDARY.: sicspoll.c polldriv.c
-all: libmat libhlib libtecsl libpsi SICServer
+all: libmat libhlib libpsi SICServer
# use this target when some of the libraries SUBLIBS might be incomplete
full: purge all
SICServer: $(OBJ) $(SUBLIBS)
- $(CC) -g -o SICServer $(OBJ) $(LIBS)
+ g++ $(DBG) -o SICServer $(OBJ) $(LIBS)
matrix/libmatrix.a: libmat
libmat:
cd matrix; make $(MFLAGS) libmatrix.a
-psi/hardsup/libhlib.a: libhlib
+$(SICSROOT)/sicspsi/hardsup/libhlib.a: libhlib
libhlib:
- cd psi/hardsup; make $(MFLAGS) libhlib.a
+ cd $(SICSROOT)/sicspsi/hardsup; make $(MFLAGS) libhlib.a
-psi/tecs/libtecsl.a: libtecsl
-
-libtecsl:
- cd psi/tecs; make $(MFLAGS) libtecsl.a
-
-psi/libpsi.a: libpsi
+$(SICSROOT)/sicspsi/libpsi.a: libpsi
libpsi:
- cd psi; make $(MFLAGS) libpsi.a
+ cd $(SICSROOT)/sicspsi; make $(MFLAGS) libpsi.a
purge:
rm -f SICServer $(SUBLIBS)
clean:
rm -f *.o *.d SICServer
- cd psi/hardsup; make $(MFLAGS) clean
+ cd $(SICSROOT)/sicspsi/hardsup; make $(MFLAGS) clean
cd matrix; make $(MFLAGS) clean
- cd psi/tecs; make $(MFLAGS) clean
- cd psi; make $(MFLAGS) clean
+ cd $(SICSROOT)/sicspsi; make $(MFLAGS) clean
Dbg.o: Dbg.c
cc -g -I/data/koenneck/include -c Dbg.c
diff --git a/makefile b/makefile
index adc02ada..34301d05 100644
--- a/makefile
+++ b/makefile
@@ -1,22 +1,4 @@
-# M. Zolliker 03.2005
+# when SICS_MAKE_VERSION is defined: use this makefile version
+# if not: show usage (see makefile_)
-%: usage
- @echo
-
-%.o: usage
- @echo
-
-default: usage
-
-usage:
- @ echo ""
- @ echo "Usage:"
- @ echo ""
- @ echo " make -f makefile_xxx [target]"
- @ echo ""
- @ echo ' where makefile_xxx is one of'
- @ echo ""
- @ ls -1 makefile_* | pr -t -o 4
-
-
-# DO NOT DELETE
+include makefile_$(SICS_MAKE_VERSION)
diff --git a/makefile_ b/makefile_
new file mode 100644
index 00000000..2c993731
--- /dev/null
+++ b/makefile_
@@ -0,0 +1,25 @@
+# M. Zolliker 03.2005
+# this file shows the correct usage of make in the sics source directory
+
+%: usage
+ @echo
+
+%.o: usage
+ @echo
+
+default: usage
+
+usage:
+ @ echo ""
+ @ echo "Usage:"
+ @ echo ""
+ @ echo " make -f makefile_xxx [target]"
+ @ echo ""
+ @ echo ' where makefile_xxx is one of'
+ @ echo ""
+ @ ls -1 makefile_?* | pr -t -o 4
+ @ echo ""
+ @ echo " or use make without args:"
+ @ echo ""
+ @ echo " setenv SICS_MAKE_VERSION slinux"
+ @ echo " make [target]"
diff --git a/makefile_alpha b/makefile_alpha
index d85e5e0a..832ab6cb 100644
--- a/makefile_alpha
+++ b/makefile_alpha
@@ -19,8 +19,7 @@ CFLAGS = -I$(HDFROOT)/include $(DFORTIFY) -DHDF4 -DHDF5 \
-g -std1 -warnprotos
BINTARGET = bin
EXTRA=
-SUBLIBS = psi/libpsi.a psi/hardsup/libhlib.a matrix/libmatrix.a \
- psi/tecs/libtecsl.a
+SUBLIBS = psi/libpsi.a psi/hardsup/libhlib.a matrix/libmatrix.a
LIBS = -L$(HDFROOT)/lib $(SUBLIBS) \
-ltcl -lfor $(HDFROOT)/lib/libhdf5.a \
$(HDFROOT)/lib/libmfhdf.a $(HDFROOT)/lib/libdf.a \
diff --git a/makefile_linux b/makefile_linux
index 059317ff..f8ee79c5 100644
--- a/makefile_linux
+++ b/makefile_linux
@@ -22,10 +22,9 @@ CFLAGS = -I$(HDFROOT)/include -I/usr/include/hdf -I$(TCLINC) -DHDF4 -DHDF5 \
BINTARGET = bin
EXTRA=nintf.o
-SUBLIBS = psi/libpsi.a psi/hardsup/libhlib.a matrix/libmatrix.a \
- psi/tecs/libtecsl.a
+SUBLIBS = psi/libpsi.a psi/hardsup/libhlib.a matrix/libmatrix.a
LIBS = -L$(HDFROOT)/lib $(SUBLIBS) $(NILIB)\
- -ltcl8.3 -lhdf5 -lmfhdf -ldf \
+ -ltcl -lNeXus -lhdf5 -lmfhdf -ldf \
-lmxml -lghttp -ljpeg -ljson -ldl -lz -lm -lc
include make_gen
diff --git a/makefile_macosx b/makefile_macosx
index 2dc98c99..6e81a4bf 100644
--- a/makefile_macosx
+++ b/makefile_macosx
@@ -22,8 +22,7 @@ CFLAGS = -I$(HDFROOT)/include -I/sw/include -DNXXML -DHDF5 -DHDF4 $(NI) -DMACOSX
BINTARGET = bin
EXTRA=nintf.o
-SUBLIBS = psi/libpsi.a psi/hardsup/libhlib.a matrix/libmatrix.a \
- psi/tecs/libtecsl.a
+SUBLIBS = psi/libpsi.a psi/hardsup/libhlib.a matrix/libmatrix.a
LIBS = -L$(HDFROOT)/lib -L/sw/lib $(SUBLIBS) $(NILIB)\
-ltcl $(HDFROOT)/lib/libhdf5.a -lmfhdf -ldf \
$(HDFROOT)/lib/libsz.a \
diff --git a/makefile_slinux b/makefile_slinux
index 3602a289..6be471f6 100644
--- a/makefile_slinux
+++ b/makefile_slinux
@@ -4,6 +4,7 @@
#
# Mark Koennecke 1996-2001
# Markus Zolliker, March 2003
+# Mark Koennecke, February 2014
#==========================================================================
# assign if the National Instrument GPIB driver is available
SINQDIR=/afs/psi.ch/project/sinq
@@ -11,20 +12,25 @@ NI= -DHAVENI
NIOBJ= nigpib.o
NILIB=$(SINQDIR)/sl6/lib/cib.o
+EPICSDIR=$(SINQDIR)/sl6/lib/linux-x86
+EPICSLIBS=$(EPICSDIR)/libezca.a $(EPICSDIR)/libca.a $(EPICSDIR)/libCom.a -lreadline -lhistory
+#EPICSLIBS=-L$(EPICSDIR) -lezca -lca -lCom
+
include sllinux_def
CC = gcc
+
CFLAGS = -I$(HDFROOT)/include -DNXXML -DHDF5 $(NI) \
- -Ipsi/hardsup -I. -MMD \
- -Werror -DCYGNUS -DNONINTF -g $(DFORTIFY) \
+ -I$(SICSROOT)/sicspsi/hardsup -I$(SICSROOT) -I. -MMD \
+ -Werror -DCYGNUS -DNONINTF $(DBG) $(DFORTIFY) \
-Wall -Wno-unused -Wunused-value -Wno-comment -Wno-switch
BINTARGET = bin
EXTRA=nintf.o
-SUBLIBS = psi/libpsi.a psi/hardsup/libhlib.a matrix/libmatrix.a \
- psi/tecs/libtecsl.a
-LIBS = -L$(HDFROOT)/lib $(SUBLIBS) $(NILIB)\
- -ltcl $(HDFROOT)/lib/libhdf5.a \
+SUBLIBS = $(SICSROOT)/sicspsi/libpsi.a $(SICSROOT)/sicspsi/hardsup/libhlib.a \
+ matrix/libmatrix.a
+LIBS = -L$(HDFROOT)/lib $(SUBLIBS) $(NILIB) $(EPICSLIBS) \
+ -ltcl -lNeXus $(HDFROOT)/lib/libhdf5.a \
$(HDFROOT)/lib/libsz.a \
$(HDFROOT)/lib/libjson.a \
-ldl -lz $(HDFROOT)/lib/libmxml.a $(HDFROOT)/lib/libghttp.a -lm -lc -lpthread
@@ -33,9 +39,3 @@ include make_gen
-include $(OBJ:.o=.d)
-
-
-
-
-
-
diff --git a/messagepipe.c b/messagepipe.c
new file mode 100644
index 00000000..c0ad59fb
--- /dev/null
+++ b/messagepipe.c
@@ -0,0 +1,118 @@
+/**
+ * An implementation for a message pipe system as described in
+ *
+ * http://eventuallyconsistent.net/2013/08/14/messaging-as-a-programming-model-part-2/
+ *
+ * A message is passed through a series of filter routines which do things.
+ *
+ * Rather then loops I try using recursion here.
+ *
+ * copyright: GPL Copyleft
+ *
+ * Mark Koennecke, November 2013
+ */
+#include
+#include
+#include
+#include
+
+/*--------------------------------------------------------------------------------*/
+typedef struct __MessagePipe {
+ void *userData;
+ mpUserKill killFunc;
+ mpFilterFunc filterFunc;
+ struct __MessagePipe *next;
+ struct __MessagePipe *previous;
+} MessagePipe;
+/*--------------------------------------------------------------------------------*/
+static int EmptyFunc(void *message, void *userData)
+{
+ return MPCONTINUE;
+}
+/*---------------------------------------------------------------------------------*/
+pMP MakeMP()
+{
+ pMP result = NULL;
+
+ result = malloc(sizeof(MessagePipe));
+ if(result != NULL){
+ memset(result,0,sizeof(MessagePipe));
+ result->filterFunc = EmptyFunc;
+ }
+ return result;
+}
+/*---------------------------------------------------------------------------------*/
+void KillMP(pMP self)
+{
+ if(self == NULL){
+ return;
+ }
+
+ pMP next = self->next;
+ if(self->userData != NULL && self->killFunc != NULL){
+ self->killFunc(self->userData);
+ }
+ free(self);
+ KillMP(next);
+}
+/*-----------------------------------------------------------------------------------*/
+int AppendMPFilter(pMP self, mpFilterFunc func, void *userData, mpUserKill usKill)
+{
+ assert(self != NULL);
+ assert(func != NULL);
+
+ if(self->next == NULL){
+ self->next = malloc(sizeof(MessagePipe));
+ if(self->next != NULL){
+ self->next->previous = self;
+ self->next->next = NULL;
+ self->next->userData = userData;
+ self->next->killFunc = usKill;
+ self->next->filterFunc = func;
+ return 0;
+ } else {
+ return 1;
+ }
+ } else {
+ return AppendMPFilter(self->next, func, userData, usKill);
+ }
+}
+/*-----------------------------------------------------------------------------------*/
+pMP PrependMPFilter(pMP self, mpFilterFunc func, void *userData, mpUserKill usKill)
+{
+ pMP result = NULL;
+
+ assert(func != NULL);
+
+ result = malloc(sizeof(MessagePipe));
+ if(result != NULL){
+ result->userData = userData;
+ result->killFunc = usKill;
+ result->filterFunc = func;
+ result->next = self;
+ result->previous = NULL;
+ return result;
+ } else {
+ /*
+ we are ignoring an error here.........
+ */
+ return self;
+ }
+}
+
+/*-----------------------------------------------------------------------------------*/
+int MPprocess(pMP self, void *message)
+{
+ int status;
+
+ if(self == NULL || self->filterFunc == NULL){
+ return MPCONTINUE;
+ } else {
+ status = self->filterFunc(message, self->userData);
+ if(status == MPSTOP){
+ return status;
+ } else {
+ return MPprocess(self->next, message);
+ }
+ }
+}
diff --git a/messagepipe.h b/messagepipe.h
new file mode 100644
index 00000000..c2f9fbfc
--- /dev/null
+++ b/messagepipe.h
@@ -0,0 +1,82 @@
+/**
+ * An implementation for a message pipe system as described in
+ *
+ * http://eventuallyconsistent.net/2013/08/14/messaging-as-a-programming-model-part-2/
+ *
+ * A message is passed through a series of filter routines which do things.
+ *
+ * copyright: GPL Copyleft
+ *
+ * Mark Koennecke, November 2013
+ */
+#ifndef __MESSAGEPIPE
+#define __MESSAGEPIPE
+
+#define MPCONTINUE 1
+#define MPSTOP 0
+
+/**
+ * The messagePipe data structure defined in messagepipe.c
+ */
+typedef struct __MessagePipe *pMP;
+
+/**
+ * Protoype of the message filter function.
+ * @param message The message to process
+ * @param Optional private data for this message filter function
+ * @return MPSTOP for stopping further processing of the filter pipe
+ * or MPCONTINUE to continue processing
+ */
+typedef int (*mpFilterFunc)(void *message, void *userData);
+
+/**
+ * A function to free the userData when it is used
+ * @param userData The data structure passed in for userData to a filter function.
+ */
+typedef void (*mpUserKill)(void *userData);
+
+
+/**
+ * Create an empty message pipe
+ * @return A message pipe structure or NULL when out of memory
+ */
+pMP MakeMP();
+
+/**
+ * Delete a message pipe
+ * @param self The message pipe to delete
+ */
+void KillMP(pMP self);
+
+/**
+ * Append a filter function to the list of message filters to process
+ * @param self The message queue to append too
+ * @param func The filter function to append
+ * @param Optional userData to pass through to the filter function
+ * @param usKill An optional function to free the userData when the message pipe gets deleted
+ * @return 0 on success, 1 when out of memory
+ */
+int AppendMPFilter(pMP self, mpFilterFunc func, void *userData, mpUserKill usKill);
+
+/**
+ * Preppend a filter function to the list of message filters to process
+ * @param self The message queue to append too
+ * @param func The filter function to append
+ * @param Optional userData to pass through to the filter function
+ * @param usKill An optional function to free the userData when the message pipe gets deleted
+ * @return An updated pointer to the message pipe.
+ */
+pMP PrependMPFilter(pMP self, mpFilterFunc func, void *userData, mpUserKill usKill);
+
+
+/**
+ * Process the message pipe with the given message
+ * @param self The messae pipe to process
+ * @param message The message to process.
+ * @return MPCONTINUE on successfull completion, MPABORT when the chain was
+ * aborted for some reason.
+ */
+int MPprocess(pMP self, void *message);
+
+
+#endif
diff --git a/moregress.c b/moregress.c
index e1e4650d..f677c336 100644
--- a/moregress.c
+++ b/moregress.c
@@ -74,10 +74,10 @@ static int RGRunTo(void *data, float newValue)
RGMotorDriver *self = NULL;
self = (RGMotorDriver *) data;
- self->target = newValue;
if (self->errorType == STARTFAIL) {
return HWFault;
}
+ self->target = newValue;
return OKOK;
}
diff --git a/motor.c b/motor.c
index 2c449252..9d6b4a58 100644
--- a/motor.c
+++ b/motor.c
@@ -82,7 +82,13 @@
#define MOVECOUNT 11
extern double DoubleTime(void);
-
+static void SetMotorError(pMotor self, char *text)
+{
+ if(self->error != NULL){
+ free(self->error);
+ }
+ self->error = strdup(text);
+}
/*-------------------------------------------------------------------------*/
static void *MotorGetInterface(void *pData, int iID)
{
@@ -383,17 +389,18 @@ static int reportAndFixError(pMotor self, SConnection * pCon)
switch (iRet) {
case MOTFAIL:
snprintf(pBueffel, 255, "ERROR: %s on %s", pError, self->name);
- SCWrite(pCon, pBueffel, eError);
+ SCWrite(pCon, pBueffel, eLogError);
newStatus = HWFault;
+ SetMotorError(self,pError);
break;
case MOTREDO:
snprintf(pBueffel, 255, "WARNING: %s on %s", pError, self->name);
- SCWrite(pCon, pBueffel, eWarning);
+ SCWrite(pCon, pBueffel, eLog);
newStatus = statusRunTo(self, pCon);
break;
case MOTOK:
snprintf(pBueffel, 255, "WARNING: %s on %s", pError, self->name);
- SCWrite(pCon, pBueffel, eWarning);
+ SCWrite(pCon, pBueffel, eLog);
newStatus = HWIdle;
break;
default:
@@ -541,7 +548,7 @@ static int MotorGetParImpl(pMotor self, char *name, float *fVal)
*fVal = self->pDriver->fLower;
return 1;
}
-
+
pPar = ObParFind(self->ParArray, name);
if (pPar) {
*fVal = pPar->fVal;
@@ -689,8 +696,8 @@ static int MotorGetHardPositionImpl(pMotor self, SConnection * pCon,
/*---------------------------------------------------------------------------*/
static long MotorRunImpl(void *sulf, SConnection * pCon, float fNew)
{
- float fHard, fCurrHard, fNewHard, fZero;
- int i, iRet, iCode, iSign;
+ float fHard;
+ int i, iRet, iCode;
char pBueffel[512];
char pError[132];
pMotor self;
@@ -709,13 +716,7 @@ static long MotorRunImpl(void *sulf, SConnection * pCon, float fNew)
SCSetInterrupt(pCon, eAbortBatch);
return 0;
}
- self->pDriver->GetPosition(self->pDriver, &fCurrHard);
- iSign = ObVal(self->ParArray, SIGN);
- fZero = ObVal(self->ParArray, SZERO);
- fNewHard = iSign * (fNew + fZero);
- if (absf(fCurrHard - fNewHard) <= ObVal(self->ParArray, PREC)) {
- return OKOK;
- }
+ SetMotorError(self,"None");
/* check boundaries first */
iRet = MotorCheckBoundaryImpl(self, fNew, &fHard, pError, 131);
@@ -723,6 +724,7 @@ static long MotorRunImpl(void *sulf, SConnection * pCon, float fNew)
snprintf(pBueffel, 511, "ERROR: %s", pError);
SCWrite(pCon, pBueffel, eError);
SCSetInterrupt(pCon, eAbortOperation);
+ SetMotorError(self,pError);
return 0;
}
@@ -745,6 +747,7 @@ static long MotorRunImpl(void *sulf, SConnection * pCon, float fNew)
ServerWriteGlobal(pBueffel, eError);
SCSetInterrupt(pCon, eAbortBatch);
self->pDrivInt->iErrorCount = 0;
+ SetMotorError(self,"Motor ALARM!!!!");
return 0;
}
@@ -769,6 +772,7 @@ static long MotorRunImpl(void *sulf, SConnection * pCon, float fNew)
SCWrite(pCon, pError, eError);
SCWrite(pCon, "\n", eError);
SCSetInterrupt(pCon, (int) ObVal(self->ParArray, INT));
+ SetMotorError(self,pError);
return HWFault;
case MOTREDO:
iRet = self->pDriver->RunTo(self->pDriver, fHard);
@@ -837,6 +841,7 @@ pMotor MotorInit(char *drivername, char *name, MotorDriver * pDriv)
pM->pDriver = pDriv;
pM->drivername = strdup(drivername);
pM->name = strdup(name);
+ pM->error = strdup("None");
/* initialise object descriptor */
@@ -1008,6 +1013,7 @@ int MotorCheckPosition(void *sulf, SConnection * pCon)
*/
extern MotorDriver *MakePiPiezo(Tcl_Interp * pTcl, char *pArray);
+extern MotorDriver *epicsMakeMotorDriver(char *baseName);
int MotorCreate(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[])
@@ -1068,6 +1074,22 @@ int MotorCreate(SConnection * pCon, SicsInterp * pSics, void *pData,
SCWrite(pCon, pBueffel, eLogError);
return 0;
}
+ } else if (strcmp(argv[2], "epics") == 0) {
+ if(argc > 3){
+ pDriver = epicsMakeMotorDriver(argv[3]);
+ if (!pDriver) {
+ return 0;
+ }
+ pNew = MotorInit("epics", argv[1], pDriver);
+ if (!pNew) {
+ snprintf(pBueffel,sizeof(pBueffel)-1, "Failure to create motor %s", argv[1]);
+ SCWrite(pCon, pBueffel, eLogError);
+ return 0;
+ }
+ } else {
+ SCWrite(pCon,"ERROR: missing basename argument to create EPICS motor",eError);
+ return 0;
+ }
} else {
site = getSite();
if (site != NULL) {
@@ -1082,10 +1104,7 @@ int MotorCreate(SConnection * pCon, SicsInterp * pSics, void *pData,
}
/* create the interpreter command */
- if (pNew->pActionRoutine)
- iRet = AddCommand(pSics, argv[1], pNew->pActionRoutine, MotorKill, pNew);
- else
- iRet = AddCommand(pSics, argv[1], MotorAction, MotorKill, pNew);
+ iRet = AddCommand(pSics, argv[1], MotorAction, MotorKill, pNew);
if (!iRet) {
snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: duplicate command %s not created", argv[1]);
SCWrite(pCon, pBueffel, eError);
@@ -1301,6 +1320,10 @@ int MotorAction(SConnection * pCon, SicsInterp * pSics, void *pData,
DeleteTokenList(pList);
SCSendOK(pCon);
return 1;
+ } /* check for error */
+ else if (strcmp(pCurrent->text, "error") == 0) {
+ SCPrintf(pCon,eValue,"%s.error = %s", argv[0], self->error);
+ return 1;
} else if (strcmp(pCurrent->text, "interest") == 0) { /* interest */
pMoti = (pMotInfo) malloc(sizeof(MotInfo));
if (!pMoti) {
@@ -1380,6 +1403,13 @@ int MotorAction(SConnection * pCon, SicsInterp * pSics, void *pData,
SCWrite(pCon, pBueffel, eValue);
DeleteTokenList(pList);
return 1;
+ } else if(strcmp(pName->text,"status") == 0){
+ if(self->running){
+ SCPrintf(pCon,eValue,"%s.status = run",argv[0]);
+ } else {
+ SCPrintf(pCon,eValue,"%s.status = idle",argv[0]);
+ }
+ return 1;
}
iRet = MotorGetPar(self, pName->text, &fValue);
if (!iRet) {
diff --git a/motor.h b/motor.h
index e109326c..c5908674 100644
--- a/motor.h
+++ b/motor.h
@@ -28,6 +28,7 @@ typedef struct __Motor {
float *fVal);
char *drivername;
char *name;
+ char *error;
MotorDriver *pDriver;
float fTarget;
float fPosition;
@@ -81,6 +82,4 @@ int MotorAction(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[]);
pMotor FindMotor(SicsInterp * pSics, char *name);
-/* Made available to oscillate.c to generate MOTEND event. Ferdi */
-void finishDriving(pMotor self, SConnection *pCon);
#endif
diff --git a/motorlist.c b/motorlist.c
index f5433864..acd7cc14 100644
--- a/motorlist.c
+++ b/motorlist.c
@@ -6,6 +6,10 @@
copyright: see file COPYRIGHT
Mark Koennecke, September 2005
+
+ modified to use the task system
+
+ Mark Koennecke, January 2014
-----------------------------------------------------------------------*/
#include "motorlist.h"
#include "lld.h"
@@ -52,7 +56,7 @@ static int MOLICheckLimits(void *data, float val, char *error, int errlen)
iRet = LLDnodePtr2First(self);
while (iRet != 0) {
LLDnodeDataTo(self, &tuktuk);
- test = tuktuk.pDriv->CheckLimits(tuktuk.data, val, error, errlen);
+ test = tuktuk.pDriv->CheckLimits(tuktuk.data, tuktuk.target, error, errlen);
if (test == 0) {
retVal = 0;
}
@@ -73,17 +77,18 @@ static int MOLICheckLimits(void *data, float val, char *error, int errlen)
------------------------------------------------------------------*/
static long MOLISetValue(void *data, SConnection * pCon, float val)
{
- int self = 0, iRet, test;
+ int self = 0, iRet;
MotControl tuktuk;
+
self = *(int *) data;
iRet = LLDnodePtr2First(self);
while (iRet != 0) {
LLDnodeDataTo(self, &tuktuk);
- test = tuktuk.pDriv->SetValue(tuktuk.data, pCon, tuktuk.target);
- if (test != 1) {
- return test;
+ tuktuk.taskID = StartDriveTask(tuktuk.data,pCon,tuktuk.name,tuktuk.target);
+ if (tuktuk.taskID < 0) {
+ return HWFault;
} else {
tuktuk.running = 1;
LLDnodeDataFrom(self, &tuktuk);
@@ -105,7 +110,7 @@ static long MOLISetValue(void *data, SConnection * pCon, float val)
------------------------------------------------------------------*/
static int MOLICheckStatus(void *data, SConnection * pCon)
{
- int self = 0, iRet, status, result = HWIdle;
+ int self = 0, iRet, status;
MotControl tuktuk;
self = *(int *) data;
@@ -114,35 +119,17 @@ static int MOLICheckStatus(void *data, SConnection * pCon)
while (iRet != 0) {
LLDnodeDataTo(self, &tuktuk);
if (tuktuk.running == 1) {
- status = tuktuk.pDriv->CheckStatus(tuktuk.data, pCon);
- switch (status) {
- case HWIdle:
- tuktuk.running = 0;
+ status = isTaskIDRunning(pServ->pTasker,tuktuk.taskID);
+ if(status == 1){
+ return HWBusy;
+ } else {
+ tuktuk.running = 0;
LLDnodeDataFrom(self, &tuktuk);
- break;
- case HWBusy:
- result = HWBusy;
- break;
- case HWFault:
- case HWPosFault:
- /**
- * It is questionable if one should not set a flag here
- * and keep polling: it is not clear if this error is a
- * communication problem or that the motor really
- * has stopped.
- */
- return status;
- break;
- default:
- /*
- this is a programming error and has to be fixed
- */
- assert(0);
}
}
iRet = LLDnodePtr2Next(self);
}
- return result;
+ return HWIdle;
}
/*---------------------------------------------------------
A special version for EIGER. I am cautious: I have problems
@@ -151,39 +138,7 @@ static int MOLICheckStatus(void *data, SConnection * pCon)
-----------------------------------------------------------*/
int MOLIEigerStatus(void *data, SConnection * pCon)
{
- int self = 0, iRet, status, result = HWIdle;
- MotControl tuktuk;
-
- self = *(int *) data;
-
- iRet = LLDnodePtr2First(self);
- while (iRet != 0) {
- LLDnodeDataTo(self, &tuktuk);
- if (tuktuk.running == 1) {
- status = tuktuk.pDriv->CheckStatus(tuktuk.data, pCon);
- switch (status) {
- case HWIdle:
- tuktuk.running = 0;
- LLDnodeDataFrom(self, &tuktuk);
- break;
- case HWBusy:
- result = HWBusy;
- break;
- case HWFault:
- case HWPosFault:
- tuktuk.running = 0;
- LLDnodeDataFrom(self, &tuktuk);
- break;
- default:
- /*
- this is a programming error and has to be fixed
- */
- assert(0);
- }
- }
- iRet = LLDnodePtr2Next(self);
- }
- return result;
+ return MOLICheckStatus(data,pCon);
}
/*----------------------------------------------------------------
diff --git a/motorlist.h b/motorlist.h
index 4821dbd2..1b168757 100644
--- a/motorlist.h
+++ b/motorlist.h
@@ -19,6 +19,7 @@ typedef struct {
pIDrivable pDriv;
void *data;
int running;
+ long taskID;
} MotControl, *pMotControl;
/*======================================================================*/
diff --git a/motorsec.c b/motorsec.c
index e0822c3b..6f0ed33a 100644
--- a/motorsec.c
+++ b/motorsec.c
@@ -47,6 +47,20 @@
#define ABS(x) (x < 0 ? -(x) : (x))
+
+/*-------------------------------------------------------------------------*/
+static void SecMotorSetError(pMotor self, char *text)
+{
+ hdbValue v;
+ pHdb node;
+
+ node = GetHipadabaNode(self->pDescriptor->parNode, "error");
+ if(node != NULL){
+ v = MakeHdbText(strdup(text));
+ UpdateHipadabaPar(node,v,NULL);
+ ReleaseHdbValue(&v);
+ }
+}
/*--------------------------------------------------------------------------*/
static int SecMotorGetPar(pMotor self, char *name, float *fVal)
{
@@ -106,15 +120,17 @@ static long SecMotorRun(void *sulf, SConnection * pCon, float fNew)
}
self->stopped = 0;
self->stopReported = 0;
+ self->fTarget = fNew;
- v = MakeHdbFloat(fNew);
- status = SetHipadabaPar(self->pDescriptor->parNode, v, pCon);
+ SecMotorSetError(sulf,"None");
node = GetHipadabaNode(self->pDescriptor->parNode, "status");
if(node != NULL){
v = MakeHdbText(strdup("run"));
UpdateHipadabaPar(node,v,pCon);
ReleaseHdbValue(&v);
}
+ v = MakeHdbFloat(fNew);
+ status = SetHipadabaPar(self->pDescriptor->parNode, v, pCon);
return status;
}
@@ -200,12 +216,17 @@ static int SecMotorLimits(void *sulf, float fVal, char *error, int iErrLen)
{
float fHard;
pMotor self;
+ int status;
assert(sulf);
self = (pMotor) sulf;
- return SecMotorCheckBoundary(self, fVal, &fHard, error, iErrLen);
+ status = SecMotorCheckBoundary(self, fVal, &fHard, error, iErrLen);
+ if(status != 1){
+ SecMotorSetError(sulf,error);
+ }
+ return status;
}
/*-----------------------------------------------------------------------*/
@@ -231,10 +252,11 @@ static int checkPosition(pMotor self, SConnection * pCon)
if (ABS(target - hard) > precision) {
if (self->retryCount >= (int) maxretry) {
SCPrintf(pCon, eLogError,
- "ERROR: Aborting %s after %d retries, off position by %f",
+ "ERROR: aborting %s after %d retries, off position by %f",
self->name, (int) maxretry, target - hard);
node = GetHipadabaNode(self->pDescriptor->parNode, "status");
assert(node != NULL);
+ SecMotorSetError(self,"Aborted positioning after many retries");
UpdateHipadabaPar(node, MakeHdbText("error"), pCon);
return HWFault;
}
@@ -277,6 +299,7 @@ static int SecMotorStatus(void *sulf, SConnection * pCon)
pHdb node = NULL;
hdbValue v;
float interrupt;
+ char error[132];
assert(sulf);
self = (pMotor) sulf;
@@ -298,8 +321,20 @@ static int SecMotorStatus(void *sulf, SConnection * pCon)
handleMoveCallback(self, pCon);
status = HWBusy;
} else if (strstr(v.v.text, "poserror") != NULL) {
+ SCWrite(pCon,"WARNING: Position not reached",eLog);
status = checkPosition(self, pCon);
+ } else if (strstr(v.v.text, "restart") != NULL) {
+ SCPrintf(pCon,eLog,"WARNING: restarting motor %s", self->name);
+ SecMotorRun(self,pCon,self->fTarget);
+ return HWBusy;
} else if (strstr(v.v.text, "error") != NULL) {
+ if(GetHdbProperty(node,"geterror",error,sizeof(error)) == 1){
+ SecMotorSetError(sulf,error);
+ }
+ node = GetHipadabaNode(self->pDescriptor->parNode, "targetposition");
+ if(GetHdbProperty(node,"geterror",error,sizeof(error)) == 1){
+ SecMotorSetError(sulf,error);
+ }
status = HWFault;
} else {
SCPrintf(pCon, eError, "ERROR: unknown motor status %s found",
@@ -333,9 +368,16 @@ static float SecMotorGetValue(void *pData, SConnection * pCon)
{
int status;
pMotor self = (pMotor) pData;
- hdbValue v;
+ hdbValue v;
+ char error[132];
+
assert(pData);
+ status = GetHdbProperty(self->pDescriptor->parNode,"geterror", error,sizeof(error));
+ if(status == 1 && strcmp(error,"none") != 0) {
+ SCPrintf(pCon,eError,"ERROR: Failed to read %s with %s", self->name, error);
+ return -9999999.99;
+ }
status = GetHipadabaPar(self->pDescriptor->parNode, &v, pCon);
if (status != 1) {
return -9999999.99;
@@ -423,7 +465,7 @@ static hdbCallbackReturn SecMotorCallback(pHdb node, void *userData,
pHdb child = NULL;
pMotor self = NULL;
float fHard, fVal, sign, zero;
- char pBueffel[512], pError[132];
+ char pBueffel[512], pError[132], *pPtr = NULL;
int status;
self = (pMotor) userData;
@@ -467,13 +509,14 @@ static hdbCallbackReturn SecMotorCallback(pHdb node, void *userData,
self->name);
SCWrite(pCon, pBueffel, eWarning);
self->errorCount = 0;
+ self->pDrivInt->iErrorCount = 0;
}
/*
* check for alarm condition
*/
SecMotorGetPar(self, "failafter", &fVal);
- if (self->pDrivInt->iErrorCount > (int) fVal) {
+ if (self->pDrivInt->iErrorCount >= (int) fVal) {
/* big alarm */
ServerWriteGlobal("ERROR: !!! MOTOR ALARM !!! MOTOR ALARM !!!",
eError);
@@ -483,6 +526,8 @@ static hdbCallbackReturn SecMotorCallback(pHdb node, void *userData,
ServerWriteGlobal(pBueffel, eError);
SCSetInterrupt(pCon, eAbortBatch);
self->pDrivInt->iErrorCount = 0;
+ child = GetHipadabaNode(self->pDescriptor->parNode, "status");
+ UpdateHipadabaPar(child, MakeHdbText("run"), pCon);
return hdbAbort;
}
@@ -490,10 +535,10 @@ static hdbCallbackReturn SecMotorCallback(pHdb node, void *userData,
self->retryCount = 0;
self->stopped = 0;
self->posCount = 0;
- child = GetHipadabaNode(self->pDescriptor->parNode, "targetposition");
- UpdateHipadabaPar(child, MakeHdbFloat(fHard), pCon);
child = GetHipadabaNode(self->pDescriptor->parNode, "status");
UpdateHipadabaPar(child, MakeHdbText("run"), pCon);
+ child = GetHipadabaNode(self->pDescriptor->parNode, "targetposition");
+ UpdateHipadabaPar(child, MakeHdbFloat(fHard), pCon);
child = GetHipadabaNode(self->pDescriptor->parNode, "hardposition");
SetHipadabaPar(child, MakeHdbFloat(fHard), pCon);
@@ -504,6 +549,12 @@ static hdbCallbackReturn SecMotorCallback(pHdb node, void *userData,
if (mm != NULL) {
pCon = (SConnection *) mm->callData;
SecMotorGetPar(self, "hardposition", &fVal);
+ child = GetHipadabaNode(self->pDescriptor->parNode, "hardposition");
+ if((pPtr = GetHdbProp(child,"geterror")) != NULL){
+ SetHdbProperty(node,"geterror",pPtr);
+ } else {
+ SetHdbProperty(node,"geterror",NULL);
+ }
fVal = hardToSoftPosition(self, fVal);
node->value.v.doubleValue = fVal;
mm->v->v.doubleValue = fVal;
@@ -518,6 +569,7 @@ static hdbCallbackReturn HardUpdateCallback(pHdb node, void *userData,
pHdbMessage message)
{
pHdbDataMessage mm = NULL;
+ pHdbPropertyChange pm = NULL;
pMotor self = (pMotor) userData;
float fVal;
hdbValue v;
@@ -532,6 +584,18 @@ static hdbCallbackReturn HardUpdateCallback(pHdb node, void *userData,
UpdateHipadabaPar(self->pDescriptor->parNode, v, mm->callData);
return hdbContinue;
}
+
+ /*
+ forward geterror
+ */
+ pm = GetPropertyChangeMessage(message);
+ if(pm != NULL){
+ if(strstr(pm->key,"geterror") != NULL){
+ SetHdbProperty(self->pDescriptor->parNode,pm->key, pm->value);
+ }
+ }
+
+
return hdbContinue;
}
@@ -611,6 +675,80 @@ static hdbCallbackReturn SecMotorZeroCallback(pHdb node, void *userData,
return hdbContinue;
}
+/*--------------------------------------------------------------------------*/
+typedef struct {
+ char *pName;
+ SConnection *pCon;
+ float lastValue;
+} MotInfo, *pMotInfo;
+/*--------------------------------------------------------------------------*/
+static void KillInfo(void *pData)
+{
+ pMotInfo self = NULL;
+
+ assert(pData);
+ self = (pMotInfo) pData;
+ if (self->pName) {
+ free(self->pName);
+ }
+ if (self->pCon != NULL) {
+ SCDeleteConnection(self->pCon);
+ }
+ free(self);
+}
+/*-------------------------------------------------------------------------*/
+static hdbCallbackReturn InterestCallback(pHdb node, void *userData,
+ pHdbMessage message)
+{
+ pHdbDataMessage mm = NULL;
+ pMotor self = (pMotor) userData;
+ float fVal;
+ hdbValue v;
+ pMotInfo priv = (pMotInfo)userData;
+
+
+ assert(self != NULL);
+
+ mm = GetHdbUpdateMessage(message);
+ if (mm != NULL) {
+ v = *mm->v;
+ if(!SCisConnected(priv->pCon)){
+ return hdbKill;
+ }
+ if(ABS(v.v.doubleValue - priv->lastValue) > .1) {
+ SCPrintf(priv->pCon,eValue,"%s.position = %f",
+ priv->pName, v.v.doubleValue);
+ priv->lastValue = v.v.doubleValue;
+ }
+ return hdbContinue;
+ }
+ return hdbContinue;
+}
+/*---------------------------------------------------------------------------*/
+static int InterestCmd(pSICSOBJ ccmd, SConnection * con,
+ Hdb * cmdNode, Hdb * par[], int nPar)
+{
+ pMotInfo priv = NULL;
+
+ priv = malloc(sizeof(MotInfo));
+ if(priv == NULL){
+ SCWrite(con,"ERROR: out of memory registering interest",eError);
+ return 0;
+ }
+
+ if(nPar >= 1 && (strcmp(par[0]->value.v.text,"UNKNOWN") != 0)) {
+ priv->pName = strdup(par[0]->value.v.text);
+ } else {
+ priv->pName = strdup(ccmd->objectNode->name);
+ }
+ priv->lastValue = .0;
+ priv->pCon = SCCopyConnection(con);
+ AppendHipadabaCallback(ccmd->objectNode,
+ MakeHipadabaCallback(InterestCallback,priv,KillInfo));
+ SCSendOK(con);
+ return 1;
+
+}
/*---------------------------------------------------------------------------*/
pMotor SecMotorInit(char *name)
{
@@ -672,6 +810,7 @@ pMotor SecMotorInit(char *name)
child = MakeHipadabaNode("sign", HIPFLOAT, 1);
SetHdbProperty(child, "__save", "true");
+ SetHdbProperty(child, "priv", "user");
AddHipadabaChild(node, child, NULL);
AppendHipadabaCallback(child,
MakeHipadabaCallback(SecMotorSignCallback, pM,
@@ -680,6 +819,7 @@ pMotor SecMotorInit(char *name)
child = MakeHipadabaNode("softzero", HIPFLOAT, 1);
SetHdbProperty(child, "__save", "true");
+ SetHdbProperty(child, "priv", "user");
AddHipadabaChild(node, child, NULL);
AppendHipadabaCallback(child,
MakeHipadabaCallback(SecMotorZeroCallback, pM,
@@ -744,6 +884,13 @@ pMotor SecMotorInit(char *name)
SetHdbProperty(child, "motname", name);
AddHipadabaChild(node, child, NULL);
+ child = MakeHipadabaNode("error", HIPTEXT, 1);
+ AddHipadabaChild(node, child, NULL);
+
+ child = AddSICSHdbPar(node,"interest", usUser, MakeSICSFunc(InterestCmd));
+ AddSICSHdbPar(child, "name", usUser, MakeHdbText("UNKNOWN"));
+
+
pM->endScriptID = 0;
/* initialise Drivable interface */
@@ -791,6 +938,8 @@ static void SecMotorKill(void *data)
free(self->pDrivInt);
}
+ RemoveHdbNodeFromParent(self->objectNode,NULL);
+
if (self->pCall) {
DeleteCallBackInterface(self->pCall);
}
@@ -821,3 +970,25 @@ int SecMotorFactory(SConnection * pCon, SicsInterp * pSics, void *pData,
SecMotorKill, pNew);
}
+
+/*--------------------------------------------------------------------------
+ everywhere we need to find a motor for a name quite frequently.......
+----------------------------------------------------------------------------*/
+pMotor FindMotor(SicsInterp * pSics, char *name)
+{
+ CommandList *pC;
+ pMotor pMot;
+
+ pC = FindCommand(pSics, name);
+ if (!pC) {
+ return NULL;
+ }
+ pMot = (pMotor) pC->pData;
+ if (!pMot) {
+ return NULL;
+ }
+ if (strcmp(pMot->pDescriptor->name, "Motor") != 0 ) {
+ return NULL;
+ }
+ return pMot;
+}
diff --git a/multicounter.c b/multicounter.c
index 91e1e09f..a5c0647a 100644
--- a/multicounter.c
+++ b/multicounter.c
@@ -37,6 +37,7 @@ typedef struct {
pICountable slaves[MAXSLAVE];
char *transferScript;
int nSlaves;
+ int checkSlaves;
} MultiCounter, *pMultiCounter;
/*--------------------------------------------------------------------------*/
static void KillMultiDriver(struct __COUNTER *data)
@@ -77,12 +78,9 @@ static int MMCCHalt(void *pData)
/*-------------------------------------------------------------------------*/
static int MMCCStart(void *pData, SConnection * pCon)
{
- int i, status, controlMonitor;
- int slavePreset, oneYear = 32000000;
+ int i, status;
pCounter pCount = NULL;
pMultiCounter self = NULL;
- char buffer[128];
- CounterMode slaveMode;
pCount = (pCounter) pData;
if (pCount != NULL) {
@@ -93,25 +91,12 @@ static int MMCCStart(void *pData, SConnection * pCon)
if (!GetCountLock(pCount->pCountInt, pCon)) {
return HWFault;
}
- controlMonitor = GetControlMonitor((pCounter) pCount);
- if (pCount->pDriv->eMode == ePreset) {
- slaveMode = eTimer;
- slavePreset = oneYear;
- } else {
- slaveMode = pCount->pDriv->eMode;
- slavePreset = pCount->pDriv->fPreset;
- }
for (i = 0; i < self->nSlaves; i++) {
- ReleaseCountLock(self->slaves[i]);
- if (i == controlMonitor) {
- self->slaves[i]->SetCountParameters(self->slaveData[i],
- pCount->pDriv->fPreset,
- pCount->pDriv->eMode);
- } else {
- self->slaves[i]->SetCountParameters(self->slaveData[i],
- slavePreset, slaveMode);
- }
+ ReleaseCountLock(self->slaves[i]);
+ self->slaves[i]->SetCountParameters(self->slaveData[i],
+ pCount->pDriv->fPreset,
+ pCount->pDriv->eMode);
status = self->slaves[i]->StartCount(self->slaveData[i], pCon);
if (status != OKOK) {
MMCCHalt(pData);
@@ -122,24 +107,18 @@ static int MMCCStart(void *pData, SConnection * pCon)
pCount->isUpToDate = 0;
pCount->tStart = time(NULL);
InvokeCallBack(pCount->pCall, COUNTSTART, pCon);
+ self->checkSlaves = 0;
return OKOK;
}
/*-------------------------------------------------------------------------*/
+
static int MMCCStatus(void *pData, SConnection * pCon)
{
- int status, ctrStatus, i, controlMonitor;
- pCounter pCountController = NULL, pSlaveCounter = NULL;
+ int status, i;
pCounter pCount = NULL, pMaster = NULL;;
pMultiCounter self = NULL;
pDummy pDum = NULL;
- enum {
- eIdle,
- eBusy,
- ePause,
- eNoBeam,
- eFault
- } statusLevel;
pCount = (pCounter) pData;
if (pCount != NULL) {
@@ -153,63 +132,47 @@ static int MMCCStatus(void *pData, SConnection * pCon)
return HWFault;
}
- status = self->slaves[0]->CheckCountStatus(self->slaveData[0], pCon);
- pMaster = (pCounter)self->slaveData[0];
- pCount->pDriv->fLastCurrent = GetControlValue(pMaster);
- controlMonitor = GetControlMonitor((pCounter) pCount);
- pCountController = (pCounter) self->slaveData[controlMonitor];
-
- /* counter states = HWIdle, HWBusy, HWPause, HWNoBeam, HWFault */
- status = HWIdle;
- statusLevel = eIdle;
- for (i = 0; i < self->nSlaves; i++) {
- pSlaveCounter = (pCounter) self->slaveData[i];
- ctrStatus = self->slaves[i]->CheckCountStatus(pSlaveCounter, pCon);
- if (statusLevel >= eFault)
- continue;
- switch (ctrStatus) {
- case HWFault:
- statusLevel = eFault;
- status = HWFault;
- break;
- case HWNoBeam:
- if (statusLevel < eNoBeam)
- statusLevel = eNoBeam;
- status = HWNoBeam;
- break;
- case HWPause:
- if (statusLevel < ePause)
- statusLevel = ePause;
- status = HWPause;
- break;
- default:
- if (pCountController->pDriv->eMode == ePreset && i == controlMonitor
- && ctrStatus == HWIdle) {
- statusLevel = eBusy; /* Allow transition to HWPause or higher */
- status = HWIdle;
- } else if (statusLevel < eBusy && ctrStatus != HWIdle) {
- /* ffr: We expect !HWIdle means HWBusy, if not the existing code should handle the exception */
- statusLevel = eBusy;
- status = ctrStatus;
- }
+ if(self->checkSlaves == 0) {
+ status = self->slaves[0]->CheckCountStatus(self->slaveData[0], pCon);
+ if (status == HWIdle || status == HWFault) {
+ /*
+ stop counting on slaves when finished or when an error
+ occurred.
+ */
+ MMCCHalt(pData);
+ ReleaseCountLock(pCount->pCountInt);
+ self->checkSlaves = 1;
+ status = HWBusy;
}
- }
- if (status == HWIdle || status == HWFault) {
+ pCount->pDriv->fLastCurrent = GetControlValue(self->slaveData[0]);
+ } else {
/*
- stop counting on slaves when finished or when an error
- occurred.
+ * wait for the detectors to report finish too. Otherwise, with the second
+ * generation HM data may not be fully transferred.
*/
- InvokeCallBack(pCount->pCall, COUNTEND, pCon);
- MMCCHalt(pCount);
- }
- for (i = 1; i < MAXSLAVE; i++) {
- if (self->slaves[i] != NULL) {
- pDum = (pDummy) self->slaveData[i];
- if (strcmp(pDum->pDescriptor->name, "HistMem") == 0) {
- HistDirty((pHistMem) self->slaveData[i]);
+ for(i = 1; i < self->nSlaves; i++){
+ status = self->slaves[i]->CheckCountStatus(self->slaveData[i], pCon);
+ if(!(status == HWIdle || status == HWFault)){
+ return status;
}
- ReleaseCountLock(self->slaves[i]);
}
+ /*
+ Warning: this assumes that slaves 1 - MAXSLAVE are histogram memories.
+ If this assumption does not hold, change this code to check if this
+ is really a histogram memory.
+ */
+ for (i = 1; i < self->nSlaves; i++) {
+ if (self->slaves[i] != NULL) {
+ pDum = (pDummy)self->slaveData[i];
+ if (strcmp(pDum->pDescriptor->name, "HistMem") == 0) {
+ HistDirty((pHistMem) self->slaveData[i]);
+ }
+ ReleaseCountLock(self->slaves[i]);
+ }
+ }
+ status = HWIdle;
+ InvokeCallBack(pCount->pCall, COUNTEND, pCon);
+ self->checkSlaves = 0;
}
return status;
}
@@ -293,8 +256,7 @@ static void loadCountData(pCounter pCount, const char *data)
pPtr = (char *) data;
pPtr = getNextMMCCNumber(pPtr, pNumber);
- // SICS-195 get time from controlling monitor
- // pCount->pDriv->fTime = atof(pNumber);
+ pCount->pDriv->fTime = atof(pNumber);
while (pPtr != NULL && i < MAXCOUNT) {
pPtr = getNextMMCCNumber(pPtr, pNumber);
pCount->pDriv->lCounts[i] = atoi(pNumber);
@@ -308,19 +270,14 @@ static int MMCCTransfer(void *pData, SConnection * pCon)
int i, retVal = OKOK, status;
char pBueffel[132];
pCounter pCount = NULL;
- pCounter pCountController = NULL, pCountSlave;
pMultiCounter self = NULL;
int tclStatus;
- int controlMonitor;
- double avCntRt;
pCount = (pCounter) pData;
if (pCount != NULL) {
self = (pMultiCounter) pCount->pDriv->pData;
}
assert(self);
- controlMonitor = GetControlMonitor(pCount);
- pCountController = (pCounter) self->slaveData[controlMonitor];
for (i = 0; i < self->nSlaves; i++) {
status = self->slaves[i]->TransferData(self->slaveData[i], pCon);
@@ -329,18 +286,8 @@ static int MMCCTransfer(void *pData, SConnection * pCon)
snprintf(pBueffel,sizeof(pBueffel)-1,
"WARNING: slave histogram %d failed to transfer data", i);
SCWrite(pCon, pBueffel, eWarning);
- } else if (pCountController->pDriv->eMode == ePreset) {
- if (i != controlMonitor) {
- pCountSlave = (pCounter) self->slaveData[i];
- avCntRt =
- pCountSlave->pDriv->lCounts[0] / pCountSlave->pDriv->fTime;
- pCountSlave->pDriv->lCounts[0] =
- avCntRt * pCountController->pDriv->fTime;
- pCountSlave->pDriv->fTime = pCountController->pDriv->fTime;
- }
}
}
- pCount->pDriv->fTime = pCountController->pDriv->fTime;
if (self->transferScript != NULL) {
MacroPush(pCon);
tclStatus = Tcl_Eval(InterpGetTcl(pServ->pSics), self->transferScript);
@@ -380,74 +327,74 @@ static void MMCCParameter(void *pData, float fPreset, CounterMode eMode)
static int MultiCounterSet(struct __COUNTER *pCount, char *name,
int iCter, float fVal)
{
- pDummy pDum;
- int i;
- pMultiCounter self = NULL;
- pCounter pCter;
+ pDummy pDum;
+ int i;
+ pMultiCounter self = NULL;
+ pCounter pCter;
+
+ self = (pMultiCounter) pCount->pData;
+ assert(self);
- self = (pMultiCounter) pCount->pData;
- assert(self);
-
- for (i = 0; i < self->nSlaves; i++) {
- pDum = (pDummy)self->slaveData[i];
- if(strcmp(pDum->pDescriptor->name, "SingleCounter") == 0){
- pCter = (pCounter)self->slaveData[i];
- if(pCter->pDriv != NULL){
- return pCter->pDriv->Set(pCter->pDriv, name, iCter, fVal);
- } else {
- return 0;
- }
- }
- }
- return 0;
+ for (i = 0; i < self->nSlaves; i++) {
+ pDum = (pDummy)self->slaveData[i];
+ if(strcmp(pDum->pDescriptor->name, "SingleCounter") == 0){
+ pCter = (pCounter)self->slaveData[i];
+ if(pCter->pDriv != NULL){
+ return pCter->pDriv->Set(pCter->pDriv, name, iCter, fVal);
+ } else {
+ return 0;
+ }
+ }
+ }
+ return 0;
}
/*-----------------------------------------------------------------------*/
static int MultiCounterGet(struct __COUNTER *pCount, char *name,
int iCter, float *fVal)
{
- pDummy pDum;
- int i;
- pMultiCounter self = NULL;
- pCounter pCter;
- pHdb node;
- hdbValue v;
+ pDummy pDum;
+ int i;
+ pMultiCounter self = NULL;
+ pCounter pCter;
+ pHdb node;
+ hdbValue v;
+
+ self = (pMultiCounter) pCount->pData;
+ assert(self);
- self = (pMultiCounter) pCount->pData;
- assert(self);
-
- for (i = 0; i < self->nSlaves; i++) {
- pDum = (pDummy)self->slaveData[i];
- if(strcmp(pDum->pDescriptor->name, "SingleCounter") == 0){
- pCter = (pCounter)self->slaveData[i];
- if(pCter->pDriv != NULL){
- return pCter->pDriv->Get(pCter->pDriv, name, iCter, fVal);
- } else {
- return 0;
- }
- }
- }
- return 0;
+ for (i = 0; i < self->nSlaves; i++) {
+ pDum = (pDummy)self->slaveData[i];
+ if(strcmp(pDum->pDescriptor->name, "SingleCounter") == 0){
+ pCter = (pCounter)self->slaveData[i];
+ if(pCter->pDriv != NULL){
+ return pCter->pDriv->Get(pCter->pDriv, name, iCter, fVal);
+ } else {
+ return 0;
+ }
+ }
+ }
+ return 0;
}
/*-----------------------------------------------------------------------*/
static int MultiCounterSend(struct __COUNTER *pCount, char *pText,
char *reply, int replylen)
{
- pDummy pDum;
- int i;
- pMultiCounter self = NULL;
- pCounter pCter;
+ pDummy pDum;
+ int i;
+ pMultiCounter self = NULL;
+ pCounter pCter;
+
+ self = (pMultiCounter) pCount->pData;
+ assert(self);
- self = (pMultiCounter) pCount->pData;
- assert(self);
-
- for (i = 0; i < self->nSlaves; i++) {
- pDum = (pDummy)self->slaveData[i];
- if(strcmp(pDum->pDescriptor->name, "SingleCounter") == 0){
- pCter = (pCounter)self->slaveData[i];
- return pCter->pDriv->Send(pCter->pDriv,pText, reply, replylen);
- }
- }
- return 0;
+ for (i = 0; i < self->nSlaves; i++) {
+ pDum = (pDummy)self->slaveData[i];
+ if(strcmp(pDum->pDescriptor->name, "SingleCounter") == 0){
+ pCter = (pCounter)self->slaveData[i];
+ return pCter->pDriv->Send(pCter->pDriv,pText, reply, replylen);
+ }
+ }
+ return 0;
}
/*---------------------------------------------------------------------*/
static int MultiCounterError(struct __COUNTER *pDriv, int *iCode,
@@ -539,30 +486,6 @@ int MakeMultiCounter(SConnection * pCon, SicsInterp * pSics,
pDriv->pData = self;
pDriv->KillPrivate = KillMultiDriver;
pDriv->iNoOfMonitors = MAXCOUNT;
- /*
- now loop through the remaining arguments, thereby entering them into
- the slave list.
- */
- self->nSlaves = 0;
- for (i = 2; i < argc; i++) {
- pCom = FindCommand(pSics, argv[i]);
- if (!pCom) {
- snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: object %s not found in MakeMultiCounter",
- argv[i]);
- SCWrite(pCon, pBueffel, eError);
- continue;
- }
- pCount = GetCountableInterface(pCom->pData);
- if (!pCount) {
- snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: object %s is NOT countable", argv[i]);
- SCWrite(pCon, pBueffel, eError);
- continue;
- }
- self->slaves[self->nSlaves] = pCount;
- self->slaveData[self->nSlaves] = pCom->pData;
- self->nSlaves++;
- }
- pDriv->iNoOfMonitors = self->nSlaves;
pNew = CreateCounter(argv[1], pDriv);
if (pNew == NULL) {
SCWrite(pCon, "ERROR: out of memory in MakeMultiCounter", eError);
@@ -585,6 +508,29 @@ int MakeMultiCounter(SConnection * pCon, SicsInterp * pSics,
pNew->pCountInt->TransferData = MMCCTransfer;
pNew->pCountInt->SetCountParameters = MMCCParameter;
+ /*
+ now loop through the remaining arguments, thereby entering them into
+ the slave list.
+ */
+ for (i = 2; i < argc; i++) {
+ pCom = FindCommand(pSics, argv[i]);
+ if (!pCom) {
+ snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: object %s not found in MakeMultiCounter",
+ argv[i]);
+ SCWrite(pCon, pBueffel, eError);
+ continue;
+ }
+ pCount = GetCountableInterface(pCom->pData);
+ if (!pCount) {
+ snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: object %s is NOT countable", argv[i]);
+ SCWrite(pCon, pBueffel, eError);
+ continue;
+ }
+ self->slaves[self->nSlaves] = pCount;
+ self->slaveData[self->nSlaves] = pCom->pData;
+ self->nSlaves++;
+ }
+
/*
now install our action command and we are done
*/
diff --git a/multicountersec.c b/multicountersec.c
new file mode 100644
index 00000000..c94b2c0f
--- /dev/null
+++ b/multicountersec.c
@@ -0,0 +1,564 @@
+/**
+ * This is a second generation multicounter. It coordinates counting multiple
+ * HM/CCD with the counter box. It also allows to override transfer such that
+ * such a counter can be used in a scan. As with the ordinary multicounter.
+ * This one is supposed to become the standard multicounter replacing the old
+ * multicounter and the hmcontrol module. The other difference is that the task
+ * mechanism will be used to keep track of counters.
+ *
+ * copyright: see file COPYRIGHT
+ *
+ * Mark Koennecke, October 2013
+ */
+#include
+#include
+#include
+#include
+#include
+#include
+#include "sicshipadaba.h"
+/*---------------------------------------------------------------------------*/
+typedef struct {
+ float fPreset;
+ float fCurrent;
+ char *pName;
+} MonEvent, *pMonEvent;
+/*-------------------------------------------------------------------------*/
+static void SecCounterSetError(pCounter self, char *text)
+{
+ hdbValue v;
+ pHdb node;
+
+ node = GetHipadabaNode(self->pDes->parNode, "error");
+ if(node != NULL){
+ v = MakeHdbText(strdup(text));
+ UpdateHipadabaPar(node,v,NULL);
+ ReleaseHdbValue(&v);
+ }
+}
+/*---------------------------------------------------------------------------------*/
+static void doCountCommand(pHdb self, SConnection *pCon, int command)
+{
+ pHdb master = NULL, slaves = NULL;
+ char *pPtr, name[80];
+ pICountable pCount = NULL;
+ void *data;
+
+ master = GetHipadabaNode(self,"master");
+ slaves = GetHipadabaNode(self,"slaves");
+ assert(master != NULL);
+ assert(slaves != NULL);
+
+ /*
+ treat master
+ */
+ data = FindCommandData(pServ->pSics,master->value.v.text,NULL);
+ if(data != NULL){
+ pCount = GetCountableInterface(data);
+ if(pCount != NULL){
+ switch(command){
+ case 1001: /* stop */
+ pCount->Halt(data);
+ break;
+ case 1002: /*pause */
+ pCount->Pause(data,pCon);
+ break;
+ case 1003: /* continue */
+ pCount->Continue(data,pCon);
+ break;
+ case 1011:
+ break;
+ default:
+ assert(0);
+ }
+ }
+ }
+
+ /*
+ treat slaves
+ */
+ pPtr = slaves->value.v.text;
+ while((pPtr = stptok(pPtr,name,sizeof(name),",")) != NULL){
+ data = FindCommandData(pServ->pSics,name,NULL);
+ if(data != NULL){
+ pCount = GetCountableInterface(data);
+ if(pCount != NULL){
+ switch(command){
+ case 1001: /* stop */
+ case 1011:
+ pCount->Halt(data);
+ break;
+ case 1002: /*pause */
+ pCount->Pause(data,pCon);
+ break;
+ case 1003: /* continue */
+ pCount->Continue(data,pCon);
+ break;
+ default:
+ assert(0);
+ }
+ }
+ }
+ if(data == NULL || pCount == NULL){
+ SCPrintf(pCon,eLogError,"ERROR: slave counter %s NOT found or unusable", name);
+ }
+ }
+}
+/*---------------------------------------------------------------------------------*/
+static void copyExponent(pHdb self, void *data)
+{
+ pHdb source = NULL, target = NULL;
+
+ pCounter count = (pCounter)data;
+ source = GetHipadabaNode(self,"exponent");
+ target = GetHipadabaNode(count->pDes->parNode,"exponent");
+ if(source != NULL && target != NULL){
+ UpdateHipadabaPar(target,MakeHdbInt(source->value.v.intValue), NULL);
+ }
+}
+/*---------------------------------------------------------------------------------*/
+static void startMultiCounting(pHdb self, SConnection *pCon)
+{
+ pHdb mode = NULL, preset = NULL, master = NULL, slaves = NULL;
+ pHdb sID, mID;
+ char *pPtr, name[80];
+ pICountable pCount = NULL;
+ void *data;
+ long slaveID, masterID;
+ CounterMode eMode;
+ hdbValue v;
+
+ mode = GetHipadabaNode(self,"mode");
+ preset = GetHipadabaNode(self,"preset");
+ master = GetHipadabaNode(self,"master");
+ slaves = GetHipadabaNode(self,"slaves");
+ sID = GetHipadabaNode(self,"slaveID");
+ mID = GetHipadabaNode(self,"masterID");
+ assert(mode != NULL);
+ assert(preset != NULL);
+ assert(master != NULL);
+ assert(slaves != NULL);
+ assert(sID != NULL);
+ assert(mID != NULL);
+
+ strtolower(mode->value.v.text);
+ if(strcmp(mode->value.v.text,"timer") == 0) {
+ eMode = eTimer;
+ } else {
+ eMode = ePreset;
+ }
+
+ /*
+ start slaves
+ */
+ slaveID = GetTaskGroupID(pServ->pTasker);
+ pPtr = slaves->value.v.text;
+ while((pPtr = stptok(pPtr,name,sizeof(name),",")) != NULL){
+ data = FindCommandData(pServ->pSics,name,NULL);
+ if(data != NULL){
+ pCount = GetCountableInterface(data);
+ if(pCount != NULL){
+ copyExponent(self,data);
+ pCount->SetCountParameters(data,preset->value.v.doubleValue,
+ eMode);
+ masterID = StartCountTask(data,pCon,name);
+ if(masterID < 0) {
+ SCPrintf(pCon,eLogError,"ERROR: failed to start slave %s, aborting", name);
+ doCountCommand(self,pCon,1001);
+ return;
+ } else {
+ AddTaskToGroup(pServ->pTasker,masterID, slaveID);
+ }
+ }
+ }
+ if(data == NULL || pCount == NULL){
+ SCPrintf(pCon,eLogError,"ERROR: slave counter %s NOT found or unusable", name);
+ }
+ }
+
+
+ /*
+ start master
+ */
+ data = FindCommandData(pServ->pSics,master->value.v.text,NULL);
+ if(data != NULL){
+ pCount = GetCountableInterface(data);
+ if(pCount != NULL){
+ copyExponent(self,data);
+ pCount->SetCountParameters(data,preset->value.v.doubleValue,
+ eMode);
+ masterID = StartCountTask(data,pCon,master->value.v.text);
+ }
+ }
+
+ v = MakeHdbInt(masterID);
+ UpdateHipadabaPar(mID,v,pCon);
+ v = MakeHdbInt(slaveID);
+ UpdateHipadabaPar(sID,v,pCon);
+
+}
+/*---------------------------------------------------------------------------------*/
+static hdbCallbackReturn MultiSecControllCallback(pHdb node,
+ void *userData,
+ pHdbMessage message)
+{
+ pHdbDataMessage mm = NULL;
+ pHdb self = NULL;
+ int code;
+ SConnection *pCon = NULL;
+
+ mm = GetHdbSetMessage(message);
+ if(mm == NULL){
+ return hdbContinue;
+ }
+
+ code = (int)mm->v->v.doubleValue;
+ pCon = (SConnection *)mm->callData;
+ self = node->mama;
+ assert(self != NULL);
+
+ switch(code){
+ case 1000: /* start */
+ startMultiCounting(self, pCon);
+ break;
+ case 1001: /* stop */
+ doCountCommand(self,pCon,code);
+ break;
+ case 1002: /*pause */
+ doCountCommand(self,pCon,code);
+ break;
+ case 1003: /* continue */
+ doCountCommand(self,pCon,code);
+ break;
+ default:
+ if(pCon != NULL){
+ SCPrintf(pCon,eLogError,"ERROR: control code %d not recognised", code);
+ return hdbAbort;
+ }
+ }
+
+ return hdbContinue;
+}
+/*-------------------------------------------------------------------------2-*/
+static int MultiSecTransfer(void *pData, SConnection * pCon)
+{
+ int i, retVal = OKOK, tclStatus;
+ char pBueffel[132];
+ pCounter pCount = NULL;
+ pHdb transfer;
+ SConnection *myCon;
+
+ pCount = (pCounter) pData;
+
+ transfer = GetHipadabaNode(pCount->objectNode,"transfer");
+ if(transfer != NULL){
+ myCon = SCCopyConnection(pCon);
+ SCsetMacro(myCon,1);
+ MacroPush(myCon);
+ tclStatus = Tcl_Eval(InterpGetTcl(pServ->pSics), transfer->value.v.text);
+ if (tclStatus != TCL_OK) {
+ snprintf(pBueffel, 131, "ERROR: TransferScript returned: %s",
+ Tcl_GetStringResult(InterpGetTcl(pServ->pSics)));
+ SCWrite(pCon, pBueffel, eError);
+ MacroPop();
+ SCDeleteConnection(myCon);
+ return HWFault;
+ }
+ MacroPop();
+ SCDeleteConnection(myCon);
+ }
+ return retVal;
+}
+/*-------------------------------------------------------------------------------------*/
+ static int isMultiMasterRunning(pCounter self, SConnection *pCon, int *status)
+ {
+ pHdb mID, master, myStatus, control, ccd, stopTime, timeNode;
+ hdbValue v;
+ long mlID;
+ void *data;
+ pICountable pCount;
+ float controlVal, tVal;
+ MonEvent sMon;
+
+ mID = GetHipadabaNode(self->objectNode,"masterID");
+ master = GetHipadabaNode(self->objectNode,"master");
+ myStatus = GetHipadabaNode(self->objectNode,"status");
+ control = GetHipadabaNode(self->objectNode,"control");
+ ccd = GetHipadabaNode(self->objectNode,"ccd");
+ stopTime = GetHipadabaNode(self->objectNode,"stopTime");
+ timeNode = GetHipadabaNode(self->objectNode,"time");
+ assert(mID != NULL);
+ assert(master != NULL);
+ assert(myStatus != NULL);
+ assert(control != NULL);
+ assert(ccd != NULL);
+ assert(stopTime != NULL);
+ assert(timeNode != NULL);
+
+
+ mlID = mID->value.v.intValue;
+ if(mlID == 0) {
+ return 0;
+ }
+
+ data = FindCommandData(pServ->pSics,master->value.v.text,NULL);
+ assert(data != NULL);
+ pCount = GetCountableInterface(data);
+ assert(pCount != NULL);
+
+ if(isTaskIDRunning(pServ->pTasker,mlID)) {
+ *status = pCount->CheckCountStatus(data,pCon);
+ controlVal = GetControlValue((pCounter)data);
+ UpdateHipadabaPar(control,MakeHdbFloat(controlVal),pCon);
+ tVal = GetCountTime((pCounter)data,pCon);
+ UpdateHipadabaPar(timeNode,MakeHdbFloat(tVal),pCon);
+ SecCounterSetError(self,"None");
+ switch(*status){
+ case HWFault:
+ UpdateHipadabaPar(myStatus,MakeHdbText("error"),pCon);
+ UpdateHipadabaPar(stopTime,MakeHdbInt(time(NULL)),pCon);
+ SecCounterSetError(self,"Master counter errror");
+ *status = HWBusy;
+ break;
+ case HWPause:
+ UpdateHipadabaPar(myStatus,MakeHdbText("paused"),pCon);
+ *status = HWPause;
+ break;
+ case HWNoBeam:
+ UpdateHipadabaPar(myStatus,MakeHdbText("nobeam"),pCon);
+ *status = HWNoBeam;
+ break;
+ default:
+ *status = HWBusy;
+ UpdateHipadabaPar(myStatus,MakeHdbText("run"),pCon);
+ if (self->iCallbackCounter > 20) {
+ MultiSecTransfer(self,pCon);
+ sMon.fCurrent = controlVal;
+ sMon.fPreset = GetCounterPreset(self);
+ sMon.pName = self->name;
+ InvokeCallBack(self->pCall, MONITOR, &sMon);
+ self->iCallbackCounter = 0;
+ } else {
+ self->iCallbackCounter++;
+ }
+ break;
+ }
+ } else {
+ /*
+ we recently stopped. Mark it so and stop slaves.
+ */
+ mID->value.v.intValue = 0;
+ *status = HWBusy;
+ UpdateHipadabaPar(myStatus,MakeHdbText("run"),pCon);
+ UpdateHipadabaPar(stopTime,MakeHdbInt(time(NULL)),pCon);
+ tVal = GetCountTime((pCounter)data,pCon);
+ UpdateHipadabaPar(timeNode,MakeHdbFloat(tVal),pCon);
+ if(ccd->value.v.intValue != 1) {
+ doCountCommand(self->objectNode,pCon,1011);
+ }
+ }
+ return 1;
+ }
+ /*-------------------------------------------------------------------------------------*/
+ static int areSlavesRunning(pCounter self, SConnection *pCon, int *status)
+ {
+ pHdb slaveID, myStatus, stopTime, ccd;
+ int i;
+
+ slaveID = GetHipadabaNode(self->objectNode,"slaveID");
+ myStatus = GetHipadabaNode(self->objectNode,"status");
+ stopTime = GetHipadabaNode(self->objectNode,"stopTime");
+ ccd = GetHipadabaNode(self->objectNode,"ccd");
+ assert(slaveID != NULL);
+ assert(myStatus != NULL);
+ assert(stopTime != NULL);
+ assert(ccd != NULL);
+
+ if(isTaskGroupRunning(pServ->pTasker,slaveID->value.v.intValue)){
+ if(ccd->value.v.intValue == 1 && time(NULL) > stopTime->value.v.intValue + 100) {
+ SCWrite(pCon,"WARNING: CCD overrun, restarting counting...", eLogError);
+ self->pCountInt->Halt(self);
+ ReleaseCountLock(self->pCountInt);
+ for(i = 0; i < 100; i++){
+ SicsWait(1);
+ if(!isTaskGroupRunning(pServ->pTasker,slaveID->value.v.intValue)){
+ self->pCountInt->StartCount(self,pCon);
+ UpdateHipadabaPar(myStatus,MakeHdbText("run"),pCon);
+ UpdateHipadabaPar(stopTime,MakeHdbInt(time(NULL)),pCon);
+ *status = HWBusy;
+ return 1;
+ }
+ }
+ SCWrite(pCon,"ERROR: failed to stop overrun CCD",eLogError);
+ *status = HWFault;
+ } else {
+ *status = HWBusy;
+ UpdateHipadabaPar(myStatus,MakeHdbText("run"),pCon);
+ return 1;
+ }
+ } else {
+ *status = HWIdle;
+ UpdateHipadabaPar(myStatus,MakeHdbText("idle"),pCon);
+ return 0;
+ }
+ return 1;
+ }
+/*------------------------------------------------------------------------------------*/
+static void multiEndCounting(pCounter self, SConnection *pCon)
+{
+
+ InvokeCallBack(self->pCall, COUNTEND, NULL);
+ ReleaseCountLock(self->pCountInt);
+ MultiSecTransfer(self,pCon);
+
+}
+/*-------------------------------------------------------------------------------------*/
+static int MultiSecStatus(void *pData, SConnection * pCon)
+{
+ int status;
+ void *data;
+ pICountable pCount = NULL;
+ pHdb mID = NULL, sID = NULL, master;
+ pCounter self = (pCounter)pData;
+
+
+ if(isMultiMasterRunning(self,pCon, &status)){
+ return status;
+ }
+
+ if(areSlavesRunning(self,pCon, &status)){
+ return status;
+ }
+
+ multiEndCounting(self,pCon);
+
+ return HWIdle;
+}
+/*---------------------------------------------------------------------------
+ Forward unknown commands to the master counter
+ -----------------------------------------------------------------------------*/
+static int MultiInvokeSICSOBJ(SConnection * pCon, SicsInterp * pSics, void *pData,
+ int argc, char *argv[])
+{
+ int status;
+ char buffer[132];
+ pHdb master = NULL;
+ pCounter self = (pCounter)pData;
+ void *data = NULL;
+ CommandList *pCom;
+
+ status = InvokeSICSOBJ(pCon, pSics, pData, argc, argv);
+ if (status == -1) {
+ master = GetHipadabaNode(self->objectNode,"master");
+ assert(master != NULL);
+ pCom = FindCommand(pSics,master->value.v.text);
+ if(pCom != NULL){
+ status = pCom->OFunc(pCon,pSics,pCom->pData,argc,argv);
+ }
+ status = 0;
+ }
+ return status;
+}
+/*-------------------------------------------------------------------------------------*/
+int MakeMultiSec(SConnection * pCon, SicsInterp * pSics, void *pData,
+ int argc, char *argv[])
+{
+ pCounter pRes = NULL;
+ int status, length;
+ pHdb node, child;
+
+ if(argc < 3) {
+ SCWrite(pCon,"ERROR: need at least a name and length to create a counter",
+ eError);
+ return 0;
+ }
+ length = atoi(argv[2]);
+
+ pRes = CreateSecCounter(pCon,"SingleCounter", argv[1], length);
+ if(pRes == NULL){
+ return 0;
+ }
+
+ pRes->pCountInt->CheckCountStatus = MultiSecStatus;
+ pRes->pCountInt->TransferData = MultiSecTransfer;
+
+ node = pRes->objectNode;
+ child = GetHipadabaNode(node,"control");
+ AppendHipadabaCallback(child,MakeHipadabaCallback(MultiSecControllCallback,NULL,NULL));
+
+ child = MakeSICSHdbPar("master", usMugger, MakeHdbText(""));
+ if (child == NULL) {
+ SCWrite(pCon,"ERROR: out of memory in MakeMultiCounterSec",eError);
+ return 0;
+ } else {
+ SetHdbProperty(child, "__save", "true");
+ AddHipadabaChild(node, child, NULL);
+ }
+
+ child = MakeSICSHdbPar("transfer", usMugger, MakeHdbText(""));
+ if (child == NULL) {
+ SCWrite(pCon,"ERROR: out of memory in MakeMultiCounterSec",eError);
+ return 0;
+ } else {
+ SetHdbProperty(child, "__save", "true");
+ AddHipadabaChild(node, child, NULL);
+ }
+
+ child = MakeSICSHdbPar("error", usMugger, MakeHdbText("None"));
+ if (child == NULL) {
+ SCWrite(pCon,"ERROR: out of memory in MakeMultiCounterSec",eError);
+ return 0;
+ } else {
+ AddHipadabaChild(node, child, NULL);
+ }
+
+ child = MakeSICSHdbPar("slaves", usMugger, MakeHdbText(""));
+ if (child == NULL) {
+ SCWrite(pCon,"ERROR: out of memory in MakeMultiCounterSec",eError);
+ return 0;
+ } else {
+ SetHdbProperty(child, "__save", "true");
+ AddHipadabaChild(node, child, NULL);
+ }
+
+ child = MakeSICSHdbPar("ccd", usMugger, MakeHdbInt(0));
+ if (child == NULL) {
+ SCWrite(pCon,"ERROR: out of memory in MakeMultiCounterSec",eError);
+ return 0;
+ } else {
+ SetHdbProperty(child, "__save", "true");
+ AddHipadabaChild(node, child, NULL);
+ }
+
+ child = MakeSICSHdbPar("stopTime", usInternal, MakeHdbInt(0));
+ if (child == NULL) {
+ SCWrite(pCon,"ERROR: out of memory in MakeMultiCounterSec",eError);
+ return 0;
+ } else {
+ AddHipadabaChild(node, child, NULL);
+ }
+
+ child = MakeSICSHdbPar("masterID", usInternal, MakeHdbInt(0));
+ if (child == NULL) {
+ SCWrite(pCon,"ERROR: out of memory in MakeMultiCounterSec",eError);
+ return 0;
+ } else {
+ AddHipadabaChild(node, child, NULL);
+ }
+ child = MakeSICSHdbPar("slaveID", usInternal, MakeHdbInt(0));
+ if (child == NULL) {
+ SCWrite(pCon,"ERROR: out of memory in MakeMultiCounterSec",eError);
+ return 0;
+ } else {
+ AddHipadabaChild(node, child, NULL);
+ }
+
+ status =
+ AddCommand(pSics, argv[1], MultiInvokeSICSOBJ, DeleteCounter,
+ (void *) pRes);
+ if (status != 1) {
+ SCPrintf(pCon,eError, "ERROR: duplicate command %s not created", argv[1]);
+ return 0;
+ }
+ return 1;
+}
diff --git a/mumo.c b/mumo.c
index 94ae6139..96b2d9cc 100644
--- a/mumo.c
+++ b/mumo.c
@@ -683,6 +683,9 @@ static void RecoverNamPos(pMulMot self, int argc, char *argv[])
decrement, increment and simple values.
DingsBums pos name - makes the current position a named
position with name name.
+ DingsBums defpos name [alias value..] - makes a named
+ position with name name. The par is a list of alias value
+ pairs with the appropriate positions for name.
DingsBums getpos - gets the current named position
DingsBums drop name - deletes the current named position
name.
@@ -841,7 +844,7 @@ int MultiWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
case RECOVERNAMPOS:
/*
This is not meant to be user command but a facility to read
- back data from sattus file. This is why the error checking
+ back data from status file. This is why the error checking
is not happening
*/
RecoverNamPos(self, argc - 2, &argv[2]);
diff --git a/mumoconf.c b/mumoconf.c
index d0f08643..cf7a5cdf 100644
--- a/mumoconf.c
+++ b/mumoconf.c
@@ -158,28 +158,6 @@ static int GetNextToken(psParser self)
return UNKNOWN;
}
-/*--------------------------------------------------------------------------
- in this code we need to find a motor for a name quite frequently.......
-*/
-pMotor FindMotor(SicsInterp * pSics, char *name)
-{
- CommandList *pC;
- pMotor pMot;
-
- pC = FindCommand(pSics, name);
- if (!pC) {
- return NULL;
- }
- pMot = (pMotor) pC->pData;
- if (!pMot) {
- return NULL;
- }
- if (strcmp(pMot->pDescriptor->name, "Motor") != 0) {
- return NULL;
- }
- return pMot;
-}
-
/*--------------------------------------------------------------------------*/
int MakeMulti(SConnection * pCon, SicsInterp * pSics, void *pData,
diff --git a/napi.c b/napi.c
deleted file mode 100644
index 197f1250..00000000
--- a/napi.c
+++ /dev/null
@@ -1,2133 +0,0 @@
-/*---------------------------------------------------------------------------
- NeXus - Neutron & X-ray Common Data Format
-
- Application Program Interface Routines
-
- Copyright (C) 1997-2006 Mark Koennecke, Przemek Klosowski
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- For further information, see
-
-----------------------------------------------------------------------------*/
-
-static const char* rscid = "$Id$"; /* Revision inserted by CVS */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "nxconfig.h"
-#include "napi.h"
-#include "nxstack.h"
-
-/*---------------------------------------------------------------------
- Recognized and handled napimount URLS
- -----------------------------------------------------------------------*/
-#define NXBADURL 0
-#define NXFILE 1
-
-/*--------------------------------------------------------------------*/
-static int iFortifyScope;
-/*----------------------------------------------------------------------
- This is a section with code for searching the NX_LOAD_PATH
- -----------------------------------------------------------------------*/
-#ifdef _WIN32
-#define LIBSEP ";"
-#define PATHSEP "\\"
-#define THREAD_LOCAL __declspec(thread)
-#else
-#define LIBSEP ":"
-#define PATHSEP "/"
-#define THREAD_LOCAL __thread
-#endif
-
-#ifdef _MSC_VER
-#define snprintf _snprintf
-#endif /* _MSC_VER */
-
-#include "nx_stptok.h"
-
-#if defined(_WIN32)
-/*
- * HDF5 on windows does not do locking for multiple threads conveniently so we will implement it ourselves.
- * Freddie Akeroyd, 16/06/2011
- */
-#include
-
-
-static CRITICAL_SECTION nx_critical;
-
-static int nxilock()
-{
- static int first_call = 1;
- if (first_call)
- {
- first_call = 0;
- InitializeCriticalSection(&nx_critical);
- }
- EnterCriticalSection(&nx_critical);
- return NX_OK;
-}
-
-static int nxiunlock(int ret)
-{
- LeaveCriticalSection(&nx_critical);
- return ret;
-}
-
-#define LOCKED_CALL(__call) \
- ( nxilock() , nxiunlock(__call) )
-
-#elif HAVE_LIBPTHREAD
-
-#include
-
-static pthread_mutex_t nx_mutex;
-
-#ifdef PTHREAD_MUTEX_RECURSIVE
-#define RECURSIVE_LOCK PTHREAD_MUTEX_RECURSIVE
-#else
-#define RECURSIVE_LOCK PTHREAD_MUTEX_RECURSIVE_NP
-#endif /* PTHREAD_MUTEX_RECURSIVE */
-
-static void nx_pthread_init()
-{
- pthread_mutexattr_t attr;
- pthread_mutexattr_init(&attr);
- pthread_mutexattr_settype(&attr, RECURSIVE_LOCK);
- pthread_mutex_init(&nx_mutex, &attr);
-}
-
-static int nxilock()
-{
- static pthread_once_t once_control = PTHREAD_ONCE_INIT;
- if (pthread_once(&once_control, nx_pthread_init) != 0)
- {
- NXReportError("pthread_once failed");
- return NX_ERROR;
- }
- if (pthread_mutex_lock(&nx_mutex) != 0)
- {
- NXReportError("pthread_mutex_lock failed");
- return NX_ERROR;
- }
- return NX_OK;
-}
-
-static int nxiunlock(int ret)
-{
- if (pthread_mutex_unlock(&nx_mutex) != 0)
- {
- NXReportError("pthread_mutex_unlock failed");
- return NX_ERROR;
- }
- return ret;
-}
-
-#define LOCKED_CALL(__call) \
- ( nxilock() , nxiunlock(__call) )
-
-#else
-
-#define LOCKED_CALL(__call) \
- __call
-
-#endif /* _WIN32 */
-
-/**
- * valid NeXus names
- */
-int validNXName(const char* name, int allow_colon)
-{
- int i;
- if (name == NULL)
- {
- return 0;
- }
- for(i=0; i= 'a' && name[i] <= 'z') ||
- (name[i] >= 'A' && name[i] <= 'Z') ||
- (name[i] >= '0' && name[i] <= '9') ||
- (name[i] == '_') )
- {
- ;
- }
- else if (allow_colon && name[i] == ':')
- {
- ;
- }
- else
- {
- return 0;
- }
- }
- return 1;
-}
-
-static int64_t* dupDimsArray(int* dims_array, int rank)
-{
- int i;
- int64_t* dims64 = (int64_t*)malloc(rank * sizeof(int64_t));
- if (dims64 != NULL)
- {
- for(i=0; i 0)
- {
- nx_cacheSize = newVal;
- return NX_OK;
- }
- return NX_ERROR;
-}
-
-/*-----------------------------------------------------------------------*/
-static NXstatus NXisXML(CONSTCHAR *filename)
-{
- FILE *fd = NULL;
- char line[132];
-
- fd = fopen(filename,"r");
- if(fd) {
- int fgets_ok = (fgets(line,131,fd) != NULL);
- fclose(fd);
- if (fgets_ok) {
- if(strstr(line,"?xml") != NULL){
- return NX_OK;
- }
- }
- else {
- return NX_ERROR;
- }
- }
- return NX_ERROR;
-}
-
-/*-------------------------------------------------------------------------*/
- static void NXNXNXReportError(void *pData, char *string)
- {
- fprintf(stderr, "%s \n", string);
- }
- /*---------------------------------------------------------------------*/
-
- static void *NXEHpData = NULL;
- static void (*NXEHIReportError)(void *pData, char *string) = NXNXNXReportError;
-#ifdef HAVE_TLS
- static THREAD_LOCAL void *NXEHpTData = NULL;
- static THREAD_LOCAL void (*NXEHIReportTError)(void *pData, char *string) = NULL;
-#endif
-
- void NXIReportError(void *pData, char *string) {
- fprintf(stderr, "Your application uses NXIReportError, but its first parameter is ignored now - you should use NXReportError.");
- NXReportError(string);
- }
-
- void NXReportError(char *string) {
-#ifdef HAVE_TLS
- if (NXEHIReportTError) {
- (*NXEHIReportTError)(NXEHpTData, string);
- return;
- }
-#endif
- if (NXEHIReportError) {
- (*NXEHIReportError)(NXEHpData, string);
- }
- }
-
- /*---------------------------------------------------------------------*/
- extern void NXMSetError(void *pData, void (*NewError)(void *pD, char *text))
- {
- NXEHpData = pData;
- NXEHIReportError = NewError;
- }
-/*----------------------------------------------------------------------*/
- extern void NXMSetTError(void *pData, void (*NewError)(void *pD, char *text))
- {
-#ifdef HAVE_TLS
- NXEHpTData = pData;
- NXEHIReportTError = NewError;
-#else
- NXMSetError(pData, NewError);
-#endif
- }
-/*----------------------------------------------------------------------*/
-extern ErrFunc NXMGetError(){
-#ifdef HAVE_TLS
- if (NXEHIReportTError) {
- return NXEHIReportTError;
- }
-#endif
- return NXEHIReportError;
-}
-
-/*----------------------------------------------------------------------*/
-static void NXNXNoReport(void *pData, char *string){
- /* do nothing */
-}
-/*----------------------------------------------------------------------*/
-
-static ErrFunc last_global_errfunc = NXNXNXReportError;
-#ifdef HAVE_TLS
-static THREAD_LOCAL ErrFunc last_thread_errfunc = NULL;
-#endif
-
-extern void NXMDisableErrorReporting()
-{
-#ifdef HAVE_TLS
- if (NXEHIReportTError) {
- last_thread_errfunc = NXEHIReportTError;
- NXEHIReportTError = NXNXNoReport;
- return;
- }
-#endif
- if (NXEHIReportError) {
- last_global_errfunc = NXEHIReportError;
- NXEHIReportError = NXNXNoReport;
- }
-}
-
-extern void NXMEnableErrorReporting()
-{
-#ifdef HAVE_TLS
- if (last_thread_errfunc) {
- NXEHIReportTError = last_thread_errfunc;
- last_thread_errfunc = NULL;
- return;
- }
-#endif
- if (last_global_errfunc) {
- NXEHIReportError = last_global_errfunc;
- last_global_errfunc = NULL;
- }
-}
-
-/*----------------------------------------------------------------------*/
-#ifdef HDF5
-#include "napi5.h"
-#endif
-#ifdef HDF4
-#include "napi4.h"
-#endif
-#ifdef NXXML
-#include "nxxml.h"
-#endif
- /* ----------------------------------------------------------------------
-
- Definition of NeXus API
-
- ---------------------------------------------------------------------*/
-static int determineFileTypeImpl(CONSTCHAR *filename)
-{
- FILE *fd = NULL;
- int iRet;
-
- /*
- this is for reading, check for existence first
- */
- fd = fopen(filename,"r");
- if(fd == NULL){
- return -1;
- }
- fclose(fd);
-#ifdef HDF5
- iRet=H5Fis_hdf5((const char*)filename);
- if( iRet > 0){
- return 2;
- }
-#endif
-#ifdef HDF4
- iRet=Hishdf((const char*)filename);
- if( iRet > 0){
- return 1;
- }
-#endif
-#ifdef NXXML
- iRet = NXisXML(filename);
- if(iRet == NX_OK){
- return 3;
- }
-#endif
- /*
- file type not recognized
- */
- return 0;
-}
-
-static int determineFileType(CONSTCHAR *filename)
-{
- return LOCKED_CALL(determineFileTypeImpl(filename));
-}
-
-/*---------------------------------------------------------------------*/
-static pNexusFunction handleToNexusFunc(NXhandle fid){
- pFileStack fileStack = NULL;
- fileStack = (pFileStack)fid;
- if(fileStack != NULL){
- return peekFileOnStack(fileStack);
- } else {
- return NULL;
- }
-}
-/*--------------------------------------------------------------------*/
-static NXstatus NXinternalopen(CONSTCHAR *userfilename, NXaccess am,
- pFileStack fileStack);
-/*----------------------------------------------------------------------*/
-NXstatus NXopen(CONSTCHAR *userfilename, NXaccess am, NXhandle *gHandle){
- int status;
- pFileStack fileStack = NULL;
-
- *gHandle = NULL;
- fileStack = makeFileStack();
- if(fileStack == NULL){
- NXReportError("ERROR: no memory to create filestack");
- return NX_ERROR;
- }
- status = NXinternalopen(userfilename,am,fileStack);
- if(status == NX_OK){
- *gHandle = fileStack;
- }
-
- return status;
-}
-/*-----------------------------------------------------------------------*/
-static NXstatus NXinternalopenImpl(CONSTCHAR *userfilename, NXaccess am, pFileStack fileStack)
- {
- int hdf_type=0;
- int iRet=0;
- NXhandle hdf5_handle = NULL;
- NXhandle hdf4_handle = NULL;
- NXhandle xmlHandle = NULL;
- pNexusFunction fHandle = NULL;
- NXstatus retstat = NX_ERROR;
- char error[1024];
- char *filename = NULL;
- int my_am = (am & NXACCMASK_REMOVEFLAGS);
-
- /* configure fortify
- iFortifyScope = Fortify_EnterScope();
- Fortify_CheckAllMemory();
- */
-
- /*
- allocate data
- */
- fHandle = (pNexusFunction)malloc(sizeof(NexusFunction));
- if (fHandle == NULL) {
- NXReportError("ERROR: no memory to create Function structure");
- return NX_ERROR;
- }
- memset(fHandle, 0, sizeof(NexusFunction)); /* so any functions we miss are NULL */
-
- /*
- test the strip flag. Elimnate it for the rest of the tests to work
- */
- fHandle->stripFlag = 1;
- if(am & NXACC_NOSTRIP){
- fHandle->stripFlag = 0;
- am = (NXaccess)(am & ~NXACC_NOSTRIP);
- }
- fHandle->checkNameSyntax = 0;
- if (am & NXACC_CHECKNAMESYNTAX) {
- fHandle->checkNameSyntax = 1;
- am = (NXaccess)(am & ~NXACC_CHECKNAMESYNTAX);
- }
-
-
- if (my_am==NXACC_CREATE) {
- /* HDF4 will be used ! */
- hdf_type=1;
- filename = strdup(userfilename);
- } else if (my_am==NXACC_CREATE4) {
- /* HDF4 will be used ! */
- hdf_type=1;
- filename = strdup(userfilename);
- } else if (my_am==NXACC_CREATE5) {
- /* HDF5 will be used ! */
- hdf_type=2;
- filename = strdup(userfilename);
- } else if (my_am==NXACC_CREATEXML) {
- /* XML will be used ! */
- hdf_type=3;
- filename = strdup(userfilename);
- } else {
- filename = locateNexusFileInPath((char *)userfilename);
- if(filename == NULL){
- NXReportError("Out of memory in NeXus-API");
- free(fHandle);
- return NX_ERROR;
- }
- /* check file type hdf4/hdf5/XML for reading */
- iRet = determineFileType(filename);
- if(iRet < 0) {
- snprintf(error,1023,"failed to open %s for reading",
- filename);
- NXReportError(error);
- free(filename);
- return NX_ERROR;
- }
- if(iRet == 0){
- snprintf(error,1023,"failed to determine filetype for %s ",
- filename);
- NXReportError(error);
- free(filename);
- free(fHandle);
- return NX_ERROR;
- }
- hdf_type = iRet;
- }
- if(filename == NULL){
- NXReportError("Out of memory in NeXus-API");
- return NX_ERROR;
- }
-
- if (hdf_type==1) {
- /* HDF4 type */
-#ifdef HDF4
- retstat = NX4open((const char *)filename,am,&hdf4_handle);
- if(retstat != NX_OK){
- free(fHandle);
- free(filename);
- return retstat;
- }
- fHandle->pNexusData=hdf4_handle;
- NX4assignFunctions(fHandle);
- pushFileStack(fileStack,fHandle,filename);
-#else
- NXReportError(
- "ERROR: Attempt to create HDF4 file when not linked with HDF4");
- retstat = NX_ERROR;
-#endif /* HDF4 */
- free(filename);
- return retstat;
- } else if (hdf_type==2) {
- /* HDF5 type */
-#ifdef HDF5
- retstat = NX5open(filename,am,&hdf5_handle);
- if(retstat != NX_OK){
- free(fHandle);
- free(filename);
- return retstat;
- }
- fHandle->pNexusData=hdf5_handle;
- NX5assignFunctions(fHandle);
- pushFileStack(fileStack,fHandle, filename);
-#else
- NXReportError(
- "ERROR: Attempt to create HDF5 file when not linked with HDF5");
- retstat = NX_ERROR;
-#endif /* HDF5 */
- free(filename);
- return retstat;
- } else if(hdf_type == 3){
- /*
- XML type
- */
-#ifdef NXXML
- retstat = NXXopen(filename,am,&xmlHandle);
- if(retstat != NX_OK){
- free(fHandle);
- free(filename);
- return retstat;
- }
- fHandle->pNexusData=xmlHandle;
- NXXassignFunctions(fHandle);
- pushFileStack(fileStack,fHandle, filename);
-#else
- NXReportError(
- "ERROR: Attempt to create XML file when not linked with XML");
- retstat = NX_ERROR;
-#endif
- } else {
- NXReportError(
- "ERROR: Format not readable by this NeXus library");
- retstat = NX_ERROR;
- }
- if (filename != NULL) {
- free(filename);
- }
- return retstat;
- }
-
-static NXstatus NXinternalopen(CONSTCHAR *userfilename, NXaccess am, pFileStack fileStack)
-{
- return LOCKED_CALL(NXinternalopenImpl(userfilename, am, fileStack));
-}
-
-
-NXstatus NXreopen(NXhandle pOrigHandle, NXhandle* pNewHandle)
-{
- pFileStack newFileStack;
- pFileStack origFileStack = (pFileStack)pOrigHandle;
- pNexusFunction fOrigHandle = NULL, fNewHandle = NULL;
- *pNewHandle = NULL;
- newFileStack = makeFileStack();
- if(newFileStack == NULL){
- NXReportError ("ERROR: no memory to create filestack");
- return NX_ERROR;
- }
- // The code below will only open the last file on a stack
- // for the moment raise an error, but this behaviour may be OK
- if (fileStackDepth(origFileStack) > 0)
- {
- NXReportError (
- "ERROR: handle stack referes to many files - cannot reopen");
- return NX_ERROR;
- }
- fOrigHandle = peekFileOnStack(origFileStack);
- if (fOrigHandle->nxreopen == NULL)
- {
- NXReportError (
- "ERROR: NXreopen not implemented for this underlying file format");
- return NX_ERROR;
- }
- fNewHandle = (NexusFunction*)malloc(sizeof(NexusFunction));
- memcpy(fNewHandle, fOrigHandle, sizeof(NexusFunction));
- LOCKED_CALL(fNewHandle->nxreopen( fOrigHandle->pNexusData, &(fNewHandle->pNexusData) ));
- pushFileStack( newFileStack, fNewHandle, peekFilenameOnStack(origFileStack) );
- *pNewHandle = newFileStack;
- return NX_OK;
-}
-
-
-/* ------------------------------------------------------------------------- */
-
- NXstatus NXclose (NXhandle *fid)
- {
- NXhandle hfil;
- int status;
- pFileStack fileStack = NULL;
- pNexusFunction pFunc=NULL;
- if (*fid == NULL)
- {
- return NX_OK;
- }
- fileStack = (pFileStack)*fid;
- pFunc = peekFileOnStack(fileStack);
- hfil = pFunc->pNexusData;
- status = LOCKED_CALL(pFunc->nxclose(&hfil));
- pFunc->pNexusData = hfil;
- free(pFunc);
- popFileStack(fileStack);
- if(fileStackDepth(fileStack) < 0){
- killFileStack(fileStack);
- *fid = NULL;
- }
- /* we can't set fid to NULL always as the handle points to a stack of files for external file support */
- /*
- Fortify_CheckAllMemory();
- */
-
- return status;
- }
-
- /*-----------------------------------------------------------------------*/
-
- NXstatus NXmakegroup (NXhandle fid, CONSTCHAR *name, CONSTCHAR *nxclass)
- {
- char buffer[256];
- pNexusFunction pFunc = handleToNexusFunc(fid);
- if ( pFunc->checkNameSyntax && (nxclass != NULL) /* && !strncmp("NX", nxclass, 2) */ && !validNXName(name, 0) )
- {
- sprintf(buffer, "ERROR: invalid characters in group name \"%s\"", name);
- NXReportError(buffer);
- return NX_ERROR;
- }
- return LOCKED_CALL(pFunc->nxmakegroup(pFunc->pNexusData, name, nxclass));
- }
- /*------------------------------------------------------------------------*/
-static int analyzeNapimount(char *napiMount, char *extFile, int extFileLen,
- char *extPath, int extPathLen){
- char *pPtr = NULL, *path = NULL;
- int length;
-
- memset(extFile,0,extFileLen);
- memset(extPath,0,extPathLen);
- pPtr = strstr(napiMount,"nxfile://");
- if(pPtr == NULL){
- return NXBADURL;
- }
- path = strrchr(napiMount,'#');
- if(path == NULL){
- length = strlen(napiMount) - 9;
- if(length > extFileLen){
- NXReportError("ERROR: internal errro with external linking");
- return NXBADURL;
- }
- memcpy(extFile,pPtr+9,length);
- strcpy(extPath,"/");
- return NXFILE;
- } else {
- pPtr += 9;
- length = path - pPtr;
- if(length > extFileLen){
- NXReportError("ERROR: internal errro with external linking");
- return NXBADURL;
- }
- memcpy(extFile,pPtr,length);
- length = strlen(path-1);
- if(length > extPathLen){
- NXReportError("ERROR: internal error with external linking");
- return NXBADURL;
- }
- strcpy(extPath,path+1);
- return NXFILE;
- }
- return NXBADURL;
-}
- /*------------------------------------------------------------------------*/
-
- NXstatus NXopengroup (NXhandle fid, CONSTCHAR *name, CONSTCHAR *nxclass)
- {
- int status, attStatus, type = NX_CHAR, length = 1023;
- NXaccess access = NXACC_READ;
- NXlink breakID;
- pFileStack fileStack;
- char nxurl[1024], exfile[512], expath[512];
- pNexusFunction pFunc = NULL;
-
- fileStack = (pFileStack)fid;
- pFunc = handleToNexusFunc(fid);
-
- status = LOCKED_CALL(pFunc->nxopengroup(pFunc->pNexusData, name, nxclass));
- if(status == NX_OK){
- pushPath(fileStack,name);
- }
- NXMDisableErrorReporting();
- attStatus = NXgetattr(fid,"napimount",nxurl,&length, &type);
- NXMEnableErrorReporting();
- if(attStatus == NX_OK){
- /*
- this is an external linking group
- */
- status = analyzeNapimount(nxurl,exfile,511,expath,511);
- if(status == NXBADURL){
- return NX_ERROR;
- }
- status = NXinternalopen(exfile, access, fileStack);
- if(status == NX_ERROR){
- return status;
- }
- status = NXopenpath(fid, expath);
- NXgetgroupID(fid,&breakID);
- setCloseID(fileStack,breakID);
- }
-
- return status;
- }
-
- /* ------------------------------------------------------------------- */
-
- NXstatus NXclosegroup (NXhandle fid)
- {
- int status;
- pFileStack fileStack = NULL;
- NXlink closeID, currentID;
-
- pNexusFunction pFunc = handleToNexusFunc(fid);
- fileStack = (pFileStack)fid;
- if(fileStackDepth(fileStack) == 0){
- status = LOCKED_CALL(pFunc->nxclosegroup(pFunc->pNexusData));
- if(status == NX_OK){
- popPath(fileStack);
- }
- return status;
- } else {
- /* we have to check for leaving an external file */
- NXgetgroupID(fid,¤tID);
- peekIDOnStack(fileStack,&closeID);
- if(NXsameID(fid,&closeID,¤tID) == NX_OK){
- NXclose(&fid);
- status = NXclosegroup(fid);
- } else {
- status = LOCKED_CALL(pFunc->nxclosegroup(pFunc->pNexusData));
- if(status == NX_OK){
- popPath(fileStack);
- }
- }
- return status;
- }
- }
-
- /* --------------------------------------------------------------------- */
-
- NXstatus NXmakedata (NXhandle fid, CONSTCHAR *name, int datatype,
- int rank, int dimensions[])
- {
- int status;
- int64_t* dims64 = dupDimsArray(dimensions, rank);
- status = NXmakedata64(fid, name, datatype, rank, dims64);
- free(dims64);
- return status;
- }
-
- NXstatus NXmakedata64 (NXhandle fid, CONSTCHAR *name, int datatype,
- int rank, int64_t dimensions[])
- {
- char buffer[256];
- pNexusFunction pFunc = handleToNexusFunc(fid);
- if ( pFunc->checkNameSyntax && !validNXName(name, 0) )
- {
- sprintf(buffer, "ERROR: invalid characters in dataset name \"%s\"", name);
- NXReportError(buffer);
- return NX_ERROR;
- }
- return LOCKED_CALL(pFunc->nxmakedata64(pFunc->pNexusData, name, datatype, rank, dimensions));
- }
-
- /* --------------------------------------------------------------------- */
-
- NXstatus NXcompmakedata (NXhandle fid, CONSTCHAR *name, int datatype,
- int rank, int dimensions[], int compress_type, int chunk_size[])
- {
- int status;
- int64_t* dims64 = dupDimsArray(dimensions, rank);
- int64_t* chunk64 = dupDimsArray(chunk_size, rank);
- status = NXcompmakedata64(fid, name, datatype, rank, dims64, compress_type, chunk64);
- free(dims64);
- free(chunk64);
- return status;
- }
-
- NXstatus NXcompmakedata64 (NXhandle fid, CONSTCHAR *name, int datatype,
- int rank, int64_t dimensions[], int compress_type, int64_t chunk_size[])
- {
- char buffer[256];
- pNexusFunction pFunc = handleToNexusFunc(fid);
- if ( pFunc->checkNameSyntax && !validNXName(name, 0) )
- {
- sprintf(buffer, "ERROR: invalid characters in dataset name \"%s\"", name);
- NXReportError(buffer);
- return NX_ERROR;
- }
- return LOCKED_CALL(pFunc->nxcompmakedata64 (pFunc->pNexusData, name, datatype, rank, dimensions, compress_type, chunk_size));
- }
-
- /* --------------------------------------------------------------------- */
-
- NXstatus NXcompress (NXhandle fid, int compress_type)
- {
- pNexusFunction pFunc = handleToNexusFunc(fid);
- return LOCKED_CALL(pFunc->nxcompress (pFunc->pNexusData, compress_type));
- }
-
-
- /* --------------------------------------------------------------------- */
-
- NXstatus NXopendata (NXhandle fid, CONSTCHAR *name)
- {
- int status, attStatus, type = NX_CHAR, length = 1023;
- NXaccess access = NXACC_READ;
- NXlink breakID;
- pFileStack fileStack;
- char nxurl[1024], exfile[512], expath[512];
- pNexusFunction pFunc = NULL;
-
- fileStack = (pFileStack)fid;
- pFunc = handleToNexusFunc(fid);
- status = LOCKED_CALL(pFunc->nxopendata(pFunc->pNexusData, name));
-
- if(status == NX_OK){
- pushPath(fileStack,name);
- }
-
- NXMDisableErrorReporting();
- attStatus = NXgetattr(fid,"napimount",nxurl,&length, &type);
- NXMEnableErrorReporting();
- if(attStatus == NX_OK){
- /*
- this is an external linking group
- */
- status = analyzeNapimount(nxurl,exfile,511,expath,511);
- if(status == NXBADURL){
- return NX_ERROR;
- }
- status = NXinternalopen(exfile, access, fileStack);
- if(status == NX_ERROR){
- return status;
- }
- status = NXopenpath(fid,expath);
- NXgetdataID(fid,&breakID);
- setCloseID(fileStack,breakID);
- }
-
- return status;
- }
-
- /* ----------------------------------------------------------------- */
-
- NXstatus NXclosedata (NXhandle fid)
- {
- int status;
- pFileStack fileStack = NULL;
- NXlink closeID, currentID;
-
- pNexusFunction pFunc = handleToNexusFunc(fid);
- fileStack = (pFileStack)fid;
-
- if(fileStackDepth(fileStack) == 0){
- status = LOCKED_CALL(pFunc->nxclosedata(pFunc->pNexusData));
- if(status == NX_OK){
- popPath(fileStack);
- }
- return status;
- } else {
- /* we have to check for leaving an external file */
- NXgetdataID(fid,¤tID);
- peekIDOnStack(fileStack,&closeID);
- if(NXsameID(fid,&closeID,¤tID) == NX_OK){
- NXclose(&fid);
- status = NXclosedata(fid);
- } else {
- status = LOCKED_CALL(pFunc->nxclosedata(pFunc->pNexusData));
- if(status == NX_OK){
- popPath(fileStack);
- }
- }
- return status;
- }
- }
-
- /* ------------------------------------------------------------------- */
-
- NXstatus NXputdata (NXhandle fid, const void *data)
- {
- pNexusFunction pFunc = handleToNexusFunc(fid);
- return LOCKED_CALL(pFunc->nxputdata(pFunc->pNexusData, data));
- }
-
- /* ------------------------------------------------------------------- */
-
- NXstatus NXputattr (NXhandle fid, CONSTCHAR *name, const void *data,
- int datalen, int iType)
- {
- char buffer[256];
- pNexusFunction pFunc = handleToNexusFunc(fid);
- if (datalen > 1 && iType != NX_CHAR)
- {
- NXReportError("NXputattr: numeric arrays are not allowed as attributes - only character strings and single numbers");
- return NX_ERROR;
- }
- if ( pFunc->checkNameSyntax && !validNXName(name, 0) )
- {
- sprintf(buffer, "ERROR: invalid characters in attribute name \"%s\"", name);
- NXReportError(buffer);
- return NX_ERROR;
- }
- return LOCKED_CALL(pFunc->nxputattr(pFunc->pNexusData, name, data, datalen, iType));
- }
-
- /* ------------------------------------------------------------------- */
-
- NXstatus NXputslab (NXhandle fid, const void *data, const int iStart[], const int iSize[])
- {
- int i, iType, rank;
- int64_t iStart64[NX_MAXRANK], iSize64[NX_MAXRANK];
- if (NXgetinfo64(fid, &rank, iStart64, &iType) != NX_OK)
- {
- return NX_ERROR;
- }
- for(i=0; i < rank; ++i)
- {
- iStart64[i] = iStart[i];
- iSize64[i] = iSize[i];
- }
- return NXputslab64(fid, data, iStart64, iSize64);
- }
-
- NXstatus NXputslab64 (NXhandle fid, const void *data, const int64_t iStart[], const int64_t iSize[])
- {
- pNexusFunction pFunc = handleToNexusFunc(fid);
- return LOCKED_CALL(pFunc->nxputslab64(pFunc->pNexusData, data, iStart, iSize));
- }
-
- /* ------------------------------------------------------------------- */
-
- NXstatus NXgetdataID (NXhandle fid, NXlink* sRes)
- {
- pNexusFunction pFunc = handleToNexusFunc(fid);
- return LOCKED_CALL(pFunc->nxgetdataID(pFunc->pNexusData, sRes));
- }
-
-
- /* ------------------------------------------------------------------- */
-
- NXstatus NXmakelink (NXhandle fid, NXlink* sLink)
- {
- pNexusFunction pFunc = handleToNexusFunc(fid);
- return LOCKED_CALL(pFunc->nxmakelink(pFunc->pNexusData, sLink));
- }
- /* ------------------------------------------------------------------- */
-
- NXstatus NXmakenamedlink (NXhandle fid, CONSTCHAR *newname, NXlink* sLink)
- {
- char buffer[256];
- pNexusFunction pFunc = handleToNexusFunc(fid);
- if ( pFunc->checkNameSyntax && !validNXName(newname, 0) )
- {
- sprintf(buffer, "ERROR: invalid characters in link name \"%s\"", newname);
- NXReportError(buffer);
- return NX_ERROR;
- }
- return LOCKED_CALL(pFunc->nxmakenamedlink(pFunc->pNexusData, newname, sLink));
- }
- /* --------------------------------------------------------------------*/
- NXstatus NXopensourcegroup(NXhandle fid)
- {
- char target_path[512];
- int status, type = NX_CHAR, length = 511;
-
- status = NXgetattr(fid,"target",target_path,&length,&type);
- if(status != NX_OK)
- {
- NXReportError("ERROR: item not linked");
- return NX_ERROR;
- }
- return NXopengrouppath(fid,target_path);
- }
- /*----------------------------------------------------------------------*/
-
- NXstatus NXflush(NXhandle *pHandle)
- {
- NXhandle hfil;
- pFileStack fileStack = NULL;
- int status;
-
- pNexusFunction pFunc=NULL;
- fileStack = (pFileStack)*pHandle;
- pFunc = peekFileOnStack(fileStack);
- hfil = pFunc->pNexusData;
- status = LOCKED_CALL(pFunc->nxflush(&hfil));
- pFunc->pNexusData = hfil;
- return status;
- }
-
-
- /*-------------------------------------------------------------------------*/
-
-
- NXstatus NXmalloc (void** data, int rank,
- int dimensions[], int datatype)
- {
- int status;
- int64_t* dims64 = dupDimsArray(dimensions, rank);
- status = NXmalloc64(data, rank, dims64, datatype);
- free(dims64);
- return status;
- }
-
- NXstatus NXmalloc64 (void** data, int rank,
- int64_t dimensions[], int datatype)
- {
- int i;
- size_t size = 1;
- *data = NULL;
- for(i=0; inxgetnextentry(pFunc->pNexusData, name, nxclass, datatype));
- }
-/*----------------------------------------------------------------------*/
-/*
-** TRIM.C - Remove leading, trailing, & excess embedded spaces
-**
-** public domain by Bob Stout
-*/
-#define NUL '\0'
-
-char *nxitrim(char *str)
-{
- char *ibuf = str;
- int i = 0;
-
- /*
- ** Trap NULL
- */
-
- if (str)
- {
- /*
- ** Remove leading spaces (from RMLEAD.C)
- */
-
- for (ibuf = str; *ibuf && isspace(*ibuf); ++ibuf)
- ;
- str = ibuf;
-
- /*
- ** Remove trailing spaces (from RMTRAIL.C)
- */
- i = strlen(str);
- while (--i >= 0)
- {
- if (!isspace(str[i]))
- break;
- }
- str[++i] = NUL;
- }
- return str;
-}
- /*-------------------------------------------------------------------------*/
-
- NXstatus NXgetdata (NXhandle fid, void *data)
- {
- int status, type, rank;
- int64_t iDim[NX_MAXRANK];
- char *pPtr, *pPtr2;
-
- pNexusFunction pFunc = handleToNexusFunc(fid);
- status = LOCKED_CALL(pFunc->nxgetinfo64(pFunc->pNexusData, &rank, iDim, &type)); /* unstripped size if string */
- /* only strip one dimensional strings */
- if ( (type == NX_CHAR) && (pFunc->stripFlag == 1) && (rank == 1) )
- {
- pPtr = (char*)malloc(iDim[0]+5);
- memset(pPtr, 0, iDim[0]+5);
- status = LOCKED_CALL(pFunc->nxgetdata(pFunc->pNexusData, pPtr));
- pPtr2 = nxitrim(pPtr);
- strncpy((char*)data, pPtr2, strlen(pPtr2)); /* not NULL terminated by default */
- free(pPtr);
- }
- else
- {
- status = LOCKED_CALL(pFunc->nxgetdata(pFunc->pNexusData, data));
- }
- return status;
- }
-/*---------------------------------------------------------------------------*/
- NXstatus NXgetrawinfo64 (NXhandle fid, int *rank,
- int64_t dimension[], int *iType)
- {
- pNexusFunction pFunc = handleToNexusFunc(fid);
- return LOCKED_CALL(pFunc->nxgetinfo64(pFunc->pNexusData, rank, dimension, iType));
- }
-
- NXstatus NXgetrawinfo (NXhandle fid, int *rank,
- int dimension[], int *iType)
- {
- int i, status;
- int64_t dims64[NX_MAXRANK];
- pNexusFunction pFunc = handleToNexusFunc(fid);
- status = LOCKED_CALL(pFunc->nxgetinfo64(pFunc->pNexusData, rank, dims64, iType));
- for(i=0; i < *rank; ++i)
- {
- dimension[i] = dims64[i];
- }
- return status;
- }
- /*-------------------------------------------------------------------------*/
-
- NXstatus NXgetinfo (NXhandle fid, int *rank,
- int dimension[], int *iType)
- {
- int i, status;
- int64_t dims64[NX_MAXRANK];
- status = NXgetinfo64(fid, rank, dims64, iType);
- for(i=0; i < *rank; ++i)
- {
- dimension[i] = dims64[i];
- }
- return status;
- }
-
- NXstatus NXgetinfo64 (NXhandle fid, int *rank,
- int64_t dimension[], int *iType)
- {
- int status;
- char *pPtr = NULL;
- pNexusFunction pFunc = handleToNexusFunc(fid);
- *rank = 0;
- status = LOCKED_CALL(pFunc->nxgetinfo64(pFunc->pNexusData, rank, dimension, iType));
- /*
- the length of a string may be trimmed....
- */
- /* only strip one dimensional strings */
- if((*iType == NX_CHAR) && (pFunc->stripFlag == 1) && (*rank == 1)){
- pPtr = (char *)malloc((dimension[0]+1)*sizeof(char));
- if(pPtr != NULL){
- memset(pPtr,0,(dimension[0]+1)*sizeof(char));
- LOCKED_CALL(pFunc->nxgetdata(pFunc->pNexusData, pPtr));
- dimension[0] = strlen(nxitrim(pPtr));
- free(pPtr);
- }
- }
- return status;
- }
-
- /*-------------------------------------------------------------------------*/
-
- NXstatus NXgetslab (NXhandle fid, void *data,
- int iStart[], int iSize[])
- {
- int i, iType, rank;
- int64_t iStart64[NX_MAXRANK], iSize64[NX_MAXRANK];
- if (NXgetinfo64(fid, &rank, iStart64, &iType) != NX_OK)
- {
- return NX_ERROR;
- }
- for(i=0; i < rank; ++i)
- {
- iStart64[i] = iStart[i];
- iSize64[i] = iSize[i];
- }
- return NXgetslab64(fid, data, iStart64, iSize64);
- }
-
- NXstatus NXgetslab64 (NXhandle fid, void *data,
- const int64_t iStart[], const int64_t iSize[])
- {
- pNexusFunction pFunc = handleToNexusFunc(fid);
- return LOCKED_CALL(pFunc->nxgetslab64(pFunc->pNexusData, data, iStart, iSize));
- }
-
- /*-------------------------------------------------------------------------*/
-
- NXstatus NXgetnextattr (NXhandle fileid, NXname pName,
- int *iLength, int *iType)
- {
- pNexusFunction pFunc = handleToNexusFunc(fileid);
- return LOCKED_CALL(pFunc->nxgetnextattr(pFunc->pNexusData, pName, iLength, iType));
- }
-
-
- /*-------------------------------------------------------------------------*/
-
- NXstatus NXgetattr (NXhandle fid, char *name, void *data, int* datalen, int* iType)
- {
- pNexusFunction pFunc = handleToNexusFunc(fid);
- return LOCKED_CALL(pFunc->nxgetattr(pFunc->pNexusData, name, data, datalen, iType));
- }
-
-
- /*-------------------------------------------------------------------------*/
-
- NXstatus NXgetattrinfo (NXhandle fid, int *iN)
- {
- pNexusFunction pFunc = handleToNexusFunc(fid);
- return LOCKED_CALL(pFunc->nxgetattrinfo(pFunc->pNexusData, iN));
- }
-
-
- /*-------------------------------------------------------------------------*/
-
- NXstatus NXgetgroupID (NXhandle fileid, NXlink* sRes)
- {
- pNexusFunction pFunc = handleToNexusFunc(fileid);
- return LOCKED_CALL(pFunc->nxgetgroupID(pFunc->pNexusData, sRes));
- }
-
- /*-------------------------------------------------------------------------*/
-
- NXstatus NXgetgroupinfo (NXhandle fid, int *iN, NXname pName, NXname pClass)
- {
- pNexusFunction pFunc = handleToNexusFunc(fid);
- return LOCKED_CALL(pFunc->nxgetgroupinfo(pFunc->pNexusData, iN, pName, pClass));
- }
-
-
- /*-------------------------------------------------------------------------*/
-
- NXstatus NXsameID (NXhandle fileid, NXlink* pFirstID, NXlink* pSecondID)
- {
- pNexusFunction pFunc = handleToNexusFunc(fileid);
- return LOCKED_CALL(pFunc->nxsameID(pFunc->pNexusData, pFirstID, pSecondID));
- }
-
- /*-------------------------------------------------------------------------*/
-
- NXstatus NXinitattrdir (NXhandle fid)
- {
- pNexusFunction pFunc = handleToNexusFunc(fid);
- return LOCKED_CALL(pFunc->nxinitattrdir(pFunc->pNexusData));
- }
- /*-------------------------------------------------------------------------*/
-
- NXstatus NXsetnumberformat (NXhandle fid,
- int type, char *format)
- {
- pNexusFunction pFunc = handleToNexusFunc(fid);
- if(pFunc->nxsetnumberformat != NULL)
- {
- return LOCKED_CALL(pFunc->nxsetnumberformat(pFunc->pNexusData,type,format));
- }
- else
- {
- /*
- silently ignore this. Most NeXus file formats do not require
- this
- */
- return NX_OK;
- }
- }
-
-
- /*-------------------------------------------------------------------------*/
-
- NXstatus NXinitgroupdir (NXhandle fid)
- {
- pNexusFunction pFunc = handleToNexusFunc(fid);
- return LOCKED_CALL(pFunc->nxinitgroupdir(pFunc->pNexusData));
- }
-/*----------------------------------------------------------------------*/
- NXstatus NXinquirefile(NXhandle handle, char *filename,
- int filenameBufferLength){
- pFileStack fileStack;
- char *pPtr = NULL;
- int length, status;
-
- pNexusFunction pFunc = handleToNexusFunc(handle);
- if (pFunc->nxnativeinquirefile != NULL) {
-
- status = LOCKED_CALL(pFunc->nxnativeinquirefile(pFunc->pNexusData, filename, filenameBufferLength));
- if (status < 0) {
- return NX_ERROR;
- } else {
- return NX_OK;
- }
-
- }
-
- fileStack = (pFileStack)handle;
- pPtr = peekFilenameOnStack(fileStack);
- if(pPtr != NULL){
- length = strlen(pPtr);
- if(length > filenameBufferLength){
- length = filenameBufferLength -1;
- }
- memset(filename,0,filenameBufferLength);
- memcpy(filename,pPtr, length);
- return NX_OK;
- } else {
- return NX_ERROR;
- }
-}
-/*------------------------------------------------------------------------*/
-NXstatus NXisexternalgroup(NXhandle fid, CONSTCHAR *name, CONSTCHAR *nxclass,
- char *url, int urlLen){
- int status, attStatus, length = 1023, type = NX_CHAR;
- char nxurl[1024];
-
- pNexusFunction pFunc = handleToNexusFunc(fid);
-
- if (pFunc->nxnativeisexternallink != NULL) {
- status = LOCKED_CALL(pFunc->nxnativeisexternallink(pFunc->pNexusData, name, url, urlLen));
- if (status == NX_OK) {
- return NX_OK;
- }
- // need to continue, could still be old style link
- }
-
- status = LOCKED_CALL(pFunc->nxopengroup(pFunc->pNexusData, name, nxclass));
- if(status != NX_OK){
- return status;
- }
- NXMDisableErrorReporting();
- attStatus = NXgetattr(fid,"napimount",nxurl,&length, &type);
- NXMEnableErrorReporting();
- LOCKED_CALL(pFunc->nxclosegroup(pFunc->pNexusData));
- if(attStatus == NX_OK){
- length = strlen(nxurl);
- if(length >= urlLen){
- length = urlLen - 1;
- }
- memset(url,0,urlLen);
- memcpy(url,nxurl,length);
- return attStatus;
- } else {
- return NX_ERROR;
- }
-}
-/*------------------------------------------------------------------------*/
-NXstatus NXisexternaldataset(NXhandle fid, CONSTCHAR *name,
- char *url, int urlLen){
- int status, attStatus, length = 1023, type = NX_CHAR;
- char nxurl[1024];
-
- pNexusFunction pFunc = handleToNexusFunc(fid);
-
- if (pFunc->nxnativeisexternallink != NULL) {
- status = LOCKED_CALL(pFunc->nxnativeisexternallink(pFunc->pNexusData, name, url, urlLen));
- if (status == NX_OK) {
- return NX_OK;
- }
- // need to continue, could still be old style link
- }
-
- status = LOCKED_CALL(pFunc->nxopendata(pFunc->pNexusData, name));
- if(status != NX_OK){
- return status;
- }
- NXMDisableErrorReporting();
- attStatus = NXgetattr(fid,"napimount",nxurl,&length, &type);
- NXMEnableErrorReporting();
- LOCKED_CALL(pFunc->nxclosedata(pFunc->pNexusData));
- if(attStatus == NX_OK){
- length = strlen(nxurl);
- if(length >= urlLen){
- length = urlLen - 1;
- }
- memset(url,0,urlLen);
- memcpy(url,nxurl,length);
- return attStatus;
- } else {
- return NX_ERROR;
- }
-}
-/*------------------------------------------------------------------------*/
-NXstatus NXlinkexternal(NXhandle fid, CONSTCHAR *name, CONSTCHAR *nxclass, CONSTCHAR *url) {
- int status, type = NX_CHAR, length=1024, urllen;
- char nxurl[1024], exfile[512], expath[512];
- pNexusFunction pFunc = handleToNexusFunc(fid);
-
- // in HDF5 we support external linking natively
- if (pFunc->nxnativeexternallink != NULL) {
- urllen = strlen(url);
- memset(nxurl, 0, length);
- if(urllen >= length){
- urllen = length - 1;
- }
- memcpy(nxurl, url, urllen);
- status = analyzeNapimount(nxurl,exfile,511,expath,511);
- if(status != NX_OK){
- return status;
- }
- status = LOCKED_CALL(pFunc->nxnativeexternallink(pFunc->pNexusData, name, exfile, expath));
- if(status != NX_OK){
- return status;
- }
- return NX_OK;
- }
-
- NXMDisableErrorReporting();
- LOCKED_CALL(pFunc->nxmakegroup(pFunc->pNexusData,name,nxclass));
- NXMEnableErrorReporting();
-
- status = LOCKED_CALL(pFunc->nxopengroup(pFunc->pNexusData,name,nxclass));
- if(status != NX_OK){
- return status;
- }
- length = strlen(url);
- status = NXputattr(fid, "napimount",url,length, type);
- if(status != NX_OK){
- return status;
- }
- LOCKED_CALL(pFunc->nxclosegroup(pFunc->pNexusData));
- return NX_OK;
-}
-/*------------------------------------------------------------------------*/
-NXstatus NXlinkexternaldataset(NXhandle fid, CONSTCHAR *name,
- CONSTCHAR *url){
- int status, type = NX_CHAR, length=1024, urllen;
- char nxurl[1024], exfile[512], expath[512];
- pNexusFunction pFunc = handleToNexusFunc(fid);
- int rank = 1;
- int64_t dims[1] = {1};
-
- //TODO cut and paste
-
- // in HDF5 we support external linking natively
- if (pFunc->nxnativeexternallink != NULL) {
- urllen = strlen(url);
- memset(nxurl, 0, length);
- if(urllen > length){
- urllen = length - 1;
- }
- memcpy(nxurl, url, urllen);
- status = analyzeNapimount(nxurl,exfile,511,expath,511);
- if(status != NX_OK){
- return status;
- }
- status = LOCKED_CALL(pFunc->nxnativeexternallink(pFunc->pNexusData, name, exfile, expath));
- if(status != NX_OK){
- return status;
- }
- return NX_OK;
- }
-
-
- status = LOCKED_CALL(pFunc->nxmakedata64(pFunc->pNexusData, name, NX_CHAR, rank, dims));
- if(status != NX_OK){
- return status;
- }
- status = LOCKED_CALL(pFunc->nxopendata(pFunc->pNexusData, name));
- if(status != NX_OK){
- return status;
- }
- length = strlen(url);
- status = NXputattr(fid, "napimount",url,length, type);
- if(status != NX_OK){
- return status;
- }
- LOCKED_CALL(pFunc->nxclosedata(pFunc->pNexusData));
- return NX_OK;
-}
-/*------------------------------------------------------------------------
- Implementation of NXopenpath
- --------------------------------------------------------------------------*/
-static int isDataSetOpen(NXhandle hfil)
-{
- NXlink id;
-
- /*
- This uses the (sensible) feauture that NXgetdataID returns NX_ERROR
- when no dataset is open
- */
- if(NXgetdataID(hfil,&id) == NX_ERROR)
- {
- return 0;
- }
- else
- {
- return 1;
- }
-}
-/*----------------------------------------------------------------------*/
-static int isRoot(NXhandle hfil)
-{
- NXlink id;
-
- /*
- This uses the feauture that NXgetgroupID returns NX_ERROR
- when we are at root level
- */
- if(NXgetgroupID(hfil,&id) == NX_ERROR)
- {
- return 1;
- }
- else
- {
- return 0;
- }
-}
-/*--------------------------------------------------------------------
- copies the next path element into element.
- returns a pointer into path beyond the extracted path
- ---------------------------------------------------------------------*/
-static char *extractNextPath(char *path, NXname element)
-{
- char *pPtr, *pStart;
- int length;
-
- pPtr = path;
- /*
- skip over leading /
- */
- if(*pPtr == '/')
- {
- pPtr++;
- }
- pStart = pPtr;
-
- /*
- find next /
- */
- pPtr = strchr(pStart,'/');
- if(pPtr == NULL)
- {
- /*
- this is the last path element
- */
- strcpy(element,pStart);
- return NULL;
- } else {
- length = pPtr - pStart;
- strncpy(element,pStart,length);
- element[length] = '\0';
- }
- return pPtr + 1;
-}
-/*-------------------------------------------------------------------*/
-static NXstatus gotoRoot(NXhandle hfil)
-{
- int status;
-
- if(isDataSetOpen(hfil))
- {
- status = NXclosedata(hfil);
- if(status == NX_ERROR)
- {
- return status;
- }
- }
- while(!isRoot(hfil))
- {
- status = NXclosegroup(hfil);
- if(status == NX_ERROR)
- {
- return status;
- }
- }
- return NX_OK;
-}
-/*--------------------------------------------------------------------*/
-static int isRelative(char *path)
-{
- if(path[0] == '.' && path[1] == '.')
- return 1;
- else
- return 0;
-}
-/*------------------------------------------------------------------*/
-static NXstatus moveOneDown(NXhandle hfil)
-{
- if(isDataSetOpen(hfil))
- {
- return NXclosedata(hfil);
- }
- else
- {
- return NXclosegroup(hfil);
- }
-}
-/*-------------------------------------------------------------------
- returns a pointer to the remaining path string to move up
- --------------------------------------------------------------------*/
-static char *moveDown(NXhandle hfil, char *path, int *code)
-{
- int status;
- char *pPtr;
-
- *code = NX_OK;
-
- if(path[0] == '/')
- {
- *code = gotoRoot(hfil);
- return path;
- }
- else
- {
- pPtr = path;
- while(isRelative(pPtr))
- {
- status = moveOneDown(hfil);
- if(status == NX_ERROR)
- {
- *code = status;
- return pPtr;
- }
- pPtr += 3;
- }
- return pPtr;
- }
-}
-/*--------------------------------------------------------------------*/
-static NXstatus stepOneUp(NXhandle hfil, char *name)
-{
- int datatype;
- NXname name2, xclass;
- char pBueffel[256];
-
- /*
- catch the case when we are there: i.e. no further stepping
- necessary. This can happen with paths like ../
- */
- if (strlen(name) < 1) {
- return NX_OK;
- }
-
- NXinitgroupdir(hfil);
-
- while(NXgetnextentry(hfil, name2, xclass, &datatype) != NX_EOD)
- {
- if(strcmp(name2,name) == 0)
- {
- if(strcmp(xclass,"SDS") == 0)
- {
- return NXopendata(hfil,name);
- } else {
- return NXopengroup(hfil,name,xclass);
- }
- }
- }
- snprintf(pBueffel,255,"ERROR: NXopenpath cannot step into %s",name);
- NXReportError( pBueffel);
- return NX_ERROR;
-}
-/*--------------------------------------------------------------------*/
-static NXstatus stepOneGroupUp(NXhandle hfil, char *name)
-{
- int datatype;
- NXname name2, xclass;
- char pBueffel[256];
-
- /*
- catch the case when we are there: i.e. no further stepping
- necessary. This can happen with paths like ../
- */
- if(strlen(name) < 1)
- {
- return NX_OK;
- }
-
- NXinitgroupdir(hfil);
- while(NXgetnextentry(hfil,name2,xclass,&datatype) != NX_EOD)
- {
-
- if(strcmp(name2,name) == 0)
- {
- if(strcmp(xclass,"SDS") == 0) {
- return NX_EOD;
- }
- else
- {
- return NXopengroup(hfil,name,xclass);
- }
- }
- }
- snprintf(pBueffel,255,"ERROR: NXopenpath cannot step into %s",name);
- NXReportError( pBueffel);
- return NX_ERROR;
-}
-/*---------------------------------------------------------------------*/
-NXstatus NXopenpath(NXhandle hfil, CONSTCHAR *path)
-{
- int status, run = 1;
- NXname pathElement;
- char *pPtr;
-
- if(hfil == NULL || path == NULL)
- {
- NXReportError(
- "ERROR: NXopendata needs both a file handle and a path string");
- return NX_ERROR;
- }
-
- pPtr = moveDown(hfil,(char *)path,&status);
- if(status != NX_OK)
- {
- NXReportError(
- "ERROR: NXopendata failed to move down in hierarchy");
- return status;
- }
-
- while(run == 1)
- {
- pPtr = extractNextPath(pPtr, pathElement);
- status = stepOneUp(hfil,pathElement);
- if(status != NX_OK)
- {
- return status;
- }
- if(pPtr == NULL)
- {
- run = 0;
- }
- }
- return NX_OK;
-}
-/*---------------------------------------------------------------------*/
-NXstatus NXopengrouppath(NXhandle hfil, CONSTCHAR *path)
-{
- int status, run = 1;
- NXname pathElement;
- char *pPtr;
-
- if(hfil == NULL || path == NULL)
- {
- NXReportError(
- "ERROR: NXopendata needs both a file handle and a path string");
- return NX_ERROR;
- }
-
- pPtr = moveDown(hfil,(char *)path,&status);
- if(status != NX_OK)
- {
- NXReportError(
- "ERROR: NXopendata failed to move down in hierarchy");
- return status;
- }
-
- while(run == 1)
- {
- pPtr = extractNextPath(pPtr, pathElement);
- status = stepOneGroupUp(hfil,pathElement);
- if(status == NX_ERROR)
- {
- return status;
- }
- if(pPtr == NULL || status == NX_EOD)
- {
- run = 0;
- }
- }
- return NX_OK;
-}
-/*---------------------------------------------------------------------*/
-NXstatus NXIprintlink(NXhandle fid, NXlink* link)
-{
- pNexusFunction pFunc = handleToNexusFunc(fid);
- return LOCKED_CALL(pFunc->nxprintlink(pFunc->pNexusData, link));
-}
-/*----------------------------------------------------------------------*/
-NXstatus NXgetpath(NXhandle fid, char *path, int pathlen){
- int status;
- pFileStack fileStack = NULL;
-
- fileStack = (pFileStack)fid;
- status = buildPath(fileStack,path,pathlen);
- if(status != 1){
- return NX_ERROR;
- }
- return NX_OK;
-}
-
-/*--------------------------------------------------------------------
- format NeXus time. Code needed in every NeXus file driver
- ---------------------------------------------------------------------*/
-char *NXIformatNeXusTime(){
- time_t timer;
- char* time_buffer = NULL;
- struct tm *time_info;
- const char* time_format;
- long gmt_offset;
-#ifdef USE_FTIME
- struct timeb timeb_struct;
-#endif
-
- time_buffer = (char *)malloc(64*sizeof(char));
- if(!time_buffer){
- NXReportError("Failed to allocate buffer for time data");
- return NULL;
- }
-
-#ifdef NEED_TZSET
- tzset();
-#endif
- time(&timer);
-#ifdef USE_FTIME
- ftime(&timeb_struct);
- gmt_offset = -timeb_struct.timezone * 60;
- if (timeb_struct.dstflag != 0)
- {
- gmt_offset += 3600;
- }
-#else
- time_info = gmtime(&timer);
- if (time_info != NULL)
- {
- gmt_offset = (long)difftime(timer, mktime(time_info));
- }
- else
- {
- NXReportError(
- "Your gmtime() function does not work ... timezone information will be incorrect\n");
- gmt_offset = 0;
- }
-#endif
- time_info = localtime(&timer);
- if (time_info != NULL)
- {
- if (gmt_offset < 0)
- {
- time_format = "%04d-%02d-%02dT%02d:%02d:%02d-%02d:%02d";
- }
- else
- {
- time_format = "%04d-%02d-%02dT%02d:%02d:%02d+%02d:%02d";
- }
- sprintf(time_buffer, time_format,
- 1900 + time_info->tm_year,
- 1 + time_info->tm_mon,
- time_info->tm_mday,
- time_info->tm_hour,
- time_info->tm_min,
- time_info->tm_sec,
- abs(gmt_offset / 3600),
- abs((gmt_offset % 3600) / 60)
- );
- }
- else
- {
- strcpy(time_buffer, "1970-01-01T00:00:00+00:00");
- }
- return time_buffer;
-}
-/*----------------------------------------------------------------------
- F77 - API - Support - Routines
- ----------------------------------------------------------------------*/
- /*
- * We store the whole of the NeXus file in the array - that way
- * we can just pass the array name to C as it will be a valid
- * NXhandle. We could store the NXhandle value in the FORTRAN array
- * instead, but that would mean writing far more wrappers
- */
- NXstatus NXfopen(char * filename, NXaccess* am,
- NXhandle pHandle)
- {
- NXstatus ret;
- NXhandle fileid = NULL;
- ret = NXopen(filename, *am, &fileid);
- if (ret == NX_OK)
- {
- memcpy(pHandle, fileid, getFileStackSize());
- }
- else
- {
- memset(pHandle, 0, getFileStackSize());
- }
- if (fileid != NULL)
- {
- free(fileid);
- }
- return ret;
- }
-/*
- * The pHandle from FORTRAN is a pointer to a static FORTRAN
- * array holding the NexusFunction structure. We need to malloc()
- * a temporary copy as NXclose will try to free() this
- */
- NXstatus NXfclose (NXhandle pHandle)
- {
- NXhandle h;
- NXstatus ret;
- h = (NXhandle)malloc(getFileStackSize());
- memcpy(h, pHandle, getFileStackSize());
- ret = NXclose(&h); /* does free(h) */
- memset(pHandle, 0, getFileStackSize());
- return ret;
- }
-
-/*---------------------------------------------------------------------*/
- NXstatus NXfflush(NXhandle pHandle)
- {
- NXhandle h;
- NXstatus ret;
- h = (NXhandle)malloc(getFileStackSize());
- memcpy(h, pHandle, getFileStackSize());
- ret = NXflush(&h); /* modifies and reallocates h */
- memcpy(pHandle, h, getFileStackSize());
- return ret;
- }
-/*----------------------------------------------------------------------*/
- NXstatus NXfmakedata(NXhandle fid, char *name, int *pDatatype,
- int *pRank, int dimensions[])
- {
- NXstatus ret;
- static char buffer[256];
- int i, *reversed_dimensions;
- reversed_dimensions = (int*)malloc(*pRank * sizeof(int));
- if (reversed_dimensions == NULL)
- {
- sprintf (buffer,
- "ERROR: Cannot allocate space for array rank of %d in NXfmakedata",
- *pRank);
- NXReportError( buffer);
- return NX_ERROR;
- }
-/*
- * Reverse dimensions array as FORTRAN is column major, C row major
- */
- for(i=0; i < *pRank; i++)
- {
- reversed_dimensions[i] = dimensions[*pRank - i - 1];
- }
- ret = NXmakedata(fid, name, *pDatatype, *pRank, reversed_dimensions);
- free(reversed_dimensions);
- return ret;
- }
-
-/*-----------------------------------------------------------------------*/
- NXstatus NXfcompmakedata(NXhandle fid, char *name,
- int *pDatatype,
- int *pRank, int dimensions[],
- int *compression_type, int chunk[])
- {
- NXstatus ret;
- static char buffer[256];
- int i, *reversed_dimensions, *reversed_chunk;
- reversed_dimensions = (int*)malloc(*pRank * sizeof(int));
- reversed_chunk = (int*)malloc(*pRank * sizeof(int));
- if (reversed_dimensions == NULL || reversed_chunk == NULL)
- {
- sprintf (buffer,
- "ERROR: Cannot allocate space for array rank of %d in NXfcompmakedata",
- *pRank);
- NXReportError( buffer);
- return NX_ERROR;
- }
-/*
- * Reverse dimensions array as FORTRAN is column major, C row major
- */
- for(i=0; i < *pRank; i++)
- {
- reversed_dimensions[i] = dimensions[*pRank - i - 1];
- reversed_chunk[i] = chunk[*pRank - i - 1];
- }
- ret = NXcompmakedata(fid, name, *pDatatype, *pRank,
- reversed_dimensions,*compression_type, reversed_chunk);
- free(reversed_dimensions);
- free(reversed_chunk);
- return ret;
- }
-/*-----------------------------------------------------------------------*/
- NXstatus NXfcompress(NXhandle fid, int *compr_type)
- {
- return NXcompress(fid,*compr_type);
- }
-/*-----------------------------------------------------------------------*/
- NXstatus NXfputattr(NXhandle fid, const char *name, const void *data,
- int *pDatalen, int *pIType)
- {
- return NXputattr(fid, name, data, *pDatalen, *pIType);
- }
-
-
- /*
- * implement snprintf when it is not available
- */
- int nxisnprintf(char* buffer, int len, const char* format, ... )
- {
- int ret;
- va_list valist;
- va_start(valist,format);
- ret = vsprintf(buffer, format, valist);
- va_end(valist);
- return ret;
- }
-
-/*--------------------------------------------------------------------------*/
-NXstatus NXfgetpath(NXhandle fid, char *path, int *pathlen)
-{
- return NXgetpath(fid,path,*pathlen);
-}
-
-const char* NXgetversion()
-{
- return NEXUS_VERSION ;
-}
-
diff --git a/napi.h b/napi.h
deleted file mode 100644
index 62b9e1a9..00000000
--- a/napi.h
+++ /dev/null
@@ -1,967 +0,0 @@
-/*---------------------------------------------------------------------------
- NeXus - Neutron & X-ray Common Data Format
-
- Application Program Interface Header File
-
- Copyright (C) 2000-2011 Mark Koennecke, Uwe Filges
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- For further information, see
-
- $Id$
-
- ----------------------------------------------------------------------------*/
-/** \file
- * Documentation for the NeXus-API version 4.3
- * 2000-2011, the NeXus International Advisory Commitee
- * \defgroup c_main C API
- * \defgroup c_types Data Types
- * \ingroup c_main
- * \defgroup c_init General Initialisation and shutdown
- * \ingroup c_main
- * \defgroup c_group Reading and Writing Groups
- * \ingroup c_main
- * \defgroup c_readwrite Reading and Writing Data
- * \ingroup c_main
- * \defgroup c_navigation General File navigation
- * \ingroup c_main
- * \defgroup c_metadata Meta data routines
- * \ingroup c_main
- * \defgroup c_linking Linking
- * \ingroup c_main
- * \defgroup c_memory Memory allocation
- * \ingroup c_main
- * \defgroup c_external External linking
- * \ingroup c_main
- */
-
-#ifndef NEXUSAPI
-#define NEXUSAPI
-
-#include
-
-/* NeXus HDF45 */
-#define NEXUS_VERSION "4.3.0" /* major.minor.patch */
-#define H5Eset_auto_vers 2
-#define H5Dopen_vers 2
-#define H5Gopen_vers 2
-#define H5Acreate_vers 2
-#define H5Dcreate_vers 2
-#define H5Gcreate_vers 2
-#define H5Aiterate_vers 2
-
-
-#define CONSTCHAR const char
-
-typedef void* NXhandle; /* really a pointer to a NexusFile structure */
-typedef int NXstatus;
-typedef char NXname[128];
-
-/*
- * Any new NXaccess_mode options should be numbered in 2^n format
- * (8, 16, 32, etc) so that they can be bit masked and tested easily.
- *
- * To test older non bit masked options (values below 8) use e.g.
- *
- * if ( (mode & NXACCMASK_REMOVEFLAGS) == NXACC_CREATE )
- *
- * To test new (>=8) options just use normal bit masking e.g.
- *
- * if ( mode & NXACC_NOSTRIP )
- *
- */
-#define NXACCMASK_REMOVEFLAGS (0x7) /* bit mask to remove higher flag options */
-
-/** \enum NXaccess_mode
- * NeXus file access codes.
- * \li NXACC_READ read-only
- * \li NXACC_RDWR open an existing file for reading and writing.
- * \li NXACC_CREATE create a NeXus HDF-4 file
- * \li NXACC_CREATE4 create a NeXus HDF-4 file
- * \li NXACC_CREATE5 create a NeXus HDF-5 file.
- * \li NXACC_CREATEXML create a NeXus XML file.
- * \li NXACC_CHECKNAMESYNTAX Check names conform to NeXus allowed characters.
- */
-typedef enum {NXACC_READ=1, NXACC_RDWR=2, NXACC_CREATE=3, NXACC_CREATE4=4,
- NXACC_CREATE5=5, NXACC_CREATEXML=6, NXACC_TABLE=8, NXACC_NOSTRIP=128, NXACC_CHECKNAMESYNTAX=256 } NXaccess_mode;
-
-/**
- * A combination of options from #NXaccess_mode
- */
-typedef int NXaccess;
-
-typedef struct {
- char *iname;
- int type;
- }info_type, *pinfo;
-
-#define NX_OK 1
-#define NX_ERROR 0
-#define NX_EOD -1
-
-#define NX_UNLIMITED -1
-
-#define NX_MAXRANK 32
-#define NX_MAXNAMELEN 64
-#define NX_MAXPATHLEN 1024
-
-
-/**
- * \ingroup c_types
- * \def NX_FLOAT32
- * 32 bit float
- * \def NX_FLOAT64
- * 64 bit float == double
- * \def NX_INT8
- * 8 bit integer == byte
- * \def NX_UINT8
- * 8 bit unsigned integer
- * \def NX_INT16
- * 16 bit integer
- * \def NX_UINT16
- * 16 bit unsigned integer
- * \def NX_INT32
- * 32 bit integer
- * \def NX_UINT32
- * 32 bit unsigned integer
- * \def NX_CHAR
- * 8 bit character
- * \def NX_BINARY
- * lump of binary data == NX_UINT8
-*/
-/*--------------------------------------------------------------------------*/
-
-/* Map NeXus to HDF types */
-#define NX_FLOAT32 5
-#define NX_FLOAT64 6
-#define NX_INT8 20
-#define NX_UINT8 21
-#define NX_BOOLEAN NX_UINT
-#define NX_INT16 22
-#define NX_UINT16 23
-#define NX_INT32 24
-#define NX_UINT32 25
-#define NX_INT64 26
-#define NX_UINT64 27
-#define NX_CHAR 4
-#define NX_BINARY 21
-
-/* Map NeXus compression methods to HDF compression methods */
-#define NX_CHUNK 0
-#define NX_COMP_NONE 100
-#define NX_COMP_LZW 200
-#define NX_COMP_RLE 300
-#define NX_COMP_HUF 400
-
-/* to test for these we use ((value / 100) == NX_COMP_LZW) */
-#define NX_COMP_LZW_LVL0 (100*NX_COMP_LZW + 0)
-#define NX_COMP_LZW_LVL1 (100*NX_COMP_LZW + 1)
-#define NX_COMP_LZW_LVL2 (100*NX_COMP_LZW + 2)
-#define NX_COMP_LZW_LVL3 (100*NX_COMP_LZW + 3)
-#define NX_COMP_LZW_LVL4 (100*NX_COMP_LZW + 4)
-#define NX_COMP_LZW_LVL5 (100*NX_COMP_LZW + 5)
-#define NX_COMP_LZW_LVL6 (100*NX_COMP_LZW + 6)
-#define NX_COMP_LZW_LVL7 (100*NX_COMP_LZW + 7)
-#define NX_COMP_LZW_LVL8 (100*NX_COMP_LZW + 8)
-#define NX_COMP_LZW_LVL9 (100*NX_COMP_LZW + 9)
-
-typedef struct {
- long iTag; /* HDF4 variable */
- long iRef; /* HDF4 variable */
- char targetPath[1024]; /* path to item to link */
- int linkType; /* HDF5: 0 for group link, 1 for SDS link */
- } NXlink;
-
-#define NXMAXSTACK 50
-
-#define CONCAT(__a,__b) __a##__b /* token concatenation */
-
-# ifdef __VMS
-# define MANGLE(__arg) __arg
-# else
-# define MANGLE(__arg) CONCAT(__arg,_)
-# endif
-
-# define NXopen MANGLE(nxiopen)
-# define NXreopen MANGLE(nxireopen)
-# define NXclose MANGLE(nxiclose)
-# define NXmakegroup MANGLE(nximakegroup)
-# define NXopengroup MANGLE(nxiopengroup)
-# define NXopenpath MANGLE(nxiopenpath)
-# define NXgetpath MANGLE(nxigetpath)
-# define NXopengrouppath MANGLE(nxiopengrouppath)
-# define NXclosegroup MANGLE(nxiclosegroup)
-# define NXmakedata MANGLE(nximakedata)
-# define NXmakedata64 MANGLE(nximakedata64)
-# define NXcompmakedata MANGLE(nxicompmakedata)
-# define NXcompmakedata64 MANGLE(nxicompmakedata64)
-# define NXcompress MANGLE(nxicompress)
-# define NXopendata MANGLE(nxiopendata)
-# define NXclosedata MANGLE(nxiclosedata)
-# define NXputdata MANGLE(nxiputdata)
-# define NXputslab MANGLE(nxiputslab)
-# define NXputslab64 MANGLE(nxiputslab64)
-# define NXputattr MANGLE(nxiputattr)
-# define NXgetdataID MANGLE(nxigetdataid)
-# define NXmakelink MANGLE(nximakelink)
-# define NXmakenamedlink MANGLE(nximakenamedlink)
-# define NXopensourcegroup MANGLE(nxiopensourcegroup)
-# define NXmalloc MANGLE(nximalloc)
-# define NXmalloc64 MANGLE(nximalloc64)
-# define NXfree MANGLE(nxifree)
-# define NXflush MANGLE(nxiflush)
-
-# define NXgetinfo MANGLE(nxigetinfo)
-# define NXgetinfo64 MANGLE(nxigetinfo64)
-# define NXgetrawinfo MANGLE(nxigetrawinfo)
-# define NXgetrawinfo64 MANGLE(nxigetrawinfo64)
-# define NXgetnextentry MANGLE(nxigetnextentry)
-# define NXgetdata MANGLE(nxigetdata)
-
-# define NXgetslab MANGLE(nxigetslab)
-# define NXgetslab64 MANGLE(nxigetslab64)
-# define NXgetnextattr MANGLE(nxigetnextattr)
-# define NXgetattr MANGLE(nxigetattr)
-# define NXgetattrinfo MANGLE(nxigetattrinfo)
-# define NXgetgroupID MANGLE(nxigetgroupid)
-# define NXgetgroupinfo MANGLE(nxigetgroupinfo)
-# define NXsameID MANGLE(nxisameid)
-# define NXinitgroupdir MANGLE(nxiinitgroupdir)
-# define NXinitattrdir MANGLE(nxiinitattrdir)
-# define NXsetnumberformat MANGLE(nxisetnumberformat)
-# define NXsetcache MANGLE(nxisetcache)
-# define NXinquirefile MANGLE(nxiinquirefile)
-# define NXisexternalgroup MANGLE(nxiisexternalgroup)
-# define NXisexternaldataset MANGLE(nxiisexternaldataset)
-# define NXlinkexternal MANGLE(nxilinkexternal)
-# define NXlinkexternaldataset MANGLE(nxilinkexternaldataset)
-# define NXgetversion MANGLE(nxigetversion)
-
-/*
- * FORTRAN helpers - for NeXus internal use only
- */
-# define NXfopen MANGLE(nxifopen)
-# define NXfclose MANGLE(nxifclose)
-# define NXfflush MANGLE(nxifflush)
-# define NXfmakedata MANGLE(nxifmakedata)
-# define NXfcompmakedata MANGLE(nxifcompmakedata)
-# define NXfcompress MANGLE(nxifcompress)
-# define NXfputattr MANGLE(nxifputattr)
-# define NXfgetpath MANGLE(nxifgetpath)
-
-/*
- * Standard interface
- *
- * Functions added here are not automatically exported from
- * a shared library/dll - the symbol name must also be added
- * to the file src/nexus_symbols.txt
- *
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
- /**
- * Open a NeXus file.
- * NXopen honours full path file names. But it also searches
- * for files in all the paths given in the NX_LOAD_PATH environment variable.
- * NX_LOAD_PATH is supposed to hold a list of path string separated by the platform
- * specific path separator. For unix this is the : , for DOS the ; . Please note
- * that crashing on an open NeXus file will result in corrupted data. Only after a NXclose
- * or a NXflush will the data file be valid.
- * \param filename The name of the file to open
- * \param access_method The file access method. This can be:
- * \li NXACC__READ read access
- * \li NXACC_RDWR read write access
- * \li NXACC_CREATE, NXACC_CREATE4 create a new HDF-4 NeXus file
- * \li NXACC_CREATE5 create a new HDF-5 NeXus file
- * \li NXACC_CREATEXML create an XML NeXus file.
- * see #NXaccess_mode
- * Support for HDF-4 is deprecated.
- * \param pHandle A file handle which will be initialized upon successfull completeion of NXopen.
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_init
- */
-extern NXstatus NXopen(CONSTCHAR * filename, NXaccess access_method, NXhandle* pHandle);
-
- /**
- * Opens an existing NeXus file a second time for e.g. access from another thread.
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_init
- */
-extern NXstatus NXreopen(NXhandle pOrigHandle, NXhandle* pNewHandle);
-
- /**
- * close a NeXus file
- * \param pHandle A NeXus file handle as returned from NXopen. pHandle is invalid after this
- * call.
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_init
- */
-extern NXstatus NXclose(NXhandle* pHandle);
-
- /**
- * flush data to disk
- * \param pHandle A NeXus file handle as initialized by NXopen.
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_readwrite
- */
-extern NXstatus NXflush(NXhandle* pHandle);
-
- /**
- * NeXus groups are NeXus way of structuring information into a hierarchy.
- * This function creates a group but does not open it.
- * \param handle A NeXus file handle as initialized NXopen.
- * \param name The name of the group
- * \param NXclass the class name of the group. Should start with the prefix NX
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_group
- */
-extern NXstatus NXmakegroup (NXhandle handle, CONSTCHAR *name, CONSTCHAR* NXclass);
-
- /**
- * Step into a group. All further access will be within the opened group.
- * \param handle A NeXus file handle as initialized by NXopen.
- * \param name The name of the group
- * \param NXclass the class name of the group. Should start with the prefix NX
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_group
- */
-extern NXstatus NXopengroup (NXhandle handle, CONSTCHAR *name, CONSTCHAR* NXclass);
-
- /**
- * Open the NeXus object with the path specified
- * \param handle A NeXus file handle as returned from NXopen.
- * \param path A unix like path string to a NeXus group or dataset. The path string
- * is a list of group names and SDS names separated with / (slash).
- * Example: /entry1/sample/name
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_navigation
- */
-extern NXstatus NXopenpath (NXhandle handle, CONSTCHAR *path);
-
- /**
- * Opens the group in which the NeXus object with the specified path exists
- * \param handle A NeXus file handle as initialized by NXopen.
- * \param path A unix like path string to a NeXus group or dataset. The path string
- * is a list of group names and SDS names separated with / (slash).
- * Example: /entry1/sample/name
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_navigation
- */
-extern NXstatus NXopengrouppath (NXhandle handle, CONSTCHAR *path);
-
- /**
- * Retrieve the current path in the NeXus file
- * \param handle a NeXus file handle
- * \param path A buffer to copy the path too
- * \param pathlen The maximum number of characters to copy into path
- * \return NX_OK or NX_ERROR
- * \ingroup c_navigation
- */
-extern NXstatus NXgetpath(NXhandle handle, char *path, int pathlen);
-
- /**
- * Closes the currently open group and steps one step down in the NeXus file
- * hierarchy.
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_group
- */
-extern NXstatus NXclosegroup(NXhandle handle);
-
- /**
- * Create a multi dimensional data array or dataset. The dataset is NOT opened.
- * \param handle A NeXus file handle as initialized by NXopen.
- * \param label The name of the dataset
- * \param datatype The data type of this data set.
- * \param rank The number of dimensions this dataset is going to have
- * \param dim An array of size rank holding the size of the dataset in each dimension. The first dimension
- * can be NX_UNLIMITED. Data can be appended to such a dimension using NXputslab.
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_readwrite
- */
-extern NXstatus NXmakedata (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int dim[]);
-
-
- /**
- * @copydoc NXmakedata()
- */
-extern NXstatus NXmakedata64 (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int64_t dim[]);
-
-
-/**
- * Create a compressed dataset. The dataset is NOT opened. Data from this set will automatically be compressed when
- * writing and decompressed on reading.
- * \param handle A NeXus file handle as initialized by NXopen.
- * \param label The name of the dataset
- * \param datatype The data type of this data set.
- * \param rank The number of dimensions this dataset is going to have
- * \param comp_typ The compression scheme to use. Possible values:
- * \li NX_COMP_NONE no compression
- * \li NX_COMP_LZW lossless Lempel Ziv Welch compression (recommended)
- * \li NX_COMP_RLE run length encoding (only HDF-4)
- * \li NX_COMP_HUF Huffmann encoding (only HDF-4)
- * \param dim An array of size rank holding the size of the dataset in each dimension. The first dimension
- * can be NX_UNLIMITED. Data can be appended to such a dimension using NXputslab.
- * \param bufsize The dimensions of the subset of the data which usually be writen in one go.
- * This is a parameter used by HDF for performance optimisations. If you write your data in one go, this
- * should be the same as the data dimension. If you write it in slabs, this is your preferred slab size.
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_readwrite
- */
-extern NXstatus NXcompmakedata (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int dim[], int comp_typ, int bufsize[]);
-
-
-/**
- * @copydoc NXcompmakedata()
- */
-extern NXstatus NXcompmakedata64 (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int64_t dim[], int comp_typ, int64_t chunk_size[]);
-
-
- /**
- * Switch compression on. This routine is superseeded by NXcompmakedata and thus
- * is deprecated.
- * \param handle A NeXus file handle as initialized by NXopen.
- * \param compr_type The compression scheme to use. Possible values:
- * \li NX_COMP_NONE no compression
- * \li NX_COMP_LZW lossless Lempel Ziv Welch compression (recommended)
- * \li NX_COMP_RLE run length encoding (only HDF-4)
- * \li NX_COMP_HUF Huffmann encoding (only HDF-4)
- * \ingroup c_readwrite
- */
-extern NXstatus NXcompress (NXhandle handle, int compr_type);
-
- /**
- * Open access to a dataset. After this call it is possible to write and read data or
- * attributes to and from the dataset.
- * \param handle A NeXus file handle as initialized by NXopen.
- * \param label The name of the dataset
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_readwrite
- */
-extern NXstatus NXopendata (NXhandle handle, CONSTCHAR* label);
-
- /**
- * Close access to a dataset.
- * \param handle A NeXus file handle as initialized by NXopen.
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_readwrite
- */
-extern NXstatus NXclosedata(NXhandle handle);
-
- /**
- * Write data to a datset which has previouly been opened with NXopendata.
- * This writes all the data in one go. Data should be a pointer to a memory
- * area matching the datatype and dimensions of the dataset.
- * \param handle A NeXus file handle as initialized by NXopen.
- * \param data Pointer to data to write.
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_readwrite
- */
-extern NXstatus NXputdata(NXhandle handle, const void* data);
-
- /**
- * Write an attribute. The kind of attribute written depends on the
- * poistion in the file: at root level, a global attribute is written, if
- * agroup is open but no dataset, a group attribute is written, if a dataset is
- * open, a dataset attribute is written.
- * \param handle A NeXus file handle as initialized by NXopen.
- * \param name The name of the attribute.
- * \param data A pointer to the data to write for the attribute.
- * \param iDataLen The length of the data in data in bytes.
- * \param iType The NeXus data type of the attribute.
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_readwrite
- */
-extern NXstatus NXputattr(NXhandle handle, CONSTCHAR* name, const void* data, int iDataLen, int iType);
-
- /**
- * Write a subset of a multi dimensional dataset.
- * \param handle A NeXus file handle as initialized by NXopen.
- * \param data A pointer to a memory area holding the data to write.
- * \param start An array holding the start indices where to start the data subset.
- * \param size An array holding the size of the data subset to write in each dimension.
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_readwrite
- */
-extern NXstatus NXputslab(NXhandle handle, const void* data, const int start[], const int size[]);
-
- /**
- * @copydoc NXputdata()
- */
-extern NXstatus NXputslab64(NXhandle handle, const void* data, const int64_t start[], const int64_t size[]);
-
- /**
- * Retrieve link data for a dataset. This link data can later on be used to link this
- * dataset into a different group.
- * \param handle A NeXus file handle as initialized by NXopen.
- * \param pLink A link data structure which will be initialized with the required information
- * for linking.
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_linking
- */
-extern NXstatus NXgetdataID(NXhandle handle, NXlink* pLink);
-
- /**
- * Create a link to the group or dataset described by pLink in the currently open
- * group.
- * \param handle A NeXus file handle as initialized by NXopen.
- * \param pLink A link data structure describing the object to link. This must have been initialized
- * by either a call to NXgetdataID or NXgetgroupID.
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_linking
- */
-extern NXstatus NXmakelink(NXhandle handle, NXlink* pLink);
-
- /**
- * Create a link to the group or dataset described by pLink in the currently open
- * group. But give the linked item a new name.
- * \param handle A NeXus file handle as initialized by NXopen.
- * \param newname The new name of the item in the currently open group.
- * \param pLink A link data structure describing the object to link. This must have been initialized
- * by either a call to NXgetdataID or NXgetgroupID.
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_linking
- */
-extern NXstatus NXmakenamedlink(NXhandle handle, CONSTCHAR* newname, NXlink* pLink);
-
- /**
- * Open the source group of a linked group or dataset. Returns an error when the item is
- * not a linked item.
- * \param handle A NeXus file handle as initialized by NXopen.
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_navigation
- */
-extern NXstatus NXopensourcegroup(NXhandle handle);
-
- /**
- * Read a complete dataset from the currently open dataset into memory.
- * \param handle A NeXus file handle as initialized by NXopen.
- * \param data A pointer to the memory area where to read the data, too. Data must point to a memory
- * area large enough to accomodate the data read. Otherwise your program may behave in unexpected
- * and unwelcome ways.
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_readwrite
- */
-extern NXstatus NXgetdata(NXhandle handle, void* data);
-
- /**
- * Retrieve information about the curretly open dataset.
- * \param handle A NeXus file handle as initialized by NXopen.
- * \param rank A pointer to an integer which will be filled with the rank of
- * the dataset.
- * \param dimension An array which will be initialized with the size of the dataset in any of its
- * dimensions. The array must have at least the size of rank.
- * \param datatype A pointer to an integer which be set to the NeXus data type code for this dataset.
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_metadata
- */
-extern NXstatus NXgetinfo(NXhandle handle, int* rank, int dimension[], int* datatype);
-
- /**
- * @copydoc NXgetinfo()
- */
-extern NXstatus NXgetinfo64(NXhandle handle, int* rank, int64_t dimension[], int* datatype);
-
- /**
- * Get the next entry in the currently open group. This is for retrieving infromation about the
- * content of a NeXus group. In order to search a group #NXgetnextentry is called in a loop until
- * #NXgetnextentry returns NX_EOD which indicates that there are no further items in the group.
- * Reset search using #NXinitgroupdir
- * \param handle A NeXus file handle as initialized by NXopen.
- * \param name The name of the object
- * \param nxclass The NeXus class name for a group or the string SDS for a dataset.
- * \param datatype The NeXus data type if the item is a SDS.
- * \return NX_OK on success, NX_ERROR in the case of an error, NX_EOD when there are no more items.
- * \ingroup c_navigation
- */
-extern NXstatus NXgetnextentry(NXhandle handle, NXname name, NXname nxclass, int* datatype);
-
- /**
- * Read a subset of data from file into memory.
- * \param handle A NeXus file handle as initialized by NXopen.
- * \param data A pointer to the memory data where to copy the data too. The pointer must point
- * to a memory area large enough to accomodate the size of the data read.
- * \param start An array holding the start indices where to start reading the data subset.
- * \param size An array holding the size of the data subset to read for each dimension.
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_readwrite
- */
-extern NXstatus NXgetslab(NXhandle handle, void* data, int start[], int size[]);
-
-
- /**
- * @copydoc NXgetslab()
- */
-extern NXstatus NXgetslab64(NXhandle handle, void* data, const int64_t start[], const int64_t size[]);
-
-/**
- * Iterate over global, group or dataset attributes depending on the currently open group or
- * dataset. In order to search attributes multiple calls to #NXgetnextattr are performed in a loop
- * until #NXgetnextattr returns NX_EOD which indicates that there are no further attributes.
- * reset search using #NXinitattrdir
- * \param handle A NeXus file handle as initialized by NXopen.
- * \param pName The name of the attribute
- * \param iLength A pointer to an integer which be set to the length of the attribute data.
- * \param iType A pointer to an integer which be set to the NeXus data type of the attribute.
- * \return NX_OK on success, NX_ERROR in the case of an error, NX_EOD when there are no more items.
- * \ingroup c_readwrite
- */
-extern NXstatus NXgetnextattr(NXhandle handle, NXname pName, int *iLength, int *iType);
-
- /**
- * Read an attribute.
- * \param handle A NeXus file handle as initialized by NXopen.
- * \param name The name of the atrribute to read.
- * \param data A pointer to a memory area large enough to hold the attributes value.
- * \param iDataLen The length of data in bytes.
- * \param iType A pointer to an integer which will had been set to the NeXus data type of the attribute.
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_readwrite
- */
-extern NXstatus NXgetattr(NXhandle handle, char* name, void* data, int* iDataLen, int* iType);
-
- /**
- * Get the count of attributes in the currently open dataset, group or global attributes when at root level.
- * \param handle A NeXus file handle as initialized by NXopen.
- * \param no_items A pointer to an integer which be set to the number of attributes available.
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_metadata
- */
-extern NXstatus NXgetattrinfo(NXhandle handle, int* no_items);
-
- /**
- * Retrieve link data for the currently open group. This link data can later on be used to link this
- * group into a different group.
- * \param handle A NeXus file handle as initialized by NXopen.
- * \param pLink A link data structure which will be initialized with the required information
- * for linking.
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_linking
- */
-extern NXstatus NXgetgroupID(NXhandle handle, NXlink* pLink);
-
- /**
- * Retrieve information about the currently open group.
- * \param handle A NeXus file handle as initialized by NXopen.
- * \param no_items A pointer to an integer which will be set to the count
- * of group elements available. This is the count of other groups and
- * data sets in this group.
- * \param name The name of the group.
- * \param nxclass The NeXus class name of the group.
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_metadata
- */
-extern NXstatus NXgetgroupinfo(NXhandle handle, int* no_items, NXname name, NXname nxclass);
-
- /**
- * Tests if two link data structures describe the same item.
- * \param handle A NeXus file handle as initialized by NXopen.
- * \param pFirstID The first link data for the test.
- * \param pSecondID The second link data structure.
- * \return NX_OK when both link data structures describe the same item, NX_ERROR else.
- * \ingroup c_linking
- */
-extern NXstatus NXsameID(NXhandle handle, NXlink* pFirstID, NXlink* pSecondID);
-
- /**
- * Resets a pending group search to the start again. To be called in a #NXgetnextentry loop when
- * a group search has to be restarted.
- * \param handle A NeXus file handle as initialized by NXopen.
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_navigation
- */
-extern NXstatus NXinitgroupdir(NXhandle handle);
-
- /**
- * Resets a pending attribute search to the start again. To be called in a #NXgetnextattr loop when
- * an attribute search has to be restarted.
- * \param handle A NeXus file handle as initialized by NXopen.
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_navigation
- */
-extern NXstatus NXinitattrdir(NXhandle handle);
-
- /**
- * Sets the format for number printing. This call has only an effect when using the XML physical file
- * format.
- * \param handle A NeXus file handle as initialized by NXopen.
- * \param type The NeXus data type to set the format for.
- * \param format The C-language format string to use for this data type.
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_readwrite
- */
-extern NXstatus NXsetnumberformat(NXhandle handle, int type, char *format);
-
- /**
- * Inquire the filename of the currently open file. FilenameBufferLength of the file name
- * will be copied into the filename buffer.
- * \param handle A NeXus file handle as initialized by NXopen.
- * \param filename The buffer to hold the filename.
- * \param filenameBufferLength The length of the filename buffer.
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_metadata
- */
-extern NXstatus NXinquirefile(NXhandle handle, char *filename, int filenameBufferLength);
-
- /**
- * Test if a group is actually pointing to an external file. If so, retrieve the URL of the
- * external file.
- * \param handle A NeXus file handle as initialized by NXopen.
- * \param name The name of the group to test.
- * \param nxclass The class name of the group to test.
- * \param url A buffer to copy the URL too.
- * \param urlLen The length of the Url buffer. At maximum urlLen bytes will be copied to url.
- * \return NX_OK when the group is pointing to an external file, NX_ERROR else.
- * \ingroup c_external
- */
-extern NXstatus NXisexternalgroup(NXhandle handle, CONSTCHAR *name, CONSTCHAR *nxclass, char *url, int urlLen);
-
-
- /**
- * Test if a dataset is actually pointing to an external file. If so, retrieve the URL of the
- * external file.
- * \param handle A NeXus file handle as initialized by NXopen.
- * \param name The name of the dataset to test.
- * \param url A buffer to copy the URL too.
- * \param urlLen The length of the Url buffer. At maximum urlLen bytes will be copied to url.
- * \return NX_OK when the dataset is pointing to an external file, NX_ERROR else.
- * \ingroup c_external
- */
-extern NXstatus NXisexternaldataset(NXhandle handle, CONSTCHAR *name, char *url, int urlLen);
-
- /**
- * Create a link to a group in an external file. This works by creating a NeXus group under the current level in
- * the hierarchy which actually points to a group in another file.
- * \param handle A NeXus file handle as initialized by NXopen.
- * \param name The name of the group which points to the external file.
- * \param nxclass The class name of the group which points to the external file.
- * \param url The URL of the external file. Currently only one URL format is supported: nxfile://path-tofile\#path-in-file.
- * This consists of two parts: the first part is of course the path to the file. The second part, path-in-file, is the
- * path to the group in the external file which appears in the first file.
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_external
- */
-extern NXstatus NXlinkexternal(NXhandle handle, CONSTCHAR *name, CONSTCHAR *nxclass, CONSTCHAR *url);
-
-
- /**
- * Create a link to a dataset in an external file. This works by creating a dataset under the current level in
- * the hierarchy which actually points to a dataset in another file.
- * \param handle A NeXus file handle as initialized by NXopen.
- * \param name The name of the dataset which points to the external file.
- * \param url The URL of the external file. Currently only one URL format is supported: nxfile://path-tofile\#path-in-file.
- * This consists of two parts: the first part is of course the path to the file. The second part, path-in-file, is the
- * path to the dataset in the external file which appears in the first file.
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_external
- */
-extern NXstatus NXlinkexternaldataset(NXhandle handle, CONSTCHAR *name, CONSTCHAR *url);
-
- /**
- * Utility function which allocates a suitably sized memory area for the dataset characteristics specified.
- * \param data A pointer to a pointer which will be initialized with a pointer to a suitably sized memory area.
- * \param rank the rank of the data.
- * \param dimensions An array holding the size of the data in each dimension.
- * \param datatype The NeXus data type of the data.
- * \return NX_OK when allocation succeeds, NX_ERROR in the case of an error.
- * \ingroup c_memory
- */
-extern NXstatus NXmalloc(void** data, int rank, int dimensions[], int datatype);
-
- /**
- * @copydoc NXmalloc()
- */
-extern NXstatus NXmalloc64(void** data, int rank, int64_t dimensions[], int datatype);
-
-
- /**
- * Utility function to return NeXus version
- * \return pointer to string in static storage. Version in
- * same format as NEXUS_VERSION string in napi.h i.e. "major.minor.patch"
- * \ingroup c_metadata
- */
-extern const char* NXgetversion();
-
- /**
- * Utility function to release the memory for data.
- * \param data A pointer to a pointer to free.
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_memory
- */
-extern NXstatus NXfree(void** data);
-
-
-/*-----------------------------------------------------------------------
- NAPI internals
-------------------------------------------------------------------------*/
- /**
- * Retrieve information about the currently open dataset. In contrast to the main function below,
- * this function does not try to find out about the size of strings properly.
- * \param handle A NeXus file handle as initialized by NXopen.
- * \param rank A pointer to an integer which will be filled with the rank of
- * the dataset.
- * \param dimension An array which will be initialized with the size of the dataset in any of its
- * dimensions. The array must have at least the size of rank.
- * \param datatype A pointer to an integer which be set to the NeXus data type code for this dataset.
- * \return NX_OK on success, NX_ERROR in the case of an error.
- * \ingroup c_metadata
- */
-extern NXstatus NXgetrawinfo(NXhandle handle, int* rank, int dimension[], int* datatype);
-
- /**
- * @copydoc NXgetrawinfo
- */
-extern NXstatus NXgetrawinfo64(NXhandle handle, int* rank, int64_t dimension[], int* datatype);
-
-/** \typedef void (*ErrFunc)(void *data, char *text)
- * All NeXus error reporting happens through this special function, the
- * ErrFunc. The NeXus-API allows to replace this error reporting function
- * through a user defined implementation. The default error function prints to stderr. User
- * defined ones may pop up dialog boxes or whatever.
- * \param data A pointer to some user defined data structure
- * \param text The text of the error message to display.
- */
-typedef void (*ErrFunc)(void *data, char *text);
-
- /**
- * Set a global error function.
- * Not threadsafe.
- * \param pData A pointer to a user defined data structure which be passed to
- * the error display function.
- * \param newErr The new error display function.
- */
-extern void NXMSetError(void *pData, ErrFunc newErr);
-
- /**
- * Set an error function for the current thread.
- * When used this overrides anything set in NXMSetError (for the current thread).
- * Use this method in threaded applications.
- * \param pData A pointer to a user defined data structure which be passed to
- * the error display function.
- * \param newErr The new error display function.
- */
-extern void NXMSetTError(void *pData, ErrFunc newErr);
-
- /**
- * Retrieve the current error display function
- * \return The current error display function.
- */
-extern ErrFunc NXMGetError();
-
- /**
- * Suppress error reports from the NeXus-API
- */
-extern void NXMDisableErrorReporting();
-
- /**
- * Enable error reports from the NeXus-API
- */
-extern void NXMEnableErrorReporting();
-
- /**
- * Dispatches the error message to the error function defined by NXMSetTError
- */
-extern void NXReportError(char *text);
-
- /**
- * Do not use, first parameter should be set by NXMSetTError
- */
-extern void NXIReportError(void *pData,char *text);
-/* extern void *NXpData; */
-extern char *NXIformatNeXusTime();
-extern NXstatus NXIprintlink(NXhandle fid, NXlink* link);
-
-/**
- * A function for setting the default cache size for HDF-5
- * \ingroup c_init
- */
-extern NXstatus NXsetcache(long newVal);
-
- typedef struct {
- NXhandle pNexusData;
- NXstatus ( *nxreopen)(NXhandle pOrigHandle, NXhandle* pNewHandle);
- NXstatus ( *nxclose)(NXhandle* pHandle);
- NXstatus ( *nxflush)(NXhandle* pHandle);
- NXstatus ( *nxmakegroup) (NXhandle handle, CONSTCHAR *name, CONSTCHAR* NXclass);
- NXstatus ( *nxopengroup) (NXhandle handle, CONSTCHAR *name, CONSTCHAR* NXclass);
- NXstatus ( *nxclosegroup)(NXhandle handle);
- NXstatus ( *nxmakedata64) (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int64_t dim[]);
- NXstatus ( *nxcompmakedata64) (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int64_t dim[], int comp_typ, int64_t bufsize[]);
- NXstatus ( *nxcompress) (NXhandle handle, int compr_type);
- NXstatus ( *nxopendata) (NXhandle handle, CONSTCHAR* label);
- NXstatus ( *nxclosedata)(NXhandle handle);
- NXstatus ( *nxputdata)(NXhandle handle, const void* data);
- NXstatus ( *nxputattr)(NXhandle handle, CONSTCHAR* name, const void* data, int iDataLen, int iType);
- NXstatus ( *nxputslab64)(NXhandle handle, const void* data, const int64_t start[], const int64_t size[]);
- NXstatus ( *nxgetdataID)(NXhandle handle, NXlink* pLink);
- NXstatus ( *nxmakelink)(NXhandle handle, NXlink* pLink);
- NXstatus ( *nxmakenamedlink)(NXhandle handle, CONSTCHAR *newname, NXlink* pLink);
- NXstatus ( *nxgetdata)(NXhandle handle, void* data);
- NXstatus ( *nxgetinfo64)(NXhandle handle, int* rank, int64_t dimension[], int* datatype);
- NXstatus ( *nxgetnextentry)(NXhandle handle, NXname name, NXname nxclass, int* datatype);
- NXstatus ( *nxgetslab64)(NXhandle handle, void* data, const int64_t start[], const int64_t size[]);
- NXstatus ( *nxgetnextattr)(NXhandle handle, NXname pName, int *iLength, int *iType);
- NXstatus ( *nxgetattr)(NXhandle handle, char* name, void* data, int* iDataLen, int* iType);
- NXstatus ( *nxgetattrinfo)(NXhandle handle, int* no_items);
- NXstatus ( *nxgetgroupID)(NXhandle handle, NXlink* pLink);
- NXstatus ( *nxgetgroupinfo)(NXhandle handle, int* no_items, NXname name, NXname nxclass);
- NXstatus ( *nxsameID)(NXhandle handle, NXlink* pFirstID, NXlink* pSecondID);
- NXstatus ( *nxinitgroupdir)(NXhandle handle);
- NXstatus ( *nxinitattrdir)(NXhandle handle);
- NXstatus ( *nxsetnumberformat)(NXhandle handle, int type, char *format);
- NXstatus ( *nxprintlink)(NXhandle handle, NXlink* link);
- NXstatus ( *nxnativeexternallink)(NXhandle handle, CONSTCHAR* name, CONSTCHAR* externalfile, CONSTCHAR* remotetarget);
- NXstatus ( *nxnativeinquirefile)(NXhandle handle, char* externalfile, const int filenamelength);
- NXstatus ( *nxnativeisexternallink)(NXhandle handle, CONSTCHAR* name, char* url, int urllen);
- int stripFlag;
- int checkNameSyntax;
- } NexusFunction, *pNexusFunction;
- /*---------------------*/
- extern long nx_cacheSize;
-
-/* FORTRAN internals */
-
- extern NXstatus NXfopen(char * filename, NXaccess* am,
- NXhandle pHandle);
- extern NXstatus NXfclose (NXhandle pHandle);
- extern NXstatus NXfputattr(NXhandle fid, const char *name, const void *data,
- int *pDatalen, int *pIType);
- extern NXstatus NXfcompress(NXhandle fid, int *compr_type);
- extern NXstatus NXfcompmakedata(NXhandle fid, char *name,
- int *pDatatype,
- int *pRank, int dimensions[],
- int *compression_type, int chunk[]);
- extern NXstatus NXfmakedata(NXhandle fid, char *name, int *pDatatype,
- int *pRank, int dimensions[]);
- extern NXstatus NXfflush(NXhandle pHandle);
- extern NXstatus NXfgetpath(NXhandle fid, char *path, int *pathlen);
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-/**
- * Freddie Akeroyd 11/8/2009
- * Add NeXus schema support - this uses BASE.xsd as the initial file
- */
-#define NEXUS_SCHEMA_VERSION "3.1" /**< version of NeXus definition schema */
-#define NEXUS_SCHEMA_ROOT "http://definition.nexusformat.org/schema/" /**< XML schema namespace specified by xmlns */
-#define NEXUS_SCHEMA_NAMESPACE NEXUS_SCHEMA_ROOT NEXUS_SCHEMA_VERSION /**< XML schema namespace specified by xmlns */
-#define NEXUS_SCHEMA_BASE "BASE"
-#define NEXUS_SCHEMA_FILE NEXUS_SCHEMA_BASE ".xsd" /**< default schema file for namespace */
-#define NEXUS_SCHEMA_URL NEXUS_SCHEMA_NAMESPACE "/" NEXUS_SCHEMA_FILE /**< location of default schema file for namespace */
-
-#endif /*NEXUSAPI*/
diff --git a/napi4.c b/napi4.c
deleted file mode 100644
index 06924f7e..00000000
--- a/napi4.c
+++ /dev/null
@@ -1,1983 +0,0 @@
-/*---------------------------------------------------------------------------
- NeXus - Neutron & X-ray Common Data Format
-
- Application Program Interface (HDF4) Routines
-
- Copyright (C) 1997-2006 Mark Koennecke, Przemek Klosowski
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- For further information, see
-
- $Id$
-
-----------------------------------------------------------------------------*/
-
-#ifdef HDF4
-
-#include
-#include
-#include
-#include
-
-#include "napi.h"
-#include "napi4.h"
-
-extern void *NXpData;
-
- typedef struct __NexusFile {
- struct iStack {
- int32 *iRefDir;
- int32 *iTagDir;
- int32 iVref;
- int32 __iStack_pad;
- int iNDir;
- int iCurDir;
- } iStack[NXMAXSTACK];
- struct iStack iAtt;
- int32 iVID;
- int32 iSID;
- int32 iCurrentVG;
- int32 iCurrentSDS;
- int iNXID;
- int iStackPtr;
- char iAccess[2];
- } NexusFile, *pNexusFile;
- /*-------------------------------------------------------------------*/
-
- static pNexusFile NXIassert(NXhandle fid)
- {
- pNexusFile pRes;
-
- assert(fid != NULL);
- pRes = (pNexusFile)fid;
- assert(pRes->iNXID == NXSIGNATURE);
- return pRes;
- }
- /*----------------------------------------------------------------------*/
-static int findNapiClass(pNexusFile pFile, int groupRef, NXname nxclass)
-{
- NXname classText, linkClass;
- int32 tags[2], attID, linkID, groupID;
-
- groupID = Vattach(pFile->iVID,groupRef,"r");
- Vgetclass(groupID, classText);
- if(strcmp(classText,"NAPIlink") != 0)
- {
- /* normal group */
- strcpy(nxclass,classText);
- Vdetach(groupID);
- return groupRef;
- }
- else
- {
- /* code for linked renamed groups */
- attID = Vfindattr(groupID,"NAPIlink");
- if(attID >= 0)
- {
- Vgetattr(groupID,attID, tags);
- linkID = Vattach(pFile->iVID,tags[1],"r");
- Vgetclass(linkID, linkClass);
- Vdetach(groupID);
- Vdetach(linkID);
- strcpy(nxclass,linkClass);
- return tags[1];
- }
- else
- {
- /* this allows for finding the NAPIlink group in NXmakenamedlink */
- strcpy(nxclass,classText);
- Vdetach(groupID);
- return groupRef;
- }
- }
-}
- /* --------------------------------------------------------------------- */
-
- static int32 NXIFindVgroup (pNexusFile pFile, CONSTCHAR *name, CONSTCHAR *nxclass)
- {
- int32 iNew, iRef, iTag;
- int iN, i;
- int32 *pArray = NULL;
- NXname pText;
-
- assert (pFile != NULL);
-
- if (pFile->iCurrentVG == 0) { /* root level */
- /* get the number and ID's of all lone Vgroups in the file */
- iN = Vlone (pFile->iVID, NULL, 0);
- if(iN == 0) {
- return NX_EOD;
- }
- pArray = (int32 *) malloc (iN * sizeof (int32));
- if (!pArray) {
- NXReportError( "ERROR: out of memory in NXIFindVgroup");
- return NX_EOD;
- }
- Vlone (pFile->iVID, pArray, iN);
-
- /* loop and check */
- for (i = 0; i < iN; i++) {
- iNew = Vattach (pFile->iVID, pArray[i], "r");
- Vgetname (iNew, pText);
- Vdetach(iNew);
- if (strcmp (pText, name) == 0) {
- pArray[i] = findNapiClass(pFile,pArray[i],pText);
- if (strcmp (pText, nxclass) == 0) {
- /* found ! */
- iNew = pArray[i];
- free (pArray);
- return iNew;
- }
- }
- }
- /* nothing found */
- free (pArray);
- return NX_EOD;
- } else { /* case in Vgroup */
- iN = Vntagrefs (pFile->iCurrentVG);
- for (i = 0; i < iN; i++) {
- Vgettagref (pFile->iCurrentVG, i, &iTag, &iRef);
- if (iTag == DFTAG_VG) {
- iNew = Vattach (pFile->iVID, iRef, "r");
- Vgetname (iNew, pText);
- Vdetach(iNew);
- if (strcmp (pText, name) == 0) {
- iRef = findNapiClass(pFile,iRef, pText);
- if (strcmp (pText, nxclass) == 0) {
- return iRef;
- }
- }
- }
- } /* end for */
- } /* end else */
- /* not found */
- return NX_EOD;
- }
-
- /*----------------------------------------------------------------------*/
-
- static int32 NXIFindSDS (NXhandle fid, CONSTCHAR *name)
- {
- pNexusFile self;
- int32 iNew, iRet, iTag, iRef;
- int32 i, iN, iA, iD1, iD2;
- NXname pNam;
- int32 iDim[H4_MAX_VAR_DIMS];
-
- self = NXIassert (fid);
-
- /* root level search */
- if (self->iCurrentVG == 0) {
- i = SDfileinfo (self->iSID, &iN, &iA);
- if (i < 0) {
- NXReportError( "ERROR: failure to read file information");
- return NX_EOD;
- }
- for (i = 0; i < iN; i++) {
- iNew = SDselect (self->iSID, i);
- SDgetinfo (iNew, pNam, &iA, iDim, &iD1, &iD2);
- if (strcmp (pNam, name) == 0) {
- iRet = SDidtoref (iNew);
- SDendaccess (iNew);
- return iRet;
- } else {
- SDendaccess (iNew);
- }
- }
- /* not found */
- return NX_EOD;
- }
- /* end root level */
- else { /* search in a Vgroup */
- iN = Vntagrefs (self->iCurrentVG);
- for (i = 0; i < iN; i++) {
- Vgettagref (self->iCurrentVG, i, &iTag, &iRef);
- /* we are now writing using DFTAG_NDG, but need others for backward compatability */
- if ((iTag == DFTAG_SDG) || (iTag == DFTAG_NDG) || (iTag == DFTAG_SDS)) {
- iNew = SDreftoindex (self->iSID, iRef);
- iNew = SDselect (self->iSID, iNew);
- SDgetinfo (iNew, pNam, &iA, iDim, &iD1, &iD2);
- if (strcmp (pNam, name) == 0) {
- SDendaccess (iNew);
- return iRef;
- }
- SDendaccess (iNew);
- }
- } /* end for */
- } /* end Vgroup */
- /* we get here, only if nothing found */
- return NX_EOD;
- }
-
- /*----------------------------------------------------------------------*/
-
- static int NXIInitDir (pNexusFile self)
- {
- int i;
- int32 iTag, iRef;
- int iStackPtr;
-
- /*
- * Note: the +1 to various malloc() operations is to avoid a
- * malloc(0), which is an error on some operating systems
- */
- iStackPtr = self->iStackPtr;
- if (self->iCurrentVG == 0 &&
- self->iStack[iStackPtr].iRefDir == NULL) { /* root level */
- /* get the number and ID's of all lone Vgroups in the file */
- self->iStack[iStackPtr].iNDir = Vlone (self->iVID, NULL, 0);
- self->iStack[iStackPtr].iRefDir =
- (int32 *) malloc (self->iStack[iStackPtr].iNDir * sizeof (int32) + 1);
- if (!self->iStack[iStackPtr].iRefDir) {
- NXReportError( "ERROR: out of memory in NXIInitDir");
- return NX_EOD;
- }
- Vlone (self->iVID,
- self->iStack[self->iStackPtr].iRefDir,
- self->iStack[self->iStackPtr].iNDir);
- } else {
- /* Vgroup level */
- self->iStack[iStackPtr].iNDir = Vntagrefs (self->iCurrentVG);
- self->iStack[iStackPtr].iRefDir =
- (int32 *) malloc (self->iStack[iStackPtr].iNDir * sizeof (int32) + 1);
- self->iStack[iStackPtr].iTagDir =
- (int32 *) malloc (self->iStack[iStackPtr].iNDir * sizeof (int32) + 1);
- if ((!self->iStack[iStackPtr].iRefDir) ||
- (!self->iStack[iStackPtr].iTagDir)) {
- NXReportError( "ERROR: out of memory in NXIInitDir");
- return NX_EOD;
- }
- for (i = 0; i < self->iStack[self->iStackPtr].iNDir; i++) {
- Vgettagref (self->iCurrentVG, i, &iTag, &iRef);
- self->iStack[iStackPtr].iRefDir[i] = iRef;
- self->iStack[iStackPtr].iTagDir[i] = iTag;
- }
- }
- self->iStack[iStackPtr].iCurDir = 0;
- return 1;
- }
-
- /*----------------------------------------------------------------------*/
-
- static void NXIKillDir (pNexusFile self)
- {
- if (self->iStack[self->iStackPtr].iRefDir) {
- free (self->iStack[self->iStackPtr].iRefDir);
- self->iStack[self->iStackPtr].iRefDir = NULL;
- }
- if (self->iStack[self->iStackPtr].iTagDir) {
- free (self->iStack[self->iStackPtr].iTagDir);
- self->iStack[self->iStackPtr].iTagDir = NULL;
- }
- self->iStack[self->iStackPtr].iCurDir = 0;
- self->iStack[self->iStackPtr].iNDir = 0;
- }
-
-
- /*-------------------------------------------------------------------------*/
-
- static int NXIInitAttDir (pNexusFile pFile)
- {
- int iRet;
- int32 iData, iAtt, iRank, iType;
- int32 iDim[H4_MAX_VAR_DIMS];
- NXname pNam;
-
- pFile->iAtt.iCurDir = 0;
- if (pFile->iCurrentSDS != 0) { /* SDS level */
- iRet = SDgetinfo (pFile->iCurrentSDS, pNam, &iRank, iDim, &iType,
- &iAtt);
- } else {
- if(pFile->iCurrentVG == 0){
- /* global level */
- iRet = SDfileinfo (pFile->iSID, &iData, &iAtt);
- } else {
- /* group attribute */
- iRet = Vnattrs(pFile->iCurrentVG);
- iAtt = iRet;
- }
- }
- if (iRet < 0) {
- NXReportError( "ERROR: HDF cannot read attribute numbers");
- pFile->iAtt.iNDir = 0;
- return NX_ERROR;
- }
- pFile->iAtt.iNDir = iAtt;
- return NX_OK;
- }
-
- /* --------------------------------------------------------------------- */
-
- static void NXIKillAttDir (pNexusFile self)
- {
- if (self->iAtt.iRefDir) {
- free (self->iAtt.iRefDir);
- self->iAtt.iRefDir = NULL;
- }
- if (self->iAtt.iTagDir) {
- free (self->iAtt.iTagDir);
- self->iAtt.iTagDir = NULL;
- }
- self->iAtt.iCurDir = 0;
- self->iAtt.iNDir = 0;
- }
-/*------------------------------------------------------------------*/
- static void NXIbuildPath(pNexusFile pFile, char *buffer, int bufLen)
- {
- int i;
- int32 groupID, iA, iD1, iD2, iDim[H4_MAX_VAR_DIMS];
- NXname pText;
-
- buffer[0] = '\0';
- for(i = 1; i <= pFile->iStackPtr; i++){
- strncat(buffer,"/",bufLen-strlen(buffer));
- groupID = Vattach(pFile->iVID,pFile->iStack[i].iVref, "r");
- if (groupID != -1)
- {
- if (Vgetname(groupID, pText) != -1) {
- strncat(buffer,pText,bufLen-strlen(buffer));
- } else {
- NXReportError( "ERROR: NXIbuildPath cannot get vgroup name");
- }
- Vdetach(groupID);
- }
- else
- {
- NXReportError( "ERROR: NXIbuildPath cannot attach to vgroup");
- }
- }
- if(pFile->iCurrentSDS != 0){
- if (SDgetinfo(pFile->iCurrentSDS,pText,&iA,iDim,&iD1,&iD2) != -1) {
- strncat(buffer,"/",bufLen-strlen(buffer));
- strncat(buffer,pText,bufLen-strlen(buffer));
- }
- else
- {
- NXReportError( "ERROR: NXIbuildPath cannot read SDS");
- }
- }
- }
- /* ----------------------------------------------------------------------
-
- Definition of NeXus API
-
- ---------------------------------------------------------------------*/
-
-
- NXstatus NX4open(CONSTCHAR *filename, NXaccess am,
- NXhandle* pHandle)
- {
- pNexusFile pNew = NULL;
- char pBuffer[512];
- char *time_puffer = NULL;
- char HDF_VERSION[64];
- uint32 lmajor, lminor, lrelease;
- int32 am1=0;
-
- *pHandle = NULL;
-
- /* mask off any options for now */
- am = (NXaccess)(am & NXACCMASK_REMOVEFLAGS);
- /* map Nexus NXaccess types to HDF4 types */
- if (am == NXACC_CREATE) {
- am1 = DFACC_CREATE;
- } else if (am == NXACC_CREATE4) {
- am1 = DFACC_CREATE;
- } else if (am == NXACC_READ) {
- am1 = DFACC_READ;
- } else if (am == NXACC_RDWR) {
- am1 = DFACC_RDWR;
- }
- /* get memory */
- pNew = (pNexusFile) malloc (sizeof (NexusFile));
- if (!pNew) {
- NXReportError( "ERROR: no memory to create File datastructure");
- return NX_ERROR;
- }
- memset (pNew, 0, sizeof (NexusFile));
-
-#if WRITE_OLD_IDENT /* not used at moment */
-/*
- * write something that can be used by OLE
- */
-
- if (am == NXACC_CREATE || am == NXACC_CREATE4) {
- if ( (file_id = Hopen(filename, am1, 0)) == -1 ) {
- sprintf (pBuffer, "ERROR: cannot open file_a: %s", filename);
- NXReportError( pBuffer);
- free (pNew);
- return NX_ERROR;
- }
- an_id = ANstart(file_id);
- ann_id = ANcreatef(an_id, AN_FILE_LABEL); /* AN_FILE_DESC */
- ANwriteann(ann_id, "NeXus", 5);
- ANendaccess(ann_id);
- ANend(an_id);
- if (Hclose(file_id) == -1) {
- sprintf (pBuffer, "ERROR: cannot close file: %s", filename);
- NXReportError( pBuffer);
- free (pNew);
- return NX_ERROR;
- }
- am = NXACC_RDWR;
- }
-#endif /* WRITE_OLD_IDENT */
-
- /* start SDS interface */
- pNew->iSID = SDstart (filename, am1);
- if (pNew->iSID <= 0) {
- sprintf (pBuffer, "ERROR: cannot open file_b: %s", filename);
- NXReportError( pBuffer);
- free (pNew);
- return NX_ERROR;
- }
-/*
- * need to create global attributes file_name file_time NeXus_version
- * at some point for new files
- */
- if (am != NXACC_READ) {
- if (SDsetattr(pNew->iSID, "NeXus_version", DFNT_CHAR8, strlen(NEXUS_VERSION), NEXUS_VERSION) < 0) {
- NXReportError( "ERROR: HDF failed to store NeXus_version attribute ");
- return NX_ERROR;
- }
- Hgetlibversion(&lmajor, &lminor, &lrelease, HDF_VERSION);
- if (SDsetattr(pNew->iSID, "HDF_version", DFNT_CHAR8, strlen(HDF_VERSION), HDF_VERSION) < 0) {
- NXReportError( "ERROR: HDF failed to store HDF_version attribute ");
- return NX_ERROR;
- }
- }
-
- time_puffer = NXIformatNeXusTime();
- if (am == NXACC_CREATE || am == NXACC_CREATE4) {
- if (SDsetattr(pNew->iSID, "file_name", DFNT_CHAR8, strlen(filename), (char*)filename) < 0) {
- NXReportError( "ERROR: HDF failed to store file_name attribute ");
- return NX_ERROR;
- }
- if(time_puffer != NULL){
- if (SDsetattr(pNew->iSID, "file_time", DFNT_CHAR8,
- strlen(time_puffer), time_puffer) < 0) {
- NXReportError(
- "ERROR: HDF failed to store file_time attribute ");
- free(time_puffer);
- return NX_ERROR;
- }
- }
- }
- if (time_puffer != NULL) {
- free(time_puffer);
- }
-
- /*
- * Otherwise we try to create the file two times which makes HDF
- * Throw up on us.
- */
- if (am == NXACC_CREATE || am == NXACC_CREATE4) {
- am = NXACC_RDWR;
- am1 = DFACC_RDWR;
- }
-
- /* Set Vgroup access mode */
- if (am == NXACC_READ) {
- strcpy(pNew->iAccess,"r");
- } else {
- strcpy(pNew->iAccess,"w");
- }
-
- /* start Vgroup API */
-
- pNew->iVID = Hopen(filename, am1, 100);
- if (pNew->iVID <= 0) {
- sprintf (pBuffer, "ERROR: cannot open file_c: %s", filename);
- NXReportError( pBuffer);
- free (pNew);
- return NX_ERROR;
- }
- Vstart (pNew->iVID);
- pNew->iNXID = NXSIGNATURE;
- pNew->iStack[0].iVref = 0; /* root! */
-
- *pHandle = (NXhandle)pNew;
- return NX_OK;
- }
-
-/*-----------------------------------------------------------------------*/
-
- NXstatus NX4close (NXhandle* fid)
- {
- pNexusFile pFile = NULL;
- int iRet;
-
- pFile = NXIassert(*fid);
- iRet = 0;
- /* close links into vGroups or SDS */
- if (pFile->iCurrentVG != 0) {
- Vdetach (pFile->iCurrentVG);
- }
- if (pFile->iCurrentSDS != 0) {
- iRet = SDendaccess (pFile->iCurrentSDS);
- }
- if (iRet < 0) {
- NXReportError( "ERROR: ending access to SDS");
- }
- /* close the SDS and Vgroup API's */
- Vend (pFile->iVID);
- iRet = SDend (pFile->iSID);
- if (iRet < 0) {
- NXReportError( "ERROR: HDF cannot close SDS interface");
- }
- iRet = Hclose (pFile->iVID);
- if (iRet < 0) {
- NXReportError( "ERROR: HDF cannot close HDF file");
- }
- /* release memory */
- NXIKillDir (pFile);
- free (pFile);
- *fid = NULL;
- return NX_OK;
- }
-
-
-/*-----------------------------------------------------------------------*/
-
-
- NXstatus NX4makegroup (NXhandle fid, CONSTCHAR *name, CONSTCHAR *nxclass)
- {
- pNexusFile pFile;
- int32 iNew, iRet;
- char pBuffer[256];
-
- pFile = NXIassert (fid);
- /*
- * Make sure that a group with the same name and nxclass does not
- * already exist.
- */
- if ((iRet = NXIFindVgroup (pFile, (char*)name, nxclass)) >= 0) {
- sprintf (pBuffer, "ERROR: Vgroup %s, class %s already exists",
- name, nxclass);
- NXReportError( pBuffer);
- return NX_ERROR;
- }
-
- /* create and configure the group */
- iNew = Vattach (pFile->iVID, -1, "w");
- if (iNew < 0) {
- NXReportError( "ERROR: HDF could not create Vgroup");
- return NX_ERROR;
- }
- Vsetname (iNew, name);
- Vsetclass (iNew, nxclass);
-
- /* Insert it into the hierarchy, when appropriate */
- iRet = 0;
- if (pFile->iCurrentVG != 0) {
- iRet = Vinsert (pFile->iCurrentVG, iNew);
- }
- Vdetach (iNew);
- if (iRet < 0) {
- NXReportError( "ERROR: HDF failed to insert Vgroup");
- return NX_ERROR;
- }
- return NX_OK;
- }
-
-
- /*------------------------------------------------------------------------*/
- NXstatus NX4opengroup (NXhandle fid, CONSTCHAR *name, CONSTCHAR *nxclass)
- {
- pNexusFile pFile;
- int32 iRef;
- char pBuffer[256];
-
- pFile = NXIassert (fid);
-
- iRef = NXIFindVgroup (pFile, (char*)name, nxclass);
- if (iRef < 0) {
- sprintf (pBuffer, "ERROR: Vgroup \"%s\", class \"%s\" NOT found", name, nxclass);
- NXReportError( pBuffer);
- return NX_ERROR;
- }
- /* are we at root level ? */
- if (pFile->iCurrentVG == 0) {
- pFile->iCurrentVG = Vattach (pFile->iVID, iRef,pFile->iAccess);
- pFile->iStackPtr++;
- pFile->iStack[pFile->iStackPtr].iVref = iRef;
- } else {
- Vdetach (pFile->iCurrentVG);
- pFile->iStackPtr++;
- pFile->iStack[pFile->iStackPtr].iVref = iRef;
- pFile->iCurrentVG = Vattach (pFile->iVID,
- pFile->iStack[pFile->iStackPtr].iVref,
- pFile->iAccess);
- }
- NXIKillDir (pFile);
- return NX_OK;
- }
- /* ------------------------------------------------------------------- */
-
-
- NXstatus NX4closegroup (NXhandle fid)
- {
- pNexusFile pFile;
-
- pFile = NXIassert (fid);
-
- /* first catch the trivial case: we are at root and cannot get
- deeper into a negative directory hierarchy (anti-directory)
- */
- if (pFile->iCurrentVG == 0) {
- NXIKillDir (pFile);
- return NX_OK;
- } else { /* Sighhh. Some work to do */
- /* close the current VG and decrement stack */
- Vdetach (pFile->iCurrentVG);
- NXIKillDir (pFile);
- pFile->iStackPtr--;
- if (pFile->iStackPtr <= 0) { /* we hit root */
- pFile->iStackPtr = 0;
- pFile->iCurrentVG = 0;
- } else {
- /* attach to the lower Vgroup */
- pFile->iCurrentVG = Vattach (pFile->iVID,
- pFile->iStack[pFile->iStackPtr].iVref,
- pFile->iAccess);
- }
- }
- return NX_OK;
- }
-
-
- /* --------------------------------------------------------------------- */
-
- NXstatus NX4makedata64 (NXhandle fid, CONSTCHAR *name, int datatype, int rank,
- int64_t dimensions[])
- {
- pNexusFile pFile;
- int32 iNew;
- char pBuffer[256];
- int i, iRet, type;
- int32 myDim[H4_MAX_VAR_DIMS];
-
- pFile = NXIassert (fid);
-
- if (dimensions[0] == NX_UNLIMITED)
- {
- dimensions[0] = SD_UNLIMITED;
- }
-
- if ((iNew = NXIFindSDS (fid, name))>=0) {
- sprintf (pBuffer, "ERROR: SDS %s already exists at this level", name);
- NXReportError( pBuffer);
- return NX_ERROR;
- }
-
- if (datatype == NX_CHAR)
- {
- type=DFNT_CHAR8;
- }
- else if (datatype == NX_INT8)
- {
- type=DFNT_INT8;
- }
- else if (datatype == NX_UINT8)
- {
- type=DFNT_UINT8;
- }
- else if (datatype == NX_INT16)
- {
- type=DFNT_INT16;
- }
- else if (datatype == NX_UINT16)
- {
- type=DFNT_UINT16;
- }
- else if (datatype == NX_INT32)
- {
- type=DFNT_INT32;
- }
- else if (datatype == NX_UINT32)
- {
- type=DFNT_UINT32;
- }
- else if (datatype == NX_FLOAT32)
- {
- type=DFNT_FLOAT32;
- }
- else if (datatype == NX_FLOAT64)
- {
- type=DFNT_FLOAT64;
- }
- else
- {
- NXReportError( "ERROR: invalid type in NX4makedata");
- return NX_ERROR;
- }
-
- if (rank <= 0) {
- sprintf (pBuffer, "ERROR: invalid rank specified for SDS %s",
- name);
- NXReportError( pBuffer);
- return NX_ERROR;
- }
-
- /*
- Check dimensions for consistency. The first dimension may be 0
- thus denoting an unlimited dimension.
- */
- for (i = 1; i < rank; i++) {
- if (dimensions[i] <= 0) {
- sprintf (pBuffer,
- "ERROR: invalid dimension %d, value %lld given for SDS %s",
- i, (long long)dimensions[i], name);
- NXReportError( pBuffer);
- return NX_ERROR;
- }
- }
-
- /* cast the dimensions array properly for non 32-bit ints */
- for(i = 0; i < rank; i++)
- {
- myDim[i] = (int32)dimensions[i];
- }
-
-
- /* behave nicely, if there is still an SDS open */
- if (pFile->iCurrentSDS != 0) {
- SDendaccess (pFile->iCurrentSDS);
- pFile->iCurrentSDS = 0;
- }
-
- /* Do not allow creation of SDS's at the root level */
- if (pFile->iCurrentVG == 0) {
- sprintf(pBuffer, "ERROR: SDS creation at root level is not permitted");
- NXReportError( pBuffer);
- return NX_ERROR;
- }
-
- /* dataset creation */
- iNew = SDcreate (pFile->iSID, (char*)name, (int32)type,
- (int32)rank, myDim);
- if (iNew < 0) {
- sprintf (pBuffer, "ERROR: cannot create SDS %s, check arguments",
- name);
- NXReportError( pBuffer);
- return NX_ERROR;
- }
- /* link into Vgroup, if in one */
- if (pFile->iCurrentVG != 0) {
- iRet = Vaddtagref (pFile->iCurrentVG, DFTAG_NDG, SDidtoref (iNew));
- }
- iRet = SDendaccess (iNew);
- if (iRet < 0) {
- NXReportError( "ERROR: HDF cannot end access to SDS");
- return NX_ERROR;
- }
- return NX_OK;
- }
-
-
- /* --------------------------------------------------------------------- */
-
-
- NXstatus NX4compmakedata64 (NXhandle fid, CONSTCHAR *name, int datatype, int rank,
- int64_t dimensions[],int compress_type, int64_t chunk_size[])
- {
- pNexusFile pFile;
- int32 iNew, iRet, type;
- char pBuffer[256];
- int i, compress_level;
- int32 myDim[H4_MAX_VAR_DIMS];
- comp_info compstruct;
-
- pFile = NXIassert (fid);
-
- if (dimensions[0] == NX_UNLIMITED)
- {
- dimensions[0] = SD_UNLIMITED;
- }
-
- if ((iNew = NXIFindSDS (fid, name))>=0) {
- sprintf (pBuffer, "ERROR: SDS %s already exists at this level", name);
- NXReportError( pBuffer);
- return NX_ERROR;
- }
-
- if (datatype == NX_CHAR)
- {
- type=DFNT_CHAR8;
- }
- else if (datatype == NX_INT8)
- {
- type=DFNT_INT8;
- }
- else if (datatype == NX_UINT8)
- {
- type=DFNT_UINT8;
- }
- else if (datatype == NX_INT16)
- {
- type=DFNT_INT16;
- }
- else if (datatype == NX_UINT16)
- {
- type=DFNT_UINT16;
- }
- else if (datatype == NX_INT32)
- {
- type=DFNT_INT32;
- }
- else if (datatype == NX_UINT32)
- {
- type=DFNT_UINT32;
- }
- else if (datatype == NX_FLOAT32)
- {
- type=DFNT_FLOAT32;
- }
- else if (datatype == NX_FLOAT64)
- {
- type=DFNT_FLOAT64;
- }
- else
- {
- NXReportError( "ERROR: invalid datatype in NX4compmakedata");
- return NX_ERROR;
- }
-
- if (rank <= 0) {
- sprintf (pBuffer, "ERROR: invalid rank specified for SDS %s",
- name);
- NXReportError( pBuffer);
- return NX_ERROR;
- }
-
- /*
- Check dimensions for consistency. The first dimension may be 0
- thus denoting an unlimited dimension.
- */
- for (i = 1; i < rank; i++) {
- if (dimensions[i] <= 0) {
- sprintf (pBuffer,
- "ERROR: invalid dimension %d, value %lld given for SDS %s",
- i, (long long)dimensions[i], name);
- NXReportError( pBuffer);
- return NX_ERROR;
- }
- }
-
- /* cast the dimensions array properly for non 32-bit ints */
- for(i = 0; i < rank; i++)
- {
- myDim[i] = (int32)dimensions[i];
- }
-
-
- /* behave nicely, if there is still an SDS open */
- if (pFile->iCurrentSDS != 0) {
- SDendaccess (pFile->iCurrentSDS);
- pFile->iCurrentSDS = 0;
- }
-
- /* Do not allow creation of SDS's at the root level */
- if (pFile->iCurrentVG == 0) {
- sprintf(pBuffer, "ERROR: SDS creation at root level is not permitted");
- NXReportError( pBuffer);
- return NX_ERROR;
- }
-
- /* dataset creation */
- iNew = SDcreate (pFile->iSID, (char*)name, (int32)type,
- (int32)rank, myDim);
- if (iNew < 0) {
- sprintf (pBuffer, "ERROR: cannot create SDS %s, check arguments",
- name);
- NXReportError( pBuffer);
- return NX_ERROR;
- }
-
- /* compress SD data set */
- compress_level = 6;
- if( (compress_type / 100) == NX_COMP_LZW )
- {
- compress_level = compress_type % 100;
- compress_type = NX_COMP_LZW;
- }
-
- if(compress_type == NX_COMP_LZW)
- {
- compstruct.deflate.level = compress_level;
- iRet = SDsetcompress(iNew, COMP_CODE_DEFLATE, &compstruct);
- if (iRet < 0)
- {
- NXReportError( "LZW-Compression failure!");
- return NX_ERROR;
- }
- }
- else if (compress_type == NX_COMP_RLE)
- {
- iRet = SDsetcompress(iNew, COMP_CODE_RLE, &compstruct);
- if (iRet < 0)
- {
- NXReportError( "RLE-Compression failure!");
- return NX_ERROR;
- }
- }
- else if (compress_type == NX_COMP_HUF)
- {
- compstruct.skphuff.skp_size = DFKNTsize(type);
- iRet = SDsetcompress(iNew, COMP_CODE_SKPHUFF, &compstruct);
- if (iRet < 0)
- {
- NXReportError( "HUF-Compression failure!");
- return NX_ERROR;
- }
- }
- else if (compress_type == NX_COMP_NONE)
- {
- /* */
- }
- else
- {
- NXReportError( "Unknown compression method!");
- return NX_ERROR;
- }
- /* link into Vgroup, if in one */
- if (pFile->iCurrentVG != 0) {
- iRet = Vaddtagref (pFile->iCurrentVG, DFTAG_NDG, SDidtoref (iNew));
- }
- iRet = SDendaccess (iNew);
- if (iRet < 0) {
- NXReportError( "ERROR: HDF cannot end access to SDS");
- return NX_ERROR;
- }
-
- return NX_OK;
- }
-
- /* --------------------------------------------------------------------- */
-
-
- NXstatus NX4compress (NXhandle fid, int compress_type)
- {
- pNexusFile pFile;
- int32 iRank, iAtt, iType, iRet;
- int32 iSize[H4_MAX_VAR_DIMS];
- comp_coder_t compress_typei = COMP_CODE_NONE;
- NXname pBuffer;
- char pError[512];
- comp_info compstruct;
- int compress_level = 6;
-
- pFile = NXIassert (fid);
-
- /* check if there is an SDS open */
- if (pFile->iCurrentSDS == 0) {
- NXReportError( "ERROR: no SDS open");
- return NX_ERROR;
- }
-
- if (compress_type == NX_COMP_NONE)
- {
- compress_typei = COMP_CODE_NONE;
- }
- else if (compress_type == NX_COMP_LZW)
- {
- compress_typei = COMP_CODE_DEFLATE;
- }
- else if ( (compress_type / 100) == NX_COMP_LZW )
- {
- compress_typei = COMP_CODE_DEFLATE;
- compress_level = compress_type % 100;
- compress_type = NX_COMP_LZW;
- }
- else if (compress_type == NX_COMP_RLE)
- {
- compress_typei = COMP_CODE_RLE;
- }
- else if
- (compress_type == NX_COMP_HUF)
- {
- compress_typei = COMP_CODE_SKPHUFF;
- }
-
- /* first read dimension information */
- SDgetinfo (pFile->iCurrentSDS, pBuffer, &iRank, iSize, &iType, &iAtt);
-
- /*
- according to compression type initialize compression
- information
- */
- if(compress_type == NX_COMP_LZW)
- {
- compstruct.deflate.level = compress_level;
- }
- else if(compress_type == NX_COMP_HUF)
- {
- compstruct.skphuff.skp_size = DFKNTsize(iType);
- }
-
- iRet = SDsetcompress(pFile->iCurrentSDS, compress_typei, &compstruct);
- if (iRet < 0) {
- sprintf (pError, "ERROR: failure to compress data to %s", pBuffer);
- NXReportError( pError);
- return NX_ERROR;
- }
- return NX_OK;
- }
-
- /* --------------------------------------------------------------------- */
-
-
- NXstatus NX4opendata (NXhandle fid, CONSTCHAR *name)
- {
- pNexusFile pFile;
- int32 iNew, attID, tags[2];
- char pBuffer[256];
- int iRet;
-
- pFile = NXIassert (fid);
-
- /* First find the reference number of the SDS */
- iNew = NXIFindSDS (fid, name);
- if (iNew < 0) {
- sprintf (pBuffer, "ERROR: SDS \"%s\" not found at this level", name);
- NXReportError( pBuffer);
- return NX_ERROR;
- }
- /* Be nice: properly close the old open SDS silently if there is
- * still an SDS open.
- */
- if (pFile->iCurrentSDS) {
- iRet = SDendaccess (pFile->iCurrentSDS);
- if (iRet < 0) {
- NXReportError( "ERROR: HDF cannot end access to SDS");
- }
- }
- /* clear pending attribute directories first */
- NXIKillAttDir (pFile);
-
- /* open the SDS, thereby watching for linked SDS under a different name */
- iNew = SDreftoindex (pFile->iSID, iNew);
- pFile->iCurrentSDS = SDselect (pFile->iSID, iNew);
- attID = SDfindattr(pFile->iCurrentSDS,"NAPIlink");
- if(attID >= 0)
- {
- SDreadattr(pFile->iCurrentSDS,attID, tags);
- SDendaccess(pFile->iCurrentSDS);
- iNew = SDreftoindex (pFile->iSID, tags[1]);
- pFile->iCurrentSDS = SDselect (pFile->iSID, iNew);
- }
-
- if (pFile->iCurrentSDS < 0) {
- NXReportError( "ERROR: HDF error opening SDS");
- pFile->iCurrentSDS = 0;
- return NX_ERROR;
- }
- return NX_OK;
- }
-
- /* ----------------------------------------------------------------- */
-
-
- NXstatus NX4closedata (NXhandle fid)
- {
- pNexusFile pFile;
- int iRet;
-
- pFile = NXIassert (fid);
-
- if (pFile->iCurrentSDS != 0) {
- iRet = SDendaccess (pFile->iCurrentSDS);
- pFile->iCurrentSDS = 0;
- if (iRet < 0) {
- NXReportError( "ERROR: HDF cannot end access to SDS");
- return NX_ERROR;
- }
- } else {
- NXReportError( "ERROR: no SDS open --> nothing to do");
- return NX_ERROR;
- }
- NXIKillAttDir (pFile); /* for attribute data */
- return NX_OK;
- }
-
-
- /* ------------------------------------------------------------------- */
-
- NXstatus NX4putdata (NXhandle fid, const void *data)
- {
- pNexusFile pFile;
- int32 iStart[H4_MAX_VAR_DIMS], iSize[H4_MAX_VAR_DIMS], iStride[H4_MAX_VAR_DIMS];
- NXname pBuffer;
- int32 iRank, iAtt, iType, iRet, i;
- char pError[512];
-
- pFile = NXIassert (fid);
-
- /* check if there is an SDS open */
- if (pFile->iCurrentSDS == 0) {
- NXReportError( "ERROR: no SDS open");
- return NX_ERROR;
- }
- /* first read dimension information */
- memset (iStart, 0, H4_MAX_VAR_DIMS * sizeof (int32));
- SDgetinfo (pFile->iCurrentSDS, pBuffer, &iRank, iSize, &iType, &iAtt);
-
- /* initialise stride to 1 */
- for (i = 0; i < iRank; i++) {
- iStride[i] = 1;
- }
-
- /* actually write */
- iRet = SDwritedata (pFile->iCurrentSDS, iStart, iStride, iSize, (void*)data);
- if (iRet < 0) {
- /* HEprint(stdout,0); */
- sprintf (pError, "ERROR: failure to write data to %s", pBuffer);
- NXReportError( pError);
- return NX_ERROR;
- }
- return NX_OK;
- }
-
- /* ------------------------------------------------------------------- */
-
- NXstatus
- NX4putattr (NXhandle fid, CONSTCHAR *name, const void *data, int datalen, int iType)
- {
- pNexusFile pFile;
- int iRet, type;
-
- pFile = NXIassert (fid);
- if (iType == NX_CHAR)
- {
- type=DFNT_CHAR8;
- }
- else if (iType == NX_INT8)
- {
- type=DFNT_INT8;
- }
- else if (iType == NX_UINT8)
- {
- type=DFNT_UINT8;
- }
- else if (iType == NX_INT16)
- {
- type=DFNT_INT16;
- }
- else if (iType == NX_UINT16)
- {
- type=DFNT_UINT16;
- }
- else if (iType == NX_INT32)
- {
- type=DFNT_INT32;
- }
- else if (iType == NX_UINT32)
- {
- type=DFNT_UINT32;
- }
- else if (iType == NX_FLOAT32)
- {
- type=DFNT_FLOAT32;
- }
- else if (iType == NX_FLOAT64)
- {
- type=DFNT_FLOAT64;
- }
- else
- {
- NXReportError( "ERROR: Invalid data type for HDF attribute");
- return NX_ERROR;
- }
- if (pFile->iCurrentSDS != 0) {
- /* SDS attribute */
- iRet = SDsetattr (pFile->iCurrentSDS, (char*)name, (int32)type,
- (int32)datalen, data);
- } else {
- if(pFile->iCurrentVG == 0){
- /* global attribute */
- iRet = SDsetattr (pFile->iSID, (char*)name, (int32)type,
- (int32)datalen, data);
- } else {
- /* group attribute */
- iRet = Vsetattr(pFile->iCurrentVG, (char *)name, (int32) type,
- (int32)datalen,data);
- }
- }
- iType = type;
- if (iRet < 0) {
- NXReportError( "ERROR: HDF failed to store attribute ");
- return NX_ERROR;
- }
- return NX_OK;
- }
-
- /* ------------------------------------------------------------------- */
-
-
- NXstatus NX4putslab64 (NXhandle fid, const void *data, const int64_t iStart[], const int64_t iSize[])
- {
- pNexusFile pFile;
- int iRet;
- int32 iStride[H4_MAX_VAR_DIMS];
- int32 myStart[H4_MAX_VAR_DIMS], mySize[H4_MAX_VAR_DIMS];
- int32 i, iRank, iType, iAtt;
- NXname pBuffer;
-
-
- pFile = NXIassert (fid);
-
- /* check if there is an SDS open */
- if (pFile->iCurrentSDS == 0) {
- NXReportError( "ERROR: no SDS open");
- return NX_ERROR;
- }
- /* initialise stride to 1 */
- for (i = 0; i < H4_MAX_VAR_DIMS; i++) {
- iStride[i] = 1;
- }
-
- SDgetinfo (pFile->iCurrentSDS, pBuffer,
- &iRank, myStart, &iType, &iAtt);
- for(i = 0; i < iRank; i++)
- {
- myStart[i] = (int32)iStart[i];
- mySize[i] = (int32)iSize[i];
- }
- /* finally write */
- iRet = SDwritedata (pFile->iCurrentSDS, myStart,
- iStride, mySize, (void*)data);
-
-
- /* deal with HDF errors */
- if (iRet < 0) {
- NXReportError( "ERROR: writing slab failed");
- return NX_ERROR;
- }
- return NX_OK;
- }
-
-
- /* ------------------------------------------------------------------- */
-
- NXstatus NX4getdataID (NXhandle fid, NXlink* sRes)
- {
- pNexusFile pFile;
- int datalen, type = NX_CHAR;
-
- pFile = NXIassert (fid);
-
- if (pFile->iCurrentSDS == 0) {
- sRes->iTag = NX_ERROR;
- return NX_ERROR;
- } else {
- sRes->iTag = DFTAG_NDG;
- sRes->iRef = SDidtoref (pFile->iCurrentSDS);
- NXMDisableErrorReporting();
- datalen = 1024;
- memset(&sRes->targetPath,0,1024);
- if(NX4getattr(fid,"target",&sRes->targetPath,&datalen,&type) != NX_OK)
- {
- NXIbuildPath(pFile,sRes->targetPath,1024);
- }
- NXMEnableErrorReporting();
- return NX_OK;
- }
- sRes->iTag = NX_ERROR;
- return NX_ERROR; /* not reached */
- }
-
-
- /* ------------------------------------------------------------------- */
-
-
- NXstatus NX4makelink (NXhandle fid, NXlink* sLink)
- {
- pNexusFile pFile;
- int32 dataID, type = DFNT_CHAR8, length;
- char name[] = "target";
-
- pFile = NXIassert (fid);
-
- if (pFile->iCurrentVG == 0) { /* root level, can not link here */
- return NX_ERROR;
- }
- Vaddtagref(pFile->iCurrentVG, sLink->iTag, sLink->iRef);
- length = strlen(sLink->targetPath);
- if(sLink->iTag == DFTAG_SDG || sLink->iTag == DFTAG_NDG ||
- sLink->iTag == DFTAG_SDS)
- {
- dataID = SDreftoindex(pFile->iSID,sLink->iRef);
- dataID = SDselect(pFile->iSID,dataID);
- SDsetattr(dataID,name,type,length,sLink->targetPath);
- SDendaccess(dataID);
- }
- else
- {
- dataID = Vattach(pFile->iVID,sLink->iRef,"w");
- Vsetattr(dataID, (char *)name, type, (int32) length, sLink->targetPath);
- Vdetach(dataID);
- }
- return NX_OK;
- }
- /* ------------------------------------------------------------------- */
-
-
- NXstatus NX4makenamedlink (NXhandle fid, CONSTCHAR* newname, NXlink* sLink)
- {
- pNexusFile pFile;
- int32 dataID, type = DFNT_CHAR8, length, dataType = NX_CHAR,
- rank = 1, attType = NX_INT32;
- int64_t iDim[1];
- char name[] = "target";
- int tags[2];
-
- pFile = NXIassert (fid);
-
- if (pFile->iCurrentVG == 0) { /* root level, can not link here */
- return NX_ERROR;
- }
-
- tags[0] = sLink->iTag;
- tags[1] = sLink->iRef;
-
- length = strlen(sLink->targetPath);
- if(sLink->iTag == DFTAG_SDG || sLink->iTag == DFTAG_NDG ||
- sLink->iTag == DFTAG_SDS)
- {
- iDim[0] = 1;
- NX4makedata64(fid,newname, dataType,rank,iDim);
- NX4opendata(fid,newname);
- NX4putattr(fid,"NAPIlink",tags, 2, attType);
- NX4closedata(fid);
- dataID = SDreftoindex(pFile->iSID,sLink->iRef);
- dataID = SDselect(pFile->iSID,dataID);
- SDsetattr(dataID,name,type,length,sLink->targetPath);
- SDendaccess(dataID);
- } else {
- NX4makegroup(fid,newname,"NAPIlink");
- NX4opengroup(fid,newname,"NAPIlink");
- NX4putattr(fid,"NAPIlink",tags, 2, attType);
- NX4closegroup(fid);
- dataID = Vattach(pFile->iVID,sLink->iRef,"w");
- Vsetattr(dataID, (char *)name, type, (int32) length, sLink->targetPath);
- Vdetach(dataID);
- }
- return NX_OK;
- }
-
- /*----------------------------------------------------------------------*/
-
- NXstatus NX4printlink (NXhandle fid, NXlink* sLink)
- {
- NXIassert (fid);
- printf("HDF4 link: iTag = %ld, iRef = %ld, target=\"%s\"\n", sLink->iTag, sLink->iRef, sLink->targetPath);
- return NX_OK;
- }
-
- /*----------------------------------------------------------------------*/
-
- NXstatus NX4flush(NXhandle *pHandle)
- {
- char *pFileName, *pCopy = NULL;
- int access, dummy, iRet, i, iStack;
- pNexusFile pFile = NULL;
- NXaccess ac;
- int *iRefs = NULL;
-
- pFile = NXIassert(*pHandle);
-
- /*
- The HDF4-API does not support a flush. We help ourselves with
- inquiring the name and access type of the file, closing it and
- opening it again. This is also the reason why this needs a pointer
- to the handle structure as the handle changes. The other thing we
- do is to store the refs of all open vGroups in a temporary array
- in order to recover the position in the vGroup hierarchy before the
- flush.
- */
- iRet = Hfidinquire(pFile->iVID,&pFileName,&access,&dummy);
- if (iRet < 0) {
- NXReportError(
- "ERROR: Failed to inquire file name for HDF file");
- return NX_ERROR;
- }
- if(pFile->iAccess[0] == 'r') {
- ac = NXACC_READ;
- }else if(pFile->iAccess[0] == 'w') {
- ac = NXACC_RDWR;
- } else {
- NXReportError(
- "ERROR: NX4flush failed to determine file access mode");
- return NX_ERROR;
- }
- pCopy = (char *)malloc((strlen(pFileName)+10)*sizeof(char));
- if(!pCopy) {
- NXReportError(
- "ERROR: Failed to allocate data for filename copy");
- return NX_ERROR;
- }
- memset(pCopy,0,strlen(pFileName)+10);
- strcpy(pCopy,pFileName);
-
- /* get refs for recovering vGroup position */
- iStack = 0;
- if(pFile->iStackPtr > 0) {
- iStack = pFile->iStackPtr + 1;
- iRefs = (int *)malloc(iStack*sizeof(int));
- if(!iRefs){
- NXReportError(
- "ERROR: Failed to allocate data for hierarchy copy");
- return NX_ERROR;
- }
- for(i = 0; i < iStack; i++){
- iRefs[i] = pFile->iStack[i].iVref;
- }
- }
-
- iRet = NX4close(pHandle);
- if(iRet != NX_OK) {
- return iRet;
- }
-
- iRet = NX4open(pCopy, ac, pHandle);
- free(pCopy);
-
- /* return to position in vGroup hierarchy */
- pFile = NXIassert(*pHandle);
- if(iStack > 0){
- pFile->iStackPtr = iStack - 1;
- for(i = 0; i < iStack; i++){
- pFile->iStack[i].iVref = iRefs[i];
- }
- free(iRefs);
- pFile->iCurrentVG = Vattach(pFile->iVID,
- pFile->iStack[pFile->iStackPtr].iVref,
- pFile->iAccess);
- }
-
- return iRet;
- }
-
- /*-------------------------------------------------------------------------*/
-
-
- NXstatus NX4getnextentry (NXhandle fid, NXname name, NXname nxclass, int *datatype)
- {
- pNexusFile pFile;
- int iRet, iStackPtr, iCurDir;
- int32 iTemp, iD1, iD2, iA;
- int32 iDim[H4_MAX_VAR_DIMS];
-
- pFile = NXIassert (fid);
-
- iStackPtr = pFile->iStackPtr;
- iCurDir = pFile->iStack[pFile->iStackPtr].iCurDir;
-
- /* first case to check for: no directory entry */
- if (pFile->iStack[pFile->iStackPtr].iRefDir == NULL) {
- iRet = NXIInitDir (pFile);
- if (iRet < 0) {
- NXReportError(
- "ERROR: no memory to store directory info");
- return NX_EOD;
- }
- }
-
- /* Next case: end of directory */
- if (iCurDir >= pFile->iStack[pFile->iStackPtr].iNDir) {
- NXIKillDir (pFile);
- return NX_EOD;
- }
-
- /* Next case: we have data! supply it and increment counter */
- if (pFile->iCurrentVG == 0) { /* root level */
- iTemp = Vattach (pFile->iVID,
- pFile->iStack[iStackPtr].iRefDir[iCurDir], "r");
- if (iTemp < 0) {
- NXReportError( "ERROR: HDF cannot attach to Vgroup");
- return NX_ERROR;
- }
- Vgetname (iTemp, name);
- Vdetach (iTemp);
- findNapiClass(pFile, pFile->iStack[pFile->iStackPtr].iRefDir[iCurDir], nxclass);
- *datatype = DFTAG_VG;
- pFile->iStack[pFile->iStackPtr].iCurDir++;
- return NX_OK;
- } else { /* in Vgroup */
- if (pFile->iStack[iStackPtr].iTagDir[iCurDir] == DFTAG_VG) {/* Vgroup */
- iTemp = Vattach (pFile->iVID,
- pFile->iStack[iStackPtr].iRefDir[iCurDir], "r");
- if (iTemp < 0) {
- NXReportError( "ERROR: HDF cannot attach to Vgroup");
- return NX_ERROR;
- }
- Vgetname (iTemp, name);
- Vdetach(iTemp);
- findNapiClass(pFile, pFile->iStack[pFile->iStackPtr].iRefDir[iCurDir], nxclass);
- *datatype = DFTAG_VG;
- pFile->iStack[pFile->iStackPtr].iCurDir++;
- Vdetach (iTemp);
- return NX_OK;
- /* we are now writing using DFTAG_NDG, but need others for backward compatability */
- } else if ((pFile->iStack[iStackPtr].iTagDir[iCurDir] == DFTAG_SDG) ||
- (pFile->iStack[iStackPtr].iTagDir[iCurDir] == DFTAG_NDG) ||
- (pFile->iStack[iStackPtr].iTagDir[iCurDir] == DFTAG_SDS)) {
- iTemp = SDreftoindex (pFile->iSID,
- pFile->iStack[iStackPtr].iRefDir[iCurDir]);
- iTemp = SDselect (pFile->iSID, iTemp);
- SDgetinfo (iTemp, name, &iA, iDim, &iD1, &iD2);
- strcpy (nxclass, "SDS");
- *datatype = iD1;
- SDendaccess (iTemp);
- pFile->iStack[pFile->iStackPtr].iCurDir++;
- return NX_OK;
- } else { /* unidentified */
- strcpy (name, "UNKNOWN");
- strcpy (nxclass, "UNKNOWN");
- *datatype = pFile->iStack[iStackPtr].iTagDir[iCurDir];
- pFile->iStack[pFile->iStackPtr].iCurDir++;
- return NX_OK;
- }
- }
- return NX_ERROR; /* not reached */
- }
-
-
- /*-------------------------------------------------------------------------*/
-
-
- NXstatus NX4getdata (NXhandle fid, void *data)
- {
- pNexusFile pFile;
- int32 iStart[H4_MAX_VAR_DIMS], iSize[H4_MAX_VAR_DIMS];
- NXname pBuffer;
- int32 iRank, iAtt, iType;
-
- pFile = NXIassert (fid);
-
- /* check if there is an SDS open */
- if (pFile->iCurrentSDS == 0) {
- NXReportError( "ERROR: no SDS open");
- return NX_ERROR;
- }
- /* first read dimension information */
- memset (iStart, 0, H4_MAX_VAR_DIMS * sizeof (int32));
- SDgetinfo (pFile->iCurrentSDS, pBuffer, &iRank, iSize, &iType, &iAtt);
- /* actually read */
- SDreaddata (pFile->iCurrentSDS, iStart, NULL, iSize, data);
- return NX_OK;
- }
-
- /*-------------------------------------------------------------------------*/
-
- NXstatus
- NX4getinfo64 (NXhandle fid, int *rank, int64_t dimension[],
- int *iType)
- {
- pNexusFile pFile;
- NXname pBuffer;
- int32 iAtt, myDim[H4_MAX_VAR_DIMS], i, iRank, mType;
-
- pFile = NXIassert (fid);
-
- /* check if there is an SDS open */
- if (pFile->iCurrentSDS == 0) {
- NXReportError( "ERROR: no SDS open");
- return NX_ERROR;
- }
- /* read information */
- SDgetinfo (pFile->iCurrentSDS, pBuffer, &iRank, myDim,
- &mType, &iAtt);
-
- /* conversion to proper ints for the platform */
- *iType = (int)mType;
- *rank = (int)iRank;
- for(i = 0; i < iRank; i++)
- {
- dimension[i] = (int)myDim[i];
- }
- return NX_OK;
- }
-
-
- /*-------------------------------------------------------------------------*/
-
-
- NXstatus NX4getslab64 (NXhandle fid, void *data, const int64_t iStart[], const int64_t iSize[])
- {
- pNexusFile pFile;
- int32 myStart[H4_MAX_VAR_DIMS], mySize[H4_MAX_VAR_DIMS];
- int32 i, iRank, iType, iAtt;
- NXname pBuffer;
-
- pFile = NXIassert (fid);
-
- /* check if there is an SDS open */
- if (pFile->iCurrentSDS == 0) {
- NXReportError( "ERROR: no SDS open");
- return NX_ERROR;
- }
-
- SDgetinfo (pFile->iCurrentSDS, pBuffer,
- &iRank, myStart, &iType, &iAtt);
- for(i = 0; i < iRank; i++)
- {
- myStart[i] = (int32)iStart[i];
- mySize[i] = (int32)iSize[i];
- }
- /* finally read */
- SDreaddata (pFile->iCurrentSDS, myStart, NULL,
- mySize, data);
- return NX_OK;
- }
-
- /*-------------------------------------------------------------------------*/
-
- NXstatus NX4getnextattr (NXhandle fileid, NXname pName,
- int *iLength, int *iType)
- {
- pNexusFile pFile;
- int iRet;
- int32 iPType, iCount, count;
-
- pFile = NXIassert (fileid);
-
- /* first check if we have to start a new attribute search */
- if (pFile->iAtt.iNDir == 0) {
- iRet = NXIInitAttDir (pFile);
- if (iRet == NX_ERROR) {
- return NX_ERROR;
- }
- }
- /* are we done ? */
- if (pFile->iAtt.iCurDir >= pFile->iAtt.iNDir) {
- NXIKillAttDir (pFile);
- return NX_EOD;
- }
- /* well, there must be data to copy */
- if (pFile->iCurrentSDS == 0) {
- if(pFile->iCurrentVG == 0) {
- /* global attribute */
- iRet = SDattrinfo (pFile->iSID, pFile->iAtt.iCurDir,
- pName, &iPType, &iCount);
- }else {
- /* group attribute */
- iRet = Vattrinfo(pFile->iCurrentVG, pFile->iAtt.iCurDir,
- pName, &iPType, &iCount, &count);
- }
- } else {
- iRet = SDattrinfo (pFile->iCurrentSDS, pFile->iAtt.iCurDir,
- pName, &iPType, &iCount);
- }
- if (iRet < 0) {
- NXReportError( "ERROR: HDF cannot read attribute info");
- return NX_ERROR;
- }
- *iLength = iCount;
- *iType = iPType;
- pFile->iAtt.iCurDir++;
- return NX_OK;
- }
-
-
- /*-------------------------------------------------------------------------*/
-
-
- NXstatus NX4getattr (NXhandle fid, char *name, void *data, int* datalen, int* iType)
- {
- pNexusFile pFile;
- int32 iNew, iType32, count;
- void *pData = NULL;
- int32 iLen, iRet;
- int type;
- char pBuffer[256];
- NXname pNam;
-
- type = *iType;
- if (type == NX_CHAR)
- {
- type=DFNT_CHAR8;
- }
- else if (type == NX_INT8)
- {
- type=DFNT_INT8;
- }
- else if (type == NX_UINT8)
- {
- type=DFNT_UINT8;
- }
- else if (type == NX_INT16)
- {
- type=DFNT_INT16;
- }
- else if (type == NX_UINT16)
- {
- type=DFNT_UINT16;
- }
- else if (type == NX_INT32)
- {
- type=DFNT_INT32;
- }
- else if (type == NX_UINT32)
- {
- type=DFNT_UINT32;
- }
- else if (type == NX_FLOAT32)
- {
- type=DFNT_FLOAT32;
- }
- else if (type == NX_FLOAT64)
- {
- type=DFNT_FLOAT64;
- }
- *datalen = (*datalen) * DFKNTsize(type);
- pFile = NXIassert (fid);
-
- /* find attribute */
- if (pFile->iCurrentSDS != 0) {
- /* SDS attribute */
- iNew = SDfindattr (pFile->iCurrentSDS, name);
- } else {
- if(pFile->iCurrentVG == 0){
- /* global attribute */
- iNew = SDfindattr (pFile->iSID, name);
- } else {
- /* group attribute */
- iNew = Vfindattr(pFile->iCurrentVG, name);
- }
- }
- if (iNew < 0) {
- sprintf (pBuffer, "ERROR: attribute \"%s\" not found", name);
- NXReportError( pBuffer);
- return NX_ERROR;
- }
- /* get more info, allocate temporary data space */
- iType32 = (int32)type;
- if (pFile->iCurrentSDS != 0) {
- iRet = SDattrinfo (pFile->iCurrentSDS, iNew, pNam, &iType32, &iLen);
- } else {
- if(pFile->iCurrentVG == 0){
- iRet = SDattrinfo (pFile->iSID, iNew, pNam, &iType32, &iLen);
- } else {
- iRet = Vattrinfo(pFile->iCurrentVG,iNew,pNam,&iType32,&count,
- &iLen);
- }
- }
- if (iRet < 0) {
- sprintf (pBuffer, "ERROR: HDF could not read attribute info");
- NXReportError( pBuffer);
- return NX_ERROR;
- }
- *iType = (int)iType32;
- iLen = iLen * DFKNTsize (*iType);
- if(*iType == NX_CHAR){
- iLen += 1;
- }
- pData = (void *) malloc (iLen);
- if (!pData) {
- NXReportError( "ERROR: allocating memory in NXgetattr");
- return NX_ERROR;
- }
- memset (pData, 0, iLen);
-
- /* finally read the data */
- if (pFile->iCurrentSDS != 0) {
- iRet = SDreadattr (pFile->iCurrentSDS, iNew, pData);
- } else {
- if(pFile->iCurrentVG == 0){
- iRet = SDreadattr (pFile->iSID, iNew, pData);
- } else {
- iRet = Vgetattr(pFile->iCurrentVG, iNew, pData);
- }
- }
- if (iRet < 0) {
- sprintf (pBuffer, "ERROR: HDF could not read attribute data");
- NXReportError( pBuffer);
- return NX_ERROR;
- }
- /* copy data to caller */
- memset (data, 0, *datalen);
- if ((*datalen <= iLen) &&
- (*iType == DFNT_UINT8 || *iType == DFNT_CHAR8 || *iType == DFNT_UCHAR8)) {
- iLen = *datalen - 1; /* this enforces NULL termination regardless of size of datalen */
- }
- memcpy (data, pData, iLen);
- *datalen = iLen / DFKNTsize(*iType);
- free (pData);
- return NX_OK;
- }
-
- /*-------------------------------------------------------------------------*/
-
-
- NXstatus NX4getattrinfo (NXhandle fid, int *iN)
- {
- pNexusFile pFile;
- int iRet;
- int32 iData, iAtt, iRank, iType;
- int32 iDim[H4_MAX_VAR_DIMS];
- NXname pNam;
-
- pFile = NXIassert (fid);
- if (pFile->iCurrentSDS != 0) { /* SDS level */
- iRet = SDgetinfo (pFile->iCurrentSDS, pNam, &iRank, iDim, &iType,
- &iAtt);
- } else {
- if(pFile->iCurrentVG == 0){
- /* global level */
- iRet = SDfileinfo (pFile->iSID, &iData, &iAtt);
- } else {
- iRet = Vnattrs(pFile->iCurrentVG);
- iAtt = iRet;
- }
- }
- if (iRet < 0) {
- NXReportError( "NX_ERROR: HDF cannot read attribute numbers");
- *iN = 0;
- return NX_ERROR;
- }
- *iN = iAtt;
- return NX_OK;
- }
-
- /*-------------------------------------------------------------------------*/
-
- NXstatus NX4getgroupID (NXhandle fileid, NXlink* sRes)
- {
- pNexusFile pFile;
-
- pFile = NXIassert (fileid);
-
- if (pFile->iCurrentVG == 0) {
- sRes->iTag = NX_ERROR;
- return NX_ERROR;
- } else {
- sRes->iTag = DFTAG_VG;
- sRes->iRef = VQueryref(pFile->iCurrentVG);
- NXIbuildPath(pFile,sRes->targetPath,1024);
- return NX_OK;
- }
- /* not reached */
- sRes->iTag = NX_ERROR;
- return NX_ERROR;
- }
-
- /*-------------------------------------------------------------------------*/
-
- NXstatus
- NX4getgroupinfo (NXhandle fid, int *iN, NXname pName, NXname pClass)
- {
- pNexusFile pFile;
-
- pFile = NXIassert (fid);
- /* check if there is a group open */
- if (pFile->iCurrentVG == 0) {
- *iN = Vlone (pFile->iVID, NULL, 0);
- strcpy (pName, "root");
- strcpy (pClass, "NXroot");
- }
- else {
- *iN = Vntagrefs (pFile->iCurrentVG);
- Vgetname (pFile->iCurrentVG, pName);
- Vgetclass (pFile->iCurrentVG, pClass);
- }
- return NX_OK;
- }
-
- /* ------------------------------------------------------------------- */
-
- NXstatus NX4sameID (NXhandle fileid, NXlink* pFirstID, NXlink* pSecondID)
- {
- NXIassert (fileid);
- if ((pFirstID->iTag == pSecondID->iTag) & (pFirstID->iRef == pSecondID->iRef)) {
- return NX_OK;
- } else {
- return NX_ERROR;
- }
- }
-
- /*-------------------------------------------------------------------------*/
-
-
- NXstatus NX4initattrdir (NXhandle fid)
- {
- pNexusFile pFile;
- int iRet;
-
- pFile = NXIassert (fid);
- NXIKillAttDir (pFile);
- iRet = NXIInitAttDir (pFile);
- if (iRet == NX_ERROR)
- return NX_ERROR;
- return NX_OK;
- }
-
-
- /*-------------------------------------------------------------------------*/
-
-
- NXstatus NX4initgroupdir (NXhandle fid)
- {
- pNexusFile pFile;
- int iRet;
-
- pFile = NXIassert (fid);
- NXIKillDir (pFile);
- iRet = NXIInitDir (pFile);
- if (iRet < 0) {
- NXReportError("NX_ERROR: no memory to store directory info");
- return NX_EOD;
- }
- return NX_OK;
- }
-
-/*--------------------------------------------------------------------*/
-void NX4assignFunctions(pNexusFunction fHandle)
-{
- fHandle->nxclose=NX4close;
- fHandle->nxreopen=NULL;
- fHandle->nxflush=NX4flush;
- fHandle->nxmakegroup=NX4makegroup;
- fHandle->nxopengroup=NX4opengroup;
- fHandle->nxclosegroup=NX4closegroup;
- fHandle->nxmakedata64=NX4makedata64;
- fHandle->nxcompmakedata64=NX4compmakedata64;
- fHandle->nxcompress=NX4compress;
- fHandle->nxopendata=NX4opendata;
- fHandle->nxclosedata=NX4closedata;
- fHandle->nxputdata=NX4putdata;
- fHandle->nxputattr=NX4putattr;
- fHandle->nxputslab64=NX4putslab64;
- fHandle->nxgetdataID=NX4getdataID;
- fHandle->nxmakelink=NX4makelink;
- fHandle->nxmakenamedlink=NX4makenamedlink;
- fHandle->nxgetdata=NX4getdata;
- fHandle->nxgetinfo64=NX4getinfo64;
- fHandle->nxgetnextentry=NX4getnextentry;
- fHandle->nxgetslab64=NX4getslab64;
- fHandle->nxgetnextattr=NX4getnextattr;
- fHandle->nxgetattr=NX4getattr;
- fHandle->nxgetattrinfo=NX4getattrinfo;
- fHandle->nxgetgroupID=NX4getgroupID;
- fHandle->nxgetgroupinfo=NX4getgroupinfo;
- fHandle->nxsameID=NX4sameID;
- fHandle->nxinitgroupdir=NX4initgroupdir;
- fHandle->nxinitattrdir=NX4initattrdir;
- fHandle->nxprintlink=NX4printlink;
- fHandle->nxnativeexternallink=NULL;
-}
-
-#endif /*HDF4*/
diff --git a/napi4.h b/napi4.h
deleted file mode 100644
index af354a57..00000000
--- a/napi4.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#ifndef NAPI4_H
-#define NAPI4_H
-
-#define NXSIGNATURE 959697
-
-#include "mfhdf.h"
-/* #include "napi4.c" */
-
-/*
- * HDF4 interface
- */
-
-extern NXstatus NX4open(CONSTCHAR *filename, NXaccess access_method, NXhandle* pHandle);
-extern NXstatus NX4close(NXhandle* pHandle);
-extern NXstatus NX4flush(NXhandle* pHandle);
-
-extern NXstatus NX4makegroup (NXhandle handle, CONSTCHAR* Vgroup, CONSTCHAR* NXclass);
-extern NXstatus NX4opengroup (NXhandle handle, CONSTCHAR* Vgroup, CONSTCHAR* NXclass);
-extern NXstatus NX4closegroup(NXhandle handle);
-
-extern NXstatus NX4makedata64 (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int64_t dim[]);
-extern NXstatus NX4compmakedata64 (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int64_t dim[], int comp_typ, int64_t bufsize[]);
-extern NXstatus NX4compress (NXhandle handle, int compr_type);
-extern NXstatus NX4opendata (NXhandle handle, CONSTCHAR* label);
-
-extern NXstatus NX4closedata(NXhandle handle);
-
-extern NXstatus NX4getdata(NXhandle handle, void* data);
-extern NXstatus NX4getslab64(NXhandle handle, void* data, const int64_t start[], const int64_t size[]);
-extern NXstatus NX4getattr(NXhandle handle, char* name, void* data, int* iDataLen, int* iType);
-
-extern NXstatus NX4putdata(NXhandle handle, const void* data);
-extern NXstatus NX4putslab64(NXhandle handle, const void* data, const int64_t start[], const int64_t size[]);
-extern NXstatus NX4putattr(NXhandle handle, CONSTCHAR* name, const void* data, int iDataLen, int iType);
-
-extern NXstatus NX4getinfo64(NXhandle handle, int* rank, int64_t dimension[], int* datatype);
-extern NXstatus NX4getgroupinfo(NXhandle handle, int* no_items, NXname name, NXname nxclass);
-extern NXstatus NX4initgroupdir(NXhandle handle);
-extern NXstatus NX4getnextentry(NXhandle handle, NXname name, NXname nxclass, int* datatype);
-extern NXstatus NX4getattrinfo(NXhandle handle, int* no_items);
-extern NXstatus NX4initattrdir(NXhandle handle);
-extern NXstatus NX4getnextattr(NXhandle handle, NXname pName, int *iLength, int *iType);
-
-extern NXstatus NX4getgroupID(NXhandle handle, NXlink* pLink);
-extern NXstatus NX4getdataID(NXhandle handle, NXlink* pLink);
-extern NXstatus NX4makelink(NXhandle handle, NXlink* pLink);
-extern NXstatus NX4printlink(NXhandle handle, NXlink* pLink);
-
-void NX4assignFunctions(pNexusFunction fHandle);
-
-
-/*
- * HDF changed from MAX_VAR_DIMS to H4_MAX_VAR_DIMS aronud 9/5/2007
- * to avoid potential conflicts with NetCDF-3 library
- */
-#ifndef H4_MAX_VAR_DIMS
-#define H4_MAX_VAR_DIMS MAX_VAR_DIMS
-#endif
-
-#endif /* NAPI4_H */
diff --git a/napi5.c b/napi5.c
deleted file mode 100644
index 810e1113..00000000
--- a/napi5.c
+++ /dev/null
@@ -1,2301 +0,0 @@
-/*---------------------------------------------------------------------------
- NeXus - Neutron & X-ray Common Data Format
-
- Application Program Interface (HDF5) Routines
-
- Copyright (C) 1997-2011 Mark Koennecke, Przemek Klosowski
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- For further information, see
-
-----------------------------------------------------------------------------*/
-
-#ifdef HDF5
-
-#include
-#include
-#include
-#include
-
-#include "napi.h"
-#include "napi5.h"
-
-#ifdef H5_VERSION_GE
-#if !H5_VERSION_GE(1,8,0)
-#error HDF5 Version must be 1.8.0 or higher
-#endif
-#endif
-
-#ifdef _MSC_VER
-#define snprintf _snprintf
-#endif /* _MSC_VER */
-
-#define NX_UNKNOWN_GROUP "" /* for when no NX_class attr */
-
-extern void *NXpData;
-
- typedef struct __NexusFile5 {
- struct iStack5 {
- char irefn[1024];
- int iVref;
- hsize_t iCurrentIDX;
- } iStack5[NXMAXSTACK];
- struct iStack5 iAtt5;
- int iFID;
- int iCurrentG;
- int iCurrentD;
- int iCurrentS;
- int iCurrentT;
- int iCurrentA;
- int iNX;
- int iNXID;
- int iStackPtr;
- char *iCurrentLGG;
- char *iCurrentLD;
- char name_ref[1024];
- char name_tmp[1024];
- char iAccess[2];
- } NexusFile5, *pNexusFile5;
-
-/*
- forward declaration of NX5closegroup in order to get rid of a nasty
- warning
-*/
-NXstatus NX5closegroup (NXhandle fid);
-/*-------------------------------------------------------------------*/
-
- static pNexusFile5 NXI5assert(NXhandle fid)
- {
- pNexusFile5 pRes;
-
- assert(fid != NULL);
- pRes = (pNexusFile5)fid;
- assert(pRes->iNXID == NX5SIGNATURE);
- return pRes;
- }
-
- /*--------------------------------------------------------------------*/
-
- static void NXI5KillDir (pNexusFile5 self)
- {
- self->iStack5[self->iStackPtr].iCurrentIDX = 0;
- }
-
- /*--------------------------------------------------------------------*/
-
- static void NXI5KillAttDir (pNexusFile5 self)
- {
- self->iAtt5.iCurrentIDX = 0;
- }
-/*---------------------------------------------------------------------*/
-static void buildCurrentPath(pNexusFile5 self, char *pathBuffer,
- int pathBufferLen){
-
- memset(pathBuffer,0,pathBufferLen);
- if(self->iCurrentG != 0) {
- strcpy(pathBuffer,"/");
- if(strlen(self->name_ref) + 1 < pathBufferLen){
- strcat(pathBuffer, self->name_ref);
- }
- }
- if(self->iCurrentD != 0){
- strcat(pathBuffer,"/");
- if(strlen(self->iCurrentLD) + strlen(pathBuffer) < pathBufferLen){
- strcat(pathBuffer,self->iCurrentLD);
- }
- }
-}
- /* ----------------------------------------------------------------------
-
- Definition of NeXus API
-
- ---------------------------------------------------------------------*/
-
- NXstatus NX5reopen(NXhandle pOrigHandle, NXhandle* pNewHandle)
-{
- pNexusFile5 pNew = NULL, pOrig = NULL;
- *pNewHandle = NULL;
- pOrig = (pNexusFile5)pOrigHandle;
- pNew = (pNexusFile5) malloc (sizeof (NexusFile5));
- if (!pNew) {
- NXReportError ("ERROR: no memory to create File datastructure");
- return NX_ERROR;
- }
- memset (pNew, 0, sizeof (NexusFile5));
- pNew->iFID = H5Freopen (pOrig->iFID);
- if (pNew->iFID <= 0) {
- NXReportError ("cannot clone file");
- free (pNew);
- return NX_ERROR;
- }
- strcpy(pNew->iAccess, pOrig->iAccess);
- pNew->iNXID = NX5SIGNATURE;
- pNew->iStack5[0].iVref = 0; /* root! */
- *pNewHandle = (NXhandle)pNew;
- return NX_OK;
-}
-
-NXstatus NX5open(CONSTCHAR *filename, NXaccess am,
- NXhandle* pHandle)
- {
- hid_t attr1,aid1, aid2, iVID;
- pNexusFile5 pNew = NULL;
- char pBuffer[512];
- char *time_buffer = NULL;
- char version_nr[10];
- unsigned int vers_major, vers_minor, vers_release, am1 ;
- hid_t fapl = -1;
- int mdc_nelmts;
- size_t rdcc_nelmts;
- size_t rdcc_nbytes;
- double rdcc_w0;
- unsigned hdf5_majnum, hdf5_minnum, hdf5_relnum;
-
- *pHandle = NULL;
-
- if (H5get_libversion(&hdf5_majnum, &hdf5_minnum, &hdf5_relnum) < 0)
- {
- NXReportError("ERROR: cannot determine HDF5 library version");
- return NX_ERROR;
- }
- if (hdf5_majnum == 1 && hdf5_minnum < 8)
- {
- NXReportError("ERROR: HDF5 library 1.8.0 or higher required");
- return NX_ERROR;
- }
-
- /* mask of any options for now */
- am = (NXaccess)(am & NXACCMASK_REMOVEFLAGS);
-
- /* turn off the automatic HDF error handling */
- H5Eset_auto(H5E_DEFAULT, NULL, NULL);
-#ifdef USE_FTIME
- struct timeb timeb_struct;
-#endif
-
-
- pNew = (pNexusFile5) malloc (sizeof (NexusFile5));
- if (!pNew) {
- NXReportError("ERROR: not enough memory to create file structure");
- return NX_ERROR;
- }
- memset (pNew, 0, sizeof (NexusFile5));
-
-
- /* start HDF5 interface */
- if (am == NXACC_CREATE5) {
- fapl = H5Pcreate(H5P_FILE_ACCESS);
- H5Pget_cache(fapl,&mdc_nelmts,&rdcc_nelmts,&rdcc_nbytes,&rdcc_w0);
- rdcc_nbytes=(size_t)nx_cacheSize;
- H5Pset_cache(fapl,mdc_nelmts,rdcc_nelmts,rdcc_nbytes,rdcc_w0);
- H5Pset_fclose_degree(fapl,H5F_CLOSE_STRONG);
- am1 = H5F_ACC_TRUNC;
- pNew->iFID = H5Fcreate (filename, am1, H5P_DEFAULT, fapl);
- } else {
- if (am == NXACC_READ) {
- am1 = H5F_ACC_RDONLY;
- } else {
- am1 = H5F_ACC_RDWR;
- }
- fapl = H5Pcreate(H5P_FILE_ACCESS);
- H5Pset_fclose_degree(fapl,H5F_CLOSE_STRONG);
- pNew->iFID = H5Fopen (filename, am1, fapl);
- }
- if(fapl != -1) {
- H5Pclose(fapl);
- }
- if (pNew->iFID <= 0) {
- sprintf (pBuffer, "ERROR: cannot open file: %s", filename);
- NXReportError( pBuffer);
- free (pNew);
- return NX_ERROR;
- }
-
-/*
- * need to create global attributes file_name file_time NeXus_version
- * at some point for new files
- */
- if (am1 != H5F_ACC_RDONLY)
- {
- iVID = H5Gopen(pNew->iFID,"/", H5P_DEFAULT);
- aid2 = H5Screate(H5S_SCALAR);
- aid1 = H5Tcopy(H5T_C_S1);
- H5Tset_size(aid1, strlen(NEXUS_VERSION));
- if (am1 == H5F_ACC_RDWR)
- {
- H5Adelete(iVID, "NeXus_version");
- }
- attr1= H5Acreate(iVID, "NeXus_version", aid1, aid2, H5P_DEFAULT, H5P_DEFAULT);
- if (attr1<0)
- {
- NXReportError(
- "ERROR: failed to store NeXus_version attribute ");
- return NX_ERROR;
- }
- if (H5Awrite(attr1, aid1,NEXUS_VERSION)<0)
- {
- NXReportError(
- "ERROR: failed to store NeXus_version attribute ");
- return NX_ERROR;
- }
- /* Close attribute dataspace */
- H5Tclose(aid1);
- H5Sclose(aid2);
- /* Close attribute */
- H5Aclose(attr1);
- H5Gclose(iVID);
- }
- if (am1 == H5F_ACC_TRUNC)
- {
- iVID = H5Gopen(pNew->iFID,"/", H5P_DEFAULT);
- aid2 = H5Screate(H5S_SCALAR);
- aid1 = H5Tcopy(H5T_C_S1);
- H5Tset_size(aid1, strlen(filename));
- attr1= H5Acreate(iVID, "file_name", aid1, aid2, H5P_DEFAULT, H5P_DEFAULT);
- if (attr1 < 0)
- {
- NXReportError(
- "ERROR: failed to store file_name attribute ");
- return NX_ERROR;
- }
- if (H5Awrite(attr1, aid1, (char*)filename) < 0)
- {
- NXReportError(
- "ERROR: failed to store file_name attribute ");
- return NX_ERROR;
- }
- H5Tclose(aid1);
- H5Sclose(aid2);
- H5Aclose(attr1);
- /* ------- library version ------*/
- H5get_libversion(&vers_major, &vers_minor, &vers_release);
- sprintf (version_nr, "%d.%d.%d", vers_major,vers_minor,vers_release);
- aid2=H5Screate(H5S_SCALAR);
- aid1 = H5Tcopy(H5T_C_S1);
- H5Tset_size(aid1, strlen(version_nr));
- attr1= H5Acreate(iVID, "HDF5_Version", aid1, aid2, H5P_DEFAULT, H5P_DEFAULT);
- if (attr1 < 0)
- {
- NXReportError(
- "ERROR: failed to store file_name attribute ");
- return NX_ERROR;
- }
- if (H5Awrite(attr1, aid1, (char*)version_nr) < 0)
- {
- NXReportError(
- "ERROR: failed to store file_name attribute ");
- return NX_ERROR;
- }
- H5Tclose(aid1);
- H5Sclose(aid2);
- H5Aclose(attr1);
- /*----------- file time */
- time_buffer = NXIformatNeXusTime();
- if(time_buffer != NULL){
- aid2=H5Screate(H5S_SCALAR);
- aid1 = H5Tcopy(H5T_C_S1);
- H5Tset_size(aid1, strlen(time_buffer));
- attr1=H5Acreate(iVID, "file_time", aid1, aid2, H5P_DEFAULT, H5P_DEFAULT);
- if (attr1 < 0)
- {
- NXReportError(
- "ERROR: failed to store file_time attribute ");
- free(time_buffer);
- return NX_ERROR;
- }
- if (H5Awrite(attr1, aid1, time_buffer) < 0)
- {
- NXReportError(
- "ERROR: failed to store file_time attribute ");
- free(time_buffer);
- return NX_ERROR;
- }
- /* Close attribute dataspace */
- H5Tclose(aid1);
- H5Sclose(aid2);
- /* Close attribute */
- H5Aclose(attr1);
- free(time_buffer);
- }
- H5Gclose(iVID);
- }
- /* Set HDFgroup access mode */
- if (am1 == H5F_ACC_RDONLY) {
- strcpy(pNew->iAccess,"r");
- } else {
- strcpy(pNew->iAccess,"w");
- }
- pNew->iNXID = NX5SIGNATURE;
- pNew->iStack5[0].iVref = 0; /* root! */
- *pHandle = (NXhandle)pNew;
- return NX_OK;
- }
-
- /* ------------------------------------------------------------------------- */
-
- NXstatus NX5close (NXhandle* fid)
- {
- pNexusFile5 pFile = NULL;
- herr_t iRet;
-
- pFile=NXI5assert(*fid);
-
- iRet=0;
- /*
- printf("HDF5 object count before close: %d\n",
- H5Fget_obj_count(pFile->iFID,H5F_OBJ_ALL));
- */
- iRet = H5Fclose(pFile->iFID);
-
- /*
- leave this here: it helps in debugging leakage problems
- printf("HDF5 object count after close: %d\n",
- H5Fget_obj_count(H5F_OBJ_ALL,H5F_OBJ_ALL));
- printf("HDF5 dataset count after close: %d\n",
- H5Fget_obj_count(H5F_OBJ_ALL,H5F_OBJ_DATASET));
- printf("HDF5 group count after close: %d\n",
- H5Fget_obj_count(H5F_OBJ_ALL,H5F_OBJ_GROUP));
- printf("HDF5 datatype count after close: %d\n",
- H5Fget_obj_count(H5F_OBJ_ALL,H5F_OBJ_DATATYPE));
- printf("HDF5 attribute count after close: %d\n",
- H5Fget_obj_count(H5F_OBJ_ALL,H5F_OBJ_ATTR));
- */
-
- if (iRet < 0) {
- NXReportError( "ERROR: cannot close HDF file");
- }
- /* release memory */
- NXI5KillDir (pFile);
- if(pFile->iCurrentLGG != NULL){
- free(pFile->iCurrentLGG);
- }
- if(pFile->iCurrentLD != NULL){
- free(pFile->iCurrentLD);
- }
- free (pFile);
- *fid = NULL;
- H5garbage_collect();
- return NX_OK;
- }
-
- /*-----------------------------------------------------------------------*/
-
- NXstatus NX5makegroup (NXhandle fid, CONSTCHAR *name, CONSTCHAR *nxclass)
- {
- pNexusFile5 pFile;
- herr_t iRet;
- hid_t iVID;
- hid_t attr1,aid1, aid2;
- char pBuffer[1024] = "";
-
- pFile = NXI5assert (fid);
- /* create and configure the group */
- if (pFile->iCurrentG==0) {
- snprintf(pBuffer,1023,"/%s",name);
- } else {
- snprintf(pBuffer,1023,"/%s/%s",pFile->name_ref,name);
- }
- iRet = H5Gcreate(pFile->iFID,(const char*)pBuffer, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
- if (iRet < 0) {
- NXReportError( "ERROR: could not create Group");
- return NX_ERROR;
- }
- iVID = iRet;
- aid2 = H5Screate(H5S_SCALAR);
- aid1 = H5Tcopy(H5T_C_S1);
- H5Tset_size(aid1, strlen(nxclass));
- attr1= H5Acreate(iVID, "NX_class", aid1, aid2, H5P_DEFAULT, H5P_DEFAULT);
- if (attr1 < 0) {
- NXReportError( "ERROR: failed to store class name");
- return NX_ERROR;
- }
- if (H5Awrite(attr1, aid1, (char*)nxclass) < 0) {
- NXReportError( "ERROR: failed to store class name");
- return NX_ERROR;
- }
- /* close group */
- iRet=H5Sclose(aid2);
- iRet=H5Tclose(aid1);
- iRet=H5Aclose(attr1);
- iRet=H5Gclose(iVID);
- return NX_OK;
- }
-
- /*------------------------------------------------------------------------*/
-
- herr_t attr_check (hid_t loc_id, const char *member_name, const H5A_info_t *unused, void *opdata)
- {
- char attr_name[8+1]; /* need to leave space for \0 as well */
-
- strcpy(attr_name,"NX_class");
- return strstr(member_name, attr_name) ? 1 : 0;
- }
- /*------------------------------------------------------------------------*/
- NXstatus NX5opengroup(NXhandle fid, CONSTCHAR *name, CONSTCHAR *nxclass)
- {
-
- pNexusFile5 pFile;
- hid_t attr1, atype;
- herr_t iRet;
- char pBuffer[1024];
- char data[128];
-
- pFile = NXI5assert (fid);
- if (pFile->iCurrentG == 0) {
- strcpy(pBuffer,name);
- } else {
- sprintf(pBuffer,"%s/%s",pFile->name_tmp,name);
- }
- iRet = H5Gopen(pFile->iFID, (const char *)pBuffer, H5P_DEFAULT);
- if (iRet < 0) {
- sprintf (pBuffer, "ERROR: group %s does not exist", pFile->name_tmp);
- NXReportError( pBuffer);
- return NX_ERROR;
- }
- pFile->iCurrentG = iRet;
- strcpy(pFile->name_tmp,pBuffer);
- strcpy(pFile->name_ref,pBuffer);
-
- if ((nxclass != NULL) && (strcmp(nxclass, NX_UNKNOWN_GROUP) != 0)) {
- /* check group attribute */
- iRet=H5Aiterate(pFile->iCurrentG,H5_INDEX_CRT_ORDER,H5_ITER_INC,0,attr_check,NULL);
- if (iRet < 0) {
- NXReportError( "ERROR: iterating through attribute list");
- return NX_ERROR;
- } else if (iRet == 1) {
- /* group attribute was found */
- } else {
- /* no group attribute available */
- NXReportError( "ERROR: no group attribute available");
- return NX_ERROR;
- }
- /* check contents of group attribute */
- attr1 = H5Aopen_by_name(pFile->iCurrentG, ".", "NX_class", H5P_DEFAULT, H5P_DEFAULT);
- if (attr1 < 0) {
- NXReportError( "ERROR: opening NX_class group attribute");
- return NX_ERROR;
- }
- atype=H5Tcopy(H5T_C_S1);
- H5Tset_size(atype,sizeof(data));
- iRet = H5Aread(attr1, atype, data);
- if (strcmp(data, nxclass) == 0) {
- /* test OK */
- } else {
- NXReportError( "ERROR: group class is not identical");
- iRet = H5Tclose(atype);
- iRet = H5Aclose(attr1);
- return NX_ERROR;
- }
- iRet = H5Tclose(atype);
- iRet = H5Aclose(attr1);
- }
-
- /* maintain stack */
- pFile->iStackPtr++;
- pFile->iStack5[pFile->iStackPtr].iVref=pFile->iCurrentG;
- strcpy(pFile->iStack5[pFile->iStackPtr].irefn,name);
- pFile->iAtt5.iCurrentIDX=0;
- pFile->iCurrentD = 0;
- if(pFile->iCurrentLGG != NULL){
- free(pFile->iCurrentLGG);
- }
- pFile->iCurrentLGG = strdup(name);
- NXI5KillDir (pFile);
- return NX_OK;
- }
-
- /* ------------------------------------------------------------------- */
-
- NXstatus NX5closegroup (NXhandle fid)
- {
- pNexusFile5 pFile;
- int i,ii;
- char *uname = NULL;
- char *u1name = NULL;
-
- pFile = NXI5assert (fid);
- /* first catch the trivial case: we are at root and cannot get
- deeper into a negative directory hierarchy (anti-directory)
- */
- if (pFile->iCurrentG == 0) {
- NXI5KillDir (pFile);
- return NX_OK;
- } else {
- /* close the current group and decrement name_ref */
- H5Gclose (pFile->iCurrentG);
- i = 0;
- i = strlen(pFile->iStack5[pFile->iStackPtr].irefn);
- ii = strlen(pFile->name_ref);
- if (pFile->iStackPtr>1) {
- ii=ii-i-1;
- } else {
- ii=ii-i;
- }
- if (ii>0) {
- uname = strdup(pFile->name_ref);
- u1name = (char*) malloc((ii+1)*sizeof(char));
- memset(u1name,0,ii);
- for (i=0; iname_ref,u1name);
- strcpy(pFile->name_tmp,u1name);
- free(uname);
- free(u1name);
- } else {
- strcpy(pFile->name_ref,"");
- strcpy(pFile->name_tmp,"");
- }
- NXI5KillDir (pFile);
- pFile->iStackPtr--;
- if (pFile->iStackPtr>0) {
- pFile->iCurrentG=pFile->iStack5[pFile->iStackPtr].iVref;
- } else {
- pFile->iCurrentG=0;
- }
- }
- return NX_OK;
- }
-/*-----------------------------------------------------------------------*/
-static hid_t nxToHDF5Type(int datatype)
-{
- hid_t type;
- if (datatype == NX_CHAR) {
- type=H5T_C_S1;
- } else if (datatype == NX_INT8) {
- type=H5T_NATIVE_CHAR;
- } else if (datatype == NX_UINT8) {
- type=H5T_NATIVE_UCHAR;
- } else if (datatype == NX_INT16) {
- type=H5T_NATIVE_SHORT;
- } else if (datatype == NX_UINT16) {
- type=H5T_NATIVE_USHORT;
- } else if (datatype == NX_INT32) {
- type=H5T_NATIVE_INT;
- } else if (datatype == NX_UINT32) {
- type=H5T_NATIVE_UINT;
- } else if (datatype == NX_INT64) {
- type = H5T_NATIVE_INT64;
- } else if (datatype == NX_UINT64) {
- type = H5T_NATIVE_UINT64;
- } else if (datatype == NX_FLOAT32) {
- type=H5T_NATIVE_FLOAT;
- } else if (datatype == NX_FLOAT64) {
- type=H5T_NATIVE_DOUBLE;
- } else {
- NXReportError( "ERROR: nxToHDF5Type: unknown type");
- type = -1;
- }
- return type;
-}
-
- /* --------------------------------------------------------------------- */
-
- NXstatus NX5compmakedata64 (NXhandle fid, CONSTCHAR *name,
- int datatype,
- int rank, int64_t dimensions[],
- int compress_type, int64_t chunk_size[])
- {
- hid_t datatype1, dataspace, iNew;
- herr_t iRet;
- hid_t type, cparms = -1;
- pNexusFile5 pFile;
- char pBuffer[256];
- int i, byte_zahl = 0;
- hsize_t chunkdims[H5S_MAX_RANK];
- hsize_t mydim[H5S_MAX_RANK], mydim1[H5S_MAX_RANK];
- hsize_t size[H5S_MAX_RANK];
- hsize_t maxdims[H5S_MAX_RANK];
- int compress_level;
- int unlimiteddim = 0;
-
- pFile = NXI5assert (fid);
- if (pFile->iCurrentG <= 0) {
- sprintf(pBuffer, "ERROR: no group open for makedata on %s", name);
- NXReportError( pBuffer);
- return NX_ERROR;
- }
-
- if (rank <= 0) {
- sprintf (pBuffer, "ERROR: invalid rank specified %s", name);
- NXReportError( pBuffer);
- return NX_ERROR;
- }
-
- type = nxToHDF5Type(datatype);
-
- /*
- Check dimensions for consistency. Dimension may be -1
- thus denoting an unlimited dimension.
- */
- for (i = 0; i < rank; i++)
- {
- chunkdims[i] = chunk_size[i];
- mydim[i] = dimensions[i];
- maxdims[i] = dimensions[i];
- size[i] = dimensions[i];
- if (dimensions[i] <= 0)
- {
- mydim[i] = 1;
- maxdims[i] = H5S_UNLIMITED;
- size[i] = 1;
- unlimiteddim = 1;
- } else {
- mydim[i] = dimensions[i];
- maxdims[i] = dimensions[i];
- size[i] = dimensions[i];
- }
- }
-
- if (datatype == NX_CHAR)
- {
- /*
- * This assumes string lenght is in the last dimensions and
- * the logic must be the same as used in NX5getslab and NX5getinfo
- *
- * search for tests on H5T_STRING
- */
- byte_zahl=mydim[rank-1];
- for(i = 0; i < rank; i++)
- {
- mydim1[i] = mydim[i];
- if (dimensions[i] <= 0)
- {
- mydim1[0] = 1;
- maxdims[0] = H5S_UNLIMITED;
- }
-
- }
- mydim1[rank-1] = 1;
- if (mydim[rank-1] > 1)
- {
- mydim[rank-1] = maxdims[rank-1] = size[rank-1] = 1;
- }
- if (chunkdims[rank-1] > 1)
- {
- chunkdims[rank-1] = 1;
- }
- dataspace=H5Screate_simple(rank,mydim1,maxdims);
- }
- else
- {
- if (unlimiteddim)
- {
- dataspace=H5Screate_simple(rank, mydim, maxdims);
- }
- else
- {
- /* dataset creation */
- dataspace=H5Screate_simple(rank, mydim, NULL);
- }
- }
- datatype1=H5Tcopy(type);
- if (datatype == NX_CHAR)
- {
- H5Tset_size(datatype1, byte_zahl);
- /* H5Tset_strpad(H5T_STR_SPACEPAD); */
- }
- compress_level = 6;
- if ( (compress_type / 100) == NX_COMP_LZW )
- {
- compress_level = compress_type % 100;
- compress_type = NX_COMP_LZW;
- }
- if(compress_type == NX_COMP_LZW)
- {
- cparms = H5Pcreate(H5P_DATASET_CREATE);
- iNew = H5Pset_chunk(cparms,rank,chunkdims);
- if (iNew < 0)
- {
- NXReportError( "ERROR: size of chunks could not be set");
- return NX_ERROR;
- }
- H5Pset_deflate(cparms,compress_level);
- iRet = H5Dcreate(pFile->iCurrentG, (char*)name, datatype1, dataspace, H5P_DEFAULT, cparms, H5P_DEFAULT);
- }
- else if (compress_type == NX_COMP_NONE)
- {
- if (unlimiteddim)
- {
- cparms = H5Pcreate(H5P_DATASET_CREATE);
- iNew = H5Pset_chunk(cparms,rank,chunkdims);
- if (iNew < 0)
- {
- NXReportError( "ERROR: size of chunks could not be set");
- return NX_ERROR;
- }
- iRet = H5Dcreate(pFile->iCurrentG, (char*)name, datatype1, dataspace, H5P_DEFAULT, cparms, H5P_DEFAULT);
- }
- else
- {
- iRet = H5Dcreate(pFile->iCurrentG, (char*)name, datatype1, dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
- }
- }
- else if (compress_type == NX_CHUNK)
- {
- cparms = H5Pcreate(H5P_DATASET_CREATE);
- iNew = H5Pset_chunk(cparms,rank,chunkdims);
- if (iNew < 0)
- {
- NXReportError("ERROR: size of chunks could not be set");
- return NX_ERROR;
- }
- iRet = H5Dcreate(pFile->iCurrentG, (char*)name, datatype1, dataspace, H5P_DEFAULT, cparms, H5P_DEFAULT);
-
- }
- else
- {
- NXReportError(
- "HDF5 doesn't support selected compression method! Dataset was saved without compression");
- iRet = H5Dcreate (pFile->iCurrentG, (char*)name, datatype1, dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
- }
- if (iRet < 0)
- {
- NXReportError( "ERROR: creating chunked dataset failed");
- return NX_ERROR;
- }
- else
- {
- pFile->iCurrentD = iRet;
- }
- if (unlimiteddim)
- {
- iNew = H5Dset_extent (pFile->iCurrentD, size);
- if (iNew < 0)
- {
- sprintf (pBuffer, "ERROR: cannot create dataset %s",
- name);
- NXReportError( pBuffer);
- return NX_ERROR;
- }
- }
- if (cparms != -1)
- {
- iRet = H5Pclose(cparms);
- }
- iRet = H5Sclose(dataspace);
- iRet = H5Tclose(datatype1);
- iRet = H5Dclose(pFile->iCurrentD);
- pFile->iCurrentD = 0;
- if (iRet < 0)
- {
- NXReportError( "ERROR: HDF cannot close dataset");
- return NX_ERROR;
- }
- return NX_OK;
- }
-
-
- /* --------------------------------------------------------------------- */
-
- NXstatus NX5makedata64 (NXhandle fid, CONSTCHAR *name, int datatype,
- int rank, int64_t dimensions[])
- {
- int64_t chunk_size[H5S_MAX_RANK];
- int i;
-
- NXI5assert(fid);
-
- memset(chunk_size,0,H5S_MAX_RANK*sizeof(int64_t));
- memcpy(chunk_size,dimensions,rank*sizeof(int64_t));
- for(i = 0; i< rank; i++) {
- if (dimensions[i] == NX_UNLIMITED || dimensions[i] <= 0){
- chunk_size[i]= 1;
- }
- }
- return NX5compmakedata64 (fid, name, datatype, rank, dimensions, NX_COMP_NONE, chunk_size);
- }
-
-
- /* --------------------------------------------------------------------- */
-
- NXstatus NX5compress (NXhandle fid, int compress_type)
- {
- printf(" NXcompress ERROR: NeXus API based on HDF5 doesn't support\n");
- printf(" NXcompress function! Using HDF5 library,\n");
- printf(" the NXcompmakedata function can be applied\n");
- printf(" for compression of data!\n");
- return NX_ERROR;
- }
-
- /* --------------------------------------------------------------------- */
-
- NXstatus NX5opendata (NXhandle fid, CONSTCHAR *name)
- {
- pNexusFile5 pFile;
- char pBuffer[256];
-
- pFile = NXI5assert (fid);
- /* clear pending attribute directories first */
- NXI5KillAttDir (pFile);
-
-
- /* find the ID number and open the dataset */
- pFile->iCurrentD = H5Dopen(pFile->iCurrentG, name, H5P_DEFAULT);
- if (pFile->iCurrentD < 0) {
- sprintf (pBuffer, "ERROR: dataset \"%s\" not found at this level", name);
- NXReportError( pBuffer);
- return NX_ERROR;
- }
- /* find the ID number of datatype */
- pFile->iCurrentT = H5Dget_type(pFile->iCurrentD);
- if (pFile->iCurrentT < 0) {
- NXReportError( "ERROR: error opening dataset");
- pFile->iCurrentT=0;
- return NX_ERROR;
- }
- /* find the ID number of dataspace */
- pFile->iCurrentS = H5Dget_space(pFile->iCurrentD);
- if (pFile->iCurrentS < 0) {
- NXReportError( "ERROR:HDF error opening dataset");
- pFile->iCurrentS=0;
- return NX_ERROR;
- }
- if(pFile->iCurrentLD != NULL){
- free(pFile->iCurrentLD);
- }
- pFile->iCurrentLD = strdup(name);
- return NX_OK;
- }
-
- /* ----------------------------------------------------------------- */
-
- NXstatus NX5closedata (NXhandle fid)
- {
- pNexusFile5 pFile;
- herr_t iRet;
-
- pFile = NXI5assert (fid);
- iRet = H5Sclose(pFile->iCurrentS);
- iRet = H5Tclose(pFile->iCurrentT);
- iRet = H5Dclose(pFile->iCurrentD);
- if (iRet < 0) {
- NXReportError( "ERROR: cannot end access to dataset");
- return NX_ERROR;
- }
- pFile->iCurrentD=0;
- return NX_OK;
- }
-
- /* ------------------------------------------------------------------- */
-
-
-
- NXstatus NX5putdata (NXhandle fid, const void *data)
- {
- pNexusFile5 pFile;
- herr_t iRet;
- int64_t myStart[H5S_MAX_RANK];
- int64_t mySize[H5S_MAX_RANK];
- hsize_t thedims[H5S_MAX_RANK],maxdims[H5S_MAX_RANK];
- int i, rank, unlimiteddim = 0;
-
- char pError[512] = "";
-
- pFile = NXI5assert (fid);
- rank = H5Sget_simple_extent_ndims(pFile->iCurrentS);
- if (rank < 0)
- {
- NXReportError("ERROR: Cannot determine dataset rank");
- return NX_ERROR;
- }
- iRet = H5Sget_simple_extent_dims(pFile->iCurrentS, thedims, maxdims);
- if (iRet < 0)
- {
- NXReportError("ERROR: Cannot determine dataset dimensions");
- return NX_ERROR;
- }
- for(i=0; iiCurrentD, pFile->iCurrentT, H5S_ALL, H5S_ALL,
- H5P_DEFAULT, data);
- if (iRet < 0) {
- snprintf (pError,sizeof(pError)-1, "ERROR: failure to write data");
- NXReportError( pError);
- return NX_ERROR;
- }
- }
- return NX_OK;
- }
-/*------------------------------------------------------------------*/
-static int getAttVID(pNexusFile5 pFile){
- int vid;
- if(pFile->iCurrentG == 0 && pFile->iCurrentD == 0){
- /* global attribute */
- vid = H5Gopen(pFile->iFID,"/", H5P_DEFAULT);
- } else if(pFile->iCurrentD != 0) {
- /* dataset attribute */
- vid = pFile->iCurrentD;
- } else {
- /* group attribute */;
- vid = pFile->iCurrentG;
- }
- return vid;
-}
-/*---------------------------------------------------------------*/
-static void killAttVID(pNexusFile5 pFile, int vid){
- if(pFile->iCurrentG == 0 && pFile->iCurrentD == 0){
- H5Gclose(vid);
- }
-}
- /* ------------------------------------------------------------------- */
-
- NXstatus NX5putattr (NXhandle fid, CONSTCHAR *name, const void *data,
-
- int datalen, int iType)
- {
- pNexusFile5 pFile;
- hid_t attr1, aid1, aid2;
- hid_t type;
- herr_t iRet;
- int vid;
-
- pFile = NXI5assert (fid);
-
- type = nxToHDF5Type(iType);
-
- /* determine vid */
- vid = getAttVID(pFile);
- aid2=H5Screate(H5S_SCALAR);
- aid1=H5Tcopy(type);
- if (iType == NX_CHAR){
- H5Tset_size(aid1,datalen);
- }
- iRet = H5Aopen_by_name(vid, ".", name, H5P_DEFAULT, H5P_DEFAULT);
- if (iRet>0) {
- H5Aclose(iRet);
- iRet=H5Adelete(vid,name);
- if (iRet<0) {
- NXReportError( "ERROR: old attribute cannot be removed! ");
- killAttVID(pFile,vid);
- return NX_ERROR;
- }
- }
- attr1 = H5Acreate(vid, name, aid1, aid2, H5P_DEFAULT, H5P_DEFAULT);
- if (attr1 < 0) {
- NXReportError( "ERROR: attribute cannot created! ");
- killAttVID(pFile,vid);
- return NX_ERROR;
- }
- if (H5Awrite(attr1,aid1,data) < 0) {
- NXReportError( "ERROR: failed to store attribute ");
- killAttVID(pFile,vid);
- return NX_ERROR;
- }
- /* Close attribute dataspace */
- iRet=H5Tclose(aid1);
- iRet=H5Sclose(aid2);
- /* Close attribute */
- iRet=H5Aclose(attr1);
- killAttVID(pFile,vid);
- return NX_OK;
- }
-
- /* ------------------------------------------------------------------- */
-
- NXstatus NX5putslab64 (NXhandle fid, const void *data, const int64_t iStart[], const int64_t iSize[])
- {
- pNexusFile5 pFile;
- int iRet, rank, i;
- hsize_t myStart[H5S_MAX_RANK];
- hsize_t mySize[H5S_MAX_RANK];
- hsize_t size[H5S_MAX_RANK],thedims[H5S_MAX_RANK],maxdims[H5S_MAX_RANK];
- hid_t filespace,dataspace;
- int unlimiteddim = 0;
-
- pFile = NXI5assert (fid);
- /* check if there is an Dataset open */
- if (pFile->iCurrentD == 0) {
- NXReportError( "ERROR: no dataset open");
- return NX_ERROR;
- }
- rank = H5Sget_simple_extent_ndims(pFile->iCurrentS);
- if (rank < 0) {
- NXReportError( "ERROR: cannot get rank");
- return NX_ERROR;
- }
- iRet = H5Sget_simple_extent_dims(pFile->iCurrentS, thedims, maxdims);
- if (iRet < 0) {
- NXReportError( "ERROR: cannot get dimensions");
- return NX_ERROR;
- }
-
- for(i = 0; i < rank; i++)
- {
- myStart[i] = iStart[i];
- mySize[i] = iSize[i];
- size[i] = iStart[i] + iSize[i];
- if (maxdims[i] == H5S_UNLIMITED) {
- unlimiteddim = 1;
- }
- }
- if (H5Tget_class(pFile->iCurrentT) == H5T_STRING)
- {
- mySize[rank - 1] = 1;
- myStart[rank - 1] = 0;
- size[rank - 1] = 1;
- }
- dataspace = H5Screate_simple(rank, mySize, NULL);
- if (unlimiteddim)
- {
- for(i = 0; i < rank; i++)
- {
- if (size[i] < thedims[i]) {
- size[i] = thedims[i];
- }
- }
- iRet = H5Dset_extent(pFile->iCurrentD, size);
- if (iRet < 0)
- {
- NXReportError( "ERROR: extend slab failed");
- return NX_ERROR;
- }
-
- filespace = H5Dget_space(pFile->iCurrentD);
-
- /* define slab */
- iRet = H5Sselect_hyperslab(filespace, H5S_SELECT_SET, myStart,
- NULL, mySize, NULL);
- /* deal with HDF errors */
- if (iRet < 0)
- {
- NXReportError( "ERROR: selecting slab failed");
- return NX_ERROR;
- }
- /* write slab */
- iRet = H5Dwrite(pFile->iCurrentD, pFile->iCurrentT, dataspace,
- filespace, H5P_DEFAULT, data);
- if (iRet < 0)
- {
- NXReportError( "ERROR: writing slab failed");
- }
- /* update with new size */
- iRet = H5Sclose(pFile->iCurrentS);
- pFile->iCurrentS = filespace;
- } else {
- /* define slab */
- iRet = H5Sselect_hyperslab(pFile->iCurrentS, H5S_SELECT_SET, myStart,
- NULL, mySize, NULL);
- /* deal with HDF errors */
- if (iRet < 0)
- {
- NXReportError( "ERROR: selecting slab failed");
- return NX_ERROR;
- }
- /* write slab */
- iRet = H5Dwrite(pFile->iCurrentD, pFile->iCurrentT, dataspace,
- pFile->iCurrentS, H5P_DEFAULT, data);
- if (iRet < 0)
- {
- NXReportError( "ERROR: writing slab failed");
- }
- }
- /* deal with HDF errors */
- iRet = H5Sclose(dataspace);
- if (iRet < 0)
- {
- NXReportError( "ERROR: closing slab failed");
- return NX_ERROR;
- }
- return NX_OK;
- }
-
- /* ------------------------------------------------------------------- */
-
- NXstatus NX5getdataID (NXhandle fid, NXlink* sRes)
- {
- pNexusFile5 pFile;
- int datalen, type = NX_CHAR;
-
- pFile = NXI5assert (fid);
-
- /*
- we cannot return ID's when no datset is open
- */
- if(pFile->iCurrentD <= 0){
- return NX_ERROR;
- }
-
- /*
- this means: if the item is already linked: use the target attribute else,
- the path to the current node
- */
- NXMDisableErrorReporting();
- datalen = 1024;
- memset(&sRes->targetPath,0,datalen*sizeof(char));
- if(NX5getattr(fid,"target",&sRes->targetPath,&datalen,&type) != NX_OK)
- {
- buildCurrentPath(pFile, sRes->targetPath, 1024);
- }
- NXMEnableErrorReporting();
- sRes->linkType = 1;
- return NX_OK;
- }
-
- /* ------------------------------------------------------------------- */
-
- NXstatus NX5printlink (NXhandle fid, NXlink* sLink)
- {
- NXI5assert(fid);
- printf("HDF5 link: targetPath = \"%s\", linkType = \"%d\"\n", sLink->targetPath, sLink->linkType);
- return NX_OK;
- }
-/*--------------------------------------------------------------------*/
-static NXstatus NX5settargetattribute(pNexusFile5 pFile, NXlink *sLink)
-{
- hid_t dataID, aid2, aid1, attID;
- herr_t status;
- char name[] = "target";
-
- /*
- set the target attribute
- */
- if(sLink->linkType > 0)
- {
- dataID = H5Dopen(pFile->iFID,sLink->targetPath, H5P_DEFAULT);
- } else {
- dataID = H5Gopen(pFile->iFID,sLink->targetPath, H5P_DEFAULT);
- }
- if(dataID < 0)
- {
- NXReportError("Internal error, path to link does not exist");
- return NX_ERROR;
- }
- status = H5Aopen_by_name(dataID,".", name, H5P_DEFAULT, H5P_DEFAULT);
- if(status > 0)
- {
- H5Aclose(status);
- status = H5Adelete(dataID,name);
- if(status < 0)
- {
- return NX_OK;
- }
- }
- aid2 = H5Screate(H5S_SCALAR);
- aid1 = H5Tcopy(H5T_C_S1);
- H5Tset_size(aid1,strlen(sLink->targetPath));
- attID = H5Acreate(dataID,name,aid1,aid2,H5P_DEFAULT, H5P_DEFAULT);
- if(attID < 0)
- {
- return NX_OK;
- }
- status = H5Awrite(attID,aid1,sLink->targetPath);
- H5Tclose(aid1);
- H5Sclose(aid2);
- H5Aclose(attID);
- if(sLink->linkType > 0){
- H5Dclose(dataID);
- } else {
- H5Gclose(dataID);
- }
- return NX_OK;
-}
-/*---------------------------------------------------------------------*/
-NXstatus NX5makenamedlink(NXhandle fid, CONSTCHAR *name, NXlink *sLink)
-{
- pNexusFile5 pFile;
- char linkTarget[1024];
-
- pFile = NXI5assert (fid);
- if (pFile->iCurrentG == 0) { /* root level, can not link here */
- return NX_ERROR;
- }
-
- /*
- build pathname to link from our current group and the name
- of the thing to link
- */
- if(strlen(pFile->name_ref) + strlen(name) + 2 < 1024)
- {
- strcpy(linkTarget,"/");
- strcat(linkTarget,pFile->name_ref);
- strcat(linkTarget,"/");
- strcat(linkTarget,name);
- }
- else
- {
- NXReportError("ERROR: path string to long");
- return NX_ERROR;
- }
-
- //targetid = H5Oopen(pFile->iFID, sLink->targetPath, H5P_DEFAULT);
- H5Lcreate_hard(pFile->iFID, sLink->targetPath, H5L_SAME_LOC, linkTarget, H5P_DEFAULT, H5P_DEFAULT);
- //H5Oclose(targetid);
-
- return NX5settargetattribute(pFile,sLink);
-}
- /* ------------------------------------------------------------------- */
-
- NXstatus NX5makelink (NXhandle fid, NXlink* sLink)
- {
- pNexusFile5 pFile;
- char linkTarget[1024];
- char *itemName = NULL;
-
- pFile = NXI5assert (fid);
- if (pFile->iCurrentG == 0) { /* root level, can not link here */
- return NX_ERROR;
- }
-
- /*
- locate name of the element to link
- */
- itemName = strrchr(sLink->targetPath,'/');
- if(itemName == NULL){
- NXReportError("ERROR: bad link structure");
- return NX_ERROR;
- }
- itemName++;
-
- /*
- build pathname to link from our current group and the name
- of the thing to link
- */
- if(strlen(pFile->name_ref) + strlen(itemName) + 2 < 1024)
- {
- strcpy(linkTarget,"/");
- strcat(linkTarget,pFile->name_ref);
- strcat(linkTarget,"/");
- strcat(linkTarget,itemName);
- }
- else
- {
- NXReportError("ERROR: path string to long");
- return NX_ERROR;
- }
-
- //targetid = H5Oopen(pFile->iFID, sLink->targetPath, H5P_DEFAULT);
- H5Lcreate_hard(pFile->iFID, sLink->targetPath, H5L_SAME_LOC, linkTarget, H5P_DEFAULT, H5P_DEFAULT);
- //H5Oclose(targetid);
-
- return NX5settargetattribute(pFile,sLink);
- }
-
- /*----------------------------------------------------------------------*/
-
- NXstatus NX5flush(NXhandle *pHandle)
- {
- pNexusFile5 pFile = NULL;
- herr_t iRet;
-
- pFile = NXI5assert (*pHandle);
- if (pFile->iCurrentD != 0)
- {
- iRet=H5Fflush(pFile->iCurrentD,H5F_SCOPE_LOCAL);
- }
- else if (pFile->iCurrentG != 0)
- {
- iRet=H5Fflush(pFile->iCurrentG,H5F_SCOPE_LOCAL);
- }
- else
- {
- iRet=H5Fflush(pFile->iFID,H5F_SCOPE_LOCAL);
- }
- if (iRet < 0){
- NXReportError( "ERROR: The object cannot be flushed");
- return NX_ERROR;
- }
- return NX_OK;
- }
-
- /*-------------------------------------------------------------------------*/
-
- /* Operator function. */
-
- herr_t nxgroup_info(hid_t loc_id, const char *name, const H5L_info_t *statbuf, void *op_data)
- {
- pinfo self = (pinfo) op_data;
- H5O_info_t object_info;
- H5Oget_info_by_name(loc_id, name, &object_info, H5P_DEFAULT);
- switch ((object_info).type) {
- case H5O_TYPE_GROUP:
- self->iname = strdup(name);
- self->type = H5O_TYPE_GROUP;
- break;
- case H5O_TYPE_DATASET:
- self->iname = strdup(name);
- self->type = H5O_TYPE_DATASET;
- break;
- default:
- // TODO defaults to group. not what we would want?
- self->type=0;
- break;
- }
- return 1;
- }
- /* --------------------------------------------------------------------- */
-
- /* Operator function. */
-
- herr_t group_info1(hid_t loc_id, const char *name, const H5L_info_t *statbuf, void *opdata)
- {
- int iNX = *((int*)opdata);
- H5O_info_t object_info;
- H5Oget_info_by_name(loc_id, name, &object_info, H5P_DEFAULT);
- switch ((object_info).type) {
- case H5O_TYPE_GROUP:
- iNX++;
- *((int*)opdata)=iNX;
- break;
- case H5O_TYPE_DATASET:
- iNX++;
- *((int*)opdata)=iNX;
- break;
- default:
- break;
- }
- return 0;
- }
-
- /*-------------------------------------------------------------------------*/
-
- NXstatus NX5getgroupinfo_recurse(NXhandle fid, int *iN, NXname pName, NXname pClass)
- {
- pNexusFile5 pFile;
- hid_t atype, attr_id, grp;
- char data[64];
-
- pFile = NXI5assert (fid);
- /* check if there is a group open */
- if (pFile->iCurrentG == 0) {
- strcpy (pName, "root");
- strcpy (pClass, "NXroot");
- pFile->iNX=0;
- grp = H5Gopen(pFile->iFID,"/",H5P_DEFAULT);
- H5Literate(grp, H5_INDEX_NAME, H5_ITER_INC, 0, group_info1, &pFile->iNX);
- H5Gclose(grp);
- *iN=pFile->iNX;
- }
- else {
- strcpy (pName,pFile->name_ref);
- attr_id = H5Aopen_by_name(pFile->iCurrentG,".", "NX_class", H5P_DEFAULT, H5P_DEFAULT);
- if (attr_id<0) {
- strcpy(pClass, NX_UNKNOWN_GROUP);
- } else {
- atype=H5Tcopy(H5T_C_S1);
- H5Tset_size(atype,sizeof(data));
- H5Aread(attr_id, atype, data);
- strcpy(pClass,data);
- pFile->iNX=0;
- grp = H5Gopen(pFile->iFID,pFile->name_ref,H5P_DEFAULT);
- H5Literate(grp, H5_INDEX_NAME, H5_ITER_INC, 0, group_info1, &pFile->iNX);
- H5Gclose(grp);
- *iN=pFile->iNX;
- H5Aclose(attr_id);
- }
- }
- return NX_OK;
- }
-/*---------------------------------------------------------------------------*/
-static int countObjectsInGroup(hid_t loc_id)
-{
- int count = 0;
- H5G_info_t numobj;
-
- herr_t status;
-
- status = H5Gget_info(loc_id, &numobj);
- if(status < 0) {
- NXReportError("Internal error, failed to retrive no of objects");
- return 0;
- }
-
- count = numobj.nlinks;
- return count;
-}
-/*----------------------------------------------------------------------------*/
- NXstatus NX5getgroupinfo (NXhandle fid, int *iN, NXname pName, NXname pClass)
- {
- pNexusFile5 pFile;
- hid_t atype, attr_id, gid;
- char data[64];
-
- pFile = NXI5assert (fid);
- /* check if there is a group open */
- if (pFile->iCurrentG == 0) {
- strcpy (pName, "root");
- strcpy (pClass, "NXroot");
- gid = H5Gopen(pFile->iFID,"/", H5P_DEFAULT);
- *iN = countObjectsInGroup(gid);
- H5Gclose(gid);
- }
- else {
- strcpy (pName,pFile->name_ref);
- attr_id = H5Aopen_by_name(pFile->iCurrentG,".", "NX_class", H5P_DEFAULT, H5P_DEFAULT);
- if (attr_id<0) {
- strcpy(pClass, NX_UNKNOWN_GROUP);
- } else {
- atype=H5Tcopy(H5T_C_S1);
- H5Tset_size(atype,sizeof(data));
- H5Aread(attr_id, atype, data);
- strcpy(pClass,data);
- pFile->iNX=0;
- *iN = countObjectsInGroup(pFile->iCurrentG);
- H5Aclose(attr_id);
- }
- }
- return NX_OK;
- }
-
-
-/*-------------------------------------------------------------------------
- * Function: hdf5ToNXType
- *
- * Purpose: Convert a HDF5 class to a NeXus type; it handles the following HDF5 classes
- * H5T_STRING
- * H5T_INTEGER
- * H5T_FLOAT
- *
- * Return: the NeXus type
- *
- *-------------------------------------------------------------------------
- */
- static int hdf5ToNXType(H5T_class_t tclass, hid_t atype)
- {
- int iPtype = -1;
- size_t size;
- H5T_sign_t sign;
-
- if (tclass==H5T_STRING)
- {
- iPtype=NX_CHAR;
- }
- else if (tclass==H5T_INTEGER)
- {
- size=H5Tget_size(atype);
- sign=H5Tget_sign(atype);
- if (size==1)
- {
- if (sign==H5T_SGN_2)
- {
- iPtype=NX_INT8;
- } else {
- iPtype=NX_UINT8;
- }
- }
- else if (size==2)
- {
- if (sign==H5T_SGN_2)
- {
- iPtype=NX_INT16;
- } else {
- iPtype=NX_UINT16;
- }
- }
- else if (size==4)
- {
- if (sign==H5T_SGN_2)
- {
- iPtype=NX_INT32;
- } else {
- iPtype=NX_UINT32;
- }
- }
- else if(size == 8)
- {
- if (sign==H5T_SGN_2)
- {
- iPtype=NX_INT64;
- } else {
- iPtype=NX_UINT64;
- }
- }
- }
- else if (tclass==H5T_FLOAT)
- {
- size=H5Tget_size(atype);
- if (size==4)
- {
- iPtype=NX_FLOAT32;
- }
- else if (size==8)
- {
- iPtype=NX_FLOAT64;
- }
- }
- if (iPtype == -1)
- {
- NXReportError( "ERROR: hdf5ToNXtype: invalid type");
- }
-
- return iPtype;
- }
-/*--------------------------------------------------------------------------*/
- static hid_t h5MemType(hid_t atype)
- {
- hid_t memtype_id = -1;
- size_t size;
- H5T_sign_t sign;
- H5T_class_t tclass;
-
- tclass = H5Tget_class(atype);
-
- if (tclass==H5T_INTEGER)
- {
- size=H5Tget_size(atype);
- sign=H5Tget_sign(atype);
- if (size==1)
- {
- if (sign==H5T_SGN_2)
- {
- memtype_id = H5T_NATIVE_INT8;
- } else {
- memtype_id = H5T_NATIVE_UINT8;
- }
- }
- else if (size==2)
- {
- if (sign==H5T_SGN_2)
- {
- memtype_id = H5T_NATIVE_INT16;
- } else {
- memtype_id = H5T_NATIVE_UINT16;
- }
- }
- else if (size==4)
- {
- if (sign==H5T_SGN_2)
- {
- memtype_id = H5T_NATIVE_INT32;
- } else {
- memtype_id = H5T_NATIVE_UINT32;
- }
- }
- else if (size==8)
- {
- if (sign==H5T_SGN_2)
- {
- memtype_id = H5T_NATIVE_INT64;
- } else {
- memtype_id = H5T_NATIVE_UINT64;
- }
- }
- } else if (tclass==H5T_FLOAT)
- {
- size=H5Tget_size(atype);
- if (size==4)
- {
- memtype_id = H5T_NATIVE_FLOAT;
- } else if (size==8) {
- memtype_id = H5T_NATIVE_DOUBLE;
- }
- }
- if (memtype_id == -1)
- {
- NXReportError( "ERROR: h5MemType: invalid type");
- }
- return memtype_id;
- }
- /*-------------------------------------------------------------------------*/
-
- NXstatus NX5getnextentry(NXhandle fid, NXname name, NXname nxclass, int *datatype)
- {
- pNexusFile5 pFile;
- hid_t grp, attr1,type,atype;
- herr_t iRet;
- int iPtype, i;
- hsize_t idx;
- H5T_class_t tclass;
- char data[128];
- char ph_name[1024];
- info_type op_data;
- herr_t iRet_iNX=-1;
- char pBuffer[256];
-
- pFile = NXI5assert (fid);
- op_data.iname = NULL;
-
- /*
- iterate to next entry in group list
- */
- idx=pFile->iStack5[pFile->iStackPtr].iCurrentIDX;
- if (strlen(pFile->name_ref) == 0) {
- /* root group */
- strcpy(pFile->name_ref,"/");
- }
- grp = H5Gopen(pFile->iFID, pFile->name_ref, H5P_DEFAULT);
- // index can be wrong here
- iRet=H5Literate(grp, H5_INDEX_NAME, H5_ITER_INC, &idx, nxgroup_info, &op_data);
- H5Gclose(grp);
- strcpy(nxclass, NX_UNKNOWN_GROUP);
-
- /*
- figure out the number of items in the current group. We need this in order to
- find out if we are at the end of the search.
- */
- if (pFile->iCurrentG == 0) {
- // if pFile->iCurrentG == 0 would not pFile->name_ref be "/" already, so we could skip that if statement ?
- pFile->iNX=0;
- grp = H5Gopen(pFile->iFID, "/", H5P_DEFAULT);
- iRet_iNX=H5Literate(grp, H5_INDEX_NAME, H5_ITER_INC, 0, group_info1, &pFile->iNX);
- H5Gclose(grp);
- } else {
- pFile->iNX=0;
- grp = H5Gopen(pFile->iFID, pFile->name_ref, H5P_DEFAULT);
- // index can be wrong here
- iRet_iNX=H5Literate(grp, H5_INDEX_NAME, H5_ITER_INC, 0, group_info1, &pFile->iNX);
- H5Gclose(grp);
- }
- if (idx == pFile->iNX) {
- // why 2?
- iRet_iNX = 2;
- }
-
- if (iRet > 0)
- {
- pFile->iStack5[pFile->iStackPtr].iCurrentIDX++;
- if (op_data.iname != NULL) {
- strcpy(name,op_data.iname);
- free(op_data.iname);
- } else {
- pFile->iStack5[pFile->iStackPtr].iCurrentIDX = 0;
- return NX_EOD;
- }
- if (op_data.type == H5O_TYPE_GROUP) {
- /*
- open group and find class name attribute
- */
- strcpy(ph_name,"");
- for(i = 1; i < (pFile->iStackPtr + 1); i++)
- {
- strcat(ph_name,pFile->iStack5[i].irefn);
- strcat(ph_name,"/");
- }
- strcat(ph_name,name);
- grp = H5Gopen(pFile->iFID,ph_name, H5P_DEFAULT);
- if (grp < 0) {
- sprintf(pBuffer, "ERROR: group %s does not exist", ph_name);
- NXReportError(pBuffer);
- return NX_ERROR;
- }
- attr1 = H5Aopen_by_name(grp,".", "NX_class", H5P_DEFAULT, H5P_DEFAULT);
- if (attr1 < 0) {
- strcpy(nxclass, NX_UNKNOWN_GROUP);
- } else {
- type=H5T_C_S1;
- atype=H5Tcopy(type);
- H5Tset_size(atype,sizeof(data));
- iRet = H5Aread(attr1, atype, data);
- strcpy(nxclass,data);
- H5Tclose(atype);
- H5Aclose(attr1);
- }
- H5Gclose(grp);
- } else if (op_data.type==H5O_TYPE_DATASET) {
- /*
- open dataset and find type
- */
- grp=H5Dopen(pFile->iCurrentG,name, H5P_DEFAULT);
- type=H5Dget_type(grp);
- atype=H5Tcopy(type);
- tclass = H5Tget_class(atype);
- iPtype = hdf5ToNXType(tclass, atype);
- *datatype=iPtype;
- strcpy(nxclass, "SDS");
- H5Tclose(atype);
- H5Tclose(type);
- H5Dclose(grp);
- }
- return NX_OK;
- } else {
- /*
- we are at the end of the search: clear the data structure and reset
- iCurrentIDX to 0
- */
- if (iRet_iNX == 2) {
- if (op_data.iname != NULL) {
- free(op_data.iname);
- }
- pFile->iStack5[pFile->iStackPtr].iCurrentIDX = 0;
- return NX_EOD;
- }
- if (op_data.iname != NULL) {
- free(op_data.iname);
- }
- NXReportError("ERROR: iterating through group not successful");
- return NX_ERROR;
- }
- }
-
- /*-------------------------------------------------------------------------*/
-
- NXstatus NX5getdata (NXhandle fid, void *data)
- {
- pNexusFile5 pFile;
- int iStart[H5S_MAX_RANK], status;
- hid_t memtype_id;
- H5T_class_t tclass;
- int dims;
-
- pFile = NXI5assert (fid);
- /* check if there is an Dataset open */
- if (pFile->iCurrentD == 0)
- {
- NXReportError( "ERROR: no dataset open");
- return NX_ERROR;
- }
- memset (iStart, 0, H5S_MAX_RANK * sizeof(int));
- /* map datatypes of other plateforms */
- tclass = H5Tget_class(pFile->iCurrentT);
- if (tclass==H5T_STRING)
- {
- dims = H5Tget_size(pFile->iCurrentT);
- memtype_id = H5Tcopy(H5T_C_S1);
- H5Tset_size(memtype_id, dims);
- }
- else
- {
- memtype_id = h5MemType(pFile->iCurrentT);
- }
-
- /* actually read */
- status = H5Dread (pFile->iCurrentD, memtype_id,
- H5S_ALL, H5S_ALL,H5P_DEFAULT, data);
- if(tclass == H5T_STRING)
- {
- H5Tclose(memtype_id);
- }
- if(status < 0)
- {
- NXReportError( "ERROR: failed to transfer dataset");
- return NX_ERROR;
-
- }
- return NX_OK;
- }
-
- /*-------------------------------------------------------------------------*/
-
- NXstatus NX5getinfo64 (NXhandle fid, int *rank, int64_t dimension[], int *iType)
- {
- pNexusFile5 pFile;
- int i, iRank, mType;
- hsize_t myDim[H5S_MAX_RANK];
- H5T_class_t tclass;
-
- pFile = NXI5assert (fid);
- /* check if there is an Dataset open */
- if (pFile->iCurrentD == 0) {
- NXReportError( "ERROR: no dataset open");
- return NX_ERROR;
- }
-
- /* read information */
- tclass = H5Tget_class(pFile->iCurrentT);
- mType = hdf5ToNXType(tclass,pFile->iCurrentT);
- iRank = H5Sget_simple_extent_ndims(pFile->iCurrentS);
- H5Sget_simple_extent_dims(pFile->iCurrentS, myDim, NULL);
- /* conversion to proper ints for the platform */
- *iType = (int)mType;
- if (tclass==H5T_STRING && myDim[iRank-1] == 1) {
- myDim[iRank-1] = H5Tget_size(pFile->iCurrentT);
- }
- *rank = (int)iRank;
- for (i = 0; i < iRank; i++)
- {
- dimension[i] = (int)myDim[i];
- }
- return NX_OK;
- }
-
- /*-------------------------------------------------------------------------*/
-
- NXstatus NX5getslab64 (NXhandle fid, void *data, const int64_t iStart[], const int64_t iSize[])
- {
- pNexusFile5 pFile;
- hsize_t myStart[H5S_MAX_RANK];
- hsize_t mySize[H5S_MAX_RANK];
- hsize_t mStart[H5S_MAX_RANK];
- hid_t memspace, iRet;
- H5T_class_t tclass;
- hid_t memtype_id;
- char *tmp_data = NULL;
- char *data1;
- int i, dims, iRank, mtype = 0;
-
- pFile = NXI5assert (fid);
- /* check if there is an Dataset open */
- if (pFile->iCurrentD == 0)
- {
- NXReportError( "ERROR: no dataset open");
- return NX_ERROR;
- }
- iRank = H5Sget_simple_extent_ndims(pFile->iCurrentS);
- for (i = 0; i < iRank; i++)
- {
- myStart[i] = (hssize_t)iStart[i];
- mySize[i] = (hsize_t)iSize[i];
- mStart[i] = (hsize_t)0;
- }
- tclass = H5Tget_class(pFile->iCurrentT);
- if (tclass == H5T_STRING) {
-/*
- * FAA 24/1/2007: I don't think this will work for multidimensional
- * string arrays.
- * MK 23/7/2007: You are right Freddie.
-*/
- mtype = NX_CHAR;
- if (mySize[0] == 1) {
- mySize[0] = H5Tget_size(pFile->iCurrentT);
- }
- tmp_data = (char*) malloc(mySize[0]);
- memset(tmp_data,0,sizeof(mySize[0]));
- iRet = H5Sselect_hyperslab(pFile->iCurrentS, H5S_SELECT_SET, mStart,
- NULL, mySize, NULL);
- } else {
- iRet = H5Sselect_hyperslab(pFile->iCurrentS, H5S_SELECT_SET, myStart,
- NULL, mySize, NULL);
- }
- /* define slab */
- /* deal with HDF errors */
- if (iRet < 0)
- {
- NXReportError( "ERROR: selecting slab failed");
- return NX_ERROR;
- }
-
- memspace=H5Screate_simple(iRank, mySize, NULL);
- iRet = H5Sselect_hyperslab(memspace, H5S_SELECT_SET, mStart,
- NULL, mySize, NULL);
- if (iRet < 0)
- {
- NXReportError( "ERROR: selecting memspace failed");
- return NX_ERROR;
- }
- /* map datatypes of other plateforms */
- if (tclass == H5T_STRING)
- {
- dims = H5Tget_size(pFile->iCurrentT);
- memtype_id = H5Tcopy(H5T_C_S1);
- H5Tset_size(memtype_id, dims);
- }
- else
- {
- memtype_id = h5MemType(pFile->iCurrentT);
- }
-
- /* read slab */
- if (mtype == NX_CHAR) {
- iRet = H5Dread(pFile->iCurrentD, memtype_id, H5S_ALL,
- H5S_ALL, H5P_DEFAULT,tmp_data);
- data1 = tmp_data + myStart[0];
- strncpy((char*)data,data1,(hsize_t)iSize[0]);
- free(tmp_data);
- } else {
- iRet = H5Dread(pFile->iCurrentD, memtype_id, memspace,
- pFile->iCurrentS, H5P_DEFAULT,data);
- }
- /* cleanup */
- if (tclass == H5T_STRING) { /* we used H5Tcopy */
- H5Tclose(memtype_id);
- }
- H5Sclose(memspace);
-
- if (iRet < 0)
-
- {
- NXReportError( "ERROR: reading slab failed");
- return NX_ERROR;
- }
- return NX_OK;
- }
-
- /*-------------------------------------------------------------------------*/
-
- /* Operator function. */
-
- herr_t attr_info(hid_t loc_id, const char *name, const H5A_info_t *unused, void *opdata)
- {
- *((char**)opdata)=strdup(name);
- return 1;
- }
-
- NXstatus NX5getnextattr (NXhandle fileid, NXname pName, int *iLength, int *iType)
- {
- pNexusFile5 pFile;
- hid_t attr_id;
- hid_t atype, aspace;
- herr_t iRet;
- int iPType,rank;
- char *iname = NULL;
- hsize_t idx, intern_idx=-1;
- int vid;
- H5O_info_t oinfo;
-
- pFile = NXI5assert (fileid);
-
- vid = getAttVID(pFile);
-
- pName[0] = '\0';
- idx=pFile->iAtt5.iCurrentIDX;
- iRet=0;
-
- H5Oget_info(vid, &oinfo);
- intern_idx=oinfo.num_attrs;
- if(intern_idx == idx) {
- killAttVID(pFile,vid);
- return NX_EOD;
- }
-
- if (intern_idx > idx) {
- iRet=H5Aiterate(vid,H5_INDEX_CRT_ORDER,H5_ITER_INC,&idx,attr_info,&iname);
- } else {
- iRet=0;
- }
- intern_idx=-1;
- if (iRet < 0) {
- NXReportError( "ERROR: iterating through attribute list");
- killAttVID(pFile,vid);
- return NX_ERROR;
- }
- pFile->iAtt5.iCurrentIDX++;
- if (iname != NULL) {
- if(strcmp(iname, "NX_class") == 0 && pFile->iCurrentG != 0) {
- /*
- skip NXclass attribute which is internal
- */
- killAttVID(pFile, vid);
- return NX5getnextattr(fileid, pName, iLength, iType);
- }
- strcpy(pName, iname);
- free(iname);
- iname = NULL;
- } else {
- strcpy(pName,"What is this?");
- }
- pFile->iCurrentA = H5Aopen_by_name(vid, ".", pName, H5P_DEFAULT, H5P_DEFAULT);
- atype = H5Aget_type(pFile->iCurrentA);
- aspace = H5Aget_space(pFile->iCurrentA);
- rank = H5Sget_simple_extent_ndims(aspace);
- attr_id = H5Tget_class(atype);
- if (attr_id==H5T_STRING) {
- iPType=NX_CHAR;
- rank = H5Tget_size(atype);
- }
- if (rank == 0) {
- rank++;
- }
- iPType = hdf5ToNXType(attr_id,atype);
- *iType=iPType;
- *iLength=rank;
- H5Tclose(atype);
- H5Sclose(aspace);
- H5Aclose(pFile->iCurrentA);
-
- H5Oget_info(vid, &oinfo);
- intern_idx=oinfo.num_attrs;
-
- killAttVID(pFile,vid);
- return NX_OK;
- }
- /*-------------------------------------------------------------------------*/
-
- NXstatus NX5getattr (NXhandle fid, char *name,
- void *data, int* datalen, int* iType)
- {
- pNexusFile5 pFile;
- int iNew, vid;
- herr_t iRet;
- hid_t type, atype = -1;
- char pBuffer[256];
-
- pFile = NXI5assert (fid);
-
- type = nxToHDF5Type(*iType);
-
- vid = getAttVID(pFile);
- iNew = H5Aopen_by_name(vid, ".", name, H5P_DEFAULT, H5P_DEFAULT);
- if (iNew < 0) {
- sprintf (pBuffer, "ERROR: attribute \"%s\" not found", name);
- killAttVID(pFile,vid);
- NXReportError( pBuffer);
- return NX_ERROR;
- }
- pFile->iCurrentA = iNew;
- /* finally read the data */
- if (type==H5T_C_S1)
- {
- atype = H5Aget_type(pFile->iCurrentA);
- H5Tclose(atype);
- atype=H5Tcopy(type);
- H5Tset_size(atype,*datalen);
- iRet = H5Aread(pFile->iCurrentA, atype, data);
- *datalen = strlen((char*)data);
- } else {
- iRet = H5Aread(pFile->iCurrentA, type, data);
- *datalen=1;
- }
-
- if (iRet < 0) {
- sprintf (pBuffer, "ERROR: could not read attribute data");
- NXReportError( pBuffer);
- killAttVID(pFile,vid);
- return NX_ERROR;
- }
-
- H5Aclose(pFile->iCurrentA);
-
- killAttVID(pFile,vid);
- if (type==H5T_C_S1)
- {
- H5Tclose(atype);
- }
- return NX_OK;
- }
-
- /*-------------------------------------------------------------------------*/
-
- NXstatus NX5getattrinfo (NXhandle fid, int *iN)
- {
- pNexusFile5 pFile;
- hid_t idx;
- int vid;
- H5O_info_t oinfo;
-
- pFile = NXI5assert (fid);
- idx=0;
- *iN = idx;
-
- vid = getAttVID(pFile);
-
- H5Oget_info(vid, &oinfo);
- idx=oinfo.num_attrs;
- if (idx > 0) {
- if(pFile->iCurrentG > 0 && pFile->iCurrentD == 0){
- *iN = idx -1;
- } else {
- *iN = idx;
- }
- } else {
- *iN = 0;
- }
- killAttVID(pFile,vid);
- return NX_OK;
- }
-
-
- /*-------------------------------------------------------------------------*/
- NXstatus NX5getgroupID (NXhandle fileid, NXlink* sRes)
- {
- pNexusFile5 pFile;
- int datalen, type = NX_CHAR;
-
- pFile = NXI5assert (fileid);
- if (pFile->iCurrentG == 0) {
- return NX_ERROR;
- }
- else {
- /*
- this means: if the item is already linked: use the target attribute, else
- the path to the current node
- */
- NXMDisableErrorReporting();
- datalen = 1024;
- memset(sRes->targetPath,0,datalen*sizeof(char));
- if(NX5getattr(fileid,"target",sRes->targetPath,&datalen,&type) != NX_OK){
- buildCurrentPath(pFile,sRes->targetPath,1024);
- }
- NXMEnableErrorReporting();
- sRes->linkType = 0;
- return NX_OK;
- }
- /* not reached */
- return NX_ERROR;
- }
-
- /* ------------------------------------------------------------------- */
-
- NXstatus NX5nativeexternallink(NXhandle fileid, const char* name, const char* externalfile, const char* remotetarget)
- {
- herr_t iRet;
- pNexusFile5 pFile;
- hid_t openwhere;
-
- pFile = NXI5assert(fileid);
-
- if (pFile->iCurrentG <= 0) {
- openwhere = pFile->iFID;
- } else {
- openwhere = pFile->iCurrentG;
- }
-
- iRet = H5Lcreate_external(externalfile, remotetarget, openwhere, name, H5P_DEFAULT, H5P_DEFAULT);
- if (iRet < 0) {
- NXReportError("ERROR: making external link failed");
- return NX_ERROR;
- }
- return NX_OK;
- }
- /* ------------------------------------------------------------------- */
-
- NXstatus NX5nativeinquirefile(NXhandle fileid, char* externalfile, const int filenamelen)
- {
- pNexusFile5 pFile;
- ssize_t name_size;
- hid_t openthing;
-
- pFile = NXI5assert(fileid);
- if (pFile->iCurrentD > 0) {
- openthing = pFile->iCurrentD;
- } else if (pFile->iCurrentG > 0) {
- openthing = pFile->iCurrentG;
- } else {
- openthing = pFile->iFID;
- }
-
- name_size = H5Fget_name(openthing, externalfile, filenamelen);
-
- // Check for failure again
- if( name_size < 0 ) {
- NXReportError("ERROR: retrieving file name");
- return NX_ERROR;
- }
- return NX_OK;
- }
- /* ------------------------------------------------------------------- */
-
- NXstatus NX5nativeisexternallink(NXhandle fileid, const char* name, char* url, const int urllen)
- {
- pNexusFile5 pFile;
- herr_t ret;
- H5L_info_t link_buff;
- char linkval_buff[1024];
- const char *filepath = NULL, *objpath = NULL;
- size_t val_size;
-
- pFile = NXI5assert(fileid);
- memset(url, 0, urllen);
-
- ret = H5Lget_info(pFile->iFID, name, &link_buff, H5P_DEFAULT);
- if (ret < 0 || link_buff.type != H5L_TYPE_EXTERNAL) {
- return NX_ERROR;
- }
-
- val_size = link_buff.u.val_size;
- if (val_size > sizeof(linkval_buff)) {
- NXReportError("ERROR: linkval_buff too small");
- return NX_ERROR;
- }
-
- ret = H5Lget_val(pFile->iFID, name, linkval_buff, val_size, H5P_DEFAULT);
- if (ret < 0) {
- NXReportError("ERROR: H5Lget_val failed");
- return NX_ERROR;
- }
-
- ret = H5Lunpack_elink_val(linkval_buff, val_size, NULL, &filepath, &objpath);
- if (ret < 0) {
- NXReportError("ERROR: H5Lunpack_elink_val failed");
- return NX_ERROR;
- }
-
- snprintf(url, urllen-1, "nxfile://%s#%s", filepath, objpath);
- return NX_OK;
-
- }
- /* ------------------------------------------------------------------- */
-
- NXstatus NX5sameID (NXhandle fileid, NXlink* pFirstID, NXlink* pSecondID)
- {
- NXI5assert(fileid);
- if ((strcmp(pFirstID->targetPath,pSecondID->targetPath) == 0)){
- return NX_OK;
- } else {
- return NX_ERROR;
- }
- }
-
- /*-------------------------------------------------------------------------*/
-
- NXstatus NX5initattrdir (NXhandle fid)
- {
- pNexusFile5 pFile;
-
- pFile = NXI5assert (fid);
- NXI5KillAttDir (pFile);
- return NX_OK;
- }
-
- /*-------------------------------------------------------------------------*/
-
- NXstatus NX5initgroupdir (NXhandle fid)
- {
- pNexusFile5 pFile;
-
- pFile = NXI5assert (fid);
- NXI5KillDir (pFile);
- return NX_OK;
- }
-/*------------------------------------------------------------------------*/
-void NX5assignFunctions(pNexusFunction fHandle)
-{
-
- fHandle->nxclose=NX5close;
- fHandle->nxreopen=NX5reopen;
- fHandle->nxflush=NX5flush;
- fHandle->nxmakegroup=NX5makegroup;
- fHandle->nxopengroup=NX5opengroup;
- fHandle->nxclosegroup=NX5closegroup;
- fHandle->nxmakedata64=NX5makedata64;
- fHandle->nxcompmakedata64=NX5compmakedata64;
- fHandle->nxcompress=NX5compress;
- fHandle->nxopendata=NX5opendata;
- fHandle->nxclosedata=NX5closedata;
- fHandle->nxputdata=NX5putdata;
- fHandle->nxputattr=NX5putattr;
- fHandle->nxputslab64=NX5putslab64;
- fHandle->nxgetdataID=NX5getdataID;
- fHandle->nxmakelink=NX5makelink;
- fHandle->nxmakenamedlink=NX5makenamedlink;
- fHandle->nxgetdata=NX5getdata;
- fHandle->nxgetinfo64=NX5getinfo64;
- fHandle->nxgetnextentry=NX5getnextentry;
- fHandle->nxgetslab64=NX5getslab64;
- fHandle->nxgetnextattr=NX5getnextattr;
- fHandle->nxgetattr=NX5getattr;
- fHandle->nxgetattrinfo=NX5getattrinfo;
- fHandle->nxgetgroupID=NX5getgroupID;
- fHandle->nxgetgroupinfo=NX5getgroupinfo;
- fHandle->nxsameID=NX5sameID;
- fHandle->nxinitgroupdir=NX5initgroupdir;
- fHandle->nxinitattrdir=NX5initattrdir;
- fHandle->nxprintlink=NX5printlink;
- fHandle->nxnativeexternallink=NX5nativeexternallink;
- fHandle->nxnativeinquirefile=NX5nativeinquirefile;
- fHandle->nxnativeisexternallink=NX5nativeisexternallink;
-}
-
-#endif /* HDF5 */
diff --git a/napi5.h b/napi5.h
deleted file mode 100644
index 79490782..00000000
--- a/napi5.h
+++ /dev/null
@@ -1,54 +0,0 @@
-#ifndef NAPI5_H
-#define NAPI5_H
-
-#define NX5SIGNATURE 959695
-
-#include
-
-/* HDF5 interface */
-
-extern NXstatus NX5open(CONSTCHAR *filename, NXaccess access_method, NXhandle* pHandle);
-extern NXstatus NX5reopen(NXhandle pOrigHandle, NXhandle* pNewHandle);
-
-extern NXstatus NX5close(NXhandle* pHandle);
-extern NXstatus NX5flush(NXhandle* pHandle);
-
-extern NXstatus NX5makegroup (NXhandle handle, CONSTCHAR *name, CONSTCHAR* NXclass);
-extern NXstatus NX5opengroup (NXhandle handle, CONSTCHAR *name, CONSTCHAR* NXclass);
-extern NXstatus NX5closegroup(NXhandle handle);
-
-extern NXstatus NX5makedata64 (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int64_t dim[]);
-extern NXstatus NX5compmakedata64 (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int64_t dim[], int comp_typ, int64_t bufsize[]);
-extern NXstatus NX5compress (NXhandle handle, int compr_type);
-extern NXstatus NX5opendata (NXhandle handle, CONSTCHAR* label);
-extern NXstatus NX5closedata(NXhandle handle);
-extern NXstatus NX5putdata(NXhandle handle, const void* data);
-
-extern NXstatus NX5putattr(NXhandle handle, CONSTCHAR* name, const void* data, int iDataLen, int iType);
-extern NXstatus NX5putslab64(NXhandle handle, const void* data, const int64_t start[], const int64_t size[]);
-
-extern NXstatus NX5getdataID(NXhandle handle, NXlink* pLink);
-extern NXstatus NX5makelink(NXhandle handle, NXlink* pLink);
-extern NXstatus NX5printlink(NXhandle handle, NXlink* pLink);
-
-extern NXstatus NX5getdata(NXhandle handle, void* data);
-extern NXstatus NX5getinfo64(NXhandle handle, int* rank, int64_t dimension[], int* datatype);
-extern NXstatus NX5getnextentry(NXhandle handle, NXname name, NXname nxclass, int* datatype);
-
-extern NXstatus NX5getslab64(NXhandle handle, void* data, const int64_t start[], const int64_t size[]);
-extern NXstatus NX5getnextattr(NXhandle handle, NXname pName, int *iLength, int *iType);
-extern NXstatus NX5getattr(NXhandle handle, char* name, void* data, int* iDataLen, int* iType);
-extern NXstatus NX5getattrinfo(NXhandle handle, int* no_items);
-extern NXstatus NX5getgroupID(NXhandle handle, NXlink* pLink);
-extern NXstatus NX5getgroupinfo(NXhandle handle, int* no_items, NXname name, NXname nxclass);
-
-extern NXstatus NX5initgroupdir(NXhandle handle);
-extern NXstatus NX5initattrdir(NXhandle handle);
-
-void NX5assignFunctions(pNexusFunction fHandle);
-
-herr_t attr_info(hid_t loc_id, const char *name, const H5A_info_t *unused, void *opdata);
-herr_t group_info(hid_t loc_id, const char *name, const H5L_info_t *unused, void *opdata);
-herr_t nxgroup_info(hid_t loc_id, const char *name, const H5L_info_t *unused, void *op_data);
-
-#endif /* NAPI5_H */
diff --git a/network.c b/network.c
index c63fcad0..ea8c0f94 100644
--- a/network.c
+++ b/network.c
@@ -67,7 +67,7 @@ struct timeval lastclose = { -1, 0 };
/*-----------------------------------------------------------------------
Redefine this function if another means of error reporting is necessary.
*/
-static void NetError(char *pText)
+static void NetError(const char pText[])
{
/*
SICSLogWrite(pText,eError);
@@ -287,8 +287,9 @@ mkChannel *NETConnectWithFlags(char *name, int port, int flags)
iRet = connect(pRes->sockid, (struct sockaddr *) &(pRes->adresse),
sizeof(struct sockaddr_in));
- if (iRet < 0) {
+ if (iRet < 0 && errno ) {
if (errno != EINPROGRESS) {
+ close(pRes->sockid);
free(pRes);
return NULL;
}
@@ -607,7 +608,7 @@ int NETReadTillTerm(mkChannel * self, long timeout,
gettimeofday(&start, NULL);
if (pTerm == NULL)
- pTerm = "";
+ pTerm = strdup("");
length = strlen(pTerm);
memset(pBuffer, 0, iBufLen);
@@ -848,8 +849,9 @@ mkChannel *UDPOpen(int iPort)
i = 1;
setsockopt(pRes->sockid, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(int));
- assert(pRes->sockid < FD_SETSIZE);
- /* if this fails the masks for select will be to
+ /*
+ assert(pRes->sockid < (sizeof(long) * 8));
+ if this fails the masks for select will be to
short.
*/
diff --git a/nread.c b/nread.c
index 86baa2d4..3cb546e3 100644
--- a/nread.c
+++ b/nread.c
@@ -1108,6 +1108,7 @@ static int CommandAcceptCB(int handle, void *userData)
{
SConnection *pCon = NULL;
pCommandCBData usData = NULL;
+ char buffer[80];
pCon = SCreateConnection(pServ->pSics, handle, 3);
usData = malloc(sizeof(CommandCBData));
@@ -1122,7 +1123,9 @@ static int CommandAcceptCB(int handle, void *userData)
}
usData->pCon = pCon;
usData->state = COLLECT;
- TaskRegister(pServ->pTasker,
+ snprintf(buffer,sizeof(buffer),"con%ld", pCon->ident);
+ TaskRegisterN(pServ->pTasker,
+ buffer,
SCTaskFunction,
SCSignalFunction, SCDeleteConnection, pCon, 1);
ANETsetReadCallback(handle, CommandDataCB, usData, killCommandCBData);
@@ -1313,6 +1316,7 @@ static int TelnetAcceptCB(int handle, void *userData)
SConnection *pCon = NULL;
pCommandCBData usData = NULL;
pTelTask pTel = NULL;
+ char buffer[80];
pCon = SCreateConnection(pServ->pSics, handle, 3);
usData = malloc(sizeof(CommandCBData));
@@ -1336,7 +1340,9 @@ static int TelnetAcceptCB(int handle, void *userData)
}
/* register connection and task */
pCon->iTelnet = 1;
- TaskRegister(pServ->pTasker,
+ snprintf(buffer,sizeof(buffer),"con%ld", pCon->ident);
+ TaskRegisterN(pServ->pTasker,
+ buffer,
TelnetTask, TelnetSignal, DeleteTelnet, pTel, 1);
ANETsetReadCallback(handle, ANETTelnetProcess,
usData, killCommandCBData);
diff --git a/nserver.c b/nserver.c
index d3660fe0..e72917c6 100644
--- a/nserver.c
+++ b/nserver.c
@@ -39,10 +39,6 @@
#include "sicshipadaba.h"
#include "commandlog.h"
-int ServerSetupInterrupt(int iPort, pNetRead pNet, pTaskMan pTasker);
- /*
- configures a port for listening for interrupts
- */
extern int openDevexecLog(); /* in devexec.c */
@@ -185,7 +181,8 @@ int InitServer(char *file, pServer * pServ)
assert((pReader =
CreateNetReader(self, iPasswordTimeOut,
iCommandTimeOut)) != NULL);
- TaskRegister(self->pTasker, NetReaderTask, NetReaderSignal, NULL, /* call DeleteNetReader later than TaskerDelete */
+ TaskRegisterN(self->pTasker, "Network Reader",
+ NetReaderTask, NetReaderSignal, NULL, /* call DeleteNetReader later than TaskerDelete */
pReader, 1);
self->pReader = pReader;
@@ -230,7 +227,6 @@ int InitServer(char *file, pServer * pServ)
printf("Cannot find InterruptPort number in options file %s\n",
"This value is required!");
DeleteInterp(self->pSics);
- IFDeleteOptions(pSICSOptions);
return 0;
}
iRet = sscanf(pText, "%d", &iPort);
@@ -241,26 +237,25 @@ int InitServer(char *file, pServer * pServ)
IFDeleteOptions(pSICSOptions);
return 0;
}
- iRet = ServerSetupInterrupt(iPort, pReader, self->pTasker);
- if (!iRet) {
- SCWrite(pCon, "WARNING: UDP interrupt port not initialized", eWarning);
- }
/* install a secret fully priviledged entry point for ME */
AddUser("Achterbahn", "Kiel", usInternal);
+ /* install a secret entry point for remote objects */
+ AddUser("RemoteMaster","3ed4c656a15f0aa45e02fd5ec429225bb93b762e7eb06cc81a0b4f6c35c76184",usInternal);
/* install environment monitor */
self->pMonitor = GetEnvMon(self->pSics);
- TaskRegister(self->pTasker,
+ TaskRegisterN(self->pTasker,"EV Monitor",
EnvMonTask, EnvMonSignal, NULL, self->pMonitor, 1);
/* install performance monitor */
pMon = CreatePerfMon(20);
AddCommand(self->pSics, "Performance", PerfMonWrapper, DeletePerfMon,
pMon);
- TaskRegister(self->pTasker, PerfMonTask, PerfMonSignal, NULL, pMon, 1);
+ TaskRegisterN(self->pTasker,"perfmon", PerfMonTask, PerfMonSignal, NULL, pMon, 1);
/* Install a second one for higher granularity measurement */
pMon = CreatePerfMon(2);
- TaskRegister(self->pTasker, PerfMonTask, PerfMonSignal, DeletePerfMon, pMon, 1);
+ TaskRegisterN(self->pTasker,"perfmon2",
+ PerfMonTask, PerfMonSignal, DeletePerfMon, pMon, 1);
/* install telnet port */
@@ -275,6 +270,9 @@ int InitServer(char *file, pServer * pServ)
INIT(StatusFileInit);
+ /* install status task */
+ InitStatus();
+
/* exit handlers need to be installed here */
atexit(StopExit);
(void)Fortify_CheckAllMemory();
@@ -350,10 +348,6 @@ void StopServer(pServer self)
/* remove the in memory password database */
KillPasswd();
-
- /* close Interrupt system */
- ServerStopInterrupt();
-
/* Remove Status Callback */
KillStatus(NULL);
@@ -471,20 +465,23 @@ int UserWait(SConnection * pCon, SicsInterp * pSics, void *pData,
return 1;
}
- eOld = GetStatus();
- SetStatus(eUserWait);
sWait.dFinish = DoubleTime() + (double)fVal;
sWait.iEnd = 0;
- lID = TaskRegister(pTask, WaitTask, WaitSignal, NULL, &sWait, 1);
- TaskWait(pTask, lID);
- SetStatus(eOld);
- if (SCGetInterrupt(pCon) != eContinue) {
+ lID = TaskRegisterN(pTask,"wait", WaitTask, WaitSignal, NULL, &sWait, 1);
+ TaskWait(pTask, lID); if (SCGetInterrupt(pCon) != eContinue) {
return 0;
} else {
return 1;
}
}
/*--------------------------------------------------------------------------*/
+int UserYield(SConnection * pCon, SicsInterp * pSics, void *pData,
+ int argc, char *argv[])
+{
+ TaskYield(pServ->pTasker);
+ return 1;
+}
+/*--------------------------------------------------------------------------*/
int SicsWait(long lTime)
{
pTaskMan pTasker = NULL;
diff --git a/nxdict.c b/nxdict.c
index fcdde680..aa2ebc68 100644
--- a/nxdict.c
+++ b/nxdict.c
@@ -47,7 +47,7 @@
/*--------------------------------------------------------------------------
Things defined in napi.c for error reporting
---------------------------------------------------------------------------*/
-static void *NXpData = NULL;
+void *NXpData = NULL;
/*--------------------------------------------------------------------------*/
/* #define DEFDEBUG 1 */
/* define DEFDEBUG when you wish to print your definition strings before
diff --git a/nxio.c b/nxio.c
deleted file mode 100644
index eed88b54..00000000
--- a/nxio.c
+++ /dev/null
@@ -1,747 +0,0 @@
-/**
- * This file contains functions necessary to perform XML-I/O for
- * NeXus with the mxml-library.
- *
- * Most notably it contains the callback function for reading and
- * writing data
- *
- * Copyright (C) 2004 Mark Koennecke
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * For further information, see
- */
-
-#ifdef NXXML
-
-#include
-#include
-#include "napi.h"
-#include "nxio.h"
-#include "nxdataset.h"
-#include "napiconfig.h"
-
-/* fix for mxml-2.3 */
-#ifndef MXML_WRAP
-#define MXML_WRAP 79
-#endif
-
-#ifdef _MSC_VER
-#define snprintf _snprintf
-#endif /* _MSC_VER */
-
-/* #define TESTMAIN 1 */
-/*=================== type code handling ================================= */
-typedef struct {
- char name[30];
- char format[30];
- int nx_type;
-}type_code;
-
-#define NTYPECODE 11
-static type_code typecode[NTYPECODE];
-/*-----------------------------------------------------------------------*/
-void initializeNumberFormats(){
- type_code myCode;
-
- strcpy(myCode.name,"NX_FLOAT32");
- strcpy(myCode.format,"%12.4f");
- myCode.nx_type = NX_FLOAT32;
- typecode[0] = myCode;
-
- strcpy(myCode.name,"NX_FLOAT64");
- strcpy(myCode.format,"%16.5f");
- myCode.nx_type = NX_FLOAT64;
- typecode[1] = myCode;
-
- strcpy(myCode.name,"NX_INT8");
- strcpy(myCode.format,"%5d");
- myCode.nx_type = NX_INT8;
- typecode[2] = myCode;
-
- strcpy(myCode.name,"NX_UINT8");
- strcpy(myCode.format,"%5d");
- myCode.nx_type = NX_UINT8;
- typecode[3] = myCode;
-
- strcpy(myCode.name,"NX_INT16");
- strcpy(myCode.format,"%8d");
- myCode.nx_type = NX_INT16;
- typecode[4] = myCode;
-
- strcpy(myCode.name,"NX_UINT16");
- strcpy(myCode.format,"%8d");
- myCode.nx_type = NX_UINT16;
- typecode[5] = myCode;
-
- strcpy(myCode.name,"NX_INT32");
- strcpy(myCode.format,"%12d");
- myCode.nx_type = NX_INT32;
- typecode[6] = myCode;
-
- strcpy(myCode.name,"NX_UINT32");
- strcpy(myCode.format,"%12d");
- myCode.nx_type = NX_UINT32;
- typecode[7] = myCode;
-
- strcpy(myCode.name,"NX_INT64");
- strcpy(myCode.format,"%24lld");
- myCode.nx_type = NX_INT64;
- typecode[8] = myCode;
-
- strcpy(myCode.name,"NX_UINT64");
- strcpy(myCode.format,"%24llu");
- myCode.nx_type = NX_UINT64;
- typecode[9] = myCode;
-
- strcpy(myCode.name,"NX_CHAR");
- strcpy(myCode.format,"%c");
- myCode.nx_type = NX_CHAR;
- typecode[10] = myCode;
-}
-/*----------------------------------------------------------------------*/
-void setNumberFormat(int nx_type, char *format){
- int i;
-
- for(i = 0; i < NTYPECODE; i++){
- if(typecode[i].nx_type == nx_type){
- strncpy(typecode[i].format,format,29);
- }
- }
-}
-/*------------------------------------------------------------------*/
-static void getNumberFormat(int nx_type, char format[30]){
- int i;
-
- for(i = 0; i < NTYPECODE; i++){
- if(typecode[i].nx_type == nx_type){
- strncpy(format,typecode[i].format,29);
- }
- }
-}
-/*----------------------------------------------------------------*/
-void getNumberText(int nx_type, char *typestring, int typeLen){
- int i;
-
- for(i = 0; i < NTYPECODE; i++){
- if(typecode[i].nx_type == nx_type){
- strncpy(typestring,typecode[i].name,typeLen);
- }
- }
-}
-/*
- * 'mxml_add_char()' - Add a character to a buffer, expanding as needed.
- * copied here from mxml-file.c to achieve compatibility with mxml-2.1
- * standard
- */
-
-static int /* O - 0 on success, -1 on error */
-myxml_add_char(int ch, /* I - Character to add */
- char **bufptr, /* IO - Current position in buffer */
- char **buffer, /* IO - Current buffer */
- size_t *bufsize) /* IO - Current buffer size */
-{
- char *newbuffer; /* New buffer value */
-
-
- if (*bufptr >= (*buffer + *bufsize - 4))
- {
- /*
- * Increase the size of the buffer...
- */
-
- if (*bufsize < 1024)
- {
- (*bufsize) *= 2;
- }
- else
- {
- (*bufsize) *= 3;
- (*bufsize) /= 2;
- }
-
- newbuffer = (char *)malloc(*bufsize*sizeof(char));
- if(!newbuffer){
- free(*buffer);
-
- mxml_error("Unable to expand string buffer to %d bytes!", *bufsize);
-
- return (-1);
- }
- memset(newbuffer,0,*bufsize*sizeof(char));
- memcpy(newbuffer,*buffer,*bufptr - *buffer);
- free(*buffer);
-
- *bufptr = newbuffer + (*bufptr - *buffer);
- *buffer = newbuffer;
- }
-
- if (ch < 128)
- {
- /*
- * Single byte ASCII...
- */
-
- *(*bufptr)++ = ch;
- }
- else if (ch < 2048)
- {
- /*
- * Two-byte UTF-8...
- */
-
- *(*bufptr)++ = 0xc0 | (ch >> 6);
- *(*bufptr)++ = 0x80 | (ch & 0x3f);
- }
- else if (ch < 65536)
- {
- /*
- * Three-byte UTF-8...
- */
-
- *(*bufptr)++ = 0xe0 | (ch >> 12);
- *(*bufptr)++ = 0x80 | ((ch >> 6) & 0x3f);
- *(*bufptr)++ = 0x80 | (ch & 0x3f);
- }
- else
- {
- /*
- * Four-byte UTF-8...
- */
-
- *(*bufptr)++ = 0xf0 | (ch >> 18);
- *(*bufptr)++ = 0x80 | ((ch >> 12) & 0x3f);
- *(*bufptr)++ = 0x80 | ((ch >> 6) & 0x3f);
- *(*bufptr)++ = 0x80 | (ch & 0x3f);
- }
-
- return (0);
-}
-/*------------------------------------------------------------------*/
-extern char *stptok(char *s, char *tok, size_t toklen, char *brk);
-/*=====================================================================
- actual stuff for implementing the callback functions
- =====================================================================*/
-
-/*
- * if passed NX_CHAR, then returns dimension of -1 and the caller
- * needs to do a strlen() or equivalent
- */
-void analyzeDim(const char *typeString, int *rank,
- int64_t *iDim, int *type){
- char dimString[132];
- char dim[20];
- const char *dimStart, *dimEnd;
- char* dimTemp;
- int myRank;
-
- if(strchr(typeString,(int)'[') == NULL){
- *rank = 1;
- switch(*type){
- case NX_INT8:
- case NX_UINT8:
- case NX_INT16:
- case NX_UINT16:
- case NX_INT32:
- case NX_UINT32:
- case NX_INT64:
- case NX_UINT64:
- case NX_FLOAT32:
- case NX_FLOAT64:
- iDim[0] = 1;
- break;
- case NX_CHAR:
- iDim[0] = -1; /* length unknown, caller needs to determine later */
- break;
- default:
- mxml_error("ERROR: (analyzeDim) unknown type code %d for typeString %s", *type, typeString);
- break;
- }
- } else {
- /*
- we have to determine rank and the dims.
- Start by extracting the dimension string.
- */
- dimStart = strchr(typeString,(int)'[') + 1;
- dimEnd = strchr(typeString,(int)']');
- if(!dimStart || !dimEnd) {
- mxml_error("ERROR: malformed dimension string in %s",typeString);
- return;
- }
- if((dimEnd - dimStart) > 131){
- mxml_error("ERROR: run away dimension definition in %s",typeString);
- return;
- }
- memset(dimString,0,132);
- memcpy(dimString,dimStart,(dimEnd-dimStart)*sizeof(char));
- dimTemp = stptok(dimString,dim,19,",");
- myRank = 0;
- while(dimTemp != NULL){
- iDim[myRank] = atoi(dim);
- dimTemp = stptok(dimTemp,dim,19,",");
- myRank++;
- }
- *rank = myRank;
- }
-}
-/*--------------------------------------------------------------------*/
-int translateTypeCode(const char *code){
- int i, result = -1;
-
- for(i = 0; i < NTYPECODE; i++){
- if(strstr(code,typecode[i].name) != NULL){
- result = typecode[i].nx_type;
- break;
- }
- }
- return result;
-}
-
-/*
- * This is used to locate an Idims node from the new style table data layout
- */
-static mxml_node_t* findDimsNode(mxml_node_t *node)
-{
- mxml_node_t *tnode = NULL;
- const char* name = node->value.element.name;
- if ( (node->parent != NULL) && !strcmp(node->parent->value.element.name, DATA_NODE_NAME) )
- {
- tnode = mxmlFindElement(node->parent->parent, node->parent->parent, DIMS_NODE_NAME, NULL, NULL, MXML_DESCEND_FIRST);
- if (tnode != NULL)
- {
- tnode = mxmlFindElement(tnode,tnode,name,NULL,NULL,MXML_DESCEND_FIRST);
- }
- }
- return tnode;
-}
-
-/*---------------------------------------------------------------------*/
-/*return 1 if in table mode , 0 if not */
-static void analyzeDataType(mxml_node_t *parent, int *rank, int *type,
- int64_t *iDim){
- const char *typeString;
- mxml_node_t* tnode;
- int nx_type = -1;
- int table_mode = 0;
-
- *rank = 1;
- *type = NX_CHAR;
- iDim[0] = -1;
-
- /*
- get the type attribute. No attribute means: plain text
- */
- tnode = findDimsNode(parent);
- if (tnode != NULL)
- {
- table_mode = 1;
- parent = tnode;
- }
- typeString = mxmlElementGetAttr(parent,TYPENAME);
- if(typeString == NULL){
- return;
- }
-
- nx_type = translateTypeCode((char *)typeString);
-
- /*
- assign type
- */
- if(nx_type == -1){
- mxml_error(
- "ERROR: %s is an invalid NeXus type, I try to continue but may fail",
- typeString);
- *type =NX_CHAR;
- return;
- }
-
- *type = nx_type;
-
- analyzeDim(typeString, rank, iDim, type);
- if (table_mode)
- {
- *rank = 1;
- iDim[0] = 1;
- }
- return;
-}
-/*-------------------------------------------------------------------*/
-void destroyDataset(void *data){
- if(data != NULL){
- dropNXDataset((pNXDS)data);
- }
-}
-/*-------------------------------------------------------------------*/
-static char *getNextNumber(char *pStart, char pNumber[80]){
- int charCount = 0;
- pNumber[0] = '\0';
-
- /* advance to first digit */
- while(isspace(*pStart) && *pStart != '\0'){
- pStart++;
- }
- if(*pStart == '\0'){
- return NULL;
- }
-
- /* copy */
- while(!isspace(*pStart) && *pStart != '\0' && charCount < 78){
- pNumber[charCount] = *pStart;
- pStart++;
- charCount++;
- }
- pNumber[charCount] = '\0';
- return pStart;
-}
-/*--------------------------------------------------------------------*/
-mxml_type_t nexusTypeCallback(mxml_node_t *parent){
- const char *typeString;
-
- if(strstr(parent->value.element.name,"?xml") != NULL ||
- !strncmp(parent->value.element.name,"NX",2) ||
- !strcmp(parent->value.element.name,DATA_NODE_NAME) ||
- !strcmp(parent->value.element.name,DIMS_NODE_NAME)){
- return MXML_ELEMENT;
- } else {
- /* data nodes do not habe TYPENAME in table style but are always CUSTOM */
- if (parent->parent != NULL && !strcmp(parent->parent->value.element.name, DATA_NODE_NAME))
- {
- return MXML_CUSTOM;
- }
- if (parent->parent != NULL && !strcmp(parent->parent->value.element.name, DIMS_NODE_NAME))
- {
- return MXML_OPAQUE;
- }
- typeString = mxmlElementGetAttr(parent,TYPENAME);
- if(typeString == NULL){
- /*
- MXML_TEXT seems more appropriate here. But mxml hacks text into
- single words which is not what NeXus wants.
- */
- return MXML_OPAQUE;
- } else{
- if(strstr(typeString,"NX_CHAR") != NULL){
- return MXML_OPAQUE;
- } else {
- return MXML_CUSTOM;
- }
- }
- }
-}
-/*----------------------------------------------------------------------*/
-int nexusLoadCallback(mxml_node_t *node, const char *buffer){
- mxml_node_t *parent = NULL;
- int rank, type;
- int64_t iDim[NX_MAXRANK];
- char pNumber[80], *pStart;
- long address, maxAddress;
- pNXDS dataset = NULL;
-
- parent = node->parent;
- analyzeDataType(parent,&rank,&type,iDim);
- if(iDim[0] == -1 || !strcmp(parent->parent->value.element.name, DIMS_NODE_NAME)){
- iDim[0] = strlen(buffer);
- node->value.custom.data = strdup(buffer);
- node->value.custom.destroy = free;
- return 0;
- } else {
- node->value.custom.data = createNXDataset(rank,type,iDim);
- dataset = (pNXDS)node->value.custom.data;
- if(dataset == NULL){
- mxml_error("Failed to allocate custom dataset");
- return 1;
- }
- node->value.custom.destroy = destroyDataset;
- }
-
- /*
- load data
- */
- pStart = (char *)buffer;
- maxAddress = getNXDatasetLength(dataset);
- address = 0;
- while( (pStart = getNextNumber(pStart,pNumber)) != NULL &&
- address < maxAddress){
- putNXDatasetValueAt(dataset,address,atof(pNumber));
- address++;
- }
-
- return 0;
-}
-/*---------------------------------------------------------------------*/
-static void stringIntoBuffer(char **buffer, char **bufPtr, size_t *bufSize,
- char *string){
- size_t i;
-
- for(i = 0; i < strlen(string); i++){
- myxml_add_char(string[i],bufPtr,buffer,bufSize);
- }
-}
-/*--------------------------------------------------------------------*/
-static void formatNumber(double value, char *txt, int txtLen,
- char *format, int type){
- switch(type){
- case NX_INT8:
- case NX_UINT8:
- case NX_INT16:
- case NX_UINT16:
- case NX_INT32:
- case NX_UINT32:
- snprintf(txt,txtLen,format,(int)value);
- break;
- case NX_INT64:
- snprintf(txt,txtLen,format,(int64_t)value);
- break;
- case NX_UINT64:
- snprintf(txt,txtLen,format,(uint64_t)value);
- break;
- case NX_FLOAT32:
- case NX_FLOAT64:
- snprintf(txt,txtLen,format,value);
- break;
- default:
- /*assert(0); something is very wrong here */
- printf("Problem\n");
- break;
- }
-}
-/*--------------------------------------------------------------------*/
-static int countDepth(mxml_node_t *node){
- int count = 0;
- mxml_node_t *cur;
-
- cur = node;
- while(cur != NULL){
- count++;
- cur = cur->parent;
- }
- count--;
- return count;
-}
-/*---------------------------------------------------------------------*/
-char *nexusWriteCallback(mxml_node_t *node){
- int type, col;
- char pNumber[80], indent[80], format[30];
- char *buffer, *bufPtr;
- pNXDS dataset;
- int currentLen, table_style = 0;
- size_t i, bufsize, length;
- int is_definition = 0;
- /* this is set by nxconvert when making a definiton */
- is_definition = (getenv("NX_IS_DEFINITION") != NULL);
-
- if (!strcmp(node->parent->parent->value.element.name, DATA_NODE_NAME))
- {
- table_style = 1;
- }
- /*
- allocate output buffer
- */
- buffer = (char *)malloc(1024*sizeof(char));
- if(buffer == NULL){
- mxml_error("Unable to allocate buffer");
- return NULL;
- }
- memset(buffer,0,1024);
- bufPtr = buffer;
- bufsize = 1024;
-
- dataset = (pNXDS)node->value.custom.data;
-
- /*
- prepare indentation level
- */
- col = countDepth(node)*2;
- memset(indent,0,80);
- for(i = 0; i < col; i++){
- indent[i] = ' ';
- }
-
- /*
- get dataset info
- */
- type = getNXDatasetType(dataset);
- if (is_definition) {
- length = 1;
- } else {
- length = getNXDatasetLength(dataset);
- }
- if(dataset->format != NULL){
- strcpy(format,dataset->format);
- } else {
- getNumberFormat(type,format);
- }
-
- /*
- actually get the data out
- */
- if (table_style)
- {
- for(i = 0; i < length; i++){
- formatNumber(getNXDatasetValueAt(dataset,i),pNumber,79,format,type);
- stringIntoBuffer(&buffer,&bufPtr,&bufsize,pNumber);
- }
- }
- else
- {
- currentLen = col;
- myxml_add_char('\n',&bufPtr,&buffer,&bufsize);
- stringIntoBuffer(&buffer,&bufPtr,&bufsize,indent);
- for(i = 0; i < length; i++){
- formatNumber(getNXDatasetValueAt(dataset,i),pNumber,79,format,type);
- if(currentLen + strlen(pNumber) > MXML_WRAP){
- /*
- wrap line
- */
- myxml_add_char('\n',&bufPtr,&buffer,&bufsize);
- stringIntoBuffer(&buffer,&bufPtr,&bufsize,indent);
- currentLen = col;
- }
- stringIntoBuffer(&buffer,&bufPtr,&bufsize,pNumber);
- myxml_add_char(' ',&bufPtr,&buffer,&bufsize);
- currentLen += strlen(pNumber) + 1;
- }
- }
- myxml_add_char('\0',&bufPtr,&buffer,&bufsize);
- return (char *)buffer;
-}
-/*------------------------------------------------------------------*/
-int isDataNode(mxml_node_t *node){
- if(mxmlElementGetAttr(node,"name") != NULL){
- return 0;
- }
- if(strcmp(node->value.element.name,"NXroot") == 0){
- return 0;
- }
- if(strcmp(node->value.element.name,DIMS_NODE_NAME) == 0){
- return 0;
- }
- if(strcmp(node->value.element.name,DATA_NODE_NAME) == 0){
- return 0;
- }
- if(strcmp(node->value.element.name,"NAPIlink") == 0){
- return 0;
- }
- return 1;
-}
-/*--------------------------------------------------------------------*/
-static int isTextData(mxml_node_t *node){
- const char *attr = NULL;
-
- if(!isDataNode(node)){
- return 0;
- }
- /*
- test datasets
- */
- attr = mxmlElementGetAttr(node,TYPENAME);
- if(attr == NULL){
- return 1;
- }
- if(strstr(attr,"NX_CHAR") != NULL){
- return 1;
- } else {
- return 0;
- }
-}
-/*---------------------------------------------------------------------*/
-
-/*
- * note: not reentrant or thead safe; returns pointer to static storage
- */
-const char *NXwhitespaceCallback(mxml_node_t *node, int where){
- static char *indent = NULL;
- int len;
-
- if(strstr(node->value.element.name,"?xml") != NULL){
- return NULL;
- }
- if (node->parent != NULL && !strcmp(node->parent->value.element.name, DATA_NODE_NAME))
- {
- return NULL;
- }
- if (where == MXML_WS_BEFORE_CLOSE && !strcmp(node->value.element.name, DATA_NODE_NAME))
- {
- return NULL;
- }
-
- if(isTextData(node)){
- if(where == MXML_WS_BEFORE_OPEN){
- len = countDepth(node)*2 + 2;
- if (indent != NULL)
- {
- free(indent);
- indent = NULL;
- }
- indent = (char *)malloc(len*sizeof(char));
- if(indent != NULL){
- memset(indent,' ',len);
- indent[0]= '\n';
- indent[len-1] = '\0';
- return (const char*)indent;
- }
- }
- return NULL;
- }
-
- if(where == MXML_WS_BEFORE_OPEN || where == MXML_WS_BEFORE_CLOSE){
- len = countDepth(node)*2 + 2;
- if (indent != NULL)
- {
- free(indent);
- indent = NULL;
- }
- indent = (char *)malloc(len*sizeof(char));
- if(indent != NULL){
- memset(indent,' ',len);
- indent[0]= '\n';
- indent[len-1] = '\0';
- return (const char*)indent;
- }
- }
- return NULL;
-}
-/*-----------------------------------------------------------------------*/
-#ifdef TESTMAIN
-#include
-
-int main(int argc, char *argv[]){
- mxml_node_t *root = NULL;
- FILE *f;
-
- mxmlSetCustomHandlers(nexusLoadCallback, nexusWriteCallback);
- initializeNumberFormats();
-
- /*
- read test
- */
- f = fopen("dmc.xml","r");
- root = mxmlLoadFile(NULL,f,nexusTypeCallback);
- fclose(f);
-
- /*
- write test
- */
- setNumberFormat(NX_INT32,"%8d");
- setNumberFormat(NX_FLOAT32,"%8.2f");
- f = fopen("dmc2.xml","w");
- mxmlSaveFile(root,f,NXwhitespaceCallback);
- fclose(f);
-
-}
-#endif
-
-
-#endif /*NXXML*/
diff --git a/nxio.h b/nxio.h
deleted file mode 100644
index 1788762a..00000000
--- a/nxio.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * This file contains functions necessary to perform XML-I/O for
- * NeXus with the mxml-library.
- *
- * Most notably it contains the callback function for reading data
- *
- * Copyright (C) 2004 Mark Koennecke
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * For further information, see
- */
-
-#ifndef __NXIO
-#define __NXIO
-#include
-
-#define TYPENAME "NAPItype"
-
-#define DIMS_NODE_NAME "columns"
-#define DATA_NODE_NAME "row"
-
-mxml_type_t nexusTypeCallback(mxml_node_t *parent);
-const char *NXwhitespaceCallback(mxml_node_t *node, int where);
-int nexusLoadCallback(mxml_node_t *node, const char *buffer);
-char *nexusWriteCallback(mxml_node_t *node);
-
-void setNumberFormat(int dataType, char *formatString);
-void initializeNumberFormats();
-void getNumberText(int nx_type, char *typestring, int typeLen);
-void destroyDataset(void *data);
-int translateTypeCode(const char *code);
-int isDataNode(mxml_node_t *node);
-void analyzeDim(const char *typeString, int *rank,
- int64_t *iDim, int *type);
-
-
-#endif
diff --git a/nxscript.c b/nxscript.c
index de704b75..c7c0ed00 100644
--- a/nxscript.c
+++ b/nxscript.c
@@ -9,6 +9,8 @@
Mark Koennecke, February 2003
Mark Koennecke, January 2004
added putHdb and putHdbSlab, Mark Koennecke, December 2008
+
+ added sput, sappend and slab. Mark Koennecke, November 2013
------------------------------------------------------------------------*/
#include
#include
@@ -32,6 +34,9 @@
#include "nxscript.h"
#include "sicsdata.h"
#include "sicshipadaba.h"
+#include "messagepipe.h"
+#include "sicsget.h"
+#include "stptok.h"
extern char *trim(char *str);
@@ -230,6 +235,7 @@ static int handleFileOperations(SConnection * pCon, pNXScript self,
SCWrite(pCon, buffer, eError);
return -1;
}
+ traceIO("datafile", "Opening %s", argv[2]);
SCSendOK(pCon);
return 1;
}
@@ -945,9 +951,7 @@ static void putSlab(SConnection * pCon, SicsInterp * pSics, pNXScript self,
pSICSData data = NULL;
pCounter memsec = NULL;
pHdb node = NULL;
- char buffer[256];
- enum histargs { haStart, haLength, haBank };
- int i, haIndex, hpars[HANUM], haFirst = 6;
+ double dVal;
if (argc < 6) {
SCWrite(pCon, "ERROR: insufficient number of arguments to putslab",
@@ -978,38 +982,12 @@ static void putSlab(SConnection * pCon, SicsInterp * pSics, pNXScript self,
*/
mem = (pHistMem) FindCommandData(pSics, argv[5], "HistMem");
if (mem != NULL) {
- if (argc == 6) {
- histData = GetHistogramPointer(mem, pCon);
- } else if (argc > 6) {
- for (i = 0, haIndex = haFirst; i < HANUM; i++, haIndex++) {
- status = Tcl_GetInt(InterpGetTcl(pSics), argv[haIndex], &hpars[i]);
- if (status != TCL_OK) {
- sprintf(buffer, "ERROR: failed to convert %s to integer",
- argv[haIndex]);
- SCWrite(pCon, buffer, eError);
- return;
- }
- }
- histData = (HistInt *) malloc(hpars[haLength] * sizeof(HistInt));
- if (!histData) {
- SCWrite(pCon, "ERROR: out of memory for reading histogram memory",
- eError);
- return;
- }
- memset(histData, 0, hpars[haLength] * sizeof(HistInt));
- status = GetHistogramDirect(mem, pCon, hpars[haBank],
- hpars[haStart],
- hpars[haStart] + hpars[haLength],
- histData,
- hpars[haLength] * sizeof(HistInt));
- }
+ histData = GetHistogramPointer(mem, pCon);
if (histData) {
- status = NXputslab(self->fileHandle, histData, start, size);
- if (status == NX_OK) {
- written = 1;
- }
- if (argc > 6)
- free(histData);
+ status = NXputslab(self->fileHandle, histData, start, size);
+ if (status == NX_OK) {
+ written = 1;
+ }
}
}
@@ -1039,6 +1017,24 @@ static void putSlab(SConnection * pCon, SicsInterp * pSics, pNXScript self,
written = 1;
}
}
+
+ /**
+ * try to look for a single double. This is a hack to make absolute_time
+ * work at BOA. A cleaner solution should be devised in a later stage.
+ * MK, June 2013
+ */
+ if(written == 0) {
+ status = Tcl_GetDouble(InterpGetTcl(pSics), argv[5], &dVal);
+ if (status != TCL_OK) {
+ written = 0;
+ } else {
+ status = NXputslab(self->fileHandle, &dVal, start, size);
+ if (status == NX_OK) {
+ written = 1;
+ }
+ }
+ }
+
/*
* drop out of hierarchy
*/
@@ -1426,7 +1422,421 @@ static void putGlobal(SConnection * pCon, SicsInterp * pSics,
}
SCSendOK(pCon);
}
+/*-----------------------------------------------------------------------
+ sget based functions
+ -------------------------------------------------------------------------*/
+static pMP putPipe = NULL;
+static pMP appendPipe = NULL;
+/*------------------------------------------------------------------------*/
+typedef struct {
+ hdbValue v;
+ char error[512];
+ char defString[1024];
+ int success;
+ int argc;
+ char **argv;
+ pNXScript nx;
+ int rank;
+ int dim[NX_MAXRANK];
+ int point;
+}PutMessage, *pPutMessage;
+/*------------------------------------------------------------------------*/
+static int CheckNoArguments(void *message, void *userData)
+{
+ pPutMessage self = (pPutMessage)message;
+ int *noArgs = (int *)userData;
+ if(self->argc < *noArgs){
+ snprintf(self->error, sizeof(self->error),"Not enough arguments, %d required",
+ *noArgs);
+ return MPSTOP;
+ }
+ return MPCONTINUE;
+}
+/*------------------------------------------------------------------------*/
+static int SGetData(void *message, void *userData)
+{
+ pPutMessage self = (pPutMessage)message;
+ int status;
+
+ status = sget(self->argv[3],&self->v);
+ if(status == 0){
+ snprintf(self->error, sizeof(self->error),"data for %s NOT found",
+ self->argv[3]);
+ return MPSTOP;
+ }
+ return MPCONTINUE;
+}
+/*-----------------------------------------------------------------------*/
+static int GetDefString(void *message, void *userData)
+{
+ pPutMessage self = (pPutMessage)message;
+ NXstatus status;
+
+ status = NXDget(self->nx->dictHandle, self->argv[2],
+ self->defString,sizeof(self->defString));
+ if(status != NX_OK){
+ snprintf(self->error, sizeof(self->error),"alias %s NOT found",
+ self->argv[2]);
+ return MPSTOP;
+ }
+ NXDtextreplace(self->nx->dictHandle,self->defString,
+ self->defString,sizeof(self->defString));
+
+
+ return MPCONTINUE;
+}
+/*------------------------------------------------------------------------*/
+static int SPutAddType(void *message, void *userData)
+{
+ pPutMessage self = (pPutMessage)message;
+ switch(self->v.dataType){
+ case HIPINT:
+ case HIPINTAR:
+ case HIPINTVARAR:
+ strncat(self->defString," -type NX_INT32 ",sizeof(self->defString));
+ break;
+ case HIPFLOAT:
+ case HIPFLOATAR:
+ case HIPFLOATVARAR:
+ strncat(self->defString," -type NX_FLOAT32 ",sizeof(self->defString));
+ break;
+ case HIPTEXT:
+ strncat(self->defString," -type NX_CHAR ",sizeof(self->defString));
+ break;
+ default :
+ snprintf(self->error, sizeof(self->error),"invalid data type %d",
+ self->v.dataType);
+ return MPSTOP;
+ }
+ return MPCONTINUE;
+}
+/*-----------------------------------------------------------------------
+Writing should not fail due to some error in padding. Thus this routine
+protects against errors but does not fail
+ ------------------------------------------------------------------------*/
+static int SPutPadding(void *message, void *userData)
+{
+ pPutMessage self = (pPutMessage)message;
+ char *pPtr = NULL, *pEnd = NULL;
+ unsigned int len = 0, i;
+
+ if(self->v.dataType == HIPTEXT && strstr(self->v.v.text,"@len") != NULL){
+ pPtr = strchr(self->v.v.text,'=');
+ pPtr++;
+ pEnd = strchr(pPtr,'@');
+ if(pPtr != NULL && pEnd != NULL){
+ *pEnd = '\0';
+ len = atoi(pPtr);
+ }
+ pPtr = malloc((len+7)*sizeof(char));
+ if(pPtr != NULL){
+ memset(pPtr,0,len*sizeof(char));
+ strncpy(pPtr,pEnd+1,len);
+ for(i = strlen(pPtr); i < len-2; i++){
+ pPtr[i] = ' ';
+ }
+ pPtr[len-1] = '!';
+ free(self->v.v.text);
+ self->v.v.text = pPtr;
+ }
+ }
+ return MPCONTINUE;
+}
+/*------------------------------------------------------------------------*/
+static int SPutDim(void *message, void *userData)
+{
+ pPutMessage self = (pPutMessage)message;
+ char dim[20], *pPtr;
+ int i;
+
+ if(self->argc > 4) {
+ pPtr = self->argv[4];
+ while((pPtr = stptok(pPtr,dim,sizeof(dim),",")) != NULL){
+ self->dim[self->rank] = atoi(dim);
+ self->rank++;
+ }
+ } else {
+ self->rank = 1;
+ switch(self->v.dataType){
+ case HIPINT:
+ case HIPFLOAT:
+ self->dim[0] = 1;
+ break;
+ case HIPINTAR:
+ case HIPINTVARAR:
+ case HIPFLOATAR:
+ case HIPFLOATVARAR:
+ self->dim[0] = self->v.arrayLength;
+ break;
+ case HIPTEXT:
+ if(self->v.v.text != NULL){
+ self->dim[0] = strlen(self->v.v.text)+1;
+ } else {
+ self->dim[0] = 1;
+ }
+ break;
+ default:
+ snprintf(self->error, sizeof(self->error),"invalid data type %d",
+ self->v.dataType);
+ return MPSTOP;
+ }
+ }
+ snprintf(dim,sizeof(dim)," -rank %d ", self->rank);
+ strncat(self->defString,dim,sizeof(self->defString));
+ strncat(self->defString," -dim {",sizeof(self->defString));
+ for(i = 0; i < self->rank; i++){
+ sprintf(dim,"%d,", self->dim[i]);
+ strncat(self->defString,dim,sizeof(self->defString));
+ }
+ pPtr = strrchr(self->defString,(int)',');
+ *pPtr = '}';
+
+ return MPCONTINUE;
+}
+/*-----------------------------------------------------------------------*/
+static int SPutWrite(void *message, void *userData)
+{
+ pPutMessage self = (pPutMessage)message;
+ NXstatus status;
+ float fVal, *fData;
+ int i;
+
+ switch(self->v.dataType){
+ case HIPINT:
+ status = NXDputdef(self->nx->fileHandle, self->nx->dictHandle,
+ self->defString, &self->v.v.intValue);
+ break;
+ case HIPFLOAT:
+ fVal = self->v.v.doubleValue;
+ status = NXDputdef(self->nx->fileHandle, self->nx->dictHandle,
+ self->defString, &fVal);
+ break;
+ case HIPINTAR:
+ case HIPINTVARAR:
+ status = NXDputdef(self->nx->fileHandle, self->nx->dictHandle,
+ self->defString, self->v.v.intArray);
+ break;
+ case HIPFLOATAR:
+ case HIPFLOATVARAR:
+ fData = malloc(self->v.arrayLength * sizeof(float));
+ if(fData == NULL){
+ snprintf(self->error, sizeof(self->error),"out of memory in SPutWrire");
+ return MPSTOP;
+ }
+ for(i = 0; i < self->v.arrayLength; i++){
+ fData[i] = self->v.v.floatArray[i];
+ }
+ status = NXDputdef(self->nx->fileHandle, self->nx->dictHandle,
+ self->defString, &fData);
+ free(fData);
+ break;
+ case HIPTEXT:
+ status = NXDputdef(self->nx->fileHandle, self->nx->dictHandle,
+ self->defString, self->v.v.text);
+ break;
+ default:
+ snprintf(self->error, sizeof(self->error),"invalid data type %d",
+ self->v.dataType);
+ return MPSTOP;
+ }
+
+ if(status == NX_OK){
+ self->success = 1;
+ } else {
+ snprintf(self->error, sizeof(self->error),"error writing %s", self->argv[2]);
+ }
+ return MPCONTINUE;
+}
+/*------------------------------------------------------------------------*/
+static void configurePutPipe()
+{
+ int *noArgs;
+ putPipe = MakeMP();
+
+ noArgs = malloc(sizeof(int));
+ *noArgs = 4;
+ AppendMPFilter(putPipe,CheckNoArguments, noArgs,free);
+ AppendMPFilter(putPipe,SGetData, NULL,NULL);
+ AppendMPFilter(putPipe,GetDefString, NULL,NULL);
+ AppendMPFilter(putPipe,SPutAddType, NULL,NULL);
+ AppendMPFilter(putPipe,SPutPadding, NULL,NULL);
+ AppendMPFilter(putPipe,SPutDim, NULL,NULL);
+ AppendMPFilter(putPipe,SPutWrite, NULL,NULL);
+}
+/*------------------------------------------------------------------------*/
+static int SAppendDim(void *message, void *userData)
+{
+ pPutMessage self = (pPutMessage)message;
+ char dim[20], *pPtr;
+ int i;
+
+ self->point = atoi(self->argv[4]);
+ self->rank = 1;
+ self->dim[0] = -1;
+
+ if(self->argc > 5) {
+ pPtr = self->argv[5];
+ while((pPtr = stptok(pPtr,dim,sizeof(dim),",")) != NULL){
+ self->dim[self->rank] = atoi(dim);
+ self->rank++;
+ }
+ } else {
+ self->rank = 1;
+ switch(self->v.dataType){
+ case HIPINT:
+ case HIPFLOAT:
+ break;
+ case HIPINTAR:
+ case HIPINTVARAR:
+ case HIPFLOATAR:
+ case HIPFLOATVARAR:
+ self->rank = 2;
+ self->dim[1] = self->v.arrayLength;
+ break;
+ case HIPTEXT:
+ self->rank = 2;
+ self->dim[1] = strlen(self->v.v.text)+1;
+ break;
+ default:
+ snprintf(self->error, sizeof(self->error),"invalid data type %d",
+ self->v.dataType);
+ return MPSTOP;
+ }
+ }
+ snprintf(dim,sizeof(dim)," -rank %d ", self->rank);
+ strncat(self->defString,dim,sizeof(self->defString));
+ strncat(self->defString," -dim {",sizeof(self->defString));
+ for(i = 0; i < self->rank; i++){
+ sprintf(dim,"%d,", self->dim[i]);
+ strncat(self->defString,dim,sizeof(self->defString));
+ }
+ pPtr = strrchr(self->defString,(int)',');
+ *pPtr = '}';
+
+ return MPCONTINUE;
+}
+/*-----------------------------------------------------------------------*/
+static int SAppendWrite(void *message, void *userData)
+{
+ pPutMessage self = (pPutMessage)message;
+ NXstatus status;
+ float fVal, *fData;
+ int i;
+ int start[NX_MAXRANK], size[NX_MAXRANK];
+
+
+ NXopenpath(self->nx->fileHandle,"/");
+ status = NXDopendef(self->nx->fileHandle, self->nx->dictHandle,
+ self->defString);
+ if(status != NX_OK){
+ snprintf(self->error, sizeof(self->error),"cannot open NeXus object");
+ return MPSTOP;
+ }
+
+ start[0] = self->point;
+ size[0] = 1;
+ for(i = 1; i < self->rank; i++){
+ start[i] = 0;
+ size[i] = self->dim[i];
+ }
+
+
+ switch(self->v.dataType){
+ case HIPINT:
+ status = NXputslab(self->nx->fileHandle,&self->v.v.intValue, start,size);
+ break;
+ case HIPFLOAT:
+ fVal = self->v.v.doubleValue;
+ status = NXputslab(self->nx->fileHandle,&fVal, start,size);
+ break;
+ case HIPINTAR:
+ case HIPINTVARAR:
+ status = NXputslab(self->nx->fileHandle,&self->v.v.intArray, start,size);
+ break;
+ case HIPFLOATAR:
+ case HIPFLOATVARAR:
+ fData = malloc(self->v.arrayLength * sizeof(float));
+ if(fData == NULL){
+ snprintf(self->error, sizeof(self->error),"out of memory in SPutWrire");
+ return MPSTOP;
+ }
+ for(i = 0; i < self->v.arrayLength; i++){
+ fData[i] = self->v.v.floatArray[i];
+ }
+ status = NXputslab(self->nx->fileHandle,fData, start,size);
+ free(fData);
+ break;
+ case HIPTEXT:
+ status = NXputslab(self->nx->fileHandle,self->v.v.text, start,size);
+ break;
+ default:
+ snprintf(self->error, sizeof(self->error),"invalid data type %d",
+ self->v.dataType);
+ return MPSTOP;
+ }
+
+ if(status == NX_OK){
+ self->success = 1;
+ } else {
+ snprintf(self->error, sizeof(self->error),"error writing %s", self->argv[2]);
+ }
+ NXopenpath(self->nx->fileHandle,"/");
+ return MPCONTINUE;
+}
+/*------------------------------------------------------------------------*/
+static void configureAppendPipe()
+{
+ int *noArgs;
+ appendPipe = MakeMP();
+
+ noArgs = malloc(sizeof(int));
+ *noArgs = 5;
+ AppendMPFilter(appendPipe,CheckNoArguments, noArgs,free);
+ AppendMPFilter(appendPipe,SGetData, NULL,NULL);
+ AppendMPFilter(appendPipe,GetDefString, NULL,NULL);
+ AppendMPFilter(appendPipe,SPutAddType, NULL,NULL);
+ AppendMPFilter(appendPipe,SAppendDim, NULL,NULL);
+ AppendMPFilter(appendPipe,SAppendWrite, NULL,NULL);
+}
+/*------------------------------------------------------------------------*/
+static int handleSPut(SConnection * pCon, SicsInterp * pSics,
+ pNXScript self, int argc, char *argv[])
+{
+ PutMessage mess;
+
+ memset(&mess, 0, sizeof(PutMessage));
+ mess.argc = argc;
+ mess.argv = argv;
+ mess.nx = self;
+ MPprocess(putPipe,&mess);
+ if(mess.success == 0){
+ SCPrintf(pCon,eLogError,"ERROR: %s", mess.error);
+ } else {
+ SCSendOK(pCon);
+ }
+ ReleaseHdbValue(&mess.v);
+ return mess.success;
+}
+/*------------------------------------------------------------------------*/
+static int handleSAppend(SConnection * pCon, SicsInterp * pSics,
+ pNXScript self, int argc, char *argv[])
+{
+ PutMessage mess;
+
+ memset(&mess, 0, sizeof(PutMessage));
+ mess.argc = argc;
+ mess.argv = argv;
+ mess.nx = self;
+ MPprocess(appendPipe,&mess);
+ if(mess.success == 0){
+ SCPrintf(pCon,eLogError,"ERROR: %s", mess.error);
+ } else {
+ SCSendOK(pCon);
+ }
+ ReleaseHdbValue(&mess.v);
+ return mess.success;
+}
/*-----------------------------------------------------------------------*/
static int handlePut(SConnection * pCon, SicsInterp * pSics,
pNXScript self, int argc, char *argv[])
@@ -1558,6 +1968,12 @@ static int handlePut(SConnection * pCon, SicsInterp * pSics,
} else if (strcmp(argv[1], "putslab16") == 0) {
/*===============*/
putSlab16(pCon, pSics, self, argc, argv);
+ } else if (strcmp(argv[1], "puts") == 0) {
+ /*===============*/
+ handleSPut(pCon, pSics, self, argc, argv);
+ } else if (strcmp(argv[1], "sappend") == 0) {
+ /*===============*/
+ handleSAppend(pCon, pSics, self, argc, argv);
} else {
SCPrintf(pCon, eLogError, "ERROR: put command %s not recognised", argv[1] );
}
@@ -1700,7 +2116,7 @@ int NXScriptAction(SConnection * pCon, SicsInterp * pSics, void *pData,
return 1;
}
- if (strstr(argv[1], "put") != NULL) {
+ if (strstr(argv[1], "put") != NULL || strstr(argv[1],"sappend") != NULL) {
handlePut(pCon, pSics, self, argc, argv);
return 1;
}
@@ -1769,6 +2185,12 @@ int MakeNXScript(SConnection * pCon, SicsInterp * pSics, void *pData,
return 0;
}
self->timeDivisor = 1;
+
+ /*
+ configure pipes
+ */
+ configurePutPipe();
+ configureAppendPipe();
/*
create with with a default name if none specified
@@ -1787,3 +2209,20 @@ int MakeNXScript(SConnection * pCon, SicsInterp * pSics, void *pData,
}
return 1;
}
+static pNXScript sysScript= NULL;
+/*-----------------------------------------------------------------------------------*/
+int isNXScriptWriting(void)
+{
+
+ if(sysScript == NULL){
+ sysScript = FindCommandData(pServ->pSics,"nxscript","NXScript");
+ }
+
+
+ if(sysScript != NULL && sysScript->fileHandle != NULL){
+ return 1;
+ } else {
+ return 0;
+ }
+
+}
diff --git a/nxscript.h b/nxscript.h
index 08b8290a..28f43cef 100644
--- a/nxscript.h
+++ b/nxscript.h
@@ -21,6 +21,7 @@ int NXScriptAction(SConnection * pCon, SicsInterp * pSics, void *pData,
char *makeFilename(SicsInterp * pSics, SConnection * pCon);
void changeExtension(char *filename, char *newExtension);
+int isNXScriptWriting(void);
/*============== a personal data structure ============================*/
typedef struct {
pObjectDescriptor pDes;
diff --git a/nxstack.c b/nxstack.c
deleted file mode 100644
index a5ba2bd7..00000000
--- a/nxstack.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- This is some code to handle a stack of NeXus files. This is used to implement
- external linking within the NeXus-API
-
- Copyright (C) 1997-2006 Mark Koennecke
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- For further information, see
-
- Added code to support the path stack for NXgetpath,
- Mark Koennecke, October 2009
-*/
-#include
-#include
-#include
-#include "nxstack.h"
-
-/*-----------------------------------------------------------------------
- Data definitions
----------------------------------------------------------------------*/
-
-typedef struct {
- pNexusFunction pDriver;
- NXlink closeID;
- char filename[1024];
-}fileStackEntry;
-
-
-typedef struct __fileStack {
- int fileStackPointer;
- fileStackEntry fileStack[MAXEXTERNALDEPTH];
- int pathPointer;
- char pathStack[NXMAXSTACK][NX_MAXNAMELEN];
-}fileStack;
-/*---------------------------------------------------------------------*/
-pFileStack makeFileStack(){
- pFileStack pNew = NULL;
-
- pNew = (pFileStack)malloc(sizeof(fileStack));
- if(pNew == NULL){
- return NULL;
- }
- memset(pNew,0,sizeof(fileStack));
- pNew->fileStackPointer = -1;
- pNew->pathPointer = -1;
- return pNew;
-}
-/*---------------------------------------------------------------------*/
-void killFileStack(pFileStack self){
- if(self != NULL){
- free(self);
- }
-}
-/*---------------------------------------------------------------------*/
-int getFileStackSize(){
- return sizeof(fileStack);
-}
-/*----------------------------------------------------------------------*/
-void pushFileStack(pFileStack self, pNexusFunction pDriv, char *file){
- size_t length;
-
- self->fileStackPointer++;
- self->fileStack[self->fileStackPointer].pDriver = pDriv;
- memset(&self->fileStack[self->fileStackPointer].closeID,0,sizeof(NXlink));
- length = strlen(file);
- if(length >= 1024){
- length = 1023;
- }
- memcpy(&self->fileStack[self->fileStackPointer].filename,file,length);
-}
-/*----------------------------------------------------------------------*/
-void popFileStack(pFileStack self){
- self->fileStackPointer--;
- if(self->fileStackPointer < -1){
- self->fileStackPointer = -1;
- }
-}
-/*----------------------------------------------------------------------*/
-pNexusFunction peekFileOnStack(pFileStack self){
- return self->fileStack[self->fileStackPointer].pDriver;
-}
-/*---------------------------------------------------------------------*/
-char *peekFilenameOnStack(pFileStack self){
- return self->fileStack[self->fileStackPointer].filename;
-}
-/*----------------------------------------------------------------------*/
-void peekIDOnStack(pFileStack self, NXlink *id){
- memcpy(id, &self->fileStack[self->fileStackPointer].closeID, sizeof(NXlink));
-}
-/*---------------------------------------------------------------------*/
-void setCloseID(pFileStack self, NXlink id){
- memcpy(&self->fileStack[self->fileStackPointer].closeID, &id, sizeof(NXlink));
-}
-/*----------------------------------------------------------------------*/
-int fileStackDepth(pFileStack self){
- return self->fileStackPointer;
-}
-/*----------------------------------------------------------------------*/
-void pushPath(pFileStack self, const char *name){
- self->pathPointer++;
- strncpy(self->pathStack[self->pathPointer],name,NX_MAXNAMELEN-1);
-}
-/*-----------------------------------------------------------------------*/
-void popPath(pFileStack self){
- self->pathPointer--;
- if(self->pathPointer < -1){
- self->pathPointer = -1;
- }
-}
-/*-----------------------------------------------------------------------*/
-int buildPath(pFileStack self, char *path, int pathlen){
- int i;
- size_t totalPathLength;
- char *totalPath;
-
- for(i = 0, totalPathLength = 5; i <= self->pathPointer; i++){
- totalPathLength += strlen(self->pathStack[i]) + 1;
- }
- totalPath = (char*)malloc(totalPathLength*sizeof(char));
- if(totalPath == NULL){
- return 0;
- }
- memset(totalPath,0,totalPathLength*sizeof(char));
- for(i = 0; i <= self->pathPointer; i++){
- strcat(totalPath,"/");
- strcat(totalPath,self->pathStack[i]);
- }
-
- strncpy(path,totalPath,pathlen-1);
- free(totalPath);
- return 1;
-}
diff --git a/nxstack.h b/nxstack.h
deleted file mode 100755
index 2faaf041..00000000
--- a/nxstack.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- This is some code to handle a stack of NeXus files. This is used to implement
- external linking within the NeXus-API
-
- Copyright (C) 1997-2006 Mark Koennecke
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- For further information, see
-
- Added functions to deal with the path stack for NXgetpath
- Mark Koennecke, October 2009
-
-*/
-#ifndef NEXUSFILESTACK
-#define NEXUSFILESTACK
-
-typedef struct __fileStack *pFileStack;
-#define MAXEXTERNALDEPTH 16
-
-pFileStack makeFileStack();
-void killFileStack(pFileStack self);
-int getFileStackSize();
-
-void pushFileStack(pFileStack self, pNexusFunction pDriv, char *filename);
-void popFileStack(pFileStack self);
-
-pNexusFunction peekFileOnStack(pFileStack self);
-char *peekFilenameOnStack(pFileStack self);
-void peekIDOnStack(pFileStack self, NXlink *id);
-void setCloseID(pFileStack self, NXlink id);
-
-int fileStackDepth(pFileStack self);
-
-void pushPath(pFileStack self, const char *name);
-void popPath(pFileStack self);
-int buildPath(pFileStack self, char *path, int pathlen);
-
-#endif
-
diff --git a/nxupdate.c b/nxupdate.c
index 67ec0773..cc7e6cb6 100644
--- a/nxupdate.c
+++ b/nxupdate.c
@@ -81,7 +81,7 @@ static int CountCallback(int iEvent, void *pEventData, void *pUser)
self->nextUpdate = time(NULL) + self->updateIntervall;
self->iEnd = 0;
self->pCon = pCon;
- TaskRegister(pServ->pTasker, UpdateTask, NULL, NULL, self, 1);
+ TaskRegisterN(pServ->pTasker, "NXupdater", UpdateTask, NULL, NULL, self, 1);
return 1;
} else if (iEvent == COUNTEND) {
self->iEnd = 1;
diff --git a/nxxml.c b/nxxml.c
deleted file mode 100644
index 131b3afe..00000000
--- a/nxxml.c
+++ /dev/null
@@ -1,1992 +0,0 @@
-/*
- * This is the implementation file for the XML file driver
- * for NeXus
- *
- * Copyright (C) 2006 Mark Koennecke
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * For further information, see
- */
-
-
-#ifdef NXXML
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include "nxio.h"
-#include "nxdataset.h"
-
-#ifdef _MSC_VER
-#define snprintf _snprintf
-#endif /* _MSC_VER */
-
-extern void *NXpData;
-extern int validNXName(const char* name, int allow_colon); /* from napi.c */
-char *nxitrim(char *str); /* from napi.c */
-
-/*----------------------- our data structures --------------------------
- One might wonder why a node stack is still needed even if this API
- operates on top of a tree API. The reason for this are the links.
- Following a link on any NXopenpath, data means a jump through the
- whole tree. In order to correctly return from such adventures,
- a stack is needed. Moreover we need it in order to keep track of the
- state of search operations.
-
- The true NXroot node is always at stack[0]. The root in the data
- structure is the ?xml element. The latter one is needed to store
- the tree.
------------------------------------------------------------------------*/
-typedef struct {
- mxml_node_t *current;
- mxml_node_t *currentChild;
- int currentAttribute;
- int options; /**< additional information about the node */
-}xmlStack;
-
-/*
- * Freddie Akeroyd, 19/03/2008
- *
- * Add in support for table style data writing - this is
- * indicated internally via the XMLSTACK_OPTION_TABLE flag
- * and separates the dimensions and data into separate nodes contained
- * in DIMS_NODE_NAME and DATA_NODE_NAME. This is a first commit and
- * involves some code duplication that will need to be cleaned up later.
- * Also writing in table style is only enabled for 1D arrays as
- * I haven't done slab writing yet which the nexus test program uses
- * for writing 2D arrays.
- *
- * Table output is enabled by opening a file with (NXACC_CREATEXML | NXACC_TABLE)
- *
- * See http://trac.nexusformat.org/code/ticket/111 for further details
- */
-#define XMLSTACK_OPTION_TABLE 0x1 /**< indicates table option in xmlStack */
-
-
-/*---------------------------------------------------------------------*/
-typedef struct {
- mxml_node_t *root; /* root node */
- int readOnly; /* read only flag */
- int tableStyle; /**< whether to output data in XML table style */
- int stackPointer; /* stack pointer */
- char filename[1024]; /* file name, for NXflush, NXclose */
- xmlStack stack[NXMAXSTACK]; /* stack */
-}XMLNexus, *pXMLNexus;
-/*===================== support functions ===============================*/
-extern char *stptok(char *s, char *tok, size_t toklen, char *brk);
-/*----------------------------------------------------------------------*/
-static mxml_node_t *getLinkTarget(pXMLNexus xmlHandle, const char *target){
- mxml_node_t *node = NULL;
- mxml_node_t *testNode = NULL;
- char path[132], *pPtr;
-
- pPtr = (char *)target + 1;
- node = xmlHandle->stack[0].current;
- while((pPtr = stptok(pPtr,path,131,"/")) != NULL){
- /*
- search for group node
- */
- testNode = mxmlFindElement(node,node,NULL,"name",path,MXML_DESCEND_FIRST);
- if(testNode == NULL){
- /*
- it can still be a data node
- */
- testNode = mxmlFindElement(node,node,path,NULL,NULL,MXML_DESCEND_FIRST);
- }
- if(testNode == NULL){
- NXReportError("Cannot follow broken link");
- return NULL;
- } else {
- node = testNode;
- }
- }
- return node;
-}
-/*==================== file functions ===================================*/
-static void errorCallbackForMxml(const char *txt){
- NXReportError((char *)txt);
-}
-/*-----------------------------------------------------------------------*/
-NXstatus NXXopen(CONSTCHAR *filename, NXaccess am,
- NXhandle* pHandle) {
- pXMLNexus xmlHandle = NULL;
- FILE *fp = NULL;
- char *time_buffer = NULL;
- mxml_node_t *current;
-
- /*
- allocate data
- */
- xmlHandle = (pXMLNexus)malloc(sizeof(XMLNexus));
- if(!xmlHandle){
- NXReportError( "Out of memory allocating XML file handle");
- return NX_ERROR;
- }
- memset(xmlHandle,0,sizeof(XMLNexus));
-
- /*
- initialize mxml XML parser
- */
- mxmlSetCustomHandlers(nexusLoadCallback, nexusWriteCallback);
- initializeNumberFormats();
- mxmlSetErrorCallback(errorCallbackForMxml);
-
- xmlHandle->tableStyle = ((am & NXACC_TABLE) ? 1 : 0);
- /*
- open file
- */
- strncpy(xmlHandle->filename,filename,1023);
- switch(am & NXACCMASK_REMOVEFLAGS){
- case NXACC_READ:
- xmlHandle->readOnly = 1;
- case NXACC_RDWR:
- fp = fopen(filename,"r");
- if(fp == NULL){
- NXReportError("Failed to open file:");
- NXReportError((char *)filename);
- free(xmlHandle);
- return NX_ERROR;
- }
- xmlHandle->root = mxmlLoadFile(NULL,fp,nexusTypeCallback);
- xmlHandle->stack[0].current = mxmlFindElement(xmlHandle->root,
- xmlHandle->root,
- "NXroot",
- NULL,NULL,
- MXML_DESCEND);
- xmlHandle->stack[0].currentChild = NULL;
- xmlHandle->stack[0].currentAttribute = 0;
- xmlHandle->stack[0].options = 0;
- fclose(fp);
- break;
- case NXACC_CREATEXML:
- xmlHandle->root = mxmlNewElement(NULL,
- "?xml version=\"1.0\" encoding=\"UTF-8\"?");
- current = mxmlNewElement(xmlHandle->root,"NXroot");
- mxmlElementSetAttr(current,"NeXus_version",NEXUS_VERSION);
- mxmlElementSetAttr(current,"XML_version","mxml");
- mxmlElementSetAttr(current,"file_name",filename);
- mxmlElementSetAttr(current,"xmlns", NEXUS_SCHEMA_NAMESPACE);
- mxmlElementSetAttr(current,"xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance");
- mxmlElementSetAttr(current,"xsi:schemaLocation",
- NEXUS_SCHEMA_NAMESPACE " " NEXUS_SCHEMA_URL);
- time_buffer = NXIformatNeXusTime();
- if(time_buffer != NULL){
- mxmlElementSetAttr(current,"file_time",time_buffer);
- free(time_buffer);
- }
- xmlHandle->stack[0].current = current;
- xmlHandle->stack[0].currentChild = NULL;
- xmlHandle->stack[0].currentAttribute = 0;
- xmlHandle->stack[0].options = 0;
- break;
- default:
- NXReportError("Bad access parameter specified in NXXopen");
- return NX_ERROR;
- }
- if(xmlHandle->stack[0].current == NULL){
- NXReportError(
- "No NXroot element in XML-file, no NeXus-XML file");
- return NX_ERROR;
- }
-
- *pHandle = xmlHandle;
- return NX_OK;
-}
-/*----------------------------------------------------------------------*/
-NXstatus NXXclose (NXhandle* fid){
- pXMLNexus xmlHandle = NULL;
- FILE *fp = NULL;
-
- xmlHandle = (pXMLNexus)*fid;
- assert(xmlHandle);
-
- if(xmlHandle->readOnly == 0) {
- fp = fopen(xmlHandle->filename,"w");
- if(fp == NULL){
- NXReportError("Failed to open NeXus XML file for writing");
- return NX_ERROR;
- }
- mxmlSaveFile(xmlHandle->root,fp,NXwhitespaceCallback);
- fclose(fp);
- }
- mxmlDelete(xmlHandle->root);
- free(xmlHandle);
- *fid = NULL;
- return NX_OK;
-}
-/*----------------------------------------------------------------------*/
-NXstatus NXXflush(NXhandle *fid){
- pXMLNexus xmlHandle = NULL;
- FILE *fp = NULL;
-
- xmlHandle = (pXMLNexus)*fid;
- assert(xmlHandle);
-
- if(xmlHandle->readOnly == 0) {
- fp = fopen(xmlHandle->filename,"w");
- if(fp == NULL){
- NXReportError("Failed to open NeXus XML file for writing");
- return NX_ERROR;
- }
- mxmlSaveFile(xmlHandle->root,fp,NXwhitespaceCallback);
- fclose(fp);
- }
- return NX_OK;
-}
-/*=======================================================================
- Group functions
-=========================================================================*/
-NXstatus NXXmakegroup (NXhandle fid, CONSTCHAR *name,
- CONSTCHAR *nxclass){
- char buffer[256];
- pXMLNexus xmlHandle = NULL;
- mxml_node_t *newGroup = NULL;
-
- xmlHandle = (pXMLNexus)fid;
- assert(xmlHandle);
-
- if (!validNXName(name, 0))
- {
- sprintf(buffer, "ERROR: invalid characters in group name \"%s\"", name);
- NXReportError(buffer);
- return NX_ERROR;
- }
-
- if(isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){
- NXReportError("Close dataset before trying to create a group");
- return NX_ERROR;
- }
-
- newGroup = mxmlNewElement(xmlHandle->stack[xmlHandle->stackPointer].current,
- nxclass);
- if(!newGroup){
- NXReportError("failed to allocate new group");
- return NX_ERROR;
- }
- mxmlElementSetAttr(newGroup,"name",name);
- return NX_OK;
-}
-/*----------------------------------------------------------------------*/
-static mxml_node_t *searchGroupLinks(pXMLNexus xmlHandle, CONSTCHAR *name,
- CONSTCHAR *nxclass){
- mxml_node_t *linkNode = NULL;
- mxml_node_t *current;
- mxml_node_t *test = NULL;
- const char *linkTarget;
- const char *linkName = NULL;
-
- current = xmlHandle->stack[xmlHandle->stackPointer].current;
- linkNode = current;
- while((linkNode = mxmlFindElement(linkNode,current,"NAPIlink",NULL,NULL,
- MXML_DESCEND_FIRST)) != NULL){
- linkTarget = mxmlElementGetAttr(linkNode,"target");
- test = getLinkTarget(xmlHandle,linkTarget);
- if(test != NULL){
- if(strcmp(test->value.element.name,nxclass) == 0){
- if(strcmp(mxmlElementGetAttr(test,"name"),name) == 0){
- return test;
- }
- }
- }
- /*
- test for named links
- */
- linkName = mxmlElementGetAttr(linkNode,"name");
- if(test != NULL && linkName != NULL){
- if(strcmp(test->value.element.name,nxclass) == 0){
- if(strcmp(linkName, name) == 0){
- return test;
- }
- }
- }
- }
- return NULL;
-}
-/*------------------------------------------------------------------------*/
-NXstatus NXXopengroup (NXhandle fid, CONSTCHAR *name,
- CONSTCHAR *nxclass){
- pXMLNexus xmlHandle = NULL;
- mxml_node_t *newGroup = NULL;
- char error[1024];
-
- xmlHandle = (pXMLNexus)fid;
- assert(xmlHandle);
-
- if(isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){
- NXReportError("Close dataset before trying to open a group");
- return NX_ERROR;
- }
- newGroup = mxmlFindElement(xmlHandle->stack[xmlHandle->stackPointer].current,
- xmlHandle->stack[xmlHandle->stackPointer].current,
- nxclass,
- "name",
- name,
- MXML_DESCEND_FIRST);
- if(newGroup == NULL){
- newGroup = searchGroupLinks(xmlHandle,name,nxclass);
- }
- if(!newGroup){
- snprintf(error,1023,"Failed to open %s, %s",name,nxclass);
- NXReportError(error);
- return NX_ERROR;
- }
- xmlHandle->stackPointer++;
- xmlHandle->stack[xmlHandle->stackPointer].current = newGroup;
- xmlHandle->stack[xmlHandle->stackPointer].currentChild = NULL;
- xmlHandle->stack[xmlHandle->stackPointer].currentAttribute = 0;
- xmlHandle->stack[xmlHandle->stackPointer].options = 0;
- return NX_OK;
-}
-/*----------------------------------------------------------------------*/
-NXstatus NXXclosegroup (NXhandle fid){
- pXMLNexus xmlHandle = NULL;
-
- xmlHandle = (pXMLNexus)fid;
- assert(xmlHandle);
-
- if(isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){
- /*
- silently fix this
- */
- NXXclosedata(fid);
- }
- if(xmlHandle->stackPointer > 0){
- xmlHandle->stackPointer--;
- }
- return NX_OK;
-}
-/*=========================================================================
- dataset functions
-=========================================================================*/
-NXstatus NXXcompmakedata64 (NXhandle fid, CONSTCHAR *name,
- int datatype,
- int rank,
- int64_t dimensions[],
- int compress_type, int64_t chunk_size[]){
- /*
- compression does not relly make sense with XML
- */
- return NXXmakedata64(fid,name,datatype,rank,dimensions);
-}
-/*-----------------------------------------------------------------------*/
-static char *buildTypeString(int datatype, int rank, int64_t dimensions[]){
- char *typestring = NULL;
- char pNumber[20];
- int i;
-
- /*
- allocate data
- */
- typestring = (char *)malloc(132*sizeof(char));
- if(!typestring){
- NXReportError("Failed to allocate typestring");
- return NULL;
- }
- memset(typestring,0,132*sizeof(char));
-
- getNumberText(datatype,typestring,130);
- if(rank > 1 || datatype == NX_CHAR || dimensions[0] > 1) {
- strcat(typestring,"[");
- snprintf(pNumber,19,"%lld", (long long)dimensions[0]);
- strncat(typestring,pNumber,130-strlen(typestring));
- for(i = 1; i < rank; i++){
- snprintf(pNumber,19,",%lld", (long long)dimensions[i]);
- strncat(typestring,pNumber,130-strlen(typestring));
- }
- strcat(typestring,"]");
- }
- return typestring;
-}
-
-/*------------------------------------------------------------------------*/
-NXstatus NXXmakedatatable64 (NXhandle fid,
- CONSTCHAR *name, int datatype,
- int rank, int64_t dimensions[]){
- pXMLNexus xmlHandle = NULL;
- mxml_node_t *dataNode = NULL, *dataNodeRoot = NULL, *dimsNode = NULL, *dimsNodeRoot = NULL;
- mxml_node_t *newData = NULL;
- mxml_node_t *current;
- char *typestring;
- int i, ndata;
- char buffer[256];
- static int64_t one = 1;
-
- xmlHandle = (pXMLNexus)fid;
- assert(xmlHandle);
- if (!validNXName(name, 0))
- {
- sprintf(buffer, "ERROR: invalid characters in dataset name \"%s\"", name);
- NXReportError(buffer);
- return NX_ERROR;
- }
-
- if(isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){
- NXReportError("Close dataset before trying to create a dataset");
- return NX_ERROR;
- }
- if(dimensions[0] < 0){
- dimensions[0] = 1;
- }
-
- current = xmlHandle->stack[xmlHandle->stackPointer].current;
-
- dimsNodeRoot = mxmlFindElement(current, current, DIMS_NODE_NAME, NULL, NULL, MXML_DESCEND_FIRST);
- if (dimsNodeRoot == NULL)
- {
- dimsNodeRoot = mxmlNewElement(current, DIMS_NODE_NAME);
- }
- dimsNode = mxmlNewElement(dimsNodeRoot, name);
- mxmlNewOpaque(dimsNode, "");
- typestring = buildTypeString(datatype,rank,dimensions);
- if(typestring != NULL){
- mxmlElementSetAttr(dimsNode,TYPENAME,typestring);
- free(typestring);
- } else {
- NXReportError("Failed to allocate typestring");
- return NX_ERROR;
- }
- ndata = 1;
- for(i=0; itype = MXML_CUSTOM;
-/* newData->value.custom.data = createNXDataset(rank,datatype,dimensions); */
- newData->value.custom.data = createNXDataset(1,datatype,&one);
- if(!newData->value.custom.data){
- NXReportError("Failed to allocate space for dataset");
- return NX_ERROR;
- }
- newData->value.custom.destroy = destroyDataset;
- }
- return NX_OK;
-}
-
-NXstatus NXXmakedata64 (NXhandle fid,
- CONSTCHAR *name, int datatype,
- int rank, int64_t dimensions[]){
- pXMLNexus xmlHandle = NULL;
- mxml_node_t *dataNode = NULL;
- mxml_node_t *newData = NULL;
- mxml_node_t *current;
- char *typestring;
- char buffer[256];
-
-
- xmlHandle = (pXMLNexus)fid;
- assert(xmlHandle);
- if (!validNXName(name, 0))
- {
- sprintf(buffer, "ERROR: invalid characters in dataset name \"%s\"", name);
- NXReportError(buffer);
- return NX_ERROR;
- }
-
- if (xmlHandle->tableStyle && datatype != NX_CHAR && dimensions[0] != NX_UNLIMITED && rank == 1)
- {
- return NXXmakedatatable64(fid,name,datatype,rank,dimensions);
- }
-
- if(isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){
- NXReportError("Close dataset before trying to create a dataset");
- return NX_ERROR;
- }
- if(dimensions[0] < 0){
- dimensions[0] = 1;
- }
-
- current = xmlHandle->stack[xmlHandle->stackPointer].current;
- dataNode = mxmlNewElement(current,name);
- typestring = buildTypeString(datatype,rank,dimensions);
- if(typestring != NULL){
- mxmlElementSetAttr(dataNode,TYPENAME,typestring);
- free(typestring);
- } else {
- NXReportError("Failed to allocate typestring");
- return NX_ERROR;
- }
- /*
- NX_CHAR maps to MXML_OPAQUE datasets
- */
- if(datatype == NX_CHAR){
- newData = mxmlNewOpaque(dataNode,"");
- return NX_OK;
- } else {
- newData = (mxml_node_t *)malloc(sizeof(mxml_node_t));
- if(!newData){
- NXReportError("Failed to allocate space for dataset");
- return NX_ERROR;
- }
- memset(newData,0,sizeof(mxml_node_t));
- mxmlAdd(dataNode, MXML_ADD_AFTER, MXML_ADD_TO_PARENT, newData);
- newData->type = MXML_CUSTOM;
- newData->value.custom.data = createNXDataset(rank,datatype,dimensions);
- if(!newData->value.custom.data){
- NXReportError("Failed to allocate space for dataset");
- return NX_ERROR;
- }
- newData->value.custom.destroy = destroyDataset;
- }
- return NX_OK;
-}
-/*----------------------------------------------------------------------*/
-static mxml_node_t *searchSDSLinks(pXMLNexus xmlHandle, CONSTCHAR *name){
- mxml_node_t *linkNode = NULL;
- mxml_node_t *current;
- mxml_node_t *test = NULL;
- const char *linkTarget;
- const char *linkName = NULL;
-
- current = xmlHandle->stack[xmlHandle->stackPointer].current;
- linkNode = current;
- while((linkNode = mxmlFindElement(linkNode,current,"NAPIlink",NULL,NULL,
- MXML_DESCEND_FIRST)) != NULL){
- linkTarget = mxmlElementGetAttr(linkNode,"target");
- test = getLinkTarget(xmlHandle,linkTarget);
- if(test != NULL){
- if(strcmp(test->value.element.name,name) == 0){
- return test;
- }
- }
- /*
- test for named links
- */
- linkName = mxmlElementGetAttr(linkNode,"name");
- if(test != NULL && linkName != NULL){
- if(strcmp(linkName,name) == 0){
- return test;
- }
- }
- }
- return NULL;
-}
-/*-----------------------------------------------------------------------*/
-NXstatus NXXopendatatable (NXhandle fid, CONSTCHAR *name){
- pXMLNexus xmlHandle = NULL;
- mxml_node_t *dataNode = NULL, *dimsNode = NULL;
- char error[1024];
-
- xmlHandle = (pXMLNexus)fid;
- assert(xmlHandle);
-
-
- if(isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){
- /*
- silently fix this
- */
- xmlHandle->stackPointer--;
- if(xmlHandle->stackPointer < 0){
- xmlHandle->stackPointer = 0;
- }
- }
-
- dimsNode = mxmlFindElement(xmlHandle->stack[xmlHandle->stackPointer].current,
- xmlHandle->stack[xmlHandle->stackPointer].current,
- DIMS_NODE_NAME,
- NULL,
- NULL,
- MXML_DESCEND_FIRST);
-
- if(!dimsNode){
- snprintf(error,1023,"Failed to open dataset %s",name);
- NXReportError(error);
- return NX_ERROR;
- }
-
- dataNode = mxmlFindElement(dimsNode,
- dimsNode,
- name,
- NULL,
- NULL,
- MXML_DESCEND_FIRST);
- if(dataNode == NULL){
- dataNode = searchSDSLinks(xmlHandle,name);
- }
- if(!dataNode){
- snprintf(error,1023,"Failed to open dataset %s",name);
- NXReportError(error);
- return NX_ERROR;
- }
- xmlHandle->stackPointer++;
- xmlHandle->stack[xmlHandle->stackPointer].current = dataNode;
- xmlHandle->stack[xmlHandle->stackPointer].currentChild = NULL;
- xmlHandle->stack[xmlHandle->stackPointer].currentAttribute = 0;
- xmlHandle->stack[xmlHandle->stackPointer].options = XMLSTACK_OPTION_TABLE;
- return NX_OK;
-}
-
-
-NXstatus NXXopendata (NXhandle fid, CONSTCHAR *name){
- pXMLNexus xmlHandle = NULL;
- mxml_node_t *dataNode = NULL, *current = NULL;
- char error[1024];
-
- xmlHandle = (pXMLNexus)fid;
- assert(xmlHandle);
-
- /* is this a table style node ? */
- current = xmlHandle->stack[xmlHandle->stackPointer].current;
- dataNode = mxmlFindElement(current,
- current,
- DATA_NODE_NAME,
- NULL,
- NULL,
- MXML_DESCEND_FIRST);
- if (dataNode != NULL)
- {
- dataNode = mxmlFindElement(dataNode,
- dataNode,
- name,
- NULL,
- NULL,
- MXML_DESCEND_FIRST);
- }
- if (dataNode != NULL)
- {
- return NXXopendatatable(fid, name);
- }
-
- if(isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){
- /*
- silently fix this
- */
- xmlHandle->stackPointer--;
- if(xmlHandle->stackPointer < 0){
- xmlHandle->stackPointer = 0;
- }
- }
-
- dataNode = mxmlFindElement(xmlHandle->stack[xmlHandle->stackPointer].current,
- xmlHandle->stack[xmlHandle->stackPointer].current,
- name,
- NULL,
- NULL,
- MXML_DESCEND_FIRST);
- if(dataNode == NULL){
- dataNode = searchSDSLinks(xmlHandle,name);
- }
- if(!dataNode){
- snprintf(error,1023,"Failed to open dataset %s",name);
- NXReportError(error);
- return NX_ERROR;
- }
- xmlHandle->stackPointer++;
- xmlHandle->stack[xmlHandle->stackPointer].current = dataNode;
- xmlHandle->stack[xmlHandle->stackPointer].currentChild = NULL;
- xmlHandle->stack[xmlHandle->stackPointer].currentAttribute = 0;
- xmlHandle->stack[xmlHandle->stackPointer].options = 0;
- return NX_OK;
-}
-/*----------------------------------------------------------------------*/
-
-NXstatus NXXclosedata (NXhandle fid){
- pXMLNexus xmlHandle = NULL;
-
- xmlHandle = (pXMLNexus)fid;
- assert(xmlHandle);
-
- if(isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){
- if(xmlHandle->stackPointer > 0){
- xmlHandle->stackPointer--;
- }
- return NX_OK;
- }
- return NX_OK;
-}
-/*----------------------------------------------------------------------*/
-static mxml_node_t *findData(mxml_node_t *node){
- mxml_node_t *baby = node;
-
- while( (baby = mxmlWalkNext(baby,node,MXML_DESCEND_FIRST)) != NULL){
- if(baby->type == MXML_OPAQUE || baby->type == MXML_CUSTOM){
- return baby;
- }
- }
- return NULL;
-}
-
-/* we only havv to deal with non-character data here */
-NXstatus NXXputdatatable (NXhandle fid, const void *data){
- pXMLNexus xmlHandle = NULL;
- mxml_node_t *userData = NULL;
- mxml_node_t *current = NULL;
- mxml_node_t *nodeRoot = NULL;
- mxml_node_t *dataNodeRoot = NULL;
- mxml_node_t *dataNode = NULL;
- const char* name;
- pNXDS dataset;
- int i, offset, length;
- xmlHandle = (pXMLNexus)fid;
- assert(xmlHandle);
- /* current points at the Idims node as done in NXXopendatatable */
- current = xmlHandle->stack[xmlHandle->stackPointer].current;
- name = current->value.element.name;
- /* we want to walk all Idata nodes and set name */
- nodeRoot = current->parent->parent;
- dataNodeRoot = nodeRoot;
- offset = 0;
- for(i=0; dataNodeRoot != NULL; i++)
- {
- dataNodeRoot = mxmlFindElement(dataNodeRoot, nodeRoot, DATA_NODE_NAME, NULL, NULL, (i == 0 ? MXML_DESCEND_FIRST : MXML_NO_DESCEND) );
- if (dataNodeRoot != NULL)
- {
- dataNode = mxmlFindElement(dataNodeRoot,dataNodeRoot,name,NULL,NULL,MXML_DESCEND_FIRST);
- if (dataNode != NULL)
- {
- userData = findData(dataNode);
- assert(userData != NULL);
- dataset = (pNXDS)userData->value.custom.data;
- assert(dataset);
- length = getNXDatasetByteLength(dataset);
- memcpy(dataset->u.ptr,(char*)data + offset,length);
- offset += length;
- }
- }
- }
- return NX_OK;
-}
-
-/*------------------------------------------------------------------------*/
-NXstatus NXXputdata (NXhandle fid, const void *data){
- pXMLNexus xmlHandle = NULL;
- mxml_node_t *userData = NULL;
- mxml_node_t *current = NULL;
- pNXDS dataset;
- int i, length, type, rank;
- int64_t dim[NX_MAXRANK];
- char *pPtr = NULL;
-
- xmlHandle = (pXMLNexus)fid;
- assert(xmlHandle);
-
- if (xmlHandle->stack[xmlHandle->stackPointer].options & XMLSTACK_OPTION_TABLE)
- {
- return NXXputdatatable(fid,data);
- }
-
- if(!isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){
- NXReportError("No dataset open");
- return NX_ERROR;
- }
-
- current = xmlHandle->stack[xmlHandle->stackPointer].current;
- userData = findData(current);
- assert(userData != NULL);
- if(userData->type == MXML_OPAQUE){
- /*
- Text data. We have to make sure that the text is \0 terminated.
- Some language bindings do not ensure that this is the case.
- */
- if(NXXgetinfo64(fid,&rank, dim, &type) == NX_OK){
- length = 1;
- for(i=0; ivalue.custom.data;
- assert(dataset);
- length = getNXDatasetByteLength(dataset);
- memcpy(dataset->u.ptr,data,length);
- }
- return NX_OK;
-}
-
-NXstatus NXXgetdatatable (NXhandle fid, void *data){
- pXMLNexus xmlHandle = NULL;
- mxml_node_t *userData = NULL;
- mxml_node_t *current = NULL;
- mxml_node_t *nodeRoot = NULL;
- mxml_node_t *dataNodeRoot = NULL;
- mxml_node_t *dataNode = NULL;
- const char* name;
- pNXDS dataset;
- int i, offset, length;
- xmlHandle = (pXMLNexus)fid;
- assert(xmlHandle);
-
- /* current points at the Idims node as done in NXXopendatatable */
- current = xmlHandle->stack[xmlHandle->stackPointer].current;
- name = current->value.element.name;
- /* we want to walk all Idata nodes and set name */
- nodeRoot = current->parent->parent;
- dataNodeRoot = nodeRoot;
- offset = 0;
- for(i=0; dataNodeRoot != NULL; i++)
- {
- dataNodeRoot = mxmlFindElement(dataNodeRoot, nodeRoot, DATA_NODE_NAME, NULL, NULL, (i == 0 ? MXML_DESCEND_FIRST : MXML_NO_DESCEND) );
- if (dataNodeRoot != NULL)
- {
- dataNode = mxmlFindElement(dataNodeRoot,dataNodeRoot,name,NULL,NULL,MXML_DESCEND_FIRST);
- if (dataNode != NULL)
- {
- userData = findData(dataNode);
- assert(userData != NULL);
- dataset = (pNXDS)userData->value.custom.data;
- assert(dataset);
- length = getNXDatasetByteLength(dataset);
- memcpy((char*)data + offset, dataset->u.ptr, length);
- offset += length;
- }
- }
- }
- return NX_OK;
-}
-
-
-/*------------------------------------------------------------------------*/
-NXstatus NXXgetdata (NXhandle fid, void *data){
- pXMLNexus xmlHandle = NULL;
- mxml_node_t *userData = NULL;
- mxml_node_t *current = NULL;
- pNXDS dataset;
- int i, length, type, rank;
- int64_t dim[NX_MAXRANK];
-
- xmlHandle = (pXMLNexus)fid;
- assert(xmlHandle);
-
- if (xmlHandle->stack[xmlHandle->stackPointer].options & XMLSTACK_OPTION_TABLE)
- {
- return NXXgetdatatable(fid,data);
- }
-
- if(!isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){
- NXReportError("No dataset open");
- return NX_ERROR;
- }
-
- current = xmlHandle->stack[xmlHandle->stackPointer].current;
- userData = findData(current);
- assert(userData != NULL);
- if(userData->type == MXML_OPAQUE){
- /*
- text data
- */
- if(NXXgetinfo64(fid,&rank, dim, &type) == NX_OK){
- length = 1;
- for(i=0; ivalue.opaque,length);
- } else {
- strcpy((char *)data,nxitrim(userData->value.opaque));
- }
-
- } else {
- dataset = (pNXDS)userData->value.custom.data;
- assert(dataset);
- length = getNXDatasetByteLength(dataset);
- memcpy(data,dataset->u.ptr,length);
- }
- return NX_OK;
-}
-/*------------------------------------------------------------------------*/
-NXstatus NXXgetinfo64 (NXhandle fid, int *rank,
- int64_t dimension[], int *iType){
- pXMLNexus xmlHandle = NULL;
- mxml_node_t *userData = NULL;
- mxml_node_t *current = NULL;
- pNXDS dataset;
- int myRank, i;
- const char *attr = NULL;
-
- xmlHandle = (pXMLNexus)fid;
- assert(xmlHandle);
-
- if(!isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){
- NXReportError("No dataset open");
- return NX_ERROR;
- }
-
- current = xmlHandle->stack[xmlHandle->stackPointer].current;
- userData = findData(current);
- assert(userData != NULL);
- if(userData->type == MXML_OPAQUE){
- /*
- text data
- */
- attr = mxmlElementGetAttr(current, TYPENAME);
- if(attr == NULL){
- *rank = 1;
- *iType = NX_CHAR;
- dimension[0]= strlen(userData->value.opaque);
- } else {
- *iType = translateTypeCode(attr);
- analyzeDim(attr,rank,dimension,iType);
- if (dimension[0] == -1) /* 1D strings are NX_CHAR not NX_CHAR[] so length will not be correct */
- {
- dimension[0] = strlen(userData->value.opaque);
- }
-
- }
- } else {
- dataset = (pNXDS)userData->value.custom.data;
- assert(dataset);
- myRank = getNXDatasetRank(dataset);
- *rank = myRank;
- *iType = getNXDatasetType(dataset);
- for(i = 0; i < myRank; i++){
- dimension[i] = getNXDatasetDim(dataset,i);
- }
- }
- return NX_OK;
-}
-/*---------------------------------------------------------------------
- clone the dataset and set the data pointer. This in order to use
- the addressing and type conversion implemented in nxdataset
----------------------------------------------------------------------*/
-static pNXDS makeSlabData(pNXDS dataset, const void *data, const int64_t size[]){
- pNXDS slabData = NULL;
- int rank, i;
-
- slabData = (pNXDS)malloc(sizeof(NXDS));
- if(slabData == NULL){
- return NULL;
- }
-
- rank = getNXDatasetRank(dataset);
- slabData->rank = rank;
- slabData->dim = (int64_t *)malloc(rank*sizeof(int64_t));
- for(i = 0; i < rank; i++){
- slabData->dim[i] = size[i];
- }
- slabData->type = getNXDatasetType(dataset);
- slabData->u.ptr = (void*)data;
- slabData->magic = dataset->magic;
- return slabData;
-}
-/*--------------------------------------------------------------------
- This goes by recursion
-----------------------------------------------------------------------*/
-static void putSlabData(pNXDS dataset, pNXDS slabData, int dim,
- const int64_t start[],
- int64_t sourcePos[], int64_t targetPos[]){
- int64_t i, rank, length;
-
- rank = getNXDatasetRank(slabData);
- length = getNXDatasetDim(slabData,dim);
- if(dim != rank-1){
- for(i = 0; i < length; i++){
- targetPos[dim] = start[dim] +i;
- sourcePos[dim] = i;
- putSlabData(dataset,slabData, dim+1,start,
- sourcePos,targetPos);
- }
- } else {
- for(i = 0; i < length; i++){
- targetPos[dim] = start[dim] +i;
- sourcePos[dim] = i;
- putNXDatasetValue(dataset,targetPos,
- getNXDatasetValue(slabData,sourcePos));
- }
- }
-}
-/*----------------------------------------------------------------------
- This is in order to support unlimited dimensions along the first axis
- -----------------------------------------------------------------------*/
-static int checkAndExtendDataset(mxml_node_t *node, pNXDS dataset,
- const int64_t start[], const int64_t size[]){
- int64_t dim0, byteLength;
- void *oldData = NULL;
- char *typestring = NULL;
-
- dim0 = start[0] + size[0];
- if(dim0 > dataset->dim[0]){
- byteLength = getNXDatasetByteLength(dataset);
- oldData = dataset->u.ptr;
- dataset->dim[0] = dim0;
- dataset->u.ptr = malloc(getNXDatasetByteLength(dataset));
- if(dataset->u.ptr == NULL){
- return 0;
- }
- memset(dataset->u.ptr,0,getNXDatasetByteLength(dataset));
- memcpy(dataset->u.ptr,oldData,byteLength);
- free(oldData);
- typestring = buildTypeString(dataset->type,dataset->rank,dataset->dim);
- if(typestring != NULL){
- mxmlElementSetAttr(node,TYPENAME,typestring);
- free(typestring);
- } else {
- NXReportError("Failed to allocate typestring");
- return 0;
- }
- }
- return 1;
-}
-
-NXstatus NXXputslabtable (NXhandle fid, const void *data,
- const int64_t iStart[], const int64_t iSize[]){
- return NX_OK;
-}
-/*----------------------------------------------------------------------*/
-NXstatus NXXputslab64 (NXhandle fid, const void *data,
- const int64_t iStart[], const int64_t iSize[]){
-
- pXMLNexus xmlHandle = NULL;
- mxml_node_t *userData = NULL;
- mxml_node_t *current = NULL;
- pNXDS dataset, slabData;
- int64_t sourcePos[NX_MAXRANK], targetPos[NX_MAXRANK];
- int status;
-
- xmlHandle = (pXMLNexus)fid;
- assert(xmlHandle);
-
- if (xmlHandle->stack[xmlHandle->stackPointer].options & XMLSTACK_OPTION_TABLE)
- {
- return NXXputslabtable(fid,data,iStart,iSize);
- }
-
- if(!isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){
- NXReportError("No dataset open");
- return NX_ERROR;
- }
-
- current = xmlHandle->stack[xmlHandle->stackPointer].current;
- userData = findData(current);
- assert(userData != NULL);
- if(userData->type == MXML_OPAQUE){
- NXReportError("This API does not support slabs on text data");
- return NX_ERROR;
- }
- dataset = (pNXDS)userData->value.custom.data;
- assert(dataset);
-
- status = checkAndExtendDataset(current,dataset,iStart,iSize);
- if(status == 0){
- NXReportError("Out of memory extending dataset");
- return NX_ERROR;
- }
-
- slabData = makeSlabData(dataset, data, iSize);
- if(slabData == NULL){
- NXReportError("Failed to allocate slab data");
- return NX_ERROR;
- }
-
-
- putSlabData(dataset,slabData,0,iStart,sourcePos,targetPos);
- free(slabData->dim);
- free(slabData);
-
- return NX_OK;
-}
-/*--------------------------------------------------------------------
- This goes by recursion
-----------------------------------------------------------------------*/
-static void getSlabData(pNXDS dataset, pNXDS slabData, int dim,
- const int64_t start[],
- int64_t sourcePos[],int64_t targetPos[]){
- int64_t i, rank, length;
-
- rank = getNXDatasetRank(slabData);
- length = getNXDatasetDim(slabData,dim);
- if(dim != rank-1){
- for(i = 0; i < length; i++){
- sourcePos[dim] = start[dim] +i;
- targetPos[dim] = i;
- getSlabData(dataset,slabData, dim+1,start,
- sourcePos,targetPos);
- }
- } else {
- for(i = 0; i < length; i++){
- sourcePos[dim] = start[dim] +i;
- targetPos[dim] = i;
- putNXDatasetValue(slabData,targetPos,
- getNXDatasetValue(dataset,sourcePos));
- }
- }
-}
-/*----------------------------------------------------------------------*/
-NXstatus NXXgetslab64 (NXhandle fid, void *data,
- const int64_t iStart[], const int64_t iSize[]){
- pXMLNexus xmlHandle = NULL;
- mxml_node_t *userData = NULL;
- mxml_node_t *current = NULL;
- pNXDS dataset, slabData;
- int64_t sourcePos[NX_MAXRANK], targetPos[NX_MAXRANK];
-
- xmlHandle = (pXMLNexus)fid;
- assert(xmlHandle);
-
- if(!isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){
- NXReportError("No dataset open");
- return NX_ERROR;
- }
-
- current = xmlHandle->stack[xmlHandle->stackPointer].current;
- userData = findData(current);
- assert(userData != NULL);
- if(userData->type == MXML_OPAQUE){
- NXReportError("This API does not support slabs on text data");
- return NX_ERROR;
- }
- dataset = (pNXDS)userData->value.custom.data;
- assert(dataset);
- slabData = makeSlabData(dataset, data, iSize);
- if(slabData == NULL){
- NXReportError("Failed to allocate slab data");
- return NX_ERROR;
- }
- getSlabData(dataset,slabData,0,iStart,sourcePos,targetPos);
- free(slabData->dim);
- free(slabData);
-
- return NX_OK;
-}
-/*----------------------------------------------------------------------*/
-static NXstatus NXXsetnumberformat(NXhandle fid,
- int type, char *format){
- pXMLNexus xmlHandle = NULL;
- mxml_node_t *current = NULL;
- mxml_node_t *userData = NULL;
- pNXDS dataset;
-
- xmlHandle = (pXMLNexus)fid;
- assert(xmlHandle);
-
- if(isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){
- current = xmlHandle->stack[xmlHandle->stackPointer].current;
- userData = findData(current);
- assert(userData != NULL);
- if(userData->type == MXML_OPAQUE){
- return NX_OK;
- }
- dataset = (pNXDS)userData->value.custom.data;
- assert(dataset);
- if(dataset->format != NULL){
- free(dataset->format);
- }
- dataset->format = strdup(format);
- } else {
- setNumberFormat(type, format);
- }
- return NX_OK;
-}
-/*============================ Attributes ============================*/
-static char *formatAttributeData(const void *data, int datalen, int iType){
- int intData = 0;
- long iValue = -99999;
- double dValue = -1e38;
- char type[20];
- char *number;
-
-
- if(iType == NX_CHAR){
-/* data may not be NULL terminated */
- number = (char*)malloc((datalen+1) * sizeof(char));
- memcpy(number, data, datalen * sizeof(char));
- number[datalen] = '\0';
- return number;
- }
-
- number = (char *)malloc(132*sizeof(char));
- if(!number){
- NXReportError("Failed to allocate attribute number buffer");
- return NULL;
- }
-
- if(datalen > 1){
- return NULL;
- }
- type[0] = '\0';
- switch(iType){
- case NX_INT32:
- iValue = ((int *)data)[0];
- intData = 1;
- strcpy(type,"NX_INT32:");
- break;
- case NX_UINT32:
- iValue = ((unsigned int *)data)[0];
- intData = 1;
- strcpy(type,"NX_UINT32:");
- break;
- case NX_INT16:
- iValue = ((short *)data)[0];
- intData = 1;
- strcpy(type,"NX_INT16:");
- break;
- case NX_UINT16:
- iValue = ((unsigned short *)data)[0];
- intData = 1;
- strcpy(type,"NX_UINT16:");
- break;
- case NX_INT8:
- iValue = (int)((char *)data)[0];
- intData = 1;
- strcpy(type,"NX_INT8:");
- break;
- case NX_UINT8:
- intData = 1;
- iValue = (int)((unsigned char *)data)[0];
- strcpy(type,"NX_UINT8:");
- break;
- case NX_FLOAT32:
- dValue = ((float *)data)[0];
- strcpy(type,"NX_FLOAT32:");
- intData = 0;
- break;
- case NX_FLOAT64:
- dValue = ((double *)data)[0];
- strcpy(type,"NX_FLOAT64:");
- intData = 0;
- break;
- }
- if(intData){
- snprintf(number,79,"%s%ld",type,iValue);
- } else {
- snprintf(number,79,"%s%f",type,dValue);
- }
- return number;
-}
-/*---------------------------------------------------------------------*/
-NXstatus NXXputattr (NXhandle fid, CONSTCHAR *name, const void *data,
- int datalen, int iType){
- char buffer[256];
- pXMLNexus xmlHandle = NULL;
- mxml_node_t *current = NULL;
- char *numberData = NULL;
-
- xmlHandle = (pXMLNexus)fid;
- assert(xmlHandle);
- if (!validNXName(name, 1))
- {
- sprintf(buffer, "ERROR: invalid characters in attribute name \"%s\"", name);
- NXReportError(buffer);
- return NX_ERROR;
- }
-
- current = xmlHandle->stack[xmlHandle->stackPointer].current;
- if(isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){
- if(strcmp(name,TYPENAME) == 0){
- NXReportError("type is a reserved attribute name, rejected");
- return NX_ERROR;
- }
- }
-
- numberData = formatAttributeData(data,datalen,iType);
- if(numberData == NULL){
- NXReportError("This API does not support non number arrays");
- return NX_ERROR;
- } else {
- mxmlElementSetAttr(current,name,numberData);
- free(numberData);
- }
- return NX_OK;
-}
-/*--------------------------------------------------------------------------*/
-NXstatus NXXgetattr (NXhandle fid, char *name,
- void *data, int* datalen, int* iType){
- pXMLNexus xmlHandle = NULL;
- mxml_node_t *current = NULL;
- const char *attribute = NULL;
- char error[1024];
- const char *attData = NULL;
- int nx_type;
-
- xmlHandle = (pXMLNexus)fid;
- assert(xmlHandle);
-
- current = xmlHandle->stack[xmlHandle->stackPointer].current;
-
- attribute = mxmlElementGetAttr(current,name);
- if(!attribute){
- snprintf(error,1023,"Attribute %s not found", name);
- NXReportError(error);
- return NX_ERROR;
- }
- nx_type = translateTypeCode((char *)attribute);
- if(nx_type < 0) {
- /*
- no type code == text attribute
- */
- nx_type = NX_CHAR;
- } else {
- /*
- We need to find the number after the type code. However, there is
- the complication of the datatype type attribute ...
- */
- if(strcmp(name,TYPENAME) == 0){
- nx_type = NX_CHAR;
- } else {
- attData = strchr(attribute,(int)':');
- if(attData == NULL){
- NXReportError("ERROR: bad attribute string, : missing");
- return NX_ERROR;
- }
- attData++;
- }
- }
- *iType = nx_type;
- switch(nx_type){
- case NX_CHAR:
- /* enforce NULL termination regardless of length of datalen */
- strncpy((char *)data, attribute, *datalen-1);
- ((char*)data)[*datalen-1] = '\0';
- /* *datalen = strlen(attribute); */
- *datalen = strlen((char*)data);
- *iType = NX_CHAR;
- break;
- case NX_INT32:
- ((int *)data)[0] = atoi(attData);
- *datalen = 1;
- break;
- case NX_UINT32:
- ((unsigned int *)data)[0] = atoi(attData);
- *datalen = 1;
- break;
- case NX_INT16:
- ((short *)data)[0] = atoi(attData);
- *datalen = 1;
- break;
- case NX_UINT16:
- ((unsigned short *)data)[0] = atoi(attData);
- *datalen = 1;
- break;
- case NX_INT8:
- ((char *)data)[0] = atoi(attData);
- *datalen = 1;
- break;
- case NX_UINT8:
- ((unsigned char *)data)[0] = atoi(attData);
- *datalen = 1;
- break;
- case NX_FLOAT32:
- ((float *)data)[0] = atof(attData);
- *datalen = 1;
- break;
- case NX_FLOAT64:
- ((double *)data)[0] = atof(attData);
- *datalen = 1;
- break;
- }
-
- return NX_OK;
-}
-
-/* find the next node, ignoring Idata */
-static mxml_node_t* find_node(mxml_node_t* node, int next)
-{
- int done = 0;
- mxml_node_t* parent_next = NULL; /* parent to use if we are in an Idims search */
- if (node == NULL)
- {
- return NULL;
- }
- if ( (node->parent != NULL) && !strcmp(node->parent->value.element.name, DIMS_NODE_NAME) )
- {
- parent_next = node->parent->next;
- }
- else
- {
- parent_next = NULL;
- }
- if (next)
- {
- if (node->next != NULL)
- {
- node = node->next;
- }
- else
- {
- node = parent_next;
- }
- }
- while(node != NULL && !done)
- {
- if ( (node->parent != NULL) && !strcmp(node->parent->value.element.name, DIMS_NODE_NAME) )
- {
- parent_next = node->parent->next;
- }
- else
- {
- parent_next = NULL;
- }
- if ( (node->type != MXML_ELEMENT) || !strcmp(node->value.element.name, DATA_NODE_NAME) )
- {
- if (node->next != NULL)
- {
- node = node->next;
- }
- else
- {
- node = parent_next;
- }
- continue;
- }
- if (!strcmp(node->value.element.name, DIMS_NODE_NAME))
- {
- node = node->child;
- continue;
- }
- done = 1;
- }
- return node;
-}
-
-/*====================== search functions =================================*/
-NXstatus NXXgetnextentry (NXhandle fid,NXname name,
- NXname nxclass, int *datatype){
- pXMLNexus xmlHandle = NULL;
- mxml_node_t *next = NULL, *userData, *node = NULL;
- int stackPtr;
- const char *target = NULL, *attname = NULL;
- pNXDS dataset;
- char pBueffel[256];
- const char *linkName = NULL;
-
- xmlHandle = (pXMLNexus)fid;
- assert(xmlHandle);
-
- if(isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){
- /*
- be nice to user: silently fix this problem
- */
- NXXclosedata(fid);
- }
-
- stackPtr = xmlHandle->stackPointer;
- if(xmlHandle->stack[stackPtr].currentChild == NULL){
- /*
- initialization of search
- */
- node = find_node(xmlHandle->stack[stackPtr].current->child, 0);
- } else {
- /*
- proceed
- */
- node = find_node(xmlHandle->stack[stackPtr].currentChild, 1);
- }
- xmlHandle->stack[stackPtr].currentChild = node;
- next = node;
- if(next == NULL){
- return NX_EOD;
- }
- if(strcmp(next->value.element.name,"NAPIlink") == 0){
- target = mxmlElementGetAttr(next,"target");
- linkName = mxmlElementGetAttr(next,"name");
- if(target == NULL){
- NXReportError("Corrupted file, NAPIlink without target");
- return NX_ERROR;
- }
- next = getLinkTarget(xmlHandle,target);
- if(next == NULL){
- NXReportError("Corrupted file, broken link");
- return NX_ERROR;
- }
- }
-
- if(isDataNode(next)){
- strcpy(name,next->value.element.name);
- strcpy(nxclass,"SDS");
- userData = findData(next);
- if(userData == NULL){
- snprintf(pBueffel,255,"Corrupted file, userData for %s not found",
- name);
- NXReportError(pBueffel);
- return NX_ERROR;
- }
- if(userData->type == MXML_OPAQUE){
- *datatype = NX_CHAR;
- } else {
- dataset = (pNXDS)userData->value.custom.data;
- assert(dataset);
- *datatype = getNXDatasetType(dataset);
- }
- } else {
- strcpy(nxclass,next->value.element.name);
- attname = mxmlElementGetAttr(next,"name");
- strcpy(name,attname);
- }
- /*
- this is for named links
- */
- if(linkName != NULL){
- strcpy(name,linkName);
- }
- return NX_OK;
-}
-/*----------------------------------------------------------------------*/
-extern NXstatus NXXinitgroupdir(NXhandle fid){
- pXMLNexus xmlHandle = NULL;
- int stackPtr;
-
- xmlHandle = (pXMLNexus)fid;
- assert(xmlHandle);
-
- if(isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){
- NXReportError("Cannot search datasets");
- return NX_ERROR;
- }
-
- stackPtr = xmlHandle->stackPointer;
- xmlHandle->stack[stackPtr].currentChild = NULL;
- return NX_OK;
-}
-/*-------------------------------------------------------------------------*/
-NXstatus NXXgetnextattr (NXhandle fid, NXname pName,
- int *iLength, int *iType){
- pXMLNexus xmlHandle = NULL;
- mxml_node_t *current = NULL;
- int stackPtr, currentAtt, nx_type;
- char *attVal;
-
- xmlHandle = (pXMLNexus)fid;
- assert(xmlHandle);
-
- stackPtr = xmlHandle->stackPointer;
-
- current = xmlHandle->stack[stackPtr].current;
- currentAtt = xmlHandle->stack[stackPtr].currentAttribute;
- if(currentAtt >=
- current->value.element.num_attrs ){
- xmlHandle->stack[stackPtr].currentAttribute = 0;
- return NX_EOD;
- }
-
- /*
- hide group name attribute
- */
- if(strcmp(current->value.element.attrs[currentAtt].name,"name") == 0
- && !isDataNode(current) ){
- xmlHandle->stack[stackPtr].currentAttribute++;
- return NXXgetnextattr(fid,pName,iLength,iType);
- }
-
- /*
- hide type attribute
- */
- if(strcmp(current->value.element.attrs[currentAtt].name,TYPENAME) == 0
- && isDataNode(current)){
- xmlHandle->stack[stackPtr].currentAttribute++;
- return NXXgetnextattr(fid,pName,iLength,iType);
- }
-
- strcpy(pName,current->value.element.attrs[currentAtt].name);
- attVal = current->value.element.attrs[currentAtt].value;
- nx_type = translateTypeCode((char *)attVal);
- if(nx_type < 0 || strcmp(pName,TYPENAME) == 0){
- /*
- no type == NX_CHAR
- */
- *iLength = strlen(attVal);
- *iType = NX_CHAR;
- } else {
- *iLength = 1;
- *iType = nx_type;
- }
-
- xmlHandle->stack[stackPtr].currentAttribute++;
- return NX_OK;
-}
-/*-------------------------------------------------------------------------*/
-extern NXstatus NXXinitattrdir(NXhandle fid){
- pXMLNexus xmlHandle = NULL;
- int stackPtr;
-
- xmlHandle = (pXMLNexus)fid;
- assert(xmlHandle);
-
- stackPtr = xmlHandle->stackPointer;
- xmlHandle->stack[stackPtr].currentAttribute = 0;
- return NX_OK;
-}
-/*-------------------------------------------------------------------------*/
-NXstatus NXXgetgroupinfo (NXhandle fid, int *iN,
- NXname pName, NXname pClass){
- pXMLNexus xmlHandle = NULL;
- mxml_node_t *node = NULL, *child = NULL;
- mxml_node_t *current = NULL;
- const char *nameAtt = NULL;
- int childCount;
-
- xmlHandle = (pXMLNexus)fid;
- assert(xmlHandle);
-
- if(isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){
- NXReportError("No group open");
- return NX_ERROR;
- }
- current = xmlHandle->stack[xmlHandle->stackPointer].current;
-
- nameAtt = mxmlElementGetAttr(current,"name");
- if(nameAtt != NULL){
- strcpy(pName,nameAtt);
- }
- strcpy(pClass,current->value.element.name);
-
-/* count all child nodes, but need to ignore DATA_NODE_NAME and
- * descend into DIMS_NODE_NAME
- */
- childCount = 0;
- node = current->child;
- while(node != NULL)
- {
- if (!strcmp(node->value.element.name, DATA_NODE_NAME))
- {
- ; /* names also exist in DIMS_NODE_NAME so do nothing here */
- }
- else if (!strcmp(node->value.element.name, DIMS_NODE_NAME))
- {
- child = node->child;
- while(child != NULL)
- {
- /* not sure why this check is needed, but you double count otherwise */
- if (child->type == MXML_ELEMENT)
- {
- childCount++;
- }
- child = child->next;
- }
- }
- else
- {
- childCount++;
- }
- node = node->next;
- }
- *iN = childCount;
- return NX_OK;
-}
-/*----------------------------------------------------------------------*/
-NXstatus NXXgetattrinfo (NXhandle fid, int *iN){
- pXMLNexus xmlHandle = NULL;
- mxml_node_t *current = NULL;
- int stackPtr, skip;
-
- xmlHandle = (pXMLNexus)fid;
- assert(xmlHandle);
-
- stackPtr = xmlHandle->stackPointer;
-
- current = xmlHandle->stack[stackPtr].current;
-
- /*
- hide type and group name attributes
- */
- skip=0;
- if(isDataNode(current)) {
- /* data nodes may have type */
- if(mxmlElementGetAttr(current,TYPENAME) != NULL) skip=1;
- } else {
- /* group nodes (except root) have name */
- if(mxmlElementGetAttr(current,"name") != NULL) skip=1;
- }
- *iN = current->value.element.num_attrs - skip;
- return NX_OK;
-}
-/*================= Linking functions =================================*/
-static int countPathChars(mxml_node_t *path[], int stackPtr){
- int count = 1;
- const char *name = NULL;
-
- while(stackPtr >= 0) {
- if(isDataNode(path[stackPtr])){
- count += strlen(path[stackPtr]->value.element.name);
- } else {
- name = mxmlElementGetAttr(path[stackPtr],"name");
- if(name != NULL){
- count += strlen(name);
- }
- }
- stackPtr--;
- count += 1;
- }
- return count;
-}
-/*-------------------------------------------------------------------*/
-static char *buildPathString(mxml_node_t *path[], int stackPtr){
- int count = 0;
- const char *name = NULL;
- char *pathString = NULL;
-
- count = countPathChars(path,stackPtr);
- pathString = (char *)malloc((count+10)*sizeof(char));
- if(pathString == NULL){
- return NULL;
- }
- memset(pathString,0,(count+10)*sizeof(char));
-
- while(stackPtr >= 0) {
- if(isDataNode(path[stackPtr])){
- strcat(pathString,"/");
- strcat(pathString,path[stackPtr]->value.element.name);
- } else {
- name = mxmlElementGetAttr(path[stackPtr],"name");
- if(name != NULL){
- strcat(pathString,"/");
- strcat(pathString,name);
- }
- }
- stackPtr--;
- }
- return pathString;
-}
-/*--------------------------------------------------------------------*/
-static char *findLinkPath(mxml_node_t *node){
- mxml_node_t **path = NULL;
- int stackPtr;
- mxml_node_t *current = NULL;
- char *result = NULL;
-
- path = (mxml_node_t **)malloc(NXMAXSTACK*sizeof(mxml_node_t *));
- if(path == NULL){
- NXReportError("ERROR: out of memory following link path");
- return NULL;
- }
- memset(path,0,NXMAXSTACK*sizeof(mxml_node_t *));
-
- /*
- first path: walk up the tree untill NXroot is found
- */
- current = node;
- stackPtr = 0;
- while(current != NULL &&
- strcmp(current->value.element.name,"NXroot") != 0){
- path[stackPtr] = current;
- stackPtr++;
- current = current->parent;
- }
- stackPtr--;
-
- /*
- path now contains the nodes to the root node in reverse order.
- From this build the path string
- */
- result = buildPathString(path,stackPtr);
- free(path);
- return result;
-}
-/*--------------------------------------------------------------------*/
-NXstatus NXXgetdataID (NXhandle fid, NXlink* sRes){
- pXMLNexus xmlHandle = NULL;
- mxml_node_t *current = NULL;
- char *linkPath = NULL;
-
- xmlHandle = (pXMLNexus)fid;
- assert(xmlHandle);
-
- if(!isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){
- return NX_ERROR;
- }
- current = xmlHandle->stack[xmlHandle->stackPointer].current;
-
- linkPath = findLinkPath(current);
- if(!linkPath){
- NXReportError("Failed to allocate link path string");
- return NX_ERROR;
- }
- strncpy(sRes->targetPath,linkPath,1023);
- free(linkPath);
- return NX_OK;
-}
-/*--------------------------------------------------------------------*/
-NXstatus NXXgetgroupID (NXhandle fid, NXlink* sRes){
- pXMLNexus xmlHandle = NULL;
- mxml_node_t *current = NULL;
- char *linkPath = NULL;
-
- xmlHandle = (pXMLNexus)fid;
- assert(xmlHandle);
-
- if(isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){
- NXReportError("No group open");
- return NX_ERROR;
- }
- current = xmlHandle->stack[xmlHandle->stackPointer].current;
-
- if(xmlHandle->stackPointer == 0){
- return NX_ERROR;
- }
-
- linkPath = findLinkPath(current);
- if(!linkPath){
- NXReportError("Failed to allocate link path string");
- return NX_ERROR;
- }
- strncpy(sRes->targetPath,linkPath,1023);
- free(linkPath);
- return NX_OK;
-}
-
-/*-----------------------------------------------------------------------*/
- NXstatus NXXprintlink (NXhandle fid, NXlink* sLink)
- {
- pXMLNexus xmlHandle = NULL;
- xmlHandle = (pXMLNexus)fid;
- assert(xmlHandle);
-
- printf("XML link: target=\"%s\"\n", sLink->targetPath);
- return NX_OK;
- }
-
-/*-----------------------------------------------------------------------*/
-NXstatus NXXmakelink (NXhandle fid, NXlink* sLink){
- pXMLNexus xmlHandle = NULL;
- mxml_node_t *current = NULL, *linkNode = NULL;
- mxml_node_t *linkedNode = NULL;
-
- xmlHandle = (pXMLNexus)fid;
- assert(xmlHandle);
-
- if(isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){
- NXReportError("No group to link to open");
- return NX_ERROR;
- }
- current = xmlHandle->stack[xmlHandle->stackPointer].current;
- linkNode = mxmlNewElement(current,"NAPIlink");
- if(!linkNode){
- NXReportError("Failed to allocate new link element");
- return NX_ERROR;
- }
- mxmlElementSetAttr(linkNode,"target",sLink->targetPath);
- linkedNode = getLinkTarget(xmlHandle,sLink->targetPath);
- if(linkedNode != NULL){
- mxmlElementSetAttr(linkedNode,"target",sLink->targetPath);
- }
- return NX_OK;
-}
-
-/*-----------------------------------------------------------------------*/
-NXstatus NXXmakenamedlink (NXhandle fid, CONSTCHAR *name, NXlink* sLink){
- pXMLNexus xmlHandle = NULL;
- mxml_node_t *current = NULL, *linkNode = NULL;
- mxml_node_t *linkedNode = NULL;
- char buffer[256];
-
- xmlHandle = (pXMLNexus)fid;
- assert(xmlHandle);
- if (!validNXName(name, 0))
- {
- sprintf(buffer, "ERROR: invalid characters in link name \"%s\"", name);
- NXReportError(buffer);
- return NX_ERROR;
- }
-
- if(isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){
- NXReportError("No group to link to open");
- return NX_ERROR;
- }
- current = xmlHandle->stack[xmlHandle->stackPointer].current;
- linkNode = mxmlNewElement(current,"NAPIlink");
- if(!linkNode){
- NXReportError("Failed to allocate new link element");
- return NX_ERROR;
- }
- mxmlElementSetAttr(linkNode,"target",sLink->targetPath);
- mxmlElementSetAttr(linkNode,"name",name);
- linkedNode = getLinkTarget(xmlHandle,sLink->targetPath);
- if(linkedNode != NULL){
- mxmlElementSetAttr(linkedNode,"target",sLink->targetPath);
- }
- return NX_OK;
-}
-/*----------------------------------------------------------------------*/
-NXstatus NXXsameID (NXhandle fileid, NXlink* pFirstID,
- NXlink* pSecondID){
- if(strcmp(pFirstID->targetPath,pSecondID->targetPath) == 0) {
- return NX_OK;
- } else {
- return NX_ERROR;
- }
-}
-/*--------------------------------------------------------------------*/
-int NXXcompress(NXhandle fid, int comp){
- /* that will throw an exception in the Java API, errors have to be fatal */
- /* NXReportError("NXcompress is deprecated, IGNORED"); */
- return NX_OK;
-}
-/*----------------------------------------------------------------------*/
-void NXXassignFunctions(pNexusFunction fHandle){
- fHandle->nxclose=NXXclose;
- fHandle->nxreopen=NULL;
- fHandle->nxflush=NXXflush;
- fHandle->nxmakegroup=NXXmakegroup;
- fHandle->nxopengroup=NXXopengroup;
- fHandle->nxclosegroup=NXXclosegroup;
- fHandle->nxmakedata64=NXXmakedata64;
- fHandle->nxcompmakedata64=NXXcompmakedata64;
- fHandle->nxcompress=NXXcompress;
- fHandle->nxopendata=NXXopendata;
- fHandle->nxclosedata=NXXclosedata;
- fHandle->nxputdata=NXXputdata;
- fHandle->nxputattr=NXXputattr;
- fHandle->nxputslab64=NXXputslab64;
- fHandle->nxgetdataID=NXXgetdataID;
- fHandle->nxmakelink=NXXmakelink;
- fHandle->nxmakenamedlink=NXXmakenamedlink;
- fHandle->nxgetdata=NXXgetdata;
- fHandle->nxgetinfo64=NXXgetinfo64;
- fHandle->nxgetnextentry=NXXgetnextentry;
- fHandle->nxgetslab64=NXXgetslab64;
- fHandle->nxgetnextattr=NXXgetnextattr;
- fHandle->nxgetattr=NXXgetattr;
- fHandle->nxgetattrinfo=NXXgetattrinfo;
- fHandle->nxgetgroupID=NXXgetgroupID;
- fHandle->nxgetgroupinfo=NXXgetgroupinfo;
- fHandle->nxsameID=NXXsameID;
- fHandle->nxinitgroupdir=NXXinitgroupdir;
- fHandle->nxinitattrdir=NXXinitattrdir;
- fHandle->nxsetnumberformat=NXXsetnumberformat;
- fHandle->nxprintlink=NXXprintlink;
- fHandle->nxnativeexternallink=NULL;
-}
-
-
-
-#endif /*NXXML*/
diff --git a/nxxml.h b/nxxml.h
deleted file mode 100644
index 03c09a2c..00000000
--- a/nxxml.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * This is the header file for the NeXus XML file driver.
- *
- * Copyright (C) 2004 Mark Koennecke
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * For further information, see
- */
-#ifndef NEXUSXML
-#define NEXUSXML
-
-extern NXstatus NXXopen(CONSTCHAR *filename,
- NXaccess access_method,
- NXhandle* pHandle);
-extern NXstatus NXXclose(NXhandle* pHandle);
-extern NXstatus NXXflush(NXhandle* pHandle);
-
-NXstatus NXXmakegroup (NXhandle fid, CONSTCHAR *name,
- CONSTCHAR *nxclass);
-NXstatus NXXopengroup (NXhandle fid, CONSTCHAR *name,
- CONSTCHAR *nxclass);
-NXstatus NXXclosegroup (NXhandle fid);
-
-NXstatus NXXcompmakedata64 (NXhandle fid, CONSTCHAR *name,
- int datatype,
- int rank,
- int64_t dimensions[],
- int compress_type, int64_t chunk_size[]);
-NXstatus NXXmakedata64 (NXhandle fid,
- CONSTCHAR *name, int datatype,
- int rank, int64_t dimensions[]);
-NXstatus NXXopendata (NXhandle fid, CONSTCHAR *name);
-NXstatus NXXclosedata (NXhandle fid);
-NXstatus NXXputdata (NXhandle fid, const void *data);
-NXstatus NXXgetdata (NXhandle fid, void *data);
-NXstatus NXXgetinfo64 (NXhandle fid, int *rank,
- int64_t dimension[], int *iType);
-NXstatus NXXputslab64 (NXhandle fid, const void *data,
- const int64_t iStart[], const int64_t iSize[]);
-NXstatus NXXgetslab64 (NXhandle fid, void *data,
- const int64_t iStart[], const int64_t iSize[]);
-NXstatus NXXputattr (NXhandle fid, CONSTCHAR *name, const void *data,
- int datalen, int iType);
-NXstatus NXXgetattr (NXhandle fid, char *name,
- void *data, int* datalen, int* iType);
-
-NXstatus NXXgetnextentry (NXhandle fid,NXname name,
- NXname nxclass, int *datatype);
-extern NXstatus NXXgetnextattr(NXhandle handle,
- NXname pName, int *iLength, int *iType);
-extern NXstatus NXXinitgroupdir(NXhandle handle);
-extern NXstatus NXXinitattrdir(NXhandle handle);
-extern NXstatus NXXgetattrinfo (NXhandle fid, int *iN);
-extern NXstatus NXXgetgroupinfo (NXhandle fid, int *iN,
- NXname pName, NXname pClass);
-
-extern NXstatus NXXgetdataID (NXhandle fid, NXlink* sRes);
-extern NXstatus NXXgetgroupID (NXhandle fid, NXlink* sRes);
-extern NXstatus NXXmakelink (NXhandle fid, NXlink* sLink);
-extern NXstatus NXXprintlink (NXhandle fid, NXlink* sLink);
-extern NXstatus NXXsameID (NXhandle fileid,
- NXlink* pFirstID, NXlink* pSecondID);
-
-void NXXassignFunctions(pNexusFunction fHandle);
-#endif
diff --git a/obdes.h b/obdes.h
index d1477dc0..fd738465 100644
--- a/obdes.h
+++ b/obdes.h
@@ -1,5 +1,5 @@
-#line 385 "interface.w"
+#line 398 "interface.w"
#line 29 "interface.w"
@@ -25,19 +25,19 @@
#include
#include
-typedef struct {
- char *name;
- int (*SaveStatus) (void *self, char *name, FILE * fd);
- void *(*GetInterface) (void *self, int iInterfaceID);
- IPair *pKeys;
- pHdb parNode;
-} ObjectDescriptor, *pObjectDescriptor;
+ typedef struct {
+ char *name;
+ int (*SaveStatus)(void *self, char *name,FILE *fd);
+ void *(*GetInterface)(void *self, int iInterfaceID);
+ IPair *pKeys;
+ pHdb parNode;
+ } ObjectDescriptor, *pObjectDescriptor;
/*---------------------------------------------------------------------------*/
-pObjectDescriptor CreateDescriptor(char *name);
-void DeleteDescriptor(pObjectDescriptor self);
-pObjectDescriptor FindDescriptor(void *pData);
-
+ pObjectDescriptor CreateDescriptor(char *name);
+ void DeleteDescriptor(pObjectDescriptor self);
+ pObjectDescriptor FindDescriptor(void *pData);
+
/*============================================================================
Objects which do not carry data need a dummy descriptor. Otherwise
drive or scan will protection fault when trying to drive something
@@ -45,26 +45,26 @@ pObjectDescriptor FindDescriptor(void *pData);
*/
typedef struct {
- pObjectDescriptor pDescriptor;
-} Dummy, *pDummy;
+ pObjectDescriptor pDescriptor;
+ }Dummy, *pDummy;
+
+ pDummy CreateDummy(char *name);
+ void KillDummy(void *pData);
-pDummy CreateDummy(char *name);
-void KillDummy(void *pData);
+ int iHasType(void *pData, char *Type);
+
+#endif
-int iHasType(void *pData, char *Type);
-
-#endif
-
-#line 386 "interface.w"
+#line 399 "interface.w"
/*--------------------------------------------------------------------------*/
/* Additional properties used by the ANSTO site to provide more information
* about each object instance, especially devices.
*/
-void SetDescriptorKey(pObjectDescriptor self, char *keyName, char *value);
-void SetDescriptorGroup(pObjectDescriptor self, char *group);
-void SetDescriptorDescription(pObjectDescriptor self, char *description);
-char *GetDescriptorKey(pObjectDescriptor self, char *keyName);
-char *GetDescriptorGroup(pObjectDescriptor self);
-char *GetDescriptorDescription(pObjectDescriptor self);
+ void SetDescriptorKey(pObjectDescriptor self, char *keyName, char *value);
+ void SetDescriptorGroup(pObjectDescriptor self, char *group);
+ void SetDescriptorDescription(pObjectDescriptor self, char *description);
+ char * GetDescriptorKey(pObjectDescriptor self, char *keyName);
+ char * GetDescriptorGroup(pObjectDescriptor self);
+ char * GetDescriptorDescription(pObjectDescriptor self);
diff --git a/ofac.c b/ofac.c
index 9fca22bb..cdc9a703 100644
--- a/ofac.c
+++ b/ofac.c
@@ -18,6 +18,8 @@
#include "sicshipadaba.h"
#include "sicsglobal.h"
+static unsigned int killStartupCommands = 1;
+
extern void DevExecInit(void); /* devexec.c */
/*--------------------------------------------------------------------------*/
static void InitGeneral(void)
@@ -34,6 +36,7 @@ static void InitGeneral(void)
INIT(SctDriveAdapterInit);
INIT(SctDriveObjInit);
INIT(SctDriveAdapterInit);
+ INIT(SICSGetInit);
INIT(LogReaderInit);
INIT(LogSetupInit);
INIT(InstallBackground);
@@ -45,6 +48,8 @@ static void InitGeneral(void)
INIT(AddGenBinProtocoll);
INIT(AddSyncedProt);
INIT(MakeTrace);
+ INIT(InitTaskOBJ);
+ INIT(RemoteObjectInit);
INIT(SiteInit); /* site specific initializations */
}
@@ -115,6 +120,7 @@ static void InitIniCommands(SicsInterp * pInter)
PCMD("TclReplaceDrivable", TclReplaceDrivable);
PCMD("transact", TransactAction);
PCMD("wait", UserWait);
+ PCMD("yield", UserYield);
PCMD("checksum", CheckSum);
/* startup commands in alphabetic order */
@@ -143,6 +149,7 @@ static void InitIniCommands(SicsInterp * pInter)
SCMD("MakeMcStasReader", McStasReaderFactory);
SCMD("MakeMono", MonoInit);
SCMD("MakeMultiCounter", MakeMultiCounter);
+ SCMD("MakeMultiSec", MakeMultiSec);
SCMD("MakeNXScript", MakeNXScript);
SCMD("MakeO2T", CreateO2T);
SCMD("MakeOscillator", MakeOscillator);
@@ -230,8 +237,14 @@ int InitObjectCommands(pServer pServ, char *file)
if (site != NULL && site->RemoveSiteCommands != NULL) {
site->RemoveSiteCommands(pSics);
}
-
- RemoveStartupCommands();
+ if(killStartupCommands){
+ RemoveStartupCommands();
+ }
isDuringInitialization = 0;
return 1;
}
+/*---------------------------------------------------------------------------------*/
+void KeepStartupCommands()
+{
+ killStartupCommands = 0;
+}
diff --git a/ofac.h b/ofac.h
index fd13d0f2..55ec03a2 100644
--- a/ofac.h
+++ b/ofac.h
@@ -21,5 +21,4 @@
#include "sics.h"
int InitObjectCommands(pServer pServ, char *file);
-
#endif
diff --git a/oscillate.c b/oscillate.c
index b6edcc5c..8a5228d0 100644
--- a/oscillate.c
+++ b/oscillate.c
@@ -4,6 +4,10 @@
copyright: see file COPYRIGHT
Mark Koennecke, November 2004
+
+ Fixed to work with second generation motors too
+
+ Mark Koennecke, September 2013
------------------------------------------------------------------------*/
#include
#include
@@ -13,25 +17,19 @@
#include "task.h"
#include "commandlog.h"
#include "oscillate.h"
-#include "status.h"
#define ABS(x) (x < 0 ? -(x) : (x))
/*================== real work =========================================*/
static void StopOscillation(pOscillator self)
{
- int savedStatus;
-
assert(self != NULL);
if (self->taskID > 0) {
- self->pMot->pDriver->Halt(self->pMot->pDriver);
+ self->pMot->pDrivInt->Halt(self->pMot);
self->stopFlag = 1;
self->taskID = -1;
}
- savedStatus = GetStatus(); /* fool status check in ObParSet (avoid "Cannot change parameter while running" message */
- SetStatus(eEager);
MotorSetPar(self->pMot, self->pCon, "accesscode", usUser);
- SetStatus(savedStatus);
if (self->debug > 0) {
WriteToCommandLog("oscillator>> ", "Stopping");
}
@@ -74,31 +72,23 @@ static int OscillationTask(void *data)
assert(self);
if (self->stopFlag == 1) {
- finishDriving(self->pMot, self->pCon);
return 0;
}
- status = self->pMot->pDriver->GetStatus(self->pMot->pDriver);
+ status = self->pMot->pDrivInt->CheckStatus(self->pMot,pServ->dummyCon);
switch (status) {
case HWFault:
case HWPosFault:
- self->pMot->pDriver->GetError(self->pMot->pDriver, &code, error, 255);
- WriteToCommandLog("oscillator>> ", error);
- pos = getCurrentTarget(self);
- errStatus =
- self->pMot->pDriver->TryAndFixIt(self->pMot->pDriver, code, pos);
- self->errorCount++;
- if (errStatus == MOTFAIL) {
- /*
- try driving the other way on a serious error
- */
- pos = getNextPos(self);
- status = MotorRun(self->pMot, self->pCon, pos);
- if (self->debug > 0) {
- snprintf(message, 131, "Started oscillation to %f, ret code = %d",
- pos, status);
- WriteToCommandLog("oscillator>>", message);
- }
+ WriteToCommandLog("oscillator>> ",
+ "ERROR occurred in oscillation, try running motor manually to find out more");
+ WriteToCommandLog("oscillator>> ",
+ "Trying to run other direction");
+ pos = getNextPos(self);
+ status = MotorRun(self->pMot, self->pCon, pos);
+ if (self->debug > 0) {
+ snprintf(message, 131, "Started oscillation to %f, ret code = %d",
+ pos, status);
+ WriteToCommandLog("oscillator>>", message);
}
break;
case HWWarn:
@@ -111,16 +101,10 @@ static int OscillationTask(void *data)
case HWBusy:
break;
case HWIdle:
- if (self->cycles > 0 && self->currcycle == self->cycles) {
- StopOscillation(self);
- return 1;
- }
pos = getNextPos(self);
status = MotorRun(self->pMot, self->pCon, pos);
if (status == OKOK) {
self->pMot->pDrivInt->iErrorCount = 0;
- if (self->cycles > 0)
- (self->currcycle)++;
}
if (self->debug > 0) {
snprintf(message, 131, "Started oscillation to %f, ret code = %d",
@@ -135,7 +119,7 @@ static int OscillationTask(void *data)
static int StartOscillation(pOscillator self, SConnection * pCon)
{
float fval;
- int status, savedStatus;
+ int status;
char error[80], pBueffel[255];
assert(self);
@@ -151,10 +135,7 @@ static int StartOscillation(pOscillator self, SConnection * pCon)
self->lowerLimit += .5;
MotorGetPar(self->pMot, "softupperlim", &self->upperLimit);
self->upperLimit -= .5;
- savedStatus = GetStatus(); /* fool status check in ObParSet (avoid "Cannot change parameter while running" message */
- SetStatus(eEager);
MotorSetPar(self->pMot, self->pCon, "accesscode", (float) usInternal);
- SetStatus(savedStatus);
self->nextTargetFlag = 0;
self->errorCount = 0;
self->stopFlag = 0;
@@ -182,7 +163,8 @@ static int StartOscillation(pOscillator self, SConnection * pCon)
/*
start task
*/
- self->taskID = TaskRegister(pServ->pTasker,
+ snprintf(pBueffel,sizeof(pBueffel),"Oscillate-%s", self->pMot->name);
+ self->taskID = TaskRegisterN(pServ->pTasker,pBueffel,
OscillationTask, NULL, NULL, self, 10);
if (self->taskID < 0) {
SCWrite(pCon, "ERROR: failed to start oscillation task", eError);
@@ -237,8 +219,6 @@ int MakeOscillator(SConnection * pCon, SicsInterp * pSics, void *pData,
memset(pNew, 0, sizeof(Oscillator));
pNew->pDes = CreateDescriptor("Oscillator");
pNew->pMot = pMot;
- pNew->cycles = 0;
- pNew->currcycle = 0;
pNew->pCon = SCCreateDummyConnection(pSics);
if (!pNew->pDes || !pNew->pCon) {
SCWrite(pCon, "ERROR: out of memory creating oscillator", eError);
@@ -277,12 +257,6 @@ int OscillatorWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
}
strtolower(argv[1]);
- if (argc == 3) {
- self->cycles = 2 * atoi(argv[2]);
- } else {
- self->cycles = 0;
- }
- self->currcycle = 0;
if (strcmp(argv[1], "start") == 0) {
return StartOscillation(self, pCon);
} else if (strcmp(argv[1], "stop") == 0) {
diff --git a/oscillate.h b/oscillate.h
index c9a2366c..6ec7eae8 100644
--- a/oscillate.h
+++ b/oscillate.h
@@ -23,8 +23,6 @@ typedef struct {
SConnection *pCon;
int errorCount;
int debug;
- int cycles;
- int currcycle;
} Oscillator, *pOscillator;
/*---------------------------------------------------------------------*/
diff --git a/outcode.c b/outcode.c
index a55ee959..7b7f8f77 100644
--- a/outcode.c
+++ b/outcode.c
@@ -1,6 +1,6 @@
/* ------------------------------------------------------------------------
The OutCode's for SICS have to be translated from text at several
- places in SICS. Wherever necessary sich code should include this file.
+ places in SICS. Wherever necessary such code should include this file.
This restricts changes to Scommon.h and this file
Mark Koennecke, November 1996
@@ -26,5 +26,5 @@ static char *pCode[] = {
"logerror",
NULL
};
-static int iNoCodes = 13;
+static int iNoCodes = 15;
#endif
diff --git a/protocol.c b/protocol.c
index aa27a960..138fbe38 100644
--- a/protocol.c
+++ b/protocol.c
@@ -290,7 +290,7 @@ static int ProtocolSet(SConnection * pCon, Protocol * pPro, char *pProName)
SCSetWriteFunc(pCon, SCWriteJSON_String);
SCSetWriteFunc(pMaster, SCWriteJSON_String);
break;
- case 5:
+ case 5: /* ACT */
SCSetWriteFunc(pMaster, SCACTWrite);
SCSetWriteFunc(pCon, SCACTWrite);
break;
@@ -489,12 +489,15 @@ int SCWriteSycamore(SConnection * pCon, char *pBuffer, int iOut)
return 0;
}
- iRet=snprintf(pBueffel,sizeof(pBueffel)-1, "[%d]:%s", pCon->sockHandle, pBuffer);
- SICSLogWrite(pBueffel, iOut);
- if (iRet >= MAXMSG) {
- snprintf(pBueffel,sizeof(pBueffel)-1, "TRUNCATED MESSAGE: message len=%d, MAXMSG=%d",strlen(pBuffer), MAXMSG);
- SICSLogWrite(pBueffel, eError);
+ /* log it for any case */
+ if (pCon->pSock) {
+ iRet = pCon->pSock->sockid;
+ } else {
+ iRet = 0;
}
+ snprintf(pBueffel,sizeof(pBueffel)-1, "Next line intended for socket: %d", iRet);
+ SICSLogWrite(pBueffel, eInternal);
+ SICSLogWrite(pBuffer, iOut);
/* write to commandlog if user or manager privilege */
if (SCGetRights(pCon) <= usUser) {
@@ -686,14 +689,15 @@ int SCWriteJSON_String(SConnection * pCon, char *pBuffer, int iOut)
if (strlen(pBuffer) == 0)
return 1;
- if (!SCinMacro(pCon)) {
- iRet=snprintf(pBueffel,sizeof(pBueffel)-1, "[%d]:%s", pCon->sockHandle, pBuffer);
- SICSLogWrite(pBueffel, iOut);
- if (iRet >= MAXMSG) {
- snprintf(pBueffel,sizeof(pBueffel)-1, "TRUNCATED MESSAGE: message len=%d, MAXMSG=%d",strlen(pBuffer), MAXMSG);
- SICSLogWrite(pBueffel, eError);
- }
+ /* log it for any case */
+ if (pCon->pSock) {
+ iRet = pCon->pSock->sockid;
+ } else {
+ iRet = 0;
}
+ snprintf(pBueffel,sizeof(pBueffel)-1, "Next line intended for socket: %d", iRet);
+ SICSLogWrite(pBueffel, eInternal);
+ SICSLogWrite(pBuffer, iOut);
/* write to commandlog if user or manager privilege */
if (SCGetRights(pCon) <= usUser) {
diff --git a/reflist.c b/reflist.c
index dd2e81bd..0a8c1645 100644
--- a/reflist.c
+++ b/reflist.c
@@ -24,6 +24,12 @@
static char undef[] = "Undefined";
#define IDXFMT " %8.4f"
#define ANGFMT " %8.2f"
+
+#define ABS(x) (x < 0 ? -(x) : (x))
+
+int CountTblCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
+ pHdb par[], int nPar); /* from hdbtable.c */
+
/*----------------------------------------------------------------------*/
typedef struct {
int idxCount;
@@ -365,6 +371,32 @@ static int ShowCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode,
return 1;
}
/*-----------------------------------------------------------------------*/
+const char *FindHKL(pSICSOBJ self, double h, double k, double l)
+{
+ pHdb node, idx;
+
+ node = GetHipadabaNode(self->objectNode, "data");
+ node = node->child;
+ while(node != NULL){
+ idx = node->child;
+ if(ABS(idx->value.v.doubleValue-h) > .1){
+ node = node->next;
+ continue;
+ }
+ idx = idx->next;
+ if(ABS(idx->value.v.doubleValue-k) > .1){
+ node = node->next;
+ continue;
+ }
+ idx = idx->next;
+ if(ABS(idx->value.v.doubleValue-l) < .1){
+ return node->name;
+ }
+ node = node->next;
+ }
+ return NULL;
+}
+/*-----------------------------------------------------------------------*/
static int NamesCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode,
pHdb par[], int nPar)
{
@@ -390,6 +422,28 @@ static int NamesCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode,
return 1;
}
/*----------------------------------------------------------------------*/
+static int RelabelCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode,
+ pHdb par[], int nPar)
+{
+ char buffer[10];
+ pHdb node = NULL;
+ int count = 0;
+
+ node = GetHipadabaNode(self->objectNode, "data");
+ node = node->child;
+ while (node != NULL) {
+ snprintf(buffer,sizeof(buffer),"%4.4d", count);
+ if(node->name != NULL){
+ free(node->name);
+ node->name = strdup(buffer);
+ }
+ count++;
+ node = node->next;
+ }
+
+ return 1;
+}
+/*----------------------------------------------------------------------*/
static int SetIndexCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode,
pHdb par[], int nPar)
{
@@ -549,6 +603,15 @@ pSICSOBJ CreateReflectionList(SConnection * pCon, SicsInterp * pSics,
SetHdbProperty(cmd,"priv","user");
AddSICSHdbPar(cmd, "id", usUser, MakeHdbText(""));
+
+ cmd = AddSICSHdbPar(pNew->objectNode, "count", usUser,
+ MakeSICSFunc(CountTblCmd));
+
+ cmd = AddSICSHdbPar(pNew->objectNode, "relabel", usUser,
+ MakeSICSFunc(RelabelCmd));
+
+
+
AddCommand(pSics, name, InterInvokeSICSOBJ, KillSICSOBJ, pNew);
return pNew;
}
@@ -679,10 +742,10 @@ int GetRefIndexID(pSICSOBJ refl, char *id, double hkl[])
snprintf(path, 132, "data/%s", id);
node = GetHipadabaNode(refl->objectNode, path);
if (node != NULL) {
- child = node->child;
- for(i = 0; i < 3; i++, child = child->next){
- hkl[i] = child->value.v.doubleValue;
- }
+ child = node->child;
+ for(i = 0; i < 3; i++, child = child->next){
+ hkl[i] = child->value.v.doubleValue;
+ }
return 1;
} else {
return 0;
diff --git a/reflist.h b/reflist.h
index ea591e7c..f96bbadf 100644
--- a/reflist.h
+++ b/reflist.h
@@ -57,4 +57,6 @@ int GetRefFlag(pSICSOBJ refl, int idx);
char *GetRefName(pSICSOBJ refl, int idx);
+const char *FindHKL(pSICSOBJ self, double h, double k, double l);
+
#endif /*REFLIST_H_ */
diff --git a/regresscter.c b/regresscter.c
index 2e6a41b3..1f582f7f 100644
--- a/regresscter.c
+++ b/regresscter.c
@@ -4,6 +4,10 @@
copyright: see file COPYRIGHT
Mark Koennecke, September 2006
+
+ Added generating a gaussian for scan testing
+
+ Mark Koennecke, April 2013
----------------------------------------------------------------------------*/
#include
#include
@@ -20,16 +24,22 @@
#define PAUSEFAIL 3
#define CONTFAIL 4
#define READFAIL 5
+#define GAUSS 6
#define STATEIDLE 0
#define STATERUN 1
#define STATEPAU 2
+/*---------------------------- for generating a gaussian -------------------*/
+#define FWHM 2.5
+#define POS 6.
+#define HEIGHT 100.
/*--------------------------------------------------------------------------*/
typedef struct {
int errType;
int recover;
int state;
time_t endTime;
+ int startCount;
} RegressSt;
/*---------------------------------------------------------------------------*/
static int RegressGetStatus(struct __COUNTER *self, float *fControl)
@@ -83,6 +93,7 @@ static int RegressStart(struct __COUNTER *self)
} else {
pSim->endTime = time(NULL) + 7;
}
+ pSim->startCount++;
return OKOK;
}
@@ -144,6 +155,7 @@ static int RegressReadValues(struct __COUNTER *self)
{
RegressSt *pSim = NULL;
int i;
+ float stddev, tmp, y;
assert(self);
pSim = (RegressSt *) self->pData;
@@ -156,6 +168,12 @@ static int RegressReadValues(struct __COUNTER *self)
for (i = 0; i < MAXCOUNT; i++) {
self->lCounts[i] = i * 10 + 5;
}
+ if(pSim->errType == GAUSS){
+ stddev = FWHM/2.254;
+ tmp = ((float)pSim->startCount - POS)/stddev;
+ y = HEIGHT*exp(-.5*tmp*tmp);
+ self->lCounts[0] = (long)y + 10;
+ }
self->lCounts[1] = self->fPreset;
self->fTime = self->fPreset;
return OKOK;
@@ -199,6 +217,9 @@ static int RegressSet(struct __COUNTER *self, char *name, int iCter,
if (strcmp(name, "errortype") == 0) {
pSim->errType = (int) FVal;
+ if(pSim->errType == GAUSS){
+ pSim->startCount = 0;
+ }
return 1;
}
if (strcmp(name, "recover") == 0) {
diff --git a/remob.c b/remob.c
index a1e649df..3aa384ea 100644
--- a/remob.c
+++ b/remob.c
@@ -953,7 +953,7 @@ static RemServer *RemServerInit(char *name, char *host, int port)
remserver->taskActive = 1;
remserver->interestActive = 0;
remserver->forwardMessages = 1;
- TaskRegister(pServ->pTasker, RemServerTask, NULL, RemServerKill,
+ TaskRegisterN(pServ->pTasker,name, RemServerTask, NULL, RemServerKill,
remserver, 1);
return remserver;
}
diff --git a/remoteobject.c b/remoteobject.c
new file mode 100644
index 00000000..5cad0a91
--- /dev/null
+++ b/remoteobject.c
@@ -0,0 +1,1008 @@
+/**
+ * Remote objects in sicsobj. This means accessing remote objects in a different
+ * SICS server from a master SICS server.
+ *
+ * Reading is implementd according to this scheme:
+ *
+ * * When a read connection is made between a local node and a remote node in slave, then a
+ * callback is installed on remote node in slave.
+ * * The callback on remote in slave sends commands to update the local node when either the
+ * value or the geterror property changes on the remote node. The commands sent are
+ * enclosed in special delimiters
+ * * A special ANET callback evaluates the data coming from slave and acts accordingly, thus
+ * updating the local node. This is driven by the general network driving code of SICS
+ *
+ * * in order to detect availability and re-availability of slave a Heartbeat Task sends a
+ * heartbeat message to slave. Thereby testing the connection regularly, trying to reconnect etc.
+ *
+ * COPRYRIGHT: see file COPYRIGHT
+ *
+ * Mark Koennecke, February 2015
+**/
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define OOM -5001 /* out of memory */
+#define TO -5002 /* timeout */
+
+static char *login = {"RemoteMaster 3ed4c656a15f0aa45e02fd5ec429225bb93b762e7eb06cc81a0b4f6c35c76184\r\n"};
+extern char *trim(char *txt);
+/*---------------------- our very private data structure -------------------*/
+typedef struct {
+ char *host;
+ int port;
+ int readHandle;
+ int writeHandle;
+ int writeInUse;
+ int readList;
+ unsigned int connected;
+ time_t nextHeartbeat;
+} RemoteOBJ, *pRemoteOBJ;
+/*----------------------------------------------------------------------------*/
+typedef struct {
+ char localNode[1024];
+ char remoteNode[1024];
+} ReadData, *pReadData;
+/*---------------------------------------------------------------------------*/
+typedef struct {
+ SConnection *sendCon;
+ char *remotePath;
+} UpdateCallback, *pUpdateCallback;
+/*----------------------------------------------------------------------------*/
+void KillRemoteOBJ(void *data)
+{
+ char roTaskName[132];
+
+ pRemoteOBJ self = (pRemoteOBJ) data;
+ if(data != NULL){
+ snprintf(roTaskName,sizeof(roTaskName),"ro-%s-%d", self->host, self->port);
+ StopTask(pServ->pTasker,roTaskName);
+ free(self->host);
+ ANETclose(self->readHandle);
+ ANETclose(self->writeHandle);
+ LLDdeleteBlob(self->readList);
+ }
+}
+/*========================= reading related code ================================*/
+static int RemoteReadCallback(int handle, void *userData)
+{
+ int length;
+ char *pPtr, *pStart, *pEnd;
+
+ pPtr = ANETreadPtr(handle,&length);
+
+ /*
+ * deal with command results
+ */
+ pStart = strstr(pPtr, "TRANSACTIONSTART");
+ pEnd = strstr(pPtr,"TRANSACTIONEND");
+ if(pStart != NULL && pEnd != NULL){
+ pStart = pStart + strlen("TRANSACTIONSTART");
+ *pEnd = '\0';
+ traceIO("RO","Received command - reply: %s", pStart);
+ pEnd += strlen("TRANSACTIONEND");
+ ANETreadConsume(handle,pEnd - pPtr);
+ }
+
+ /*
+ * deal with update messages
+ */
+ pStart = strstr(pPtr, "SROC:");
+ pEnd = strstr(pPtr,":EROC\r\n");
+ if(pStart != NULL && pEnd != NULL){
+ pStart += strlen("SROC:");
+ *pEnd = '\0';
+ InterpExecute(pServ->pSics, pServ->dummyCon,pStart);
+ traceIO("RO", "Received %s from remote", pStart);
+ pEnd += strlen("EROC\r\n");
+ ANETreadConsume(handle,pEnd - pPtr);
+ }
+
+ /*
+ * deal with heartbeats
+ */
+ if((pStart = strstr(pPtr,"Poch")) != NULL){
+ ANETreadConsume(handle,(pStart+4) - pPtr);
+ }
+
+ /*
+ If there is more stuff to process: recurse
+ */
+ pPtr = ANETreadPtr(handle,&length);
+ if(length > 0 &&
+ ( strstr(pPtr,":EROC\r\n") != NULL ||
+ strstr(pPtr,"TRANSACTIONEND") != NULL
+ || strstr(pPtr,"Poch") != NULL ) ) {
+ RemoteReadCallback(handle,userData);
+ }
+
+ return 1;
+}
+/*-----------------------------------------------------------------------------*/
+static int transactCommand(int handle, char *command, char *reply, int replyLen)
+{
+ char *toSend = NULL;
+ char *prefix = {"transact "};
+ int status, length, type;
+ time_t start;
+ char *pPtr;
+
+ /*
+ * read possible dirt of the line
+ */
+ pPtr = ANETreadPtr(handle,&length);
+ ANETreadConsume(handle,length);
+
+
+ toSend = malloc(strlen(command) + strlen(prefix) + 1);
+ if(toSend == NULL){
+ return OOM;
+ }
+ strcpy(toSend, prefix);
+ strcat(toSend, command);
+ status = ANETwrite(handle,toSend,strlen(toSend));
+ free(toSend);
+ if(status != 1){
+ return status;
+ }
+
+ /*
+ * wait for a reply for max 2 seconds
+ */
+ start = time(NULL);
+ while(time(NULL) < start + 2.0){
+ ANETprocess();
+ pPtr = ANETreadPtr(handle,&length);
+ if(length > 0 && strstr(pPtr,"TRANSACTIONFINISHED") != NULL){
+ strncpy(reply,pPtr,replyLen);
+ ANETreadConsume(handle,length);
+ return 1;
+ }
+ usleep(100);
+ }
+
+ /*
+ * here we have run into a timeout
+ */
+ ANETreadConsume(handle,length);
+ return TO;
+
+}
+/*----------------------------------------------------------------------------*/
+static void ConnectRemoteObject(pRemoteOBJ self)
+{
+ char *pPtr, command[1024];
+ int length, status;
+ ReadData rd;
+ pHdb node;
+
+
+ if(self->connected){
+ return;
+ }
+
+ self->readHandle = ANETconnect(self->host, self->port);
+ self->writeHandle = ANETconnect(self->host, self->port);
+ if(self->readHandle < 0 || self->writeHandle < 0){
+ self->connected = 0;
+ traceIO("RO","Failed to connect to remote objects at %s, port %d",
+ self->host, self->port);
+ return;
+ }
+ traceIO("RO","Connected to %s, port %d for remote objects",
+ self->host, self->port);
+
+ /*
+ Default login with hard coded manager login. Defined in
+ nserver.c
+ */
+ ANETwrite(self->readHandle,login,strlen(login));
+ ANETwrite(self->writeHandle,login,strlen(login));
+ usleep(500);
+ ANETprocess();
+ /*
+ eat the login responses
+ */
+ pPtr = ANETreadPtr(self->readHandle, &length);
+ ANETreadConsume(self->readHandle,length);
+ pPtr = ANETreadPtr(self->writeHandle, &length);
+ ANETreadConsume(self->writeHandle,length);
+
+
+ /*
+ * install the read callback
+ */
+ ANETsetReadCallback(self->readHandle,RemoteReadCallback, NULL, NULL);
+
+ /*
+ * Remove geterror on read nodes and reinstall callbacks for reconnects
+ */
+ status = LLDnodePtr2First(self->readList);
+ while(status != 0) {
+ LLDblobData(self->readList,&rd);
+ node = FindHdbNode(NULL,rd.localNode,NULL);
+ if(node != NULL){
+ SetHdbProperty(node,"geterror",NULL);
+ snprintf(command,sizeof(command),"fulltransact addremotecb %s %s \r\n",
+ rd.remoteNode, rd.localNode);
+ ANETwrite(self->readHandle,command,strlen(command));
+ }
+ status = LLDnodePtr2Next(self->readList);
+ }
+
+ transactCommand(self->writeHandle,"protocol set withcode\r\n", command,sizeof(command));
+
+ self->connected = 1;
+ self->writeInUse = 0;
+}
+/*-----------------------------------------------------------------------------*/
+static void MarkDisconnected(pRemoteOBJ self)
+{
+ int status;
+ ReadData rd;
+ pHdb node;
+
+ status = LLDnodePtr2First(self->readList);
+ while(status != 0) {
+ LLDblobData(self->readList,&rd);
+ node = FindHdbNode(NULL,rd.localNode,NULL);
+ if(node != NULL){
+ SetHdbProperty(node,"geterror","Disconnected from remote server");
+ }
+ status = LLDnodePtr2Next(self->readList);
+ }
+ self->connected = 0;
+ }
+/*-----------------------------------------------------------------------------*/
+static hdbCallbackReturn ROUpdateCallback(pHdb currentNode, void *userData,
+ pHdbMessage mes)
+{
+ pUpdateCallback uppi = (pUpdateCallback)userData;
+ hdbDataMessage *mm = NULL;
+ pDynString text;
+ char *prefix = {"SROC:hupdate "};
+ char *postfix= {":EROC\r\n"};
+ char *txt = NULL;
+ int length;
+ pHdbPropertyChange propChange = NULL;
+
+ mm = GetHdbUpdateMessage(mes);
+ if(mm != NULL){
+ /*
+ * remove myself when the connection is dead...
+ */
+ if(!SCisConnected(uppi->sendCon)){
+ return hdbKill;
+ }
+ /*
+ * format and send the update command to master
+ */
+ text = formatValue(*(mm->v), currentNode);
+ length = GetDynStringLength(text) +
+ strlen(prefix) + strlen(postfix) + strlen(uppi->remotePath) +5;
+ txt = malloc(length*sizeof(char));
+ if(txt == NULL){
+ return hdbContinue;
+ }
+ snprintf(txt,length,"%s %s %s %s", prefix, uppi->remotePath,
+ GetCharArray(text), postfix);
+ SCWrite(uppi->sendCon,txt,eValue);
+ free(txt);
+ DeleteDynString(text);
+ }
+
+ propChange = GetPropertyChangeMessage(mes);
+ if(propChange != NULL){
+ /*
+ * remove myself when the connection is dead...
+ */
+ if(!SCisConnected(uppi->sendCon)){
+ return hdbKill;
+ }
+ length = strlen("SROC:hdelprop ") + strlen(uppi->remotePath) +
+ strlen(propChange->key) + 10;
+ if(propChange->value != NULL){
+ length += strlen(propChange->value);
+ }
+ txt = malloc(length*sizeof(char));
+ if(txt == NULL){
+ return hdbContinue;
+ }
+ if(propChange->value == NULL){
+ snprintf(txt,length,"SROC:hdelprop %s %s %s", uppi->remotePath,
+ propChange->key,postfix);
+ } else {
+ snprintf(txt,length,"SROC:hsetprop %s %s %s %s", uppi->remotePath,
+ propChange->key,propChange->value, postfix);
+ }
+ SCWrite(uppi->sendCon,txt,eValue);
+ free(txt);
+ }
+
+ return hdbContinue;
+}
+/*-----------------------------------------------------------------------------*/
+static hdbCallbackReturn GetErrorCallback(pHdb currentNode, void *userData,
+ pHdbMessage mes)
+{
+ hdbDataMessage *mm= NULL;
+ char *geterror, error[512];
+ SConnection *con = NULL;
+
+
+ mm = GetHdbGetMessage(mes);
+ if (mm != NULL) {
+ con = mm->callData;
+ geterror = GetHdbProp(currentNode, "geterror");
+ if (geterror != NULL) {
+ snprintf(error,sizeof(error),"ERROR: %s", geterror);
+ SCWrite(con, error, eError);
+ if (mm->v->dataType == HIPTEXT) {
+ if (mm->v->v.text != NULL) {
+ free(mm->v->v.text);
+ }
+ mm->v->v.text = strdup(error);
+ }
+ return hdbAbort;
+ }
+ }
+ return hdbContinue;
+}
+/*-----------------------------------------------------------------------------*/
+static void KillUpdateStruct(void *data)
+{
+ pUpdateCallback self = (pUpdateCallback)data;
+ if(data != NULL){
+ SCDeleteConnection(self->sendCon);
+ free(self->remotePath);
+ free(self);
+ }
+}
+/*-----------------------------------------------------------------------------*/
+static int ConnectRead(pRemoteOBJ self, SConnection * pCon, ReadData rd)
+{
+ char command[1024], reply[1024], *pPtr;
+ int status, type;
+ pHdb localNode = NULL;
+
+ /*
+ * Initialize....
+ */
+ localNode = FindHdbNode(NULL,rd.localNode, pCon);
+ if(localNode == NULL){
+ SCPrintf(pCon,eError,"ERROR: local node %s not found", rd.localNode);
+ return 0;
+ }
+
+ /**
+ * Refuse duplicate connections
+ */
+ pPtr = GetHdbProp(localNode,"remoteread");
+ if(pPtr != NULL){
+ SCPrintf(pCon,eError,"ERROR: %s is already connected to %s", rd.localNode, pPtr);
+ return 0;
+ }
+
+ /*
+ * Get information about the remote node and check compatability
+ */
+ snprintf(command,sizeof(command),"hinfo %s\r\n", rd.remoteNode);
+ status = transactCommand(self->writeHandle,command,reply,sizeof(reply));
+ if(status != 1){
+ /*
+ * try a reconnect,
+ * when fails:
+ * Warning
+ * add blob
+ */
+ self->connected = 0;
+ ConnectRemoteObject(self);
+ status = transactCommand(self->writeHandle,command,reply,sizeof(reply));
+ if(status != 1){
+ SCPrintf(pCon,eWarning,"WARNING: cannot yet reach slave %s, but continuing...",
+ self->host);
+ MarkDisconnected(self);
+ LLDblobAdd(self->readList,&rd,sizeof(rd));
+ AppendHipadabaCallback(localNode, MakeHipadabaCallback(GetErrorCallback,
+ NULL,NULL));
+ SetHdbProperty(localNode,"remoteread",rd.remoteNode);
+ return 1;
+ }
+ }
+ if(strstr(reply, "ERROR") != NULL){
+ SCPrintf(pCon,eError,"%s while trying to contact remote node %s",
+ reply, rd.remoteNode);
+ return 0;
+ }
+ /* only interested in type: answer is of style: type,nochildren,length */
+ pPtr = strchr(reply,',');
+ *pPtr= '\0';
+ type = convertHdbType(reply);
+ if(type != localNode->value.dataType){
+ SCPrintf(pCon,eError,
+ "ERROR: data type mismatch between local %s and remote %s, local type %d, remote type %d",
+ rd.localNode, rd.remoteNode, localNode->value.dataType, type);
+ return 0;
+ }
+
+ /*
+ * Make an entry in the read list
+ */
+ LLDblobAdd(self->readList,&rd,sizeof(rd));
+ AppendHipadabaCallback(localNode, MakeHipadabaCallback(GetErrorCallback,
+ NULL,NULL));
+
+ SetHdbProperty(localNode,"remoteread",rd.remoteNode);
+
+ /*
+ * Install a callback on the remote node to update the master. The remote should
+ * then immediatly send an update which will be processed by the read callback.
+ */
+ snprintf(command,sizeof(command),"fulltransact addremotecb %s %s \r\n",
+ rd.remoteNode, rd.localNode);
+ ANETwrite(self->readHandle,command,strlen(command));
+
+ return 1;
+}
+
+/*-----------------------------------------------------------------------------*/
+static int ConnectreadCmd(pSICSOBJ ccmd, SConnection * pCon,
+ Hdb * cmdNode, Hdb * par[], int nPar)
+{
+ ReadData rd;
+ pHdb localNode = NULL;
+ char command[1024], reply[1024], *pPtr;
+ int status, type;
+ pRemoteOBJ self;
+
+
+ if(nPar < 2) {
+ SCWrite(pCon,"ERROR: need path to local node and remote node for connectread",
+ eError);
+ return 0;
+ }
+
+ /*
+ * Initialize....
+ */
+ strncpy(rd.localNode ,par[0]->value.v.text, sizeof(rd.localNode));
+ strncpy(rd.remoteNode ,par[1]->value.v.text, sizeof(rd.remoteNode));
+ self = (pRemoteOBJ)ccmd->pPrivate;
+
+ status = ConnectRead(self,pCon,rd);
+
+ if(status == 1){
+ SCSendOK(pCon);
+ }
+
+ return status;
+}
+/*-----------------------------------------------------------------------------*/
+static int HeartbeatTask(void *pData)
+{
+ pRemoteOBJ self = (pRemoteOBJ)pData;
+ int status;
+ char command[] = {"Poch\r\n"};
+
+ if (time(NULL) > self->nextHeartbeat){
+ status = ANETwrite(self->readHandle,command, strlen(command));
+ if(status != 1){
+ traceIO("RO","Trying a reconnect to %s, %d", self->host, self->port);
+ self->connected = 0;
+ ConnectRemoteObject(self);
+ if(!self->connected){
+ MarkDisconnected(self);
+ }
+ }
+ self->nextHeartbeat = time(NULL) + 10;
+ }
+ return 1;
+}
+/*============================= writing related code ===========================
+ The logic here is to use the standard writeHandle when available. I expect most
+ communication to be short and to happen through the writeHandle. If that one is
+ in use, a new connection will be built.
+ ---------------------------------------------------------------------------------
+ suppress all superfluous OK from the slave
+ -----------------------------------------------------------------------------------*/
+#include
+static OutCode findOutCode(char *txt)
+{
+ int i;
+
+ for(i = 0; i < iNoCodes; i++){
+ if(strstr(txt,pCode[i]) != NULL){
+ return i;
+ }
+ }
+ return eValue;
+}
+/*--------------------------------------------------------------------------------*/
+static void printSICS(char *answer, SConnection *pCon)
+{
+ char line[1024], *pPtr, *pCode;
+ OutCode eCode;
+
+ pPtr = answer;
+ while(pPtr != NULL){
+ memset(line,0,sizeof(line));
+ pPtr = stptok(pPtr,line,sizeof(line),"\n");
+ if(strstr(line,"OK") == NULL){
+ pCode = strstr(line,"@@");
+ if(pCode != NULL){
+ *pCode = '\0';
+ pCode += 2;
+ eCode = findOutCode(trim(pCode));
+
+ } else {
+ eCode = eValue;
+ }
+ SCWrite(pCon,line,eCode);
+ }
+ }
+}
+/*---------------------------------------------------------------------------------*/
+static int PrepareWriteHandle(pRemoteOBJ self, SConnection *pCon, int *newHandle)
+{
+ int handle, length;
+ char *answer = NULL;
+ char command[80];
+
+ if(self->writeInUse) {
+ handle = ANETconnect(self->host,self->port);
+ if(handle < 0){
+ traceIO("RO","Failed to connect to %s at %d", self->host, self->port);
+ if(pCon != NULL){
+ SCPrintf(pCon,eError,"ERROR: Failed to connect to %s %d", self->host, self->port);
+ }
+ return handle;
+ }
+ ANETwrite(handle,login,strlen(login));
+ usleep(500);
+ ANETprocess();
+ /*
+ eat the login responses
+ */
+ answer = ANETreadPtr(handle, &length);
+ ANETreadConsume(handle,length);
+ *newHandle = 1;
+
+ transactCommand(handle,"protocol set withcode\r\n", command,sizeof(command));
+
+ } else {
+ self->writeInUse = 1;
+ handle = self->writeHandle;
+ /*
+ eat dirt from the line
+ */
+ answer = ANETreadPtr(handle, &length);
+ ANETreadConsume(handle,length);
+ }
+ return handle;
+}
+/*---------------------------------------------------------------------------------*/
+static void ProcessWriteResponse(pRemoteOBJ self, int handle, SConnection *pCon)
+{
+ char *answer = NULL, *pEnd, *command = NULL;
+ int length;
+
+ while(1){
+ TaskYield(pServ->pTasker);
+ if(!ANETvalidHandle(handle)){
+ SCPrintf(pCon,eError,"ERROR: Disconnected from %s", self->host);
+ break;
+ }
+ answer = ANETreadPtr(handle,&length);
+ if(length > 0 && (pEnd = strstr(answer,"TRANSACTIONFINISHED")) != NULL){
+ if(pCon != NULL){
+ *pEnd = '\0';
+ printSICS(answer,pCon);
+ }
+ traceIO("RO","%s:%d: Received %s", self->host, self->port,answer);
+ ANETreadConsume(handle,length);
+ break;
+ }
+ }
+
+}
+/*---------------------------------------------------------------------------------*/
+static hdbCallbackReturn ROWriteCallback(pHdb currentNode, void *userData,
+ pHdbMessage mes)
+{
+ pHdbDataMessage mm = NULL;
+ int handle, status, length, newHandle = 0;
+ pRemoteOBJ self = (pRemoteOBJ)userData;
+ SConnection *pCon = NULL;
+ pDynString data;
+ char *remoteNode;
+ char *command, *answer, *pEnd;
+
+
+ if((mm = GetHdbSetMessage(mes)) != NULL){
+ pCon = (SConnection *)mm->callData;
+ handle = PrepareWriteHandle(self,pCon,&newHandle);
+ if(handle < 0){
+ return hdbAbort;
+ }
+
+ /*
+ build the command to send
+ */
+ data = formatValue(*(mm->v),currentNode);
+ remoteNode = GetHdbProp(currentNode,"remotewrite");
+ length = 40 + strlen(remoteNode) + GetDynStringLength(data);
+ command = malloc(length*sizeof(char));
+ if(command == NULL){
+ if(pCon != NULL){
+ SCWrite(pCon,"ERROR: out of memory writing remote node",eError);
+ }
+ return hdbAbort;
+ }
+ snprintf(command,length,"transact hset %s %s\r\n",remoteNode, GetCharArray(data));
+
+ /*
+ write
+ */
+ traceIO("RO","%s:%d: Sending %s ", self->host, self->port, command);
+ status = ANETwrite(handle,command,strlen(command));
+ free(command);
+ DeleteDynString(data);
+ if(status < 0){
+ if(pCon != NULL){
+ SCPrintf(pCon,eError,"ERROR: remote %s on %s disconnected", remoteNode, self->host);
+ }
+ return hdbAbort;
+ }
+
+ /*
+ wait for a response: TRANSACTIONFINISHED
+ */
+ ProcessWriteResponse(self,handle,pCon);
+
+ /*
+ Is there a termination script?
+ */
+ command = GetHdbProp(currentNode,"termscript");
+ if(command != NULL){
+ while(1) {
+ TaskYield(pServ->pTasker);
+ Tcl_Eval(InterpGetTcl(pServ->pSics),command);
+ answer = (char *)Tcl_GetStringResult(InterpGetTcl(pServ->pSics));
+ if(strstr(answer,"idle") != NULL){
+ answer = ANETreadPtr(handle,&length);
+ printSICS(answer,pCon);
+ traceIO("RO","%s:%d:Received %s", self->host,self->port,answer);
+ ANETreadConsume(handle,length);
+ break;
+ }
+ }
+ }
+
+
+ if(newHandle){
+ ANETclose(handle);
+ } else {
+ self->writeInUse = 0;
+ }
+
+ }
+
+ return hdbContinue;
+}
+/*------------------------------------------------------------------------------*/
+static int ConnectWrite(pRemoteOBJ self, SConnection *pCon, ReadData rd)
+{
+ pHdb localNode = NULL;
+ char command[1024], reply[1024], *pPtr;
+ int status, type;
+
+ localNode = FindHdbNode(NULL,rd.localNode, pCon);
+ if(localNode == NULL){
+ SCPrintf(pCon,eError,"ERROR: local node %s not found", rd.localNode);
+ return 0;
+ }
+
+ pPtr = GetHdbProp(localNode,"remotewrite");
+ if(pPtr != NULL){
+ SCPrintf(pCon,eError,"ERROR: %s alread connected to %s", rd.localNode,
+ rd.remoteNode);
+ return 0;
+ }
+
+ SetHdbProperty(localNode,"remotewrite",rd.remoteNode);
+ AppendHipadabaCallback(localNode, MakeHipadabaCallback(ROWriteCallback,
+ self,NULL));
+
+ /*
+ * Get information about the remote node and check compatability
+ */
+ snprintf(command,sizeof(command),"hinfo %s\r\n", rd.remoteNode);
+ status = transactCommand(self->writeHandle,command,reply,sizeof(reply));
+ if(status != 1){
+ SCPrintf(pCon,eWarning,"WARNING: cannot yet reach slave %s, but continuing...",
+ self->host);
+ MarkDisconnected(self);
+ return 0;
+ }
+ if(strstr(reply, "ERROR") != NULL){
+ SCPrintf(pCon,eError,"%s while trying to contact remote node %s",
+ reply, rd.remoteNode);
+ return 0;
+ }
+ /* only interested in type: answer is of style: type,nochildren,length */
+ pPtr = strchr(reply,',');
+ *pPtr= '\0';
+ type = convertHdbType(reply);
+ if(type != localNode->value.dataType){
+ SCPrintf(pCon,eError,
+ "ERROR: data type mismatch between local %s and remote %s, local type %d, remote type %d",
+ rd.localNode, rd.remoteNode, localNode->value.dataType, type);
+ return 0;
+ }
+
+ return 1;
+}
+/*---------------------------------------------------------------------------------*/
+static int ConnectwriteCmd(pSICSOBJ ccmd, SConnection * pCon,
+ Hdb * cmdNode, Hdb * par[], int nPar)
+{
+ ReadData rd;
+ int status;
+ pRemoteOBJ self;
+
+
+ if(nPar < 2) {
+ SCWrite(pCon,"ERROR: need path to local node and remote node for connectwrite",
+ eError);
+ return 0;
+ }
+
+ /*
+ * Initialize....
+ */
+ strncpy(rd.localNode ,par[0]->value.v.text, sizeof(rd.localNode));
+ strncpy(rd.remoteNode ,par[1]->value.v.text, sizeof(rd.remoteNode));
+ self = (pRemoteOBJ)ccmd->pPrivate;
+
+ status = ConnectWrite(self,pCon,rd);
+
+ if(status == 1){
+ SCSendOK(pCon);
+ }
+ return status;
+}
+/*============================ remote execute =================================*/
+static int RemoteExecute(pRemoteOBJ self, SConnection *pCon, char *command)
+{
+ int status, handle, newHandle = 0, length;
+ char *answer, *pEnd;
+
+ handle = PrepareWriteHandle(self,pCon,&newHandle);
+ if(handle < 0){
+ return 0;
+ }
+
+ /*
+ write, thereby taking care to prefix with transact and for proper termination
+ */
+ if(strstr(command,"transact") == NULL){
+ ANETwrite(handle,"transact ", sizeof("transact "));
+ }
+ status = ANETwrite(handle,command,strlen(command));
+ if(strstr(command,"\n") == NULL){
+ ANETwrite(handle,"\r\n",2);
+ }
+ if(status < 0){
+ traceIO("RO","Disconnect from %s while executing %s", self->host, command);
+ if(pCon != NULL){
+ SCPrintf(pCon,eError,"ERROR: Disconnected from %s %d", self->host, self->port);
+ }
+ return 0;
+ }
+
+ /*
+ wait for response
+ */
+ while(1){
+ TaskYield(pServ->pTasker);
+ if(!ANETvalidHandle(handle)){
+ if(pCon != NULL){
+ SCPrintf(pCon,eError,"ERROR: Disconnected from %s %d", self->host, self->port);
+ }
+ break;
+ }
+ answer = ANETreadPtr(handle,&length);
+ if(length > 0 && (pEnd = strstr(answer,"TRANSACTIONFINISHED")) != NULL){
+ if(pCon != NULL){
+ *pEnd = '\0';
+ SCPrintf(pCon,eValue,answer);
+ }
+ ANETreadConsume(handle,length);
+ break;
+ }
+ }
+
+ if(newHandle){
+ ANETclose(handle);
+ } else {
+ self->writeInUse = 0;
+ }
+
+ return 1;
+}
+/*------------------------------------------------------------------------------*/
+static int RemoteExecuteCmd(pSICSOBJ ccmd, SConnection * pCon,
+ Hdb * cmdNode, Hdb * par[], int nPar)
+{
+ int status, i;
+ char *pPtr;
+ Tcl_DString com;
+ pDynString val;
+ pRemoteOBJ self;
+
+ self = (pRemoteOBJ)ccmd->pPrivate;
+
+ Tcl_DStringInit(&com);
+ for (i = 0; i < nPar; i++) {
+ val = formatValue(par[i]->value, par[i]);
+ if (val != NULL) {
+ Tcl_DStringAppend(&com, " ", 1);
+ pPtr = GetCharArray(val);
+ Tcl_DStringAppend(&com, pPtr, strlen(pPtr));
+ DeleteDynString(val);
+ }
+ }
+
+ status = RemoteExecute(self,pCon,Tcl_DStringValue(&com));
+ Tcl_DStringFree(&com);
+
+ return status;
+
+}
+/*============================= connect command ================================*/
+static int ConnectCmd(pSICSOBJ ccmd, SConnection * pCon,
+ Hdb * cmdNode, Hdb * par[], int nPar)
+{
+ pRemoteOBJ self;
+
+ self = (pRemoteOBJ)ccmd->pPrivate;
+ ConnectRemoteObject(self);
+
+ if(self->connected){
+ SCSendOK(pCon);
+ } else {
+ SCPrintf(pCon,eError,"ERROR: failed to connect to %s %d", self->host, self->port);
+ return 0;
+ }
+
+ return 1;
+}
+/*============================ object initialisation etc =======================*/
+static int MakeRemoteObject(SConnection *pCon, SicsInterp *pSics, void *pData,
+ int argc, char *argv[])
+{
+ pSICSOBJ pNew = NULL;
+ pRemoteOBJ self = NULL;
+ int status;
+ pHdb cmd;
+ char roTaskName[256];
+
+ if(argc < 4) {
+ SCWrite(pCon,"ERROR: need name and remote host name and port in order to create remote object",
+ eError);
+ return 0;
+ }
+
+ strtolower(argv[1]);
+ if(FindCommand(pSics,argv[1]) != NULL){
+ SCPrintf(pCon,eError, "ERROR: command %s already exists!", argv[1]);
+ return 0;
+ }
+
+ pNew = MakeSICSOBJ(argv[1],"RemoteOBJ");
+ self = calloc(1, sizeof(RemoteOBJ));
+ if(pNew == NULL || self == NULL){
+ SCWrite(pCon,"ERROR: out of memory creating remote object", eError);
+ return 0;
+ }
+ pNew->pPrivate = self;
+ pNew->KillPrivate = KillRemoteOBJ;
+ self->host = strdup(argv[2]);
+ self->port = atoi(argv[3]);
+ self->readList = LLDblobCreate();
+ ConnectRemoteObject(self);
+
+ cmd = AddSICSHdbPar(pNew->objectNode,
+ "connectread", usMugger, MakeSICSFunc(ConnectreadCmd));
+ AddSICSHdbPar(cmd, "localnode", usMugger, MakeHdbText(""));
+ AddSICSHdbPar(cmd, "remotenode", usMugger, MakeHdbText(""));
+
+
+ cmd = AddSICSHdbPar(pNew->objectNode,
+ "connectwrite", usMugger, MakeSICSFunc(ConnectwriteCmd));
+ AddSICSHdbPar(cmd, "localnode", usMugger, MakeHdbText(""));
+ AddSICSHdbPar(cmd, "remotenode", usMugger, MakeHdbText(""));
+
+
+ cmd = AddSICSHdbPar(pNew->objectNode,
+ "exe", usMugger, MakeSICSFunc(RemoteExecuteCmd));
+ AddSICSHdbPar(cmd, "args", usMugger, MakeHdbText(""));
+
+ cmd = AddSICSHdbPar(pNew->objectNode,
+ "connect", usMugger, MakeSICSFunc(ConnectCmd));
+
+
+ status = AddCommand(pSics,
+ argv[1],
+ InterInvokeSICSOBJ,
+ KillSICSOBJ, pNew);
+
+ snprintf(roTaskName,sizeof(roTaskName),"ro-%s-%d", self->host, self->port);
+ TaskRegisterN(pServ->pTasker, roTaskName, HeartbeatTask, NULL,NULL,self,1);
+
+ return status;
+}
+/*----------------------------------------------------------------------------------------*/
+static int AddRemoteCallback(SConnection *pCon, SicsInterp *pSics, void *pData,
+ int argc, char *argv[])
+{
+ pHdb localNode = NULL;
+ pUpdateCallback up = NULL;
+
+ if(argc < 3) {
+ SCWrite(pCon,"ERROR: need path to local node and remote node for updatecb",
+ eError);
+ return 0;
+ }
+
+ localNode = FindHdbNode(NULL,argv[1], pCon);
+ if(localNode == NULL){
+ SCPrintf(pCon,eError,"ERROR: local node %s not found", argv[1]);
+ return 0;
+ }
+
+ up = malloc(sizeof(UpdateCallback));
+ if(up == NULL){
+ SCWrite(pCon,"ERROR: out of memory installing update callback",eError);
+ return 0;
+ }
+ up->sendCon = SCCopyConnection(pCon);
+ up->remotePath = strdup(argv[2]);
+ AppendHipadabaCallback(localNode, MakeHipadabaCallback(ROUpdateCallback,
+ up,KillUpdateStruct));
+ /**
+ * This is meant to send an update immediatly such that the remote node
+ * is updated right away,
+ */
+ NotifyHipadabaPar(localNode, NULL);
+
+ SCSendOK(pCon);
+ return 1;
+
+}
+/*----------------------------------------------------------------------------------------*/
+void RemoteObjectInit(void)
+{
+
+ AddCommand(pServ->pSics,
+ "makeremo",
+ MakeRemoteObject,
+ NULL,NULL);
+
+ AddCommand(pServ->pSics,
+ "addremotecb",
+ AddRemoteCallback,
+ NULL,NULL);
+
+
+}
diff --git a/rs232controller.c b/rs232controller.c
index 33b21bdc..eaa3b098 100644
--- a/rs232controller.c
+++ b/rs232controller.c
@@ -609,7 +609,6 @@ static void encodeTerminator(char *result, char *terminator)
if (terminator == NULL) {
result[0] = '\0';
- return;
}
len = strlen(terminator);
snprintf(pBuffer,sizeof(pBuffer)-1, "0x%x", (int) terminator[0]);
diff --git a/rwpuffer.c b/rwpuffer.c
index a678e700..68acf5e0 100644
--- a/rwpuffer.c
+++ b/rwpuffer.c
@@ -4,6 +4,11 @@
* copyright: see file COPYRIGHT
*
* Mark Koennecke, January 2009
+ *
+ * added resizing option and MakeBigRWPuffer in order to support transfer
+ * of large amounts of image data on few connections
+ *
+ * Mark Koennecke, August 2014
*/
#include
#include
@@ -15,6 +20,7 @@ typedef struct __RWBuffer {
int length;
int startPtr;
int endPtr;
+ int maxSize;
} RWBuffer;
/*----------------------------------------------------------------------*/
prwBuffer MakeRWPuffer(int size)
@@ -32,9 +38,18 @@ prwBuffer MakeRWPuffer(int size)
self->length = size;
self->startPtr = 0;
self->endPtr = 0;
+ self->maxSize = size;
return self;
}
-
+/*------------------------------------------------------------------------*/
+prwBuffer MakeBigRWPuffer(int size, int maxSize)
+{
+ prwBuffer result = MakeRWPuffer(size);
+ if(result != NULL){
+ result->maxSize = maxSize;
+ }
+ return result;
+}
/*------------------------------------------------------------------------*/
void KillRWBuffer(prwBuffer self)
{
@@ -46,16 +61,51 @@ void KillRWBuffer(prwBuffer self)
}
free(self);
}
+/*------------------------------------------------------------------------*/
+int CanStoreRWBuffer(prwBuffer self, void *data, int count)
+{
+ int length;
+ char *ptr;
+ length = self->endPtr - self->startPtr;
+ if (count + length >= self->length ) {
+ if(self->length < self->maxSize){
+ ptr = calloc(self->maxSize,sizeof(char));
+ if(ptr == NULL) {
+ return 0;
+ }
+ memcpy(ptr,self->data, length*sizeof(char));
+ free(self->data);
+ self->data = ptr;
+ self->length = self->maxSize;
+ } else {
+ return 0;
+ }
+ }
+ return 1;
+}
/*------------------------------------------------------------------------*/
int StoreRWBuffer(prwBuffer self, void *data, int count)
{
int length;
+ char *ptr;
length = self->endPtr - self->startPtr;
if (count + length >= self->length ) {
+ if(self->length < self->maxSize){
+ ptr = calloc(self->maxSize,sizeof(char));
+ if(ptr == NULL) {
printf("HELP: RWBuffer overrun!!!!\n");
- return 0;
+ return 0;
+ }
+ memcpy(ptr,self->data, length*sizeof(char));
+ free(self->data);
+ self->data = ptr;
+ self->length = self->maxSize;
+ } else {
+ printf("HELP: RWBuffer overrun!!!!\n");
+ return 0;
+ }
}
if (count + self->endPtr > self->length) {
memmove(self->data, self->data + self->startPtr, length);
@@ -81,5 +131,6 @@ void RemoveRWBufferData(prwBuffer self, int count)
if (self->startPtr >= self->endPtr) {
self->startPtr = 0;
self->endPtr = 0;
+ memset(self->data,0,self->length*sizeof(char));
}
}
diff --git a/rwpuffer.h b/rwpuffer.h
index e69795b4..59ec439e 100644
--- a/rwpuffer.h
+++ b/rwpuffer.h
@@ -16,6 +16,13 @@ typedef struct __RWBuffer *prwBuffer;
* \return NULL on success, else a pointer to t a new rwPuffer
*/
prwBuffer MakeRWPuffer(int size);
+/**
+ * \brief create a RW buffer which can grow.
+ * \param size The size of the buffer.
+ * \param maxSize The maximum size of the buffer.
+ * \return NULL on success, else a pointer to t a new rwPuffer
+ */
+prwBuffer MakeBigRWPuffer(int size, int maxSize);
/**
* \brief delete a rw buffer.
* \param self The rwPuffer to delete.
@@ -29,6 +36,14 @@ void KillRWBuffer(prwBuffer self);
* \return 1 on success, 0 on failure
*/
int StoreRWBuffer(prwBuffer self, void *data, int count);
+/**
+ * \brief Test if the data can be stored in the rwBuffer
+ * \param self The rw buffer to store the data in
+ * \param data pointer to the data to store
+ * \param count The number of bytes to store
+ * \return 1 when OK, 0 when buffer full
+ */
+int CanStoreRWBuffer(prwBuffer self, void *data, int count);
/**
* \brief Get a pointer to the current buffer data
* \param self the buffer to get the data from
diff --git a/sansbc.c b/sansbc.c
index e40e1e44..2d0d0f83 100644
--- a/sansbc.c
+++ b/sansbc.c
@@ -101,8 +101,7 @@ static int COGCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
return 0;
}
- hm = FindCommandData(pServ->pSics,
- par[0]->value.v.text, "HistMem");
+ hm = FindHM(pServ->pSics, par[0]->value.v.text);
if(hm == NULL){
SCPrintf(pCon,eError,"ERROR: hm %s not found", par[0]->value.v.text);
return 0;
@@ -137,8 +136,7 @@ static int COCCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
return 0;
}
- hm = FindCommandData(pServ->pSics,
- par[0]->value.v.text, "HistMem");
+ hm = FindHM(pServ->pSics, par[0]->value.v.text);
if(hm == NULL){
SCPrintf(pCon,eError,"ERROR: hm %s not found", par[0]->value.v.text);
return 0;
@@ -173,8 +171,7 @@ static int StatCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
return 0;
}
- hm = FindCommandData(pServ->pSics,
- par[0]->value.v.text, "HistMem");
+ hm = FindHM(pServ->pSics, par[0]->value.v.text);
if(hm == NULL){
SCPrintf(pCon,eError,"ERROR: hm %s not found", par[0]->value.v.text);
return 0;
diff --git a/scan.c b/scan.c
index 98675fa2..97ca1140 100644
--- a/scan.c
+++ b/scan.c
@@ -241,31 +241,6 @@ int AddScanVar(pScanData self, SicsInterp * pSics, SConnection * pCon,
return 1;
}
-/*-------------------------------------------------------------------------*/
-int ReplaceScanVar(pScanData self, SicsInterp * pSics, SConnection * pCon,
- int index, float fStart, float fStep)
-{
- pVarEntry pVar = NULL;
- void *pPtr = NULL;
-
- if (self->iActive) {
- SCWrite(pCon, "ERROR: cannot change parameters while scan is running",
- eError);
- return 0;
- }
-
- DynarGet(self->pScanVar, index, &pPtr);
- pVar = (pVarEntry) pPtr;
- if (pVar == NULL) {
- return 0;
- }
- pVar->fStart = fStart;
- pVar->fStep = fStep;
-
- /* put it away */
- DynarReplace(self->pScanVar, index, pVar, sizeof(VarEntry));
- return 1;
-}
/*-------------------------------------------------------------------------*/
int AddLogVar(pScanData self, SicsInterp * pSics, SConnection * pCon,
char *name)
@@ -669,6 +644,7 @@ int DoScan(pScanData self, int iNP, int iMode, float fPreset,
return 0;
}
+ self->iActive = 1;
self->iNP = iNP;
self->iMode = iMode;
self->fPreset = fPreset;
@@ -682,13 +658,15 @@ int DoScan(pScanData self, int iNP, int iMode, float fPreset,
if (!iRet) {
self->pCon = NULL;
self->pSics = NULL;
+ self->iActive = 0;
return 0;
}
- self->iActive = 1;
iRet = ScanLoop(self);
- ScriptScanFinish(self);
+ if(self->pCon != NULL && self->pSics != NULL){
+ ScriptScanFinish(self);
+ }
InvokeCallBack(self->pCall, SCANEND, self);
SendQuieck(QUIECK, self->pFile);
self->iActive = 0;
@@ -1021,7 +999,11 @@ int GetScanVarName(pScanData self, int iWhich, char *pName, int iLength)
return 0;
}
}
-
+/*---------------------------------------------------------------------*/
+int isScanRunning(pScanData self)
+{
+ return self->iActive;
+}
/*---------------------------------------------------------------------*/
int GetScanVarStep(pScanData self, int iWhich, float *fStep)
{
@@ -1641,12 +1623,12 @@ int ScanWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[])
{
pScanData self = NULL;
- char pBueffel[512], varname[512];
+ char pBueffel[512];
double fStep, fStart, fPreset;
float *fData = NULL;
- int lNP, foundMatch=0;
+ int lNP;
int iChannel;
- int iRet, iMode, i, varnum;
+ int iRet, iMode, i;
char *pPtr = NULL, pItem[20];
long *lData = NULL, lID;
int *iData;
@@ -1742,6 +1724,12 @@ int ScanWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
SCWrite(pCon, pBueffel, eValue);
return 1;
}
+/*-------- isactive */
+ else if (strcmp(argv[1], "isactive") == 0) {
+ snprintf(pBueffel,sizeof(pBueffel)-1, "%s.active = %d", argv[0], self->iActive);
+ SCWrite(pCon, pBueffel, eValue);
+ return 1;
+ }
/*--------- getvardata */
else if (strcmp(argv[1], "getvardata") == 0) {
/* we need an integer parameter saying which */
@@ -1898,26 +1886,8 @@ int ScanWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
SCWrite(pCon, pBueffel, eError);
return 0;
}
- if (self->iScanVar == 0) {
- iRet = AddScanVar(self, pSics, pCon, argv[2], (float) fStart,
- (float) fStep);
- } else {
- foundMatch = 0;
- for (varnum = 0; varnum < self->iScanVar; varnum++) {
- GetScanVarName(self, varnum, varname, 512);
- if (strcmp(argv[2], varname) == 0) {
- foundMatch = 1;
- break;
- }
- }
- if (foundMatch) {
- iRet = ReplaceScanVar(self, pSics, pCon, varnum, (float) fStart,
- (float) fStep);
- } else {
- iRet = AddScanVar(self, pSics, pCon, argv[2], (float) fStart,
- (float) fStep);
- }
- }
+ iRet = AddScanVar(self, pSics, pCon, argv[2],
+ (float) fStart, (float) fStep);
if (iRet) {
SCSendOK(pCon);
}
diff --git a/scan.h b/scan.h
index f9e2ca2e..37e13960 100644
--- a/scan.h
+++ b/scan.h
@@ -40,6 +40,7 @@ int GetScanVarStep(pScanData self, int iWhich, float *fStep);
int GetScanMonitor(pScanData self, int iWhich, long *lData, int iDataLen);
int GetScanNP(pScanData self);
float GetScanPreset(pScanData self);
+int isScanRunning(pScanData self);
int ScanIntegrate(pScanData self, float *fSum, float *fVariance);
diff --git a/script.c b/script.c
index 5568e3cf..73a5303a 100644
--- a/script.c
+++ b/script.c
@@ -143,11 +143,17 @@ int SetSICSInterrupt(SConnection * pCon, SicsInterp * pSics, void *pData,
return 1;
}
-/*-------------------------------------------------------------------------*/
+/*-------------------------------------------------------------------------
+This method does nothing anymore. Status is now calculated from the state
+of SICS and no longer explicitly set. I left the code in because I am to
+lazy to find all use cases and eliminate them
+
+M.K. 07/2014
+--------------------------------------------------------------------------*/
int SetSICSStatus(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[])
{
- int iInt;
+ int iInt = 0;
char pBueffel[132];
assert(pCon);
@@ -166,6 +172,13 @@ int SetSICSStatus(SConnection * pCon, SicsInterp * pSics, void *pData,
return 0;
}
+ SCWrite(pCon,"Status is calculated, cannot be set manually any longer", eValue);
+ return 1;
+
+ /*
+ The code below is defunct and just here for documentary reasons
+ */
+
/* is there a value ? */
if (argc < 2) {
SCWrite(pCon, "ERROR: missing parameter for SetStatus", eError);
@@ -174,7 +187,7 @@ int SetSICSStatus(SConnection * pCon, SicsInterp * pSics, void *pData,
/* actually do a job */
strtolower(argv[1]);
- iInt = SetStatusFromText(argv[1]);
+ /* iInt = SetStatusFromText(argv[1]); */
if (iInt) {
SCSendOK(pCon);
return 1;
@@ -193,7 +206,7 @@ static int isNum(char *pText)
for (i = 0; i < strlen(pText); i++) {
if (!isdigit(pText[i])) {
- if (!((pText[i] == '+') || (pText[i] == '-') || (pText[i] == '.'))) {
+ if (!((pText[i] == '+') || (pText[i] == '-') || (pText[i] == '.') || (tolower(pText[i]) == 'e' ))) {
iRet = 0;
break;
}
diff --git a/scriptcontext.c b/scriptcontext.c
index cf5c7634..f9a5d926 100644
--- a/scriptcontext.c
+++ b/scriptcontext.c
@@ -15,6 +15,7 @@
#include "macro.h"
#include "syncedprot.h"
#include "scriptcontext.h"
+#include "sctcomtask.h"
typedef struct ContextItem {
struct ContextItem *next;
@@ -47,6 +48,7 @@ typedef struct SctData {
int inMacro;
Hdb *node;
long syncid;
+ int busy;
} SctData;
/* data for updatescript */
@@ -351,9 +353,9 @@ int SctCallInContext(SConnection * con, char *script, Hdb * node,
ret = Tcl_EvalEx(pTcl, script, l, 0);
result = (char *) Tcl_GetStringResult(pTcl);
if (ret != TCL_OK && result[0] != '\0') {
- if (strncmp(result, "ERROR:", 6) == 0) {
- /* remove "ERROR:", as it will be added later */
- result += 6;
+ if (strncmp(result, "ERROR: ", 7) == 0) {
+ /* remove "ERROR: ", as it will be added later */
+ result += 7;
if (result[0] == ' ') {
result++;
}
@@ -422,7 +424,10 @@ static char *SctActionHandler(void *actionData, char *lastReply,
} else {
con = controller->conn;
}
+ data->busy = 1;
+
/*
+ * Check if this is a followup call.
* If this is a followup call, the I/O system will have set the
* property result to the data from the device. Read this now and
* print it if diagnostics is required.
@@ -446,6 +451,8 @@ static char *SctActionHandler(void *actionData, char *lastReply,
}
/*
+ * Make sure that the state property is set to the name of the property
+ * which holds the name of the script to run at this stage.
* When this is a followup, we use the content of the
* state field as the property storing the next script to
* run. If this is the start of a chain this is set to the
@@ -486,8 +493,15 @@ static char *SctActionHandler(void *actionData, char *lastReply,
sct->sendCalled = 0;
SyncedBegin(data->syncid);
ret = SctCallInContext(con, script, node, controller, &result);
+ if (result[0] == '\0') {
+ ret = 0;
+ result = "empty response - probably missing return statement";
+ }
SyncedEnd(data->syncid);
sct->sendNode = NULL;
+ /*
+ * Process the results of the script run
+ */
if (ret == 0) {
/*
* an error occurred in the script: store error message in
@@ -615,7 +629,8 @@ static char *SctActionHandler(void *actionData, char *lastReply,
free(script);
script = NULL;
/*
- * If there is data to send, check it and do so
+ * If there is data to send, check it and do so. This also exits the
+ * quick script loop by returning the data to send to Devser.
*/
if (sct->sendCalled) {
send = GetProp(node, controller->node, "send");
@@ -637,6 +652,10 @@ static char *SctActionHandler(void *actionData, char *lastReply,
}
SCPrintf(con, eLogError, "ERROR: too many quick scripts chained");
finish:
+ /*
+ * This section is always called when the script chain ends: either due to
+ * error or by successfull termination.
+ */
if (strcmp(data->name, "write") == 0) {
if (GetHdbProp(node, "writestatus") != NULL) {
SetHdbProperty(node, "writestatus", "commandsent");
@@ -651,6 +670,7 @@ finish:
SCDeleteConnection(data->conCtx);
data->conCtx = NULL;
}
+ data->busy = 0;
return send;
}
@@ -862,6 +882,7 @@ static hdbCallbackReturn SctActionCallback(Hdb * node, void *userData,
data->inMacro = SCinMacro(con);
tracePar(node->name,"Queued %s to %s",node->name, GetCharArray(text));
data->syncid = SyncedIncr(0);
+ data->busy = 1;
DevQueue(data->controller->devser, data, prio,
SctWriteHandler, SctMatch, SctEndData, SctDataInfo);
/* kill function SctEndData does not kill, data is owned by the node (callback list) */
@@ -894,7 +915,7 @@ static hdbCallbackReturn SctActionCallback(Hdb * node, void *userData,
return hdbContinue;
}
-static char *ParText(Hdb * cmdNode, char *name,
+char *ParText(Hdb * cmdNode, char *name,
int nPar, char *defaultValue)
{
Hdb *par;
@@ -1179,7 +1200,7 @@ void SctQueueNode(SctController * controller, Hdb * node,
data->answered = 1;
data->syncid = SyncedIncr(0);
-
+ data->busy = 1;
if (DevQueue(data->controller->devser, data, prio,
SctWriteHandler, SctMatch, SctKillData, SctDataInfo)) {
if (con != NULL) {
@@ -1408,6 +1429,13 @@ typedef struct SctTransact {
SctController *controller;
} SctTransact, *pSctTransact;
+static char * SctTransactInfo(void *d)
+{
+ SctTransact *st = d;
+ return strdup(st->command);
+}
+
+
static void KillSctTransact(void *data)
{
pSctTransact self = (pSctTransact) data;
@@ -1447,16 +1475,7 @@ static char *TransactionHandler(void *actionData, char *lastReply,
return st->command;
} else {
st->sent = 2;
- /*
- if (st->controller->verbose) {
- SCPrintf(st->con, eLog, "%6.3f reply : %s", secondsOfMinute(), lastReply);
- }
- if (st->controller->fd != NULL) {
- fprintf(st->controller->fd,"%6.3f reply : %s\n", secondsOfMinute(), lastReply);
- }
- */
- /* printf("Transact: %s got %s\n", st->command, lastReply); */
- if (lastReply == NULL) {
+ if (lastReply == NULL) {
lastReply = "";
}
if(st->controller != NULL){
@@ -1519,15 +1538,9 @@ static int SctTransactCmd(pSICSOBJ ccmd, SConnection * con,
st->reply = NULL;
DevQueue(c->devser, st, WritePRIO,
- TransactionHandler, SctTransactMatch, NULL, NULL);
+ TransactionHandler, SctTransactMatch, NULL, SctTransactInfo);
while (st->sent != 2) {
TaskYield(pServ->pTasker);
- /* not yet tested:
- if (SCGetInterrupt(con) != eContinue) {
- DevUnschedule(c->devser, st, TransactionHandler, SctTransactMatch);
- break;
- }
- */
}
if (st->reply != NULL) {
SCWrite(con,st->reply,eValue);
@@ -1565,7 +1578,53 @@ static int SctSendCmd(pSICSOBJ ccmd, SConnection * con,
SetHdbProperty(c->node, "reply", "");
DevQueue(c->devser, st, prio,
- SendHandler, SctTransactMatch, KillSctTransact, NULL);
+ SendHandler, SctTransactMatch, KillSctTransact, SctTransactInfo);
+ return 1;
+}
+
+static int SctProcessCmd(pSICSOBJ ccmd, SConnection * con,
+ Hdb * cmdNode, Hdb * par[], int nPar)
+{
+ SctData *data = NULL;
+ SctController *c;
+ time_t startTime;
+
+ c = (SctController *) ccmd->pPrivate;
+
+ if(nPar < 1 || par[0] == NULL){
+ SCWrite(con,"ERROR: no node to process found", eError);
+ return 0;
+ }
+
+ data = calloc(sizeof(SctData), 1);
+ if (data == NULL) {
+ SCWrite(con, "ERROR: out of memory in SctProcessCommand", eError);
+ return 0;
+ }
+
+ data->node = FindHdbNode(NULL,par[0]->value.v.text, con);
+ if(data->node == NULL){
+ SCPrintf(con,eError,"ERROR: node %s to process not found", par[0]->value.v.text);
+ return 0;
+ }
+ if(nPar > 1) {
+ data->name = strdup(par[1]->value.v.text);
+ } else {
+ data->name = strdup("read");
+ }
+ data->controller = c;
+ data->conCtx = SCCopyConnection(con);
+ data->busy = 1;
+ data->inMacro = SCinMacro(con);
+
+ startTime = time(NULL);
+ DevQueue(c->devser, data, WritePRIO,
+ SctWriteHandler, SctTransactMatch, NULL, SctDataInfo);
+ while (data->busy == 1 && time(NULL) < startTime + 20) {
+ TaskYield(pServ->pTasker);
+ }
+ SctKillData(data);
+
return 1;
}
@@ -1584,8 +1643,14 @@ static int SctReconnect(pSICSOBJ ccmd, SConnection * con,
{
SctController *c;
char *reconnectScript, *result;
+ char *hostport;
c = (SctController *) ccmd->pPrivate;
+ hostport = ParText(cmdNode, "hostport", nPar, "");
+ if (strcmp(hostport, "unconnected") == 0) {
+ DevDisconnect(c->devser);
+ return 1;
+ }
DevReconnect(c->devser, ParText(cmdNode, "hostport", nPar, ""));
reconnectScript = GetProp(c->node, c->node, "reconnect_script");
if (reconnectScript && reconnectScript[0] != '\0') {
@@ -1659,6 +1724,25 @@ static int SctTimeout(pSICSOBJ ccmd, SConnection * con,
return 1;
}
+static int SctReconnectInterval(pSICSOBJ ccmd, SConnection * con,
+ Hdb * cmdNode, Hdb * par[], int nPar)
+{
+ SctController *c;
+ char *result;
+ hdbValue *v = &cmdNode->child->value;
+ int interval;
+
+ c = (SctController *) ccmd->pPrivate;
+ if (nPar == 0) {
+ interval = -1; /* read only */
+ } else {
+ interval = v->v.intValue;
+ }
+ v->v.intValue = DevReconnectInterval(c->devser, interval);
+ SCPrintf(con, eValue, "%d", v->v.intValue);
+ return 1;
+}
+
static int SctStatus(pSICSOBJ ccmd, SConnection * con,
Hdb * cmdNode, Hdb * par[], int nPar)
{
@@ -1757,7 +1841,7 @@ static void SctKillController(void *c)
}
if (pServ->pTasker) {
- TaskRegister(pServ->pTasker, SctDeferredTask, NULL, SctDeferredFree,
+ TaskRegisterN(pServ->pTasker,"killsct", SctDeferredTask, NULL, SctDeferredFree,
controller, 0);
} else {
free(controller);
@@ -1870,6 +1954,11 @@ static int SctMakeController(SConnection * con, SicsInterp * sics,
AddSICSHdbPar(cmd, "data", usMugger, MakeHdbText(""));
AddSICSHdbPar(cmd, "prio", usMugger, MakeHdbText(""));
+ cmd = AddSICSHdbPar(controller->node,
+ "processnode", usUser, MakeSICSFunc(SctProcessCmd));
+ AddSICSHdbPar(cmd, "node", usUser, MakeHdbText(""));
+ AddSICSHdbPar(cmd, "command", usUser, MakeHdbText("read"));
+
cmd = AddSICSHdbPar(controller->node,
"disconnect", usMugger, MakeSICSFunc(SctDisconnect));
@@ -1895,6 +1984,10 @@ static int SctMakeController(SConnection * con, SicsInterp * sics,
"timeout", usSpy, MakeSICSFunc(SctTimeout));
AddSICSHdbPar(cmd, "value", usUser, MakeHdbFloat(-1.0));
+ cmd = AddSICSHdbPar(controller->node,
+ "reconnectinterval", usSpy, MakeSICSFunc(SctReconnectInterval));
+ AddSICSHdbPar(cmd, "value", usUser, MakeHdbInt(-1));
+
/* get the actual timeout value */
SctTimeout(ccmd, con, cmd, &par, 0);
@@ -1934,6 +2027,7 @@ void SctInit(void)
sct->desc = CreateDescriptor("ScriptContext");
AddCommand(pServ->pSics, "sct", SctCommand, SctKill, sct);
AddCmd("makesctcontroller", SctMakeController);
+ AddCmd("makesctcomtask", SctMakeComTask);
}
int SctVerbose(SctController * c)
@@ -1941,3 +2035,15 @@ int SctVerbose(SctController * c)
return c->verbose;
}
+DevSer *SctGetDevser(void *data)
+{
+ SctController *c;
+
+ pSICSOBJ ccmd = (pSICSOBJ)data;
+ assert(ccmd);
+ assert(strcmp(ccmd->pDes->name,"SctController") == 0);
+
+
+ c = (SctController *) ccmd->pPrivate;
+ return c->devser;
+}
diff --git a/scriptcontext.h b/scriptcontext.h
index 5e71c0a3..946c7500 100644
--- a/scriptcontext.h
+++ b/scriptcontext.h
@@ -35,5 +35,10 @@ int SctCallInContext(SConnection * con, char *script, Hdb * node,
* \return 1 for verbose, 0 for silent
*/
int SctVerbose(SctController * c);
-
+/**
+ * retrieve the device serializer
+ * \param data A pointer to a SICSObject representing a SctController
+ * \param A pointer the the device serializer
+ */
+DevSer *SctGetDevser(void *data);
#endif
diff --git a/sctcomtask.c b/sctcomtask.c
new file mode 100644
index 00000000..56796261
--- /dev/null
+++ b/sctcomtask.c
@@ -0,0 +1,517 @@
+/**
+ * This is another approach at using the scriptcontext system. It introduces
+ * the concept of a communication task which is executed against a device serializer,
+ * accessed via a given ScriptContext. Clients can:
+ * - Create CommTasks
+ * - Figure out their state
+ * - Retrieve reply data
+ * - wait for a ComTask to finish.
+ *
+ * The purpose sctcomtask will keep a cache of pending and finished communications.
+ * Old runs will be deleted periodically. Nevertheless the cache can be listed in order
+ * to figure out what happened.
+ *
+ * The intended use is for C-code or scripts to interact in a serial manner with
+ * the asynchronous communication system implemented in devser and ascon. As a
+ * standalone implementation this would share tons of code with scriptcontext, thus
+ * this has been implemented as an add on module to scriptcontext.
+ *
+ * copyright: see file COPYRIGHT
+ *
+ * Mark Koennecke, December 2012
+ */
+#include
+#include "sctcomtask.h"
+#include "scriptcontext.h"
+#include "sicsobj.h"
+#include "sicsutil.h"
+#include "sicshipadaba.h"
+
+static unsigned int mamaID = 0L;
+
+extern char *ParText(Hdb * cmdNode, char *name,
+ int nPar, char *defaultValue);
+
+/*----------------------------------------------------------------*/
+typedef struct{
+ char *sendData;
+ char *replyData;
+ int replyDataLength;
+ int ID;
+ double startTime;
+ double endTime;
+ ComTaskState state;
+}ComTask, *pComTask;
+
+/*----------------------------------------------------------------*/
+struct ComTaskManager{
+ DevSer *devser;
+ unsigned int halfQueueLength;
+ ComTask *TaskQueue;
+ unsigned int iPtr;
+};
+/*-----------------------------------------------------------------*/
+static void KillComTaskData(ComTask *queue, int length)
+{
+ int i;
+
+ for(i = 0; i < length; i++){
+ if(queue[i].sendData != NULL){
+ free(queue[i].sendData);
+ queue[i].sendData = NULL;
+ }
+ if(queue[i].replyData != NULL){
+ free(queue[i].replyData);
+ queue[i].replyData = NULL;
+ }
+ }
+}
+/*-----------------------------------------------------------------*/
+static char *ComTaskHandler(void *data, char *replyData, int commError)
+{
+ pComTask task = (pComTask)data;
+ assert(task != NULL);
+
+ if(replyData == NULL){
+ task->state = eRunning;
+ return task->sendData;
+ } else {
+ if(task->replyData != NULL){
+ free(task->replyData);
+ }
+ task->replyData = strdup(replyData);
+ task->replyDataLength = strlen(replyData);
+ task->endTime = DoubleTime();
+ task->state = eFinished;
+ return NULL;
+ }
+}
+/*-----------------------------------------------------------------*/
+static int ComTaskMatch(void *data1, void *data2)
+{
+ pComTask task1 = (pComTask)data1;
+ pComTask task2 = (pComTask)data2;
+
+ assert(task1 && task2);
+
+ if(task1->ID == task2->ID){
+ return 1;
+ } else {
+ return 0;
+ }
+}
+/*----------------------------------------------------------------*/
+static char *stateName[] = {
+ "waiting",
+ "running",
+ "finished",
+ "unknown"
+};
+
+static char* StateToText(ComTaskState state)
+{
+ return stateName[(int)state];
+}
+/*----------------------------------------------------------------*/
+static char* ComTaskInfo(void *data)
+{
+ char *info = NULL;
+ char buf[] = {"NA"};
+ char *reply;
+ int length = 256;
+
+ pComTask task = (pComTask)data;
+ assert(data != NULL);
+
+ if(task->sendData != NULL){
+ length += strlen(task->sendData);
+ }
+ if(task->replyData != NULL){
+ length += strlen(task->replyData);
+ }
+ info = calloc(length,sizeof(char));
+ if(info == NULL){
+ return info;
+ }
+ if(task->replyData == NULL){
+ reply = buf;
+ } else {
+ reply = task->replyData;
+ }
+ snprintf(info,length,"%s:%s:%lf:%s:%lf", StateToText(task->state),
+ task->sendData,task->startTime, reply, task->endTime);
+ return info;
+}
+/*----------------------------------------------------------------*/
+int StartComTask(ComTaskManager *manager, char *priority, char *sendData)
+{
+ int ID, i;
+ unsigned int ptr;
+ DevPrio prio;
+
+ assert(manager != NULL && priority != NULL);
+
+ ID = mamaID;
+ mamaID++;
+ if(mamaID < 0){
+ mamaID = 0;
+ }
+
+ if(manager->iPtr >= 2*manager->halfQueueLength){
+ KillComTaskData(manager->TaskQueue,manager->halfQueueLength);
+ memmove(manager->TaskQueue,&manager->TaskQueue[manager->halfQueueLength],
+ manager->halfQueueLength*sizeof(ComTask));
+ /**
+ * The pointers need to be cleared, not freed, in order to
+ * prevent double freeing when reusing them.
+ */
+ for(i = manager->halfQueueLength; i < 2*manager->halfQueueLength; i++){
+ manager->TaskQueue[i].sendData = NULL;
+ manager->TaskQueue[i].replyData = NULL;
+ }
+ manager->iPtr = manager->halfQueueLength;
+ }
+ ptr = manager->iPtr;
+ manager->iPtr++;
+
+ manager->TaskQueue[ptr].ID = ID;
+ manager->TaskQueue[ptr].startTime = DoubleTime();
+ manager->TaskQueue[ptr].endTime = 0.;
+ manager->TaskQueue[ptr].state = eWaiting;
+ if(manager->TaskQueue[ptr].sendData != NULL){
+ free(manager->TaskQueue[ptr].sendData);
+ }
+ manager->TaskQueue[ptr].sendData = strdup(sendData);
+ if(manager->TaskQueue[ptr].replyData != NULL){
+ free(manager->TaskQueue[ptr].replyData);
+ }
+ manager->TaskQueue[ptr].replyData = NULL;
+
+ prio = DevText2Prio(priority);
+ DevQueue(manager->devser,
+ &manager->TaskQueue[ptr],
+ prio,
+ ComTaskHandler,
+ ComTaskMatch,
+ NULL,
+ ComTaskInfo);
+
+ return ID;
+}
+/*-----------------------------------------------------------------*/
+static int StartComTaskCmd(pSICSOBJ ccmd, SConnection * con,
+ Hdb * cmdNode, Hdb * par[], int nPar)
+{
+ char *priority, *sendData;
+ int lID;
+ ComTaskManager *manni = NULL;
+
+ if(nPar < 2) {
+ SCWrite(con,"ERROR: need priorty and send data as parameters",eError);
+ return 0;
+ }
+
+ priority = ParText(cmdNode,"priority",nPar,"read");
+ sendData = ParText(cmdNode,"send",nPar,"None");
+
+ manni = (ComTaskManager *)ccmd->pPrivate;
+ lID = StartComTask(manni, priority, sendData);
+ SCPrintf(con,eValue,"comtaskid = %ld", lID);
+ return 1;
+
+}
+/*-----------------------------------------------------------------*/
+static int ComTaskCompare(const void *data1, const void *data2)
+{
+ pComTask task1 = (pComTask)data1;
+ pComTask task2 = (pComTask)data2;
+
+ assert(task1 && task2);
+
+ if(task1->ID < task2->ID){
+ return -1;
+ } else if(task1->ID > task2->ID){
+ return 1;
+ } else {
+ return 0;
+ }
+}
+/*------------------------------------------------------------------*/
+ComTaskState GetComTaskState(ComTaskManager *manager, int comTaskID)
+{
+ ComTask key;
+ ComTask *task = NULL;
+
+ key.ID = comTaskID;
+
+ task = bsearch(&key,manager->TaskQueue,manager->iPtr,
+ sizeof(ComTask), ComTaskCompare);
+ if(task == NULL){
+ return eUnknown;
+ } else {
+ return task->state;
+ }
+}
+/*-----------------------------------------------------------------*/
+static int GetComTaskStateCmd(pSICSOBJ ccmd, SConnection * con,
+ Hdb * cmdNode, Hdb * par[], int nPar)
+{
+ int lID;
+ ComTaskManager *manni = NULL;
+ ComTaskState state;
+
+ if(nPar < 1) {
+ SCWrite(con,"ERROR: need task ID parameter",eError);
+ return 0;
+ }
+ lID = par[0]->value.v.intValue;
+
+ manni = (ComTaskManager *)ccmd->pPrivate;
+ state = GetComTaskState(manni,lID);
+ SCPrintf(con,eValue,"%d = %s", lID, StateToText(state));
+
+
+ return 1;
+}
+/*------------------------------------------------------------------*/
+const char *GetComTaskReply(ComTaskManager *manager,
+ int comTaskID, int *length)
+{
+ ComTask key;
+ ComTask *task = NULL;
+
+ key.ID = comTaskID;
+
+ task = bsearch(&key,manager->TaskQueue,manager->iPtr,
+ sizeof(ComTask), ComTaskCompare);
+ if(task == NULL || task->state != eFinished){
+ return NULL;
+ } else {
+ return (const char *)task->replyData;
+ }
+}
+/*-----------------------------------------------------------------*/
+static int GetComTaskReplyCmd(pSICSOBJ ccmd, SConnection * con,
+ Hdb * cmdNode, Hdb * par[], int nPar)
+{
+ int lID;
+ int length;
+ ComTaskManager *manni = NULL;
+ const char *reply;
+
+ if(nPar < 1) {
+ SCWrite(con,"ERROR: need task ID parameter",eError);
+ return 0;
+ }
+ lID = par[0]->value.v.intValue;
+
+ manni = (ComTaskManager *)ccmd->pPrivate;
+ reply = GetComTaskReply(manni,lID,&length);
+ if(reply == NULL){
+ SCPrintf(con,eError,"No reply for %ld found", lID);
+ return 0;
+ } else {
+ SCPrintf(con,eValue,"%d = %s", lID, reply);
+ }
+
+ return 1;
+}
+/*------------------------------------------------------------*/
+void ComTaskWait(ComTaskManager *manager, int comTaskID)
+{
+
+ ComTask key;
+ ComTask *task = NULL;
+
+ key.ID = comTaskID;
+
+ task = bsearch(&key,manager->TaskQueue,manager->iPtr,
+ sizeof(ComTask), ComTaskCompare);
+ if(task == NULL){
+ return;
+ }
+ /**
+ * Hmmmmhhhh. It might be better to start a SICS task here and
+ * wait for it terminate. But this would essentially also call
+ * TaskYield or, worse, Taskwait.
+ */
+ while(task->state != eFinished){
+ TaskYield(pServ->pTasker);
+ }
+}
+/*-----------------------------------------------------------------*/
+static int ComTaskWaitCmd(pSICSOBJ ccmd, SConnection * con,
+ Hdb * cmdNode, Hdb * par[], int nPar)
+{
+ int lID;
+ ComTaskManager *manni = NULL;
+
+ if(nPar < 1) {
+ SCWrite(con,"ERROR: need task ID parameter",eError);
+ return 0;
+ }
+ lID = par[0]->value.v.intValue;
+
+ manni = (ComTaskManager *)ccmd->pPrivate;
+ ComTaskWait(manni,lID);
+ SCWrite(con,"Done",eValue);
+
+ return 1;
+}
+/*-----------------------------------------------------------------*/
+static int ComTaskListAllCmd(pSICSOBJ ccmd, SConnection * con,
+ Hdb * cmdNode, Hdb * par[], int nPar)
+{
+ ComTaskManager *manni = NULL;
+ pDynString list = NULL;
+ int i;
+ char *info;
+
+ manni = (ComTaskManager *)ccmd->pPrivate;
+ list = CreateDynString(256,256);
+ if(list == NULL){
+ SCWrite(con,"ERROR: out of memory listing ComTasks", eError);
+ return 0;
+ }
+
+ for(i = 0; i < manni->iPtr; i++){
+ info = ComTaskInfo((void *)&manni->TaskQueue[i]);
+ DynStringConcat(list,info);
+ DynStringConcatChar(list,'\n');
+ free(info);
+ }
+ SCWrite(con,GetCharArray(list),eValue);
+ DeleteDynString(list);
+
+ return 1;
+}
+/*--------------------------------------------------------------------*/
+static int ComTaskListPendingCmd(pSICSOBJ ccmd, SConnection * con,
+ Hdb * cmdNode, Hdb * par[], int nPar)
+{
+ ComTaskManager *manni = NULL;
+ pDynString list = NULL;
+ int i;
+ char *info;
+
+ manni = (ComTaskManager *)ccmd->pPrivate;
+ list = CreateDynString(256,256);
+ if(list == NULL){
+ SCWrite(con,"ERROR: out of memory listing ComTasks", eError);
+ return 0;
+ }
+
+ for(i = 0; i < manni->iPtr; i++){
+ if(manni->TaskQueue[i].state != eFinished){
+ info = ComTaskInfo((void *)&manni->TaskQueue[i]);
+ DynStringConcat(list,info);
+ DynStringConcatChar(list,'\n');
+ free(info);
+ }
+ }
+ SCWrite(con,GetCharArray(list),eValue);
+ DeleteDynString(list);
+
+ return 1;
+}
+
+/*-----------------------------------------------------------------*/
+static ComTaskManager *MakeComTaskManager(int length)
+{
+ ComTaskManager *manni = NULL;
+ manni = calloc(1, sizeof(ComTaskManager));
+ if(manni != NULL){
+ manni->halfQueueLength=length;
+ manni->TaskQueue = calloc(length*2,sizeof(ComTask));
+ if(manni->TaskQueue == NULL){
+ free(manni);
+ return NULL;
+ }
+ }
+ return manni;
+}
+/*-----------------------------------------------------------------*/
+static void KillComTaskManager(void *data)
+{
+ ComTaskManager *manni = (ComTaskManager *)data;
+
+ if(manni == NULL){
+ return;
+ }
+
+ if(manni->TaskQueue != NULL){
+ free(manni->TaskQueue);
+ }
+ KillComTaskData(manni->TaskQueue,manni->halfQueueLength*2);
+ free(manni);
+
+}
+/*-----------------------------------------------------------------*/
+int SctMakeComTask(SConnection * con, SicsInterp * sics,
+ void *object, int argc, char *argv[])
+{
+ SICSOBJ *ccmd;
+ pHdb cmd = NULL;
+ ComTaskManager *manni = NULL;
+ int length = 64;
+
+ if (argc < 3) {
+ SCWrite(con,"ERROR: need at least comtaskmanager name and sctcontroller as arguments",
+ eError);
+ return 0;
+ }
+
+ ccmd = (SICSOBJ *)FindCommandData(sics,argv[2],"SctController");
+ if(ccmd == NULL){
+ SCPrintf(con,eError,"ERROR: SctController %s not found",argv[2]);
+ return 0;
+ }
+
+ if(argc > 3) {
+ length = atoi(argv[3]);
+ }
+
+ manni = MakeComTaskManager(length);
+ if(manni == NULL){
+ SCWrite(con,"ERROR: out of memory allocating ComTaskmanager",eError);
+ return 0;
+ }
+ manni->devser = SctGetDevser(ccmd);
+ assert(manni->devser != NULL);
+
+ ccmd = MakeSICSOBJv(argv[1], "SctComTask", HIPNONE, usSpy);
+ assert(ccmd);
+ ccmd->pPrivate = manni;
+ ccmd->KillPrivate = KillComTaskManager;
+
+ AddCommand(pServ->pSics, argv[1], InterInvokeSICSOBJ, KillSICSOBJ, ccmd);
+ RegisterSICSOBJKillCmd(ccmd, argv[1]);
+ SetDescriptorKey(ccmd->pDes, "creationCommand", "0");
+
+ cmd = AddSICSHdbPar(ccmd->objectNode,
+ "start", usUser, MakeSICSFunc(StartComTaskCmd));
+ AddSICSHdbPar(cmd, "priority", usUser, MakeHdbText(""));
+ AddSICSHdbPar(cmd, "send", usUser, MakeHdbText("None"));
+
+ cmd = AddSICSHdbPar(ccmd->objectNode,
+ "state", usUser, MakeSICSFunc(GetComTaskStateCmd));
+ AddSICSHdbPar(cmd, "id", usUser, MakeHdbInt(0));
+
+ cmd = AddSICSHdbPar(ccmd->objectNode,
+ "reply", usUser, MakeSICSFunc(GetComTaskReplyCmd));
+ AddSICSHdbPar(cmd, "id", usUser, MakeHdbInt(0));
+
+ cmd = AddSICSHdbPar(ccmd->objectNode,
+ "wait", usUser, MakeSICSFunc(ComTaskWaitCmd));
+ AddSICSHdbPar(cmd, "id", usUser, MakeHdbInt(0));
+
+ cmd = AddSICSHdbPar(ccmd->objectNode,
+ "listall", usSpy, MakeSICSFunc(ComTaskListAllCmd));
+
+ cmd = AddSICSHdbPar(ccmd->objectNode,
+ "listpend", usSpy, MakeSICSFunc(ComTaskListPendingCmd));
+
+
+ return 1;
+}
+/*-------------------------------------------------------------------------------*/
diff --git a/sctcomtask.h b/sctcomtask.h
new file mode 100644
index 00000000..b2bec46d
--- /dev/null
+++ b/sctcomtask.h
@@ -0,0 +1,78 @@
+/**
+ * This is another approach at using the scriptcontext system. It introduces
+ * the concept of a communication task which is executed against a device serializer,
+ * accessed via a given ScriptContext. Clients can:
+ * - Create CommTasks
+ * - Figure out their state
+ * - Retrieve reply data
+ * - wait for a ComTask to finish.
+ *
+ * The the purpose sctcomtask will keep a cache of pending and finished communications.
+ * Old runs will be deleted periodically. Nevertheless the cache can be listed in order
+ * to figure out what happened.
+ *
+ * The intended use is for C-code or scripts to interact in a serial manner with
+ * the asynchronous communication system implemented in devser and ascon. As a
+ * standalone implementation would share tons of code with scriptcontext, this has
+ * been implemented as an add on module to scriptcontext.
+ *
+ * copyright: see file COPYRIGHT
+ *
+ * Mark Koennecke, December 2012
+ */
+#ifndef __SCTCOMTASK
+#define __SCTCOMTASK
+#include
+
+typedef struct ComTaskManager ComTaskManager;
+
+typedef enum {
+ eWaiting,
+ eRunning,
+ eFinished,
+ eUnknown
+} ComTaskState;
+
+
+/**
+ * Standard SIS installation function
+ */
+int SctMakeComTask(SConnection * con, SicsInterp * sics,
+ void *object, int argc, char *argv[]);
+/*============================ client interface section ===========================*/
+/**
+ * Start a communication task
+ * @param manager the communication task manager to start the communication with
+ * @param priority The priority of the task
+ * @param sendData The data to send to the device
+ * @return A positive com task ID on success, -1 on failure.
+ */
+int StartComTask(ComTaskManager *manager, char *priority, char *sendData);
+/**
+ * Retrive the state of a communication task
+ * @param manager the communication task manager
+ * @param comTaskID The ID of the communication task to test
+ * @return The state of the task
+ */
+ComTaskState GetComTaskState(ComTaskManager *manager, int comTaskID);
+/**
+ * Retrive the reply of a communication task
+ * @param manager the communication task manager
+ * @param comTaskID The ID of the communication task to test
+ * @param length An output parameter set to the length of the data returned
+ * @return NULL when this is called erroneously, the reply data else. The client is
+ * not supposed to delete the reply data. On the other hand, the client cannot rely
+ * on the data to be available for ever. Make a copy if long term storage of the reply
+ * data is necessary.
+ */
+const char *GetComTaskReply(ComTaskManager *manager, int comTaskID, int *length);
+/**
+ * Wait for a communication task to finish
+ * @param manager the communication task manager
+ * @param comTaskID The ID of the communication task to test
+ * Please note that eventual timeouts are handled by devser and ascon.
+ */
+void ComTaskWait(ComTaskManager *manager, int comTaskID);
+
+
+#endif
diff --git a/sctdriveadapter.c b/sctdriveadapter.c
index 98cf6739..c3f7e3d5 100644
--- a/sctdriveadapter.c
+++ b/sctdriveadapter.c
@@ -174,11 +174,11 @@ static int SCTDRIVCheckStatus(void *data, SConnection * pCon)
SCPrintf(pCon, eError, " script %s returned %s", script, result);
}
}
- if (strstr(result, "busy") != NULL) {
+ if (strstr(result, "run") != NULL) {
return HWBusy;
} else if (strstr(result, "posfault") != NULL) {
return HWPosFault;
- } else if (strstr(result, "fault") != NULL) {
+ } else if (strstr(result, "error") != NULL) {
return HWFault;
} else if (strstr(result, "idle") != NULL) {
return HWIdle;
diff --git a/sctdriveobj.c b/sctdriveobj.c
index dc0d4b18..c47ef8a7 100644
--- a/sctdriveobj.c
+++ b/sctdriveobj.c
@@ -148,8 +148,6 @@ static long SCTDRIVSetValue(void *data, SConnection * pCon, float val)
}
pPriv->pCon = SCCopyConnection(pCon);
- StopByData(pServ->pExecutor, data);
-
v = MakeHdbFloat(val);
SetHdbProperty(self->objectNode, "writestatus", "start");
status = SetHipadabaPar(self->objectNode, v, pCon);
@@ -166,7 +164,7 @@ static long SCTDRIVSetValue(void *data, SConnection * pCon, float val)
OKOK or HWIdle when the motor finished driving
HWFault when a hardware problem ocurred
HWPosFault when the hardware cannot reach a position
- Errors are duly to be printed to pCon
+ Errors are duely to be printed to pCon
For real motors CheckStatus again shall try hard to fix any
issues with the motor
------------------------------------------------------------------*/
@@ -214,11 +212,11 @@ static int SCTDRIVCheckStatus(void *data, SConnection * pCon)
SCPrintf(pCon, eError, " script %s returned %s", script, result);
}
}
- if (strstr(result, "busy") != NULL) {
+ if (strstr(result, "run") != NULL) {
return HWBusy;
} else if (strstr(result, "posfault") != NULL) {
return HWPosFault;
- } else if (strstr(result, "fault") != NULL) {
+ } else if (strstr(result, "error") != NULL) {
return HWFault;
} else if (strstr(result, "idle") != NULL) {
return HWIdle;
diff --git a/selector.c b/selector.c
index 76f887df..16a8c76b 100644
--- a/selector.c
+++ b/selector.c
@@ -113,10 +113,10 @@ pSicsSelector CreateSelector(char *name, pMotor pTheta, pMotor pTwoTheta,
/* create all the parameters */
ObParInit(pRes->pParams, SS, "ss", 1., usUser);
- ObParInit(pRes->pParams, B1C1, "vk1", 1., usInternal);
- ObParInit(pRes->pParams, B1C2, "vk2", 1., usInternal);
- ObParInit(pRes->pParams, B2C1, "hk1", 1., usInternal);
- ObParInit(pRes->pParams, B2C2, "hk2", 1., usInternal);
+ ObParInit(pRes->pParams, B1C1, "vk1", 1., usMugger);
+ ObParInit(pRes->pParams, B1C2, "vk2", 1., usMugger);
+ ObParInit(pRes->pParams, B2C1, "hk1", 1., usMugger);
+ ObParInit(pRes->pParams, B2C2, "hk2", 1., usMugger);
ObParInit(pRes->pParams, LATD, "dd", 2.087, usMugger);
ObParInit(pRes->pParams, RIGHTS, "access", usUser, usMugger);
diff --git a/serialwait.c b/serialwait.c
index b03f02a3..bb73952f 100644
--- a/serialwait.c
+++ b/serialwait.c
@@ -194,7 +194,7 @@ int SerialSicsExecute(void **pData, char *pCommand,
control.data = CreateDynString(1024, 1024);
/* start task */
- lTask = TaskRegister(pServ->pTasker,
+ lTask = TaskRegisterN(pServ->pTasker,"serialwait",
SWTask, SWSignal, NULL, &control, 1);
/* wait for it to end */
TaskWait(pServ->pTasker, lTask);
diff --git a/sicscron.c b/sicscron.c
index 5697771c..da2ec5d3 100644
--- a/sicscron.c
+++ b/sicscron.c
@@ -9,6 +9,8 @@
Mark Koennecke, November 1999
modified to give more error output: Mark Koennecke, December 2010
+
+ added more functionality: list, stop, count
------------------------------------------------------------------------*/
#include
#include
@@ -29,9 +31,13 @@ typedef struct {
Statistics *stat;
} Cron, *pCron;
+typedef enum {cron_list, cron_stop, cron_count} CronFunc;
+
typedef struct {
SConnection *pCon;
- int dolater;
+ CronFunc func;
+ char *cmd;
+ int cnt;
} CronListData;
/*------------------------------------------------------------------------*/
@@ -58,13 +64,12 @@ static void KillCron(void *pData)
static int CronTask(void *pData)
{
Statistics *old;
-
pCron self = (pCron) pData;
int iRet;
Tcl_Interp *pTcl = pServ->pSics->pTcl;
time_t now;
- struct tm *nowtm;
- char buffer[1024];
+ struct tm tm;
+ char datim[24];
if (!self) {
return 0;
@@ -79,16 +84,12 @@ static int CronTask(void *pData)
MacroPop();
if (iRet != TCL_OK) {
if (strcmp(pTcl->result, "stop") == 0) {
- snprintf(buffer,1024,"sicscron script '%s' stopped",
- self->pCommand);
- SCPrintf(self->pCon, eLogError, buffer);
- WriteToCommandLog("SICSCRON:", buffer);
+ SCPrintf(self->pCon, eLogError, "sicscron script '%s' stopped", self->pCommand);
self->iEnd = 0;
return 0;
}
- snprintf(buffer,1024,"ERROR in sicscron script '%s': %s", self->pCommand, pTcl->result);
- SCPrintf(self->pCon, eLogError,buffer);
- WriteToCommandLog("SICSCRON:", buffer);
+
+ SCPrintf(self->pCon, eLogError, "ERROR in sicscron script '%s': %s", self->pCommand, pTcl->result);
}
if (self->iEnd == 2) { /* dolater command */
self->iEnd = 0;
@@ -98,10 +99,10 @@ static int CronTask(void *pData)
if (now > self->tNext)
self->tNext = now;
}
-/* printf("CronTask return: %d\n", self->iEnd > 0);*/
- if(self->iEnd <= 0){
- snprintf(buffer,1024,"crontask terminating at %s on %d", ctime(&now), self->iEnd);
- WriteToCommandLog("SICSCRON", buffer);
+ if (self->iEnd <= 0) {
+ tm = *localtime(&now);
+ strftime(datim, sizeof datim, "%Y-%m-%d %T", &tm);
+ SCPrintf(self->pCon, eLog, "crontask'%s' terminating at %s", self->pCommand, datim);
}
return self->iEnd > 0;
}
@@ -121,17 +122,30 @@ static void CronSignal(void *pData, int iID, void *pSigData)
self->iEnd = 0;
}
}
- if (iID == CRONLIST) {
+ if (iID == CRONFUNC) {
data = pSigData;
- if (self->iEnd == 2 && data->dolater) {
+ switch (data->func) {
+ case cron_list:
tm = *localtime(&self->tNext);
strftime(datim, sizeof datim, "%Y-%m-%d %T", &tm);
- SCPrintf(data->pCon, eLog, "%s %s", datim, self->pCommand);
- } else if (self->iEnd == 1 && !data->dolater) {
- tm = *localtime(&self->tNext);
- strftime(datim, sizeof datim, "%Y-%m-%d %T", &tm);
- SCPrintf(data->pCon, eLog, "%s %8d %s", datim,
- self->iInterval, self->pCommand);
+ if (self->iInterval < 0) {
+ SCPrintf(data->pCon, eLog, "%s %s", datim, self->pCommand);
+ } else {
+ SCPrintf(data->pCon, eLog, "%s %8d %s", datim,
+ self->iInterval, self->pCommand);
+ }
+ break;
+ case cron_stop:
+ if (strcmp(data->cmd, self->pCommand) == 0) {
+ self->iEnd = 0;
+ data->cnt++;
+ }
+ break;
+ case cron_count:
+ if (strcmp(data->cmd, self->pCommand) == 0) {
+ data->cnt++;
+ }
+ break;
}
}
}
@@ -150,22 +164,38 @@ int MakeCron(SConnection * pCon, SicsInterp * pSics, void *pData,
return 0;
}
- if (argc == 2 && strcasecmp(argv[1], "list") == 0) {
- if (strcasecmp(argv[0], "dolater") == 0) {
- data.dolater = 1;
- SCPrintf(pCon, eError, "Date Time Command");
- } else {
- data.dolater = 0;
- SCPrintf(pCon, eError, "Date Time Interval Command");
- }
+ if (argc >= 2 && strcasecmp(argv[1], "list") == 0) {
+ data.func = cron_list;
+ SCPrintf(pCon, eLog, "Date Time Interval Command");
data.pCon = pCon;
- TaskSignal(pServ->pTasker, CRONLIST, &data);
+ TaskSignal(pServ->pTasker, CRONFUNC, &data);
+ return 1;
+ }
+
+ if (argc > 2 && strcasecmp(argv[1], "stop") == 0) {
+ data.func = cron_stop;
+ data.cmd = argv[2];
+ data.cnt = 0;
+ TaskSignal(pServ->pTasker, CRONFUNC, &data);
+ SCPrintf(pCon, eValue, "%d cron jobs stopped", data.cnt);
+ return 1;
+ }
+
+ if (argc > 2 && strcasecmp(argv[1], "count") == 0) {
+ data.func = cron_count;
+ data.cmd = argv[2];
+ data.cnt = 0;
+ TaskSignal(pServ->pTasker, CRONFUNC, &data);
+ SCPrintf(pCon, eValue, "%d", data.cnt);
return 1;
}
/* enough arguments? */
if (argc < 3) {
SCPrintf(pCon, eError, "ERROR: usage: %s