Added utils and tests for it. It's a work in progress. ArrayFIFOTest is still not finished.
This commit is contained in:
332
.cproject
Normal file
332
.cproject
Normal file
@ -0,0 +1,332 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?fileVersion 4.0.0?>
|
||||
|
||||
<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
<cconfiguration id="cdt.managedbuild.toolchain.gnu.base.1356606915">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.base.1356606915" moduleId="org.eclipse.cdt.core.settings" name="Default">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactName="${ProjName}" buildProperties="" description="" id="cdt.managedbuild.toolchain.gnu.base.1356606915" name="Default" parent="org.eclipse.cdt.build.core.emptycfg">
|
||||
<folderInfo id="cdt.managedbuild.toolchain.gnu.base.1356606915.922814002" name="/" resourcePath="">
|
||||
<toolChain id="cdt.managedbuild.toolchain.gnu.base.1290391524" name="cdt.managedbuild.toolchain.gnu.base" superClass="cdt.managedbuild.toolchain.gnu.base">
|
||||
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.base.1695206694" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
|
||||
<builder id="cdt.managedbuild.target.gnu.builder.base.1065831114" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.base"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.archiver.base.766076070" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.1359276119" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base">
|
||||
<option id="gnu.cpp.compiler.option.include.paths.1856220007" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value="/opt/epics/base/include"/>
|
||||
<listOptionValue builtIn="false" value="/opt/epics/base/include/os/Linux"/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/pvDataCPP/include}""/>
|
||||
</option>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1316200261" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.compiler.base.1053490390" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base">
|
||||
<option id="gnu.c.compiler.option.include.paths.1102959803" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value="/opt/epics/base/include"/>
|
||||
<listOptionValue builtIn="false" value="/opt/epics/base/include/os/Linux"/>
|
||||
</option>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1997080176" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.linker.base.1783519900" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.1802914254" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base">
|
||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1133209566" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
</inputType>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.assembler.base.898309292" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base">
|
||||
<option id="gnu.both.asm.option.include.paths.288017456" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath"/>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.342310237" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
||||
</tool>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings">
|
||||
<externalSettings containerId="pvDataCPP;" factoryId="org.eclipse.cdt.core.cfg.export.settings.sipplier"/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="makefileGenerator">
|
||||
<runAction arguments="-E -P -v -dD" command="" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/${specs_file}"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'g++ -E -P -v -dD "${plugin_state_location}/specs.cpp"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/specs.c"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.base.1356606915;cdt.managedbuild.toolchain.gnu.base.1356606915.922814002;cdt.managedbuild.tool.gnu.cpp.compiler.base.1359276119;cdt.managedbuild.tool.gnu.cpp.compiler.input.1316200261">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="makefileGenerator">
|
||||
<runAction arguments="-E -P -v -dD" command="" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/${specs_file}"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'g++ -E -P -v -dD "${plugin_state_location}/specs.cpp"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/specs.c"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.base.1356606915;cdt.managedbuild.toolchain.gnu.base.1356606915.922814002;cdt.managedbuild.tool.gnu.c.compiler.base.1053490390;cdt.managedbuild.tool.gnu.c.compiler.input.1997080176">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="makefileGenerator">
|
||||
<runAction arguments="-E -P -v -dD" command="" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/${specs_file}"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'g++ -E -P -v -dD "${plugin_state_location}/specs.cpp"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/specs.c"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
</scannerConfigBuildInfo>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets">
|
||||
<buildTargets>
|
||||
<target name="all" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>all</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="clean" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>clean</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>false</runAllBuilders>
|
||||
</target>
|
||||
</buildTargets>
|
||||
</storageModule>
|
||||
</cconfiguration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<project id="pvAccessCPP.null.2070236580" name="pvAccessCPP"/>
|
||||
</storageModule>
|
||||
</cproject>
|
80
.project
Normal file
80
.project
Normal file
@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>pvAccessCPP</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
<project>pvDataCPP</project>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||
<triggers>clean,full,incremental,</triggers>
|
||||
<arguments>
|
||||
<dictionary>
|
||||
<key>?name?</key>
|
||||
<value></value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.append_environment</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.autoBuildTarget</key>
|
||||
<value>all</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildArguments</key>
|
||||
<value></value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildCommand</key>
|
||||
<value>make</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
|
||||
<value>clean</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.contents</key>
|
||||
<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
|
||||
<value>false</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableFullBuild</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.fullBuildTarget</key>
|
||||
<value>all</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.stopOnError</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||
<nature>org.eclipse.cdt.core.ccnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
@ -1,5 +1,7 @@
|
||||
TOP = ..
|
||||
include $(TOP)/configure/CONFIG
|
||||
DIRS += ca
|
||||
DIRS += utils testUtils
|
||||
DIRS += client testClient #server
|
||||
#DIRS += localImpl remoteClientImpl remoteServerImpl
|
||||
#DIRS += localImplTest remoteImplTest
|
||||
|
17
pvAccessApp/ca/Makefile
Normal file
17
pvAccessApp/ca/Makefile
Normal file
@ -0,0 +1,17 @@
|
||||
TOP=../..
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
INC += caConstants.h
|
||||
INC += version.h
|
||||
|
||||
LIBSRCS += version.cpp
|
||||
|
||||
LIBRARY = pvAccess
|
||||
|
||||
#pvMisc_LIBS += Com
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
#----------------------------------------
|
||||
# ADD RULES AFTER THIS LINE
|
||||
|
79
pvAccessApp/ca/caConstants.h
Normal file
79
pvAccessApp/ca/caConstants.h
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* constants.hpp
|
||||
*
|
||||
* Created on: Oct 8, 2010
|
||||
* Author: Miha Vitorovic
|
||||
*/
|
||||
|
||||
#ifndef CONSTANTS_H_
|
||||
#define CONSTANTS_H_
|
||||
|
||||
#include <pvIntrospect.h>
|
||||
|
||||
using namespace epics::pvData;
|
||||
|
||||
namespace epics {
|
||||
namespace pvAccess {
|
||||
|
||||
/** CA protocol magic number */
|
||||
const int8 CA_MAGIC = 0xCA;
|
||||
|
||||
/** CA protocol major revision (implemented by this library). */
|
||||
const int8 CA_MAJOR_PROTOCOL_REVISION = 5;
|
||||
|
||||
/** CA protocol minor revision (implemented by this library). */
|
||||
const int8 CA_MINOR_PROTOCOL_REVISION = 0;
|
||||
|
||||
/** Unknown CA protocol minor revision. */
|
||||
const int8 CA_UNKNOWN_MINOR_PROTOCOL_REVISION = 0;
|
||||
|
||||
/** CA magic/major version signature (e.g. 0xCA50). */
|
||||
const int16 CA_MAGIC_AND_MAJOR_VERSION = CA_MAGIC<<8
|
||||
|CA_MAJOR_PROTOCOL_REVISION<<4;
|
||||
|
||||
/** CA magic/version signature (e.g. 0xCA51). */
|
||||
const int16 CA_MAGIC_AND_VERSION = CA_MAGIC<<8
|
||||
|CA_MAJOR_PROTOCOL_REVISION<<4|CA_MINOR_PROTOCOL_REVISION;
|
||||
|
||||
/** CA protocol port base. */
|
||||
const int32 CA_PORT_BASE = 5056;
|
||||
|
||||
/** Default CA server port. */
|
||||
const int32 CA_SERVER_PORT = CA_PORT_BASE+2*CA_MAJOR_PROTOCOL_REVISION;
|
||||
|
||||
/** Default CA beacon port. */
|
||||
const int32 CA_BROADCAST_PORT = CA_SERVER_PORT+1;
|
||||
|
||||
/** CA protocol message header size. */
|
||||
const int16 CA_MESSAGE_HEADER_SIZE = 8;
|
||||
|
||||
/**
|
||||
* UDP maximum send message size.
|
||||
* MAX_UDP: 1500 (max of ethernet and 802.{2,3} MTU) - 20/40(IPv4/IPv6)
|
||||
* - 8(UDP) - some reserve (the MTU of Ethernet is currently independent
|
||||
* of its speed variant)
|
||||
*/
|
||||
const int32 MAX_UDP_SEND = 1440;
|
||||
|
||||
/** UDP maximum receive message size. */
|
||||
const int32 MAX_UDP_RECV = 0xFFFF+16;
|
||||
|
||||
/** TCP maximum receive message size. */
|
||||
const int32 MAX_TCP_RECV = 1024*16;
|
||||
|
||||
/** Maximum number of search requests in one search message. */
|
||||
const int32 MAX_SEARCH_BATCH_COUNT = 0xFFFF;
|
||||
|
||||
/** Default priority (corresponds to POSIX SCHED_OTHER) */
|
||||
const int16 CA_DEFAULT_PRIORITY = 0;
|
||||
|
||||
/** Unreasonable channel name length. */
|
||||
const int32 UNREASONABLE_CHANNEL_NAME_LENGTH = 500;
|
||||
|
||||
/** Invalid data type. */
|
||||
const int16 INVALID_DATA_TYPE = (short)0xFFFF;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONSTANTS_H_ */
|
52
pvAccessApp/ca/version.cpp
Normal file
52
pvAccessApp/ca/version.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* version.cpp
|
||||
*
|
||||
* Created on: Oct 8, 2010
|
||||
* Author: Miha Vitorovic
|
||||
*/
|
||||
|
||||
#include "version.h"
|
||||
|
||||
namespace epics {
|
||||
namespace pvAccess {
|
||||
|
||||
using epics::pvData::String;
|
||||
|
||||
const String Version::getLongVersionString() const {
|
||||
String ret;
|
||||
ret += getProductName();
|
||||
ret += " [";
|
||||
ret += getImplementationLanguage();
|
||||
ret += "] v";
|
||||
ret += getMajorVersion();
|
||||
ret += ".";
|
||||
ret += getMinorVersion();
|
||||
ret += ".";
|
||||
if(getDevelopmentVersion()>0) {
|
||||
ret += "D";
|
||||
ret += getDevelopmentVersion();
|
||||
} else
|
||||
ret += getMaintenanceVersion();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const String Version::getVersionString() const {
|
||||
String ret;
|
||||
ret += getProductName();
|
||||
ret += " v";
|
||||
ret += getMajorVersion();
|
||||
ret += ".";
|
||||
ret += getMinorVersion();
|
||||
ret += ".";
|
||||
if(getDevelopmentVersion()>0) {
|
||||
ret += "D";
|
||||
ret += getDevelopmentVersion();
|
||||
} else
|
||||
ret += getMaintenanceVersion();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
135
pvAccessApp/ca/version.h
Normal file
135
pvAccessApp/ca/version.h
Normal file
@ -0,0 +1,135 @@
|
||||
/*
|
||||
* version.h
|
||||
*
|
||||
* Created on: Oct 8, 2010
|
||||
* Author: Miha Vitorovic
|
||||
*/
|
||||
|
||||
#ifndef VERSION_H_
|
||||
#define VERSION_H_
|
||||
|
||||
#include <pvType.h>
|
||||
#include <noDefaultMethods.h>
|
||||
|
||||
namespace epics {
|
||||
namespace pvAccess {
|
||||
|
||||
using epics::pvData::String;
|
||||
|
||||
class Version : public epics::pvData::NoDefaultMethods {
|
||||
public:
|
||||
/**
|
||||
* Default constructor.
|
||||
* @param productName product name.
|
||||
* @param implementationLangugage implementation language.
|
||||
* @param majorVersion major version.
|
||||
* @param minorVersion minor version.
|
||||
* @param maintenanceVersion maintenance version.
|
||||
* @param developmentVersion development version.
|
||||
*/
|
||||
Version(String productName, String implementationLangugage,
|
||||
int majorVersion, int minorVersion, int maintenanceVersion,
|
||||
int developmentVersion) :
|
||||
_productName(productName), _implementationLanguage(
|
||||
implementationLangugage), _majorVersion(majorVersion),
|
||||
_minorVersion(minorVersion), _maintenanceVersion(
|
||||
maintenanceVersion), _developmentVersion(
|
||||
developmentVersion) {
|
||||
}
|
||||
|
||||
/** The name of the product */
|
||||
const inline String getProductName() const {
|
||||
return _productName;
|
||||
}
|
||||
|
||||
/** Implementation Language: C++
|
||||
*/
|
||||
inline const String getImplementationLanguage() const {
|
||||
return _implementationLanguage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Major version number. This changes only when there is a
|
||||
* significant, externally apparent enhancement from the previous release.
|
||||
* 'n' represents the n'th version.
|
||||
*
|
||||
* Clients should carefully consider the implications of new versions as
|
||||
* external interfaces and behaviour may have changed.
|
||||
*/
|
||||
inline int getMajorVersion() const {
|
||||
return _majorVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Minor vesion number. This changes when:
|
||||
* <ul>
|
||||
* <li>a new set of functionality is to be added</li>
|
||||
* <li>API or behaviour change</li>
|
||||
* <li>its designated as a reference release</li>
|
||||
* </ul>
|
||||
*/
|
||||
inline int getMinorVersion() const {
|
||||
return _minorVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maintenance version number. Optional identifier used to designate
|
||||
* maintenance drop applied to a specific release and contains fixes for
|
||||
* defects reported. It maintains compatibility with the release and
|
||||
* contains no API changes. When missing, it designates the final and
|
||||
* complete development drop for a release.
|
||||
*/
|
||||
inline int getMaintenanceVersion() const {
|
||||
return _maintenanceVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Development drop number. Optional identifier designates development drop
|
||||
* of a specific release. D01 is the first development drop of a new
|
||||
* release.
|
||||
*
|
||||
* Development drops are works in progress towards a compeleted, final
|
||||
* release. A specific development drop may not completely implement all
|
||||
* aspects of a new feature, which may take several development drops to
|
||||
* complete. At the point of the final drop for the release, the D suffix
|
||||
* will be omitted.
|
||||
*
|
||||
* Each 'D' drops can contain functional enhancements as well as defect
|
||||
* fixes. 'D' drops may not be as stable as the final releases.
|
||||
*/
|
||||
inline int getDevelopmentVersion() const {
|
||||
return _developmentVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the long version string. Version String formatted like <BR/><CODE>
|
||||
* "<B>ProductName </B> \[<B>ImplementationLanguage</B>\] 'v'v.r[.dd|<B>D</B>nn]"
|
||||
* </CODE> <BR/>e.g. <BR/><CODE>"<B>CAJ </B> [<B>Java</B>] v1.0.1"</CODE>
|
||||
* <BR/>
|
||||
*
|
||||
* @return String denoting current version
|
||||
*/
|
||||
const String getLongVersionString() const;
|
||||
|
||||
/**
|
||||
* Get the basic version string. Version String formatted like <BR/><CODE>
|
||||
* "<B>ProductName </B> 'v'v.r[.dd|<B>D</B>nn]"
|
||||
* </CODE> <BR/>e.g. <BR/><CODE>"<B>CAJ </B> v1.0.1"</CODE>
|
||||
* <BR/>
|
||||
*
|
||||
* @return String denoting current version
|
||||
*/
|
||||
const String getVersionString() const;
|
||||
|
||||
private:
|
||||
String _productName;
|
||||
String _implementationLanguage;
|
||||
int _majorVersion;
|
||||
int _minorVersion;
|
||||
int _maintenanceVersion;
|
||||
int _developmentVersion;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* VERSION_H_ */
|
20
pvAccessApp/testUtils/Makefile
Normal file
20
pvAccessApp/testUtils/Makefile
Normal file
@ -0,0 +1,20 @@
|
||||
TOP=../..
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
PROD_HOST += hexDumpTest
|
||||
hexDumpTest_SRCS += hexDumpTest.cpp
|
||||
hexDumpTest_LIBS += pvAccUtils
|
||||
|
||||
PROD_HOST += wildcharMatcherTest
|
||||
wildcharMatcherTest_SRCS += wildcharMatcherTest.cpp
|
||||
wildcharMatcherTest_LIBS += pvAccUtils Com
|
||||
|
||||
PROD_HOST += arrayFIFOTest
|
||||
arrayFIFOTest_SRCS += arrayFIFOTest.cpp
|
||||
arrayFIFOTest_LIBS += pvAccUtils Com
|
||||
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
#----------------------------------------
|
||||
# ADD RULES AFTER THIS LINE
|
47
pvAccessApp/testUtils/arrayFIFOTest.cpp
Normal file
47
pvAccessApp/testUtils/arrayFIFOTest.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* arrayFIFOTest.cpp
|
||||
*
|
||||
* Created on: Nov 9, 2010
|
||||
* Author: Miha Vitorovic
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <epicsAssert.h>
|
||||
|
||||
#include "arrayFIFO.h"
|
||||
|
||||
using namespace epics::pvAccess;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
ArrayFIFO<int> fifo;
|
||||
|
||||
assert(fifo.size()==0);
|
||||
assert(fifo.isEmpty());
|
||||
|
||||
cout<<"Testing clear..."<<endl;
|
||||
fifo.push(3);
|
||||
assert(fifo.size()==1);
|
||||
|
||||
fifo.clear();
|
||||
assert(fifo.isEmpty());
|
||||
|
||||
cout<<"Testing push/pop..."<<endl;
|
||||
fifo.push(5);
|
||||
fifo.push(6);
|
||||
fifo.push(7);
|
||||
assert(fifo.size()==3);
|
||||
|
||||
assert(fifo.pop()==7);
|
||||
assert(fifo.size()==2);
|
||||
|
||||
assert(fifo.pop()==6);
|
||||
assert(fifo.size()==1);
|
||||
|
||||
assert(fifo.pop()==5);
|
||||
assert(fifo.size()==0);
|
||||
|
||||
cout<<"\nPASSED!\n";
|
||||
return 0;
|
||||
}
|
28
pvAccessApp/testUtils/hexDumpTest.cpp
Normal file
28
pvAccessApp/testUtils/hexDumpTest.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* HexDumpTest.cpp
|
||||
*
|
||||
* Created on: Nov 8, 2010
|
||||
* Author: Miha Vitorovic
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "hexDump.h"
|
||||
|
||||
using namespace epics::pvAccess;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
char TO_DUMP[] = "pvAccess dump test\0\1\2\3\4\5\6\254\255\256";
|
||||
|
||||
hexDump("test", (int8*)TO_DUMP, 18+9);
|
||||
|
||||
hexDump("only text", (int8*)TO_DUMP, 18);
|
||||
|
||||
hexDump("22 byte test", (int8*)TO_DUMP, 22);
|
||||
|
||||
cout<<endl;
|
||||
|
||||
return 0;
|
||||
}
|
62
pvAccessApp/testUtils/wildcharMatcherTest.cpp
Normal file
62
pvAccessApp/testUtils/wildcharMatcherTest.cpp
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* wildcharMatcher.cpp
|
||||
*
|
||||
* Created on: Nov 8, 2010
|
||||
* Author: Miha Vitorovic
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <epicsAssert.h>
|
||||
|
||||
#include "wildcharMatcher.h"
|
||||
|
||||
using namespace epics::pvAccess;
|
||||
using std::cout;
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
String testString = "Test string for matcher";
|
||||
|
||||
cout<<"testSet(\"[abc]\",1,'a').\n";
|
||||
assert(testSet("[abc]", 1, 'a'));
|
||||
cout<<"testSet(\"[abc]\",1,'b').\n";
|
||||
assert(testSet("[abc]", 1, 'b'));
|
||||
cout<<"testSet(\"[abc]\",1,'c').\n";
|
||||
assert(testSet("[abc]", 1, 'c'));
|
||||
cout<<"testSet(\"[abc]\",1,'d').\n";
|
||||
assert(!testSet("[abc]", 1, 'd'));
|
||||
cout<<"testSet(\"[!abc]\",1,'d').\n";
|
||||
assert(testSet("[!abc]", 1, 'd'));
|
||||
cout<<"testSet(\"[a-c]\",1,'d').\n";
|
||||
assert(!testSet("[a-c]", 1, 'd'));
|
||||
cout<<"testSet(\"[!a-c]\",1,'d').\n";
|
||||
assert(testSet("[!a-c]", 1, 'd'));
|
||||
cout<<"testSet(\"[ac-f]\",1,'d').\n";
|
||||
assert(testSet("[ac-f]", 1, 'd'));
|
||||
cout<<"testSet(\"[!ac-f]\",1,'d').\n";
|
||||
assert(!testSet("[!ac-f]", 1, 'd'));
|
||||
|
||||
|
||||
cout<<"\n";
|
||||
|
||||
cout<<"Test string is: \""<<testString<<"\"\n";
|
||||
|
||||
cout<<"Testing for '*'\n";
|
||||
assert(match("*", testString));
|
||||
cout<<"Testing for 'test*'.\n";
|
||||
assert(!match("test*", testString));
|
||||
cout<<"Testing for '*est*'.\n";
|
||||
assert(match("*est*", testString));
|
||||
cout<<"Testing for '?est*'.\n";
|
||||
assert(match("?est*", testString));
|
||||
cout<<"Testing for '??est*'.\n";
|
||||
assert(!match("??est*", testString));
|
||||
cout<<"Testing for '*string*'.\n";
|
||||
assert(match("*string*", testString));
|
||||
cout<<"Testing for '*[abc]tring*'.\n";
|
||||
assert(!match("*[abc]tring*", testString));
|
||||
cout<<"Testing for '*[!abc]tring*'.\n";
|
||||
assert(match("*[!abc]tring*", testString));
|
||||
cout<<"Testing for '*[p-z]tring*'.\n";
|
||||
assert(match("*[p-z]tring*", testString));
|
||||
cout<<"\nPASSED!\n";
|
||||
}
|
19
pvAccessApp/utils/Makefile
Normal file
19
pvAccessApp/utils/Makefile
Normal file
@ -0,0 +1,19 @@
|
||||
TOP=../..
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
INC += hexDump.h
|
||||
INC += wildcharMatcher.h
|
||||
INC += arrayFIFO.h
|
||||
|
||||
LIBSRCS += hexDump.cpp
|
||||
LIBSRCS += wildcharMatcher.cpp
|
||||
|
||||
LIBRARY = pvAccUtils
|
||||
|
||||
#pvAccess_LIBS += Com
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
#----------------------------------------
|
||||
# ADD RULES AFTER THIS LINE
|
||||
|
376
pvAccessApp/utils/arrayFIFO.h
Normal file
376
pvAccessApp/utils/arrayFIFO.h
Normal file
@ -0,0 +1,376 @@
|
||||
/*
|
||||
* arrayFIFO.h
|
||||
*
|
||||
* Created on: Nov 8, 2010
|
||||
* Author: Miha Vitorovic
|
||||
*/
|
||||
|
||||
#ifndef ARRAYFIFO_H_
|
||||
#define ARRAYFIFO_H_
|
||||
|
||||
#include <lock.h>
|
||||
#include <epicsException.h>
|
||||
|
||||
using epics::pvData::Mutex;
|
||||
using epics::pvData::Lock;
|
||||
using epics::pvData::BaseException;
|
||||
|
||||
namespace epics {
|
||||
namespace pvAccess {
|
||||
|
||||
template <class T>
|
||||
class ArrayFIFO {
|
||||
public:
|
||||
/**
|
||||
* Constructs an empty array deque with an initial capacity
|
||||
* sufficient to hold 16 elements. Array FIFO is designed to hold
|
||||
* objects allocated on the heap.
|
||||
*/
|
||||
ArrayFIFO();
|
||||
|
||||
/**
|
||||
* Constructs an empty array deque with an initial capacity
|
||||
* sufficient to hold the specified number of elements. Array FIFO
|
||||
* is designed to hold objects allocated on the heap.
|
||||
*
|
||||
* @param[in] numElements lower bound on initial capacity of the deque
|
||||
*/
|
||||
ArrayFIFO(size_t numElements);
|
||||
~ArrayFIFO();
|
||||
|
||||
/**
|
||||
* Inserts the specified element at the front of this deque.
|
||||
*
|
||||
* @param[in] e the element to add.
|
||||
*/
|
||||
void addFirst(const T e);
|
||||
|
||||
/**
|
||||
* Inserts the specified element at the end of this deque.
|
||||
* @param[in] e the element to add
|
||||
*/
|
||||
void addLast(const T e);
|
||||
|
||||
T pollFirst();
|
||||
T pollLast();
|
||||
T peekFirst();
|
||||
T peekLast();
|
||||
|
||||
/**
|
||||
* Pushes an element onto the stack represented by this deque. In other
|
||||
* words, inserts the element at the front of this deque.
|
||||
*
|
||||
* @param[in] e the element to push
|
||||
*/
|
||||
void push(const T e);
|
||||
|
||||
/**
|
||||
* Pops an element from the stack represented by this deque. In other
|
||||
* words, removes and returns the first element of this deque.
|
||||
*
|
||||
* @return the element at the front of this deque (which is the top
|
||||
* of the stack represented by this deque), <code>null</code> if no element available.
|
||||
*/
|
||||
T pop();
|
||||
|
||||
/**
|
||||
* Looks at the object at the top of this stack without removing it
|
||||
* from the stack.
|
||||
* @return the object at the top of this stack (the last item
|
||||
* of the <tt>Vector</tt> object).
|
||||
*/
|
||||
T peek();
|
||||
|
||||
/**
|
||||
* Returns the number of elements in this deque.
|
||||
* @return the number of elements in this deque
|
||||
*/
|
||||
size_t size();
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this deque contains no elements.
|
||||
*
|
||||
* @return <tt>true</tt> if this deque contains no elements
|
||||
*/
|
||||
bool isEmpty();
|
||||
|
||||
/**
|
||||
* Removes all of the elements from this deque.
|
||||
* The deque will be empty after this call returns.
|
||||
*
|
||||
* @param freeElements tells the methods to automatically free
|
||||
* the memory of all the elments in the FIFO. Default is {@code true}
|
||||
*/
|
||||
void clear();
|
||||
|
||||
/**
|
||||
* Removes the first occurrence of the specified element in this
|
||||
* deque (when traversing the deque from head to tail).
|
||||
* If the deque does not contain the element, it is unchanged.
|
||||
* More formally, removes the first element <tt>e</tt> such that
|
||||
* <tt>o.equals(e)</tt> (if such an element exists).
|
||||
* Returns <tt>true</tt> if this deque contained the specified element
|
||||
* (or equivalently, if this deque changed as a result of the call).
|
||||
*
|
||||
* @param o element to be removed from this deque, if present
|
||||
* @return <tt>true</tt> if the deque contained the specified element
|
||||
*/
|
||||
bool remove(const T e);
|
||||
|
||||
private:
|
||||
T* _elements; // array of pointers
|
||||
size_t _head, _tail, _size;
|
||||
Mutex _mutex;
|
||||
static int MIN_INITIAL_CAPACITY;
|
||||
|
||||
/**
|
||||
* Allocate empty array to hold the given number of elements.
|
||||
* @param[in] numElements the number of elements to hold
|
||||
*/
|
||||
void allocateElements(const size_t numElements);
|
||||
|
||||
/**
|
||||
* Double the capacity of this deque. Call only when full, i.e.,
|
||||
* when head and tail have wrapped around to become equal.
|
||||
*/
|
||||
void doubleCapacity();
|
||||
|
||||
void arraycopy(T* src, size_t srcPos, T* dest, size_t destPos, size_t length);
|
||||
|
||||
/**
|
||||
* Removes the element at the specified position in the elements array,
|
||||
* adjusting head and tail as necessary. This can result in motion of
|
||||
* elements backwards or forwards in the array.
|
||||
*
|
||||
* <p>This method is called delete rather than remove to emphasize
|
||||
* that its semantics differ from those of {@link List#remove(int)}.
|
||||
*
|
||||
* @return true if elements moved backwards
|
||||
*/
|
||||
bool del(const size_t i);
|
||||
|
||||
};
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* g++ requires template definition inside a header file.
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
template<class T>
|
||||
int ArrayFIFO<T>::MIN_INITIAL_CAPACITY = 8;
|
||||
|
||||
template<class T>
|
||||
void ArrayFIFO<T>::arraycopy(T* src, size_t srcPos, T* dest,
|
||||
size_t destPos, size_t length) {
|
||||
for(size_t i = 0; i<length; i++)
|
||||
dest[destPos++] = src[srcPos++];
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void ArrayFIFO<T>::allocateElements(size_t numElements) {
|
||||
_size = MIN_INITIAL_CAPACITY;
|
||||
// Find the best power of two to hold elements.
|
||||
// Tests "<=" because arrays aren't kept full.
|
||||
if(numElements>=_size) {
|
||||
_size = numElements;
|
||||
_size |= (_size>>1);
|
||||
_size |= (_size>>2);
|
||||
_size |= (_size>>4);
|
||||
_size |= (_size>>8);
|
||||
_size |= (_size>>16);
|
||||
_size++;
|
||||
}
|
||||
_elements = new T[_size];
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void ArrayFIFO<T>::doubleCapacity() {
|
||||
size_t p = _head;
|
||||
size_t n = _size;
|
||||
size_t r = n-p; // number of elements to the right of p
|
||||
size_t newCapacity = n<<1;
|
||||
T* a = new T[newCapacity];
|
||||
arraycopy(_elements, p, a, 0, r);
|
||||
arraycopy(_elements, 0, a, r, p);
|
||||
delete _elements;
|
||||
_elements = a;
|
||||
_size = newCapacity;
|
||||
_head = 0;
|
||||
_tail = n;
|
||||
|
||||
}
|
||||
|
||||
template<class T>
|
||||
ArrayFIFO<T>::ArrayFIFO() :
|
||||
_head(0), _tail(0), _size(16), _mutex() {
|
||||
_elements = new T[16];
|
||||
}
|
||||
|
||||
template<class T>
|
||||
ArrayFIFO<T>::ArrayFIFO(size_t numElements) :
|
||||
_head(0), _tail(0), _mutex() {
|
||||
allocateElements(numElements);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
ArrayFIFO<T>::~ArrayFIFO() {
|
||||
delete _elements;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void ArrayFIFO<T>::addFirst(const T e) {
|
||||
Lock lock(&_mutex);
|
||||
|
||||
_elements[_head = (_head-1)&(_size-1)] = e;
|
||||
if(_head==_tail) doubleCapacity();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void ArrayFIFO<T>::addLast(const T e) {
|
||||
Lock lock(&_mutex);
|
||||
|
||||
_elements[_tail] = e;
|
||||
if((_tail = (_tail+1)&(_size-1))==_head) doubleCapacity();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T ArrayFIFO<T>::pollFirst() {
|
||||
Lock lock(&_mutex);
|
||||
|
||||
if(isEmpty()) THROW_BASE_EXCEPTION("ArrayFIFO empty");
|
||||
|
||||
size_t h = _head;
|
||||
T result = _elements[h]; // Element is null if deque empty
|
||||
_elements[h] = NULL; // Must null out slot
|
||||
_head = (h+1)&(_size-1);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T ArrayFIFO<T>::pollLast() {
|
||||
Lock lock(&_mutex);
|
||||
|
||||
if(isEmpty()) THROW_BASE_EXCEPTION("ArrayFIFO empty");
|
||||
|
||||
int t = (_tail-1)&(_size-1);
|
||||
T result = _elements[t];
|
||||
_tail = t;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T ArrayFIFO<T>::peekFirst() {
|
||||
Lock lock(&_mutex);
|
||||
|
||||
if(isEmpty()) THROW_BASE_EXCEPTION("ArrayFIFO empty");
|
||||
|
||||
return _elements[_head];
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T ArrayFIFO<T>::peekLast() {
|
||||
Lock lock(&_mutex);
|
||||
|
||||
if(isEmpty()) THROW_BASE_EXCEPTION("ArrayFIFO empty");
|
||||
|
||||
return _elements[(_tail-1)&(_size-1)];
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void ArrayFIFO<T>::push(const T e) {
|
||||
addLast(e);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T ArrayFIFO<T>::pop() {
|
||||
return pollLast();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T ArrayFIFO<T>::peek() {
|
||||
return peekFirst();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
size_t ArrayFIFO<T>::size() {
|
||||
Lock lock(&_mutex);
|
||||
|
||||
return (_tail-_head)&(_size-1);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool ArrayFIFO<T>::isEmpty() {
|
||||
Lock lock(&_mutex);
|
||||
|
||||
return _head==_tail;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void ArrayFIFO<T>::clear() {
|
||||
Lock lock(&_mutex);
|
||||
|
||||
_head = _tail = 0;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool ArrayFIFO<T>::del(const size_t i) {
|
||||
int mask = _size-1;
|
||||
int h = _head;
|
||||
int t = _tail;
|
||||
int front = (i-h)&mask;
|
||||
int back = (t-i)&mask;
|
||||
|
||||
// Invariant: head <= i < tail mod circularity
|
||||
if(front>=((t-h)&mask)) THROW_BASE_EXCEPTION(
|
||||
"Illegal State Exception"); // concurrency problem!!!
|
||||
|
||||
// Optimize for least element motion
|
||||
if(front<back) {
|
||||
if(h<=i) {
|
||||
arraycopy(_elements, h, _elements, h+1, front);
|
||||
}
|
||||
else { // Wrap around
|
||||
arraycopy(_elements, 0, _elements, 1, i);
|
||||
_elements[0] = _elements[mask];
|
||||
arraycopy(_elements, h, _elements, h+1, mask-h);
|
||||
}
|
||||
_elements[h] = NULL;
|
||||
_head = (h+1)&mask;
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if(i<t) { // Copy the null tail as well
|
||||
arraycopy(_elements, i+1, _elements, i, back);
|
||||
_tail = t-1;
|
||||
}
|
||||
else { // Wrap around
|
||||
arraycopy(_elements, i+1, _elements, i, mask-i);
|
||||
_elements[mask] = _elements[0];
|
||||
arraycopy(_elements, 1, _elements, 0, t);
|
||||
_tail = (t-1)&mask;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool ArrayFIFO<T>::remove(const T e) {
|
||||
Lock lock(&_mutex);
|
||||
|
||||
if(isEmpty()) return false; // nothing to do
|
||||
|
||||
int mask = _size-1;
|
||||
int i = _head;
|
||||
while(i!=_tail) {
|
||||
if(e == _elements[i]) {
|
||||
del(i);
|
||||
return true;
|
||||
}
|
||||
i = (i+1)&mask;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* ARRAYFIFO_H_ */
|
113
pvAccessApp/utils/hexDump.cpp
Normal file
113
pvAccessApp/utils/hexDump.cpp
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* hexDump.cpp
|
||||
*
|
||||
* Created on: Nov 3, 2010
|
||||
* Author: Miha Vitorovic
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include "hexDump.h"
|
||||
|
||||
using namespace epics::pvData;
|
||||
|
||||
namespace epics {
|
||||
namespace pvAccess {
|
||||
|
||||
String toHex(int8);
|
||||
char toAscii(int8);
|
||||
|
||||
void hexDump(const String name, const int8 *bs, int len) {
|
||||
hexDump(name, bs, 0, len);
|
||||
}
|
||||
|
||||
void hexDump(const String name, const int8 *bs, int start, int len) {
|
||||
hexDump("", name, bs, start, len);
|
||||
}
|
||||
|
||||
void hexDump(const String prologue, const String name, const int8 *bs,
|
||||
int start, int len) {
|
||||
|
||||
std::stringstream header;
|
||||
|
||||
header<<prologue<<std::endl<<"Hexdump ["<<name<<"] size = "<<len;
|
||||
|
||||
String out(header.str());
|
||||
|
||||
String chars;
|
||||
|
||||
for(int i = start; i<(start+len); i++) {
|
||||
if(((i-start)%16)==0) {
|
||||
out += chars;
|
||||
out += '\n';
|
||||
chars.clear();
|
||||
}
|
||||
|
||||
chars += toAscii(bs[i]);
|
||||
|
||||
out += toHex(bs[i]);
|
||||
|
||||
if(((i-start)%4)==3) {
|
||||
chars += ' ';
|
||||
out += ' ';
|
||||
}
|
||||
}
|
||||
|
||||
if(len%16!=0) {
|
||||
int pad = 0;
|
||||
int delta_bytes = 16-(len%16);
|
||||
|
||||
//rest of line (no of bytes)
|
||||
//each byte takes two chars plus one ws
|
||||
pad = delta_bytes*3;
|
||||
|
||||
//additional whitespaces after four bytes
|
||||
pad += (delta_bytes/4);
|
||||
|
||||
for(int i = 0; i<pad; i++)
|
||||
chars.insert(0, " ");
|
||||
}
|
||||
|
||||
out += chars;
|
||||
std::cout<<out;
|
||||
}
|
||||
|
||||
/**
|
||||
* byte to hexchar mapping.
|
||||
*/
|
||||
static const char lookup[] = { '0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
|
||||
|
||||
/**
|
||||
* Get hex representation of byte.
|
||||
* @param b
|
||||
* @return string hex representation of byte.
|
||||
*/
|
||||
String toHex(int8 b) {
|
||||
String sb;
|
||||
|
||||
int upper = (b>>4)&0x0F;
|
||||
sb += lookup[upper];
|
||||
|
||||
int lower = b&0x0F;
|
||||
sb += lookup[lower];
|
||||
|
||||
sb += ' ';
|
||||
|
||||
return sb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ASCII representation of byte, dot if non-readable.
|
||||
* @param b
|
||||
* @return ASCII representation of byte, dot if non-readable.
|
||||
*/
|
||||
char toAscii(int8 b) {
|
||||
if(b>(int8)31&&b<(int8)127)
|
||||
return (char)b;
|
||||
else
|
||||
return '.';
|
||||
}
|
||||
|
||||
}
|
||||
}
|
49
pvAccessApp/utils/hexDump.h
Normal file
49
pvAccessApp/utils/hexDump.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* hexDump.h
|
||||
*
|
||||
* Created on: Nov 3, 2010
|
||||
* Author: user
|
||||
*/
|
||||
|
||||
#ifndef HEXDUMP_H_
|
||||
#define HEXDUMP_H_
|
||||
|
||||
#include <pvType.h>
|
||||
|
||||
using namespace epics::pvData;
|
||||
|
||||
namespace epics {
|
||||
namespace pvAccess {
|
||||
|
||||
/**
|
||||
* Output a buffer in hex format.
|
||||
* @param name name (description) of the message.
|
||||
* @param bs buffer to dump
|
||||
* @param len first bytes (length) to dump.
|
||||
*/
|
||||
void hexDump(const String name, const int8 *bs, int len);
|
||||
|
||||
/**
|
||||
* Output a buffer in hex format.
|
||||
* @param[in] name name (description) of the message.
|
||||
* @param[in] bs buffer to dump
|
||||
* @param[in] start dump message using given offset.
|
||||
* @param[in] len first bytes (length) to dump.
|
||||
*/
|
||||
void hexDump(const String name, const int8 *bs, int start, int len);
|
||||
|
||||
/**
|
||||
* Output a buffer in hex format.
|
||||
* @param[in] prologue string to prefixed to debug output, can be <code>null</code>
|
||||
* @param[in] name name (description) of the message.
|
||||
* @param[in] bs buffer to dump
|
||||
* @param[in] start dump message using given offset.
|
||||
* @param[in] len first bytes (length) to dump.
|
||||
*/
|
||||
void hexDump(const String prologue, const String name, const int8 *bs,
|
||||
int start, int len);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HEXDUMP_H_ */
|
268
pvAccessApp/utils/wildcharMatcher.cpp
Normal file
268
pvAccessApp/utils/wildcharMatcher.cpp
Normal file
@ -0,0 +1,268 @@
|
||||
/*
|
||||
* wildcharMatcher.cpp
|
||||
*
|
||||
* Created on: Nov 4, 2010
|
||||
* Author: Miha Vitorovic
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "wildcharMatcher.h"
|
||||
|
||||
using std::cout;
|
||||
|
||||
namespace epics {
|
||||
namespace pvAccess {
|
||||
|
||||
/** Wildchar matcher debug */
|
||||
const bool WCM_DEBUG = false;
|
||||
|
||||
/** Value of initial state */
|
||||
const int WCM_INITIAL = 0;
|
||||
|
||||
/** Value of final state */
|
||||
const int WCM_FINAL = 2;
|
||||
|
||||
/** Value of error state */
|
||||
const int WCM_ERROR = 99;
|
||||
|
||||
/** Any character (except control, unless escaped) */
|
||||
const int WCM_TOKEN_CHAR = 0;
|
||||
|
||||
/** Token for end of set: ] */
|
||||
const int WCM_TOKEN_END = 1;
|
||||
|
||||
/** Token for negation: */
|
||||
const int WCM_TOKEN_NOT = 2;
|
||||
|
||||
/** Token for range specification: - */
|
||||
const int WCM_TOKEN_MINUS = 3;
|
||||
|
||||
/**
|
||||
* Transition table holds the nextState used in set parsing. Rows define
|
||||
* states, columns define tokens. transitions[1][3] = 5 means: if in state
|
||||
* 1 next token is 3, goto state 5
|
||||
*/
|
||||
const int TRANSITIONS[][4] = { { 1, WCM_FINAL, 3, 4 }, { 1, WCM_FINAL,
|
||||
WCM_ERROR, 5 }, { WCM_ERROR, WCM_ERROR, WCM_ERROR, WCM_ERROR },
|
||||
{ 1, WCM_FINAL, WCM_ERROR, 4 }, { 6, WCM_ERROR, WCM_ERROR,
|
||||
WCM_ERROR }, { 6, WCM_FINAL, WCM_ERROR, WCM_ERROR }, {
|
||||
1, WCM_FINAL, WCM_ERROR, WCM_ERROR } };
|
||||
|
||||
int getToken(const char ch) {
|
||||
switch(ch) {
|
||||
case ']':
|
||||
return WCM_TOKEN_END;
|
||||
case '!':
|
||||
return WCM_TOKEN_NOT;
|
||||
case '-':
|
||||
return WCM_TOKEN_MINUS;
|
||||
default:
|
||||
return WCM_TOKEN_CHAR;
|
||||
}
|
||||
}
|
||||
|
||||
bool testSet(const String pattern, int offset, const char ch) {
|
||||
int n = pattern.length();
|
||||
|
||||
int state = WCM_INITIAL;
|
||||
int nextToken = ' ';
|
||||
char nextChar = ' ';
|
||||
char ch1 = ' ';
|
||||
|
||||
bool found = false;
|
||||
|
||||
bool negate = false;
|
||||
|
||||
while(!found) {
|
||||
// Check for offset in case of final state, which is over the limit,
|
||||
// if ] is at the end of the string.
|
||||
if(offset<n) {
|
||||
nextChar = pattern.at(offset);
|
||||
|
||||
if(nextChar=='\\') {
|
||||
// Any escaped sequence is two characters, otherwise error will
|
||||
// be throws, since this is an invalid sequence anyway
|
||||
nextChar = pattern.at(offset+1);
|
||||
nextToken = WCM_TOKEN_CHAR;
|
||||
offset++;
|
||||
}
|
||||
else {
|
||||
nextToken = getToken(nextChar);
|
||||
}
|
||||
}
|
||||
|
||||
switch(state) {
|
||||
case WCM_INITIAL:
|
||||
if(nextToken==WCM_TOKEN_NOT) {
|
||||
negate = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// No break, states 0, 1, 3, 6 have same next condition.
|
||||
case 1:
|
||||
if(nextToken==WCM_TOKEN_END) return found^negate;
|
||||
case 3:
|
||||
case 6:
|
||||
if(nextToken==WCM_TOKEN_CHAR) {
|
||||
found = (ch==nextChar);
|
||||
ch1 = nextChar;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
// condition [-a...
|
||||
found = (ch<=nextChar);
|
||||
break;
|
||||
case 5:
|
||||
if(nextToken==WCM_TOKEN_CHAR) found = ((ch>=ch1)&&(ch
|
||||
<=nextChar)); // condition ...a-z...
|
||||
if(nextToken==WCM_TOKEN_END) found = (ch>=ch1); // condition ...a-]
|
||||
break;
|
||||
}
|
||||
|
||||
if(WCM_DEBUG) {
|
||||
cout<<"( "<<state<<" -> "<<TRANSITIONS[state][nextToken]
|
||||
<<" ) token = "<<nextToken<<" char = "<<nextChar
|
||||
<<", found = "<<found<<", negate = "<<negate;
|
||||
}
|
||||
|
||||
// Lookup next state in transition table and check for valid pattern
|
||||
state = TRANSITIONS[state][nextToken];
|
||||
|
||||
if(state==WCM_ERROR) return false;
|
||||
// don't bother, this is a no match anyway
|
||||
// throw new RuntimeException("Invalid pattern");
|
||||
|
||||
if(state==WCM_FINAL) return found^negate;
|
||||
|
||||
offset++;
|
||||
}
|
||||
|
||||
return found^negate;
|
||||
}
|
||||
|
||||
bool parse(const String pattern, const int ofp, const String str,
|
||||
const int ofs) {
|
||||
int lp = pattern.length();
|
||||
int ls = str.length();
|
||||
|
||||
int ip = ofp; // index into pattern string
|
||||
|
||||
int is = ofs; // index into test string
|
||||
|
||||
char chp, chs;
|
||||
|
||||
if(WCM_DEBUG) {
|
||||
if((ip>-1)&&(is>-1)&&(ip<lp)&&(is<ls)) {
|
||||
cout<<"parse: "<<pattern.substr(ip)<<" "<<str.substr(is);
|
||||
}
|
||||
}
|
||||
|
||||
// Match happens only, if we parse both strings exactly to the end
|
||||
while(ip<lp) {
|
||||
chp = pattern.at(ip);
|
||||
|
||||
if(WCM_DEBUG) {
|
||||
if((ip>-1)&&(is>-1)&&(ip<lp)&&(is<ls)) {
|
||||
cout<<pattern.substr(ip)<<" "<<str.substr(is);
|
||||
}
|
||||
}
|
||||
|
||||
switch(chp) {
|
||||
case '[':
|
||||
// Each set must be close with a ], otherwise it is invalid.
|
||||
int end = pattern.find(']', ip);
|
||||
|
||||
if(end==-1) return false;
|
||||
|
||||
// Is this set followed by a *
|
||||
bool isWildchar = ((end+1)<lp)&&(pattern.at(end+1)=='*');
|
||||
|
||||
if(is<ls)
|
||||
chs = str.at(is);
|
||||
else
|
||||
return parse(pattern, end+2, str, is);
|
||||
|
||||
// Does this character match
|
||||
bool thisChar = testSet(pattern, ip+1, chs);
|
||||
|
||||
// Check for single character match only if there is no
|
||||
// * at the end.
|
||||
if(!thisChar&&!isWildchar) return false; // Return only if this character does not match
|
||||
|
||||
if(isWildchar) {
|
||||
// If this character does not match, maybe this set
|
||||
// can be skipped entirely
|
||||
if(!thisChar) {
|
||||
ip = end+2;
|
||||
break;
|
||||
}
|
||||
|
||||
// Special case when this character matches, although
|
||||
// it should not: a[a-z]*z == az
|
||||
if(parse(pattern, end+2, str, is)) return true;
|
||||
|
||||
// Try to match next character
|
||||
if(parse(pattern, ip, str, is+1)) return true;
|
||||
}
|
||||
|
||||
// Single character matched, set was processed, since
|
||||
// no * was at the end.
|
||||
ip = end+1;
|
||||
is++;
|
||||
break;
|
||||
case '?':
|
||||
// Obvious
|
||||
ip++;
|
||||
is++;
|
||||
break;
|
||||
case '*':
|
||||
// Trailing asterisk means that string matches till the end.
|
||||
// Also, checks if this is last char in the string
|
||||
if(ip+1==lp) return true;
|
||||
|
||||
// Skip the *
|
||||
do {
|
||||
ip++;
|
||||
chp = pattern.at(ip);
|
||||
} while((ip+1<lp)&&(chp=='*'));
|
||||
|
||||
// But perform a special check and solve it by recursing
|
||||
// from new position
|
||||
if(chp=='?'&&parse(pattern, ip, str, is)) return true;
|
||||
|
||||
// Iterate through all possible matches in the test string
|
||||
int i = is;
|
||||
|
||||
while(i<ls) {
|
||||
// Stupid brute force, but isn't as bad as it seems.
|
||||
// Try all possible matches in the test string.
|
||||
if(parse(pattern, ip, str, i)) return true;
|
||||
|
||||
i++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Literal match
|
||||
if(is==ls||pattern.at(ip)!=str.at(is)) return false;
|
||||
|
||||
ip++;
|
||||
is++;
|
||||
}
|
||||
}
|
||||
|
||||
// There could be several * at the end of the pattern, although the
|
||||
// test string is at the end.
|
||||
while((ip<lp)&&((pattern.at(ip))=='*'))
|
||||
ip++;
|
||||
|
||||
// Same condition as with while loop
|
||||
return (is==ls)&&(ip==lp);
|
||||
}
|
||||
|
||||
bool match(const String pattern, const String str) {
|
||||
return parse(pattern, 0, str, 0);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
64
pvAccessApp/utils/wildcharMatcher.h
Normal file
64
pvAccessApp/utils/wildcharMatcher.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* wildcharMatcher.h
|
||||
*
|
||||
* Created on: Nov 4, 2010
|
||||
* Author: Miha Vitorovic
|
||||
*/
|
||||
|
||||
#ifndef WILDCHARMATCHER_H_
|
||||
#define WILDCHARMATCHER_H_
|
||||
|
||||
#include <pvType.h>
|
||||
|
||||
using epics::pvData::String;
|
||||
|
||||
namespace epics {
|
||||
namespace pvAccess {
|
||||
|
||||
/**
|
||||
* DFA for parsing set strings. DFA was obtained from JFlex using the rule
|
||||
* : macro: CHAR = [^-\]\!] (everything except ], ! and - rule :
|
||||
* [!]?(-{CHAR})?(({CHAR}-{CHAR})|({CHAR}))({CHAR}-)?\] Result of
|
||||
* optimized NDFA is Character classes: class 0: [0-'
|
||||
* ']['"'-',']['.'-'\']['^'-65535] class 1: [']'] class 2: ['!'] class
|
||||
* 3: ['-'] Transition graph (for class goto state) State 0: 0 -> 1, 1 ->
|
||||
* 2, 2 -> 3, 3 -> 4 State 1: 0 -> 1, 1 -> 2, 3 -> 5 State [FINAL] State
|
||||
* 3: 0 -> 1, 1 -> 2, 3 -> 4 State 4: 0 -> 6 State 5: 0 -> 6, 1 -> 2 State
|
||||
* 6: 0 -> 1, 1 -> 2
|
||||
*
|
||||
* @param pattern DOCUMENT ME!
|
||||
* @param offset DOCUMENT ME!
|
||||
* @param ch DOCUMENT ME!
|
||||
*
|
||||
* @return DOCUMENT ME!
|
||||
*/
|
||||
bool testSet(const String pattern, int offset, const char ch);
|
||||
|
||||
/**
|
||||
* Recursive method for parsing the string. To avoid copying the strings,
|
||||
* the method accepts offset indices into both parameters.
|
||||
*
|
||||
* @param pattern Pattern used in parsing
|
||||
* @param ofp Offset into pattern string (ofp > 0)
|
||||
* @param str String to test
|
||||
* @param ofs Offset into test string (ofs > 0);
|
||||
*
|
||||
* @return boolean Do the strings match
|
||||
*/
|
||||
bool parse(const String pattern, const int ofp, const String str,
|
||||
const int ofs);
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*
|
||||
* @param pattern DOCUMENT ME!
|
||||
* @param str DOCUMENT ME!
|
||||
*
|
||||
* @return DOCUMENT ME!
|
||||
*/
|
||||
bool match(const String pattern, const String str);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* WILDCHARMATCHER_H_ */
|
Reference in New Issue
Block a user